feat(gemini): add thought signature preservation for thinking models #1382
+121
−54
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem Statement
Issue #1199 - Gemini thinking models (like
gemini-3-pro-previewandgemini-3-flash-preview) requirethought_signatureto be preserved for function calls in multi-turn conversations. Without this, the API returns:Additionally, when no tools are provided, the implementation was sending empty tool arrays causing:
Solution
This PR implements proper thought signature preservation for Gemini thinking models:
thought_signaturefrom function calls during streaming and includes it when sending function calls back to the APIthought_signaturedata (instead of UTF-8 which fails on binary data)toolsparameter in the API request when there are actual tools to sendtoolUsewithoutthoughtSignatureto text representation to handle old session history gracefullyChanges Made
src/strands/models/gemini.py:base64import for proper binary data encoding_format_request_content_part()to:thoughtSignaturewhen sendingreasoningContentthoughtSignaturewhen sendingtoolUsewith signaturetoolUsewithoutthoughtSignatureto text representation_format_request_tools()to only create Tool objects whentool_specsare provided_format_request_config()to conditionally includetoolsonly when non-empty_format_chunk()to base64-encodethought_signaturewhen capturing from streaming responsestests/strands/models/test_gemini.py:test_stream_request_with_reasoningto use valid base64 signaturetest_stream_request_with_tool_useto includethoughtSignaturetest_stream_request_with_tool_use_no_thought_signaturefor backwards compatibilitytest_stream_request_with_gemini_toolsto expect correct tools formattest_stream_response_reasoningto expect base64-encoded signatureTesting
Alignment with Development Tenets
Breaking Changes
None - this is backwards compatible. Old sessions without
thoughtSignaturewill have tool calls converted to text representation, preserving conversation context.Closes #1199