Skip to content

fix(google-genai): localize JSON wrapping of tool responses to Gemini…#1468

Draft
alexheifetz wants to merge 1 commit intomainfrom
fix/matryoshka-tool-json-response-gemini-with-strategy
Draft

fix(google-genai): localize JSON wrapping of tool responses to Gemini…#1468
alexheifetz wants to merge 1 commit intomainfrom
fix/matryoshka-tool-json-response-gemini-with-strategy

Conversation

@alexheifetz
Copy link
Contributor

This pull request introduces a provider-specific strategy for adapting tool response content before sending it to LLMs, addressing format requirements such as mandatory JSON for Google GenAI. The main change is the addition of a pluggable ToolResponseContentAdapter interface, allowing each LLM provider to specify how tool responses are formatted (e.g., plain text passthrough for OpenAI, JSON wrapping for Google GenAI). This refactoring keeps provider-specific logic out of the shared message conversion infrastructure and is thoroughly tested.

Provider-specific tool response adaptation

  • Added the ToolResponseContentAdapter interface and a default PASSTHROUGH implementation for providers that accept plain text, as well as a JsonWrappingToolResponseContentAdapter for providers like Google GenAI that require tool responses to be valid JSON objects.
  • Updated SpringAiLlmService and SpringAiLlmMessageSender to accept and use a configurable toolResponseContentAdapter, defaulting to PASSTHROUGH. This adapter is now used during message conversion for tool responses. [1] [2] [3] [4] [5] [6] [7]

Google GenAI integration

  • Updated Google GenAI model auto-configuration to supply the JsonWrappingToolResponseContentAdapter, ensuring all tool responses sent to Gemini are valid JSON and avoiding data loss or errors. [1] [2] [3]

Testing and validation

  • Added comprehensive unit tests for both adapters (PASSTHROUGH and JsonWrappingToolResponseContentAdapter) covering plain text, JSON, whitespace, and edge cases.
  • Extended message conversion and service tests to verify correct adapter application, defaulting, custom adapter usage, and preservation through object copying. [1] [2]

These changes ensure that tool responses are correctly formatted for each provider, improving reliability and maintainability of LLM integrations.

… provider

Google GenAI requires tool responses (FunctionResponse.response) to be
valid JSON objects. Plain text causes JsonParseException or silent data
loss resulting in hallucinations (#1391).

Introduce ToolResponseContentAdapter strategy interface — following the
same per-provider pattern as OptionsConverter — so each provider can
adapt tool response content at the Spring AI boundary:

- PASSTHROUGH (default): OpenAI, Anthropic, Bedrock — unchanged
- JsonWrappingToolResponseContentAdapter: Gemini — wraps non-JSON
  content as {"result": "..."}, passes JSON through

Threaded through SpringAiLlmService → SpringAiLlmMessageSender →
toSpringAiMessage(), wired in GoogleGenAiModelsConfig.

Fixes #1391
@sonarqubecloud
Copy link

sonarqubecloud bot commented Mar 4, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant