Skip to content

fix: use dummy thought_signature for cross-model Gemini function calls#2155

Merged
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/i-ve-set-a-model-on-a-tool-to-google-gem-a37899ae
Mar 18, 2026
Merged

fix: use dummy thought_signature for cross-model Gemini function calls#2155
dgageot merged 1 commit intodocker:mainfrom
dgageot:board/i-ve-set-a-model-on-a-tool-to-google-gem-a37899ae

Conversation

@dgageot
Copy link
Member

@dgageot dgageot commented Mar 18, 2026

Problem

When a tool has a per-tool model override set to a Gemini 3+ model (e.g. google/gemini-3.1-flash-lite-preview) while the main agent uses a different provider (e.g. Anthropic Haiku), the Gemini API returns a 400 INVALID_ARGUMENT error:

Function call is missing a thought_signature in functionCall parts.

This happens because the main model generates assistant messages with tool calls that have no ThoughtSignature (a Gemini-specific concept). When the conversation history is replayed to Gemini during per-tool model routing, it rejects the function call parts.

Fix

Use the Google-documented sentinel value "skip_thought_signature_validator" as a fallback when the original message has no ThoughtSignature. This tells the Gemini API to skip signature validation for replayed history.

See: https://ai.google.dev/gemini-api/docs/thought-signatures

Changes

  • pkg/model/provider/gemini/client.go: Added thoughtSignatureOrDefault() helper that returns the real signature when present, or the skip sentinel otherwise. Applied in the tool-call conversion path.
  • pkg/model/provider/gemini/client_test.go: Added table-driven tests covering: real signature preserved, nil signature fallback, empty (non-nil) signature fallback, and multiple tool calls with text.

@dgageot dgageot requested a review from a team as a code owner March 18, 2026 09:26
Copy link

@docker-agent docker-agent bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment: 🟢 APPROVE

No issues found. The implementation correctly:

  • Uses len(sig) > 0 to handle both nil and empty byte slices
  • Applies the thought signature consistently to all parts (text and function calls)
  • Includes comprehensive test coverage for all edge cases
  • Follows the Google-documented approach for cross-model function call replay

The fix properly addresses the INVALID_ARGUMENT error when replaying non-Gemini tool calls to Gemini models.

Gemini 3+ models require a thought_signature on functionCall parts. When
conversation history is generated by a non-Gemini model (e.g. Anthropic
during per-tool model routing), no signature exists, causing a 400
INVALID_ARGUMENT error.

Use the Google-documented sentinel value "skip_thought_signature_validator"
as a fallback when the original message has no ThoughtSignature.

Assisted-By: docker-agent
@dgageot dgageot force-pushed the board/i-ve-set-a-model-on-a-tool-to-google-gem-a37899ae branch from 8f7c1fd to 2b65d28 Compare March 18, 2026 09:31
@dgageot dgageot merged commit f81fb4f into docker:main Mar 18, 2026
4 checks passed
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.

2 participants