-
Notifications
You must be signed in to change notification settings - Fork 503
Feat/preserve thought signature for gemini3 #1227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Feat/preserve thought signature for gemini3 #1227
Conversation
- Add thoughtSignature field to ToolUse TypedDict as optional field - Add thoughtSignature to ContentBlockStartToolUse TypedDict - Preserve thoughtSignature during streaming event processing - Fixes compatibility with Gemini 3 Pro thinking mode This change enables proper multi-turn function calling with Gemini 3 Pro, which requires thought_signature to be passed back in subsequent requests. Resolves: Gemini 3 Pro 400 error for missing thought_signature See: https://ai.google.dev/gemini-api/docs/thought-signatures
- Capture thought_signature from Gemini function call responses - Base64 encode thought_signature for storage in message history - Decode and pass thought_signature back to Gemini in subsequent requests - Configure thinking_config to disable thinking text but preserve signatures - Add NotRequired import to content.py for type safety This complements the framework changes by implementing Gemini-specific handling of thought signatures for proper multi-turn function calling with Gemini 3 Pro. See: https://ai.google.dev/gemini-api/docs/thought-signatures
- Fix variable name conflict with thought_signature - Break long lines to comply with 120 character limit - Use explicit type annotations for thought signature variables
ed1837d to
a20b7ea
Compare
|
@dpolistwm I see that you have created two new test files. I dont recommend that, the tools test file already exists here and creating new test files for testing small logic is something the maintainers wouldn't like I think. Make sure you only add tests for the fix you are proposing. The best option I think here would be just waiting for a maintainer to see what approach they would take. Thanks. |
- Rename test_tools.py -> test_tool_use.py (tests ToolUse TypedDict) - Rename test_content.py -> test_content_block_start_tool_use.py (tests ContentBlockStartToolUse TypedDict) This makes the test file names more descriptive and avoids confusion with tests/strands/tools/test_tools.py
|
@dpolistwm , I meant the test file already exists for tools here https://github.com/strands-agents/sdk-python/blob/93997f0b947875a80e694b511711acce8f693704/tests/strands/tools/test_tools.py, so your tests would go there. But there shouldnt be a need to be creating new test files, since most of the test files already exist in strands. For the fix your proposing those tests are not needed at all since you only added a attribute to those files. Make sure you run |
- Removed test_content_block_start_tool_use.py (~96 lines) - Removed test_tool_use.py (~107 lines) These tests only verified basic Python dict behavior without testing any SDK logic. All meaningful coverage is maintained by integration tests in test_streaming.py which test actual thoughtSignature handling through the streaming pipeline.
|
Makes sense, @Ratish1 |
The test_handle_content_block_start_with_thought_signature() function was redundant because the parameterized test already covers the same functionality (line 127-130). This standalone test just repeated the same assertions without testing any additional edge cases or coverage. Removed ~23 lines of duplicate test code while maintaining full coverage.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Added two new tests to cover previously missing code paths:
1. test_stream_request_with_invalid_base64_thought_signature()
- Covers base64 decode error handling (lines 151-153)
- Verifies graceful degradation when thoughtSignature contains
invalid base64 data
- Tests error logging without crashing the request
2. test_stream_response_tool_use_with_string_thought_signature()
- Covers string-to-bytes conversion path (lines 308-309)
- Tests edge case where thought_signature is returned as string
instead of bytes from Gemini API
- Verifies proper UTF-8 encoding and base64 conversion
Coverage improvement: 3 previously uncovered code paths now tested.
|
The above commit enhances coverage of Gemini models, including lines that implement the new thoughtSignature preservation functionality |
|
Guys, do I need to do something else here? Let me know... |
Description
This PR adds support for preserving Gemini's
thoughtSignaturefield during function calling, which is required by Gemini 3 Pro for multi-turn conversations with tools.Problem
When using Gemini 3 Pro with function calling, the model returns a
thought_signaturefield that must be passed back in subsequent requests. Currently, Strands drops this field during streaming and message reconstruction, causing 400 errors:Unable to submit request because function call tool_name in the 2. content block is missing a thought_signature
This affects multi-turn conversations, nested agents, and any workflow requiring multiple function call exchanges with Gemini 3 Pro.
Solution
Framework Changes:
src/strands/types/tools.py: AddedthoughtSignature: NotRequired[str]toToolUseTypedDict (changed tototal=Falseto support optional field)src/strands/types/content.py: AddedthoughtSignature: NotRequired[str]toContentBlockStartToolUseTypedDict and addedNotRequiredimportsrc/strands/event_loop/streaming.py: PreservethoughtSignaturewhen processing streaming chunks (2 locations: extracting from tool use data and passing through to ToolUse object creation)Gemini Provider Changes:
4.
src/strands/models/gemini.py:thought_signaturefrom Gemini function call responsesthinking_configto disable thinking text while preserving signaturesTechnical Details
The
thoughtSignatureis an encrypted token provided by Gemini that preserves the model's reasoning context. It's:NotRequired[str]) that doesn't affect other providersReference: Gemini Thought Signatures Documentation
Related Issues
None - this is a new feature to support Gemini 3 Pro's function calling requirements.
Documentation PR
N/A - No documentation changes needed (inline code comments added for clarity)
Type of Change
New feature
Testing
How have you tested the change?
Tested with:
gemini-3-pro-preview) with function callingResults:
thought_signatureVerified in consuming repositories:
Note on CI: There is 1 pre-existing mypy error in
src/strands/tools/tools.py:47(unused type: ignore comment) that is unrelated to these changes. All type checking passes for the files modified in this PR.hatch run prepareChecklist
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
Related Issues
Fixes #1199