spring-projects / spring-projects/spring-ai

Provide a built-in `ToolCallResultConverter` for plain text tool results

Open Beginner friendly
#6,849 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage
Dominant language
Java
Stars
9.5k
Forks
2.9k
Avg merge
1d 10h
Merged PRs (30d)
5

Description

Proposal

It would be useful for Spring AI to include a small built-in ToolCallResultConverter for tools that intentionally return plain text.
The converter could return String values as-is, while delegating non-String results to the existing DefaultToolCallResultConverter.

For example:

@Tool(resultConverter = TextToolCallResultConverter.class)
String readLog() {
	return "Log uploaded. Access it at /tmp/log.txt";
}

The model receives:

Log uploaded. Access it at /tmp/log.txt

not:

"Log uploaded. Access it at /tmp/log.txt"

Current Behavior

DefaultToolCallResultConverter uses Jackson to serialize tool results.
That is a sensible default for structured results such as objects, maps, lists, records, images, and null.
It also means that Java String results are returned as JSON string literals.

Users can already write their own converter, but the plain-text case seems common enough that it would be nice not to repeat that boilerplate in every application.
Many tool methods naturally return text: file paths, summaries, status messages, diagnostics, command output, or log excerpts.

Changing the default converter to return raw String values would be a breaking behavior change.
An opt-in converter would give users this behavior without changing existing applications.

Context

This is related to the tool result conversion behavior documented in api/tools.adoc.
The extension point already exists, so this is mostly about providing a reusable implementation with clear semantics.

A possible implementation would be:

public final class TextToolCallResultConverter implements ToolCallResultConverter {

	private static final ToolCallResultConverter DEFAULT_CONVERTER = new DefaultToolCallResultConverter();

	@Override
	public String convert(@Nullable Object result, @Nullable Type returnType) {
		if (result instanceof String text) {
			return text;
		}
		return DEFAULT_CONVERTER.convert(result, returnType);
	}

}

This preserves default behavior for non-text results, including void, null, maps, lists, records, and images.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with DefaultToolCallResultConverter and the ToolCallResultConverter extension point, then read the related documentation in api/tools.adoc. Add the opt-in converter so String results remain plain text while other values retain the default conversion behavior, and verify the documented cases including null, structured values, and images.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend-api-design
Issue type
Feature
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.