- Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix GoogleModel thinking signature not stored on tool calls when streaming #3647
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
Fix GoogleModel thinking signature not stored on tool calls when streaming #3647
Conversation
| @jerry-heygen Do you have example code that is failing on Because this part is incorrect:
The logic here prefers reading pydantic-ai/pydantic_ai_slim/pydantic_ai/models/google.py Lines 793 to 803 in f2bb374
So it shouldn't be necessary for the signature to (also) be on As you can see in the PR diff, all of the I'd like to understand the specific scenario in which that wasn't happening, so we can fix it -- adding |
| Hi @DouweM , so what we have observed on the last release version (v1.26.0) was that the thought signature had been both missing from the We had to downgrade to v1.21.0 where the thought signature is preserved in the ThinkingPart and we have extensively tested that, the tool call quality is higher and more following to the previous thinking when either we use v1.21.0 or this modified branch as in this PR, compared to v1.26.0. |
| @jerry-heygen Thanks for the additional context. I think the bug I introduced in #3516 is that this logic passes pydantic-ai/pydantic_ai_slim/pydantic_ai/models/google.py Lines 734 to 743 in f2bb374
Which then passes it into pydantic-ai/pydantic_ai_slim/pydantic_ai/_parts_manager.py Lines 295 to 297 in f2bb374
pydantic-ai/pydantic_ai_slim/pydantic_ai/_parts_manager.py Lines 306 to 308 in f2bb374
But then the pydantic-ai/pydantic_ai_slim/pydantic_ai/messages.py Lines 1646 to 1655 in f2bb374
And here: pydantic-ai/pydantic_ai_slim/pydantic_ai/messages.py Lines 1690 to 1741 in f2bb374
Can you please look into fixing it at that level, instead of by restoring the |
| @DouweM sure, I've reverted previous changes and applied the correct fix. PTAL |
Summary
ThinkingPart.signaturewas never populated for Google model responses (introduced in Don't insert emptyThinkingPartwhenGoogleresponse ends in text withthought_signature#3516)thought_signatureto be sent back to maintain reasoning continuitythought_signatureon the part following the thinking content (e.g., TextPart or ToolCallPart), not on the ThinkingPart itselfThinkingPart.signatureProblem
After #3516,
ThinkingPart.signaturewas alwaysnull. The signature was being stored inprovider_detailson the TextPart/ToolCallPart, but never preserved on the ThinkingPart.This is critical because when sending message history back to Google,
_content_model_response()reads fromThinkingPart.signatureto include the signature on the next part. Without it, thinking context is lost in multi-turn conversations.Per Google's documentation:
Solution
Non-streaming path: Track
last_thinking_partand when a non-thinking part arrives withthought_signature, apply it back toThinkingPart.signature.Streaming path: When a non-thinking part with
thought_signaturearrives, emit ahandle_thinking_deltaevent with the signature to update the previous thinking part.Test plan
test_google_thought_signature_on_thinking_partverifies round-trip behaviorsignature=IsStr()on ThinkingParts