Skip to content

Conversation

@Cozmopolit
Copy link
Contributor

Motivation and Context

Fixes #13417

Gemini 2.5/3 Pro with thinking enabled requires thoughtSignature tokens for function calling. Without this fix, function calling fails with HTTP 400:

Function call is missing a thought_signature in functionCall parts

This PR implements full ThoughtSignature support as specified in Google's Thought Signatures documentation.

Full Specification used for this Fix is attached.

Description

This PR adds thoughtSignature support to the Gemini connector:

Model Changes:

  • Add ThoughtSignature property to GeminiPart for JSON serialization
  • Add ThoughtSignature property to GeminiFunctionToolCall to carry signature through SK abstractions
  • Add ThoughtSignature property to GeminiMetadata for text response signatures
  • Add constructor overload to GeminiChatMessageContent accepting GeminiPart[] for signature capture

Response Processing:

  • Capture thoughtSignature from function call responses into GeminiFunctionToolCall
  • Capture thoughtSignature from text responses into GeminiMetadata

Request Building:

  • Restore thoughtSignature to function call parts when building requests from chat history
  • Restore thoughtSignature to text parts for model messages

Bug Fixes:

  • Fix empty ToolCalls list incorrectly treated as containing tools (streaming path)
  • Fix grammar: "an Gemini" → "a Gemini" in XML doc comment

Test Coverage:

  • 29 new unit tests covering serialization, capture, restore, and edge cases
  • All 376 tests pass

Contribution Checklist

semantic-kernel-gemini-connector-pr.md

… calling

Implements support for Gemini's thoughtSignature token which is required
when using function calling with thinking mode enabled (Gemini 2.5 Pro).

Changes:
- Add ThoughtSignature property to GeminiPart for JSON serialization
- Add ThoughtSignature property to GeminiFunctionToolCall (follows OpenAI Id pattern)
- Add constructor overload to GeminiChatMessageContent accepting GeminiPart[]
- Update response processing to capture ThoughtSignature from function calls
- Add ThoughtSignature to GeminiMetadata for text responses
- Include ThoughtSignature when building request parts for function calls
- Restore ThoughtSignature from Metadata for text response history
- Fix empty ToolCalls check in streaming path (is not null -> is { Count: > 0 })
- Fix grammar: 'an Gemini' -> 'a Gemini' in XML doc

Fixes microsoft#13417
Add comprehensive unit tests for ThoughtSignature functionality:
- GeminiPartTests: 8 tests for serialization/deserialization
- GeminiFunctionToolCallTests: 5 tests for ThoughtSignature capture
- GeminiRequestTests: 7 tests for request building with ThoughtSignature
- GeminiMetadataTests: 4 tests for ThoughtSignature property (new file)
- GeminiChatGenerationFunctionCallingTests: 3 tests for response processing
- GeminiChatStreamingFunctionCallingTests: 2 tests for empty ToolCalls handling

Add test data files:
- chat_function_with_thought_signature_response.json
- chat_text_with_thought_signature_response.json

Fix streaming auto-invoke loop:
- Reset LastMessage at start of each iteration to detect tool calls
- Exit loop when no tool calls found (prevents infinite loop)

All 376 tests pass.
@Cozmopolit Cozmopolit requested a review from a team as a code owner December 13, 2025 16:46
@moonbox3 moonbox3 added .NET Issue or Pull requests regarding .NET code kernel Issues or pull requests impacting the core kernel labels Dec 13, 2025
@github-actions github-actions bot changed the title Add ThoughtSignature support for Gemini function calling .Net: Add ThoughtSignature support for Gemini function calling Dec 13, 2025
@Cozmopolit
Copy link
Contributor Author

@microsoft-github-policy-service agree

@TommyAgami92
Copy link

Any forecast when this will be merged? we cannot use Gemini 3 flash with functions.

@roldengarm
Copy link
Contributor

@Cozmopolit have you tested this with Gemini 3 Flash?
I ran into the bug that functions were not called with Gemini 3; only with Gemini 2. I reproduced it with a console app, see here.
When I merge in this branch, the problem still exists, it doesn't call functions. I've let Claude fix it quickly, and it was related to thoughts.

See the fix here.

@TommyAgami92
Copy link

@roldengarm did it fix the issue? you were able to call functions with gemini 3 flash using this fix?

@roldengarm
Copy link
Contributor

@TommyAgami92 yes, with the fix I did, it works fine with function calling and thoughts enabled.

If you want to check out for yourself, see this branch and instructions to run here

It has all changes from @Cozmopolit from this branch as well, so I can't raise a PR (yet). But, at this stage I think this PR is not complete as it doesn't work for me with Gemini3 without my fixes.

@TommyAgami92
Copy link

@roldengarm thanks a lot , will check it out!

@Cozmopolit
Copy link
Contributor Author

@roldengarm

Will check out your branch and amend this PR tommorow. Thanks!

When thinking is enabled, Gemini 3 models may return function calls across
multiple streaming chunks, each with its own ThoughtSignature. The previous
implementation only processed the first chunk with tool calls, causing
subsequent function calls to be silently dropped.

Changes:
- Accumulate all tool calls from streaming chunks (preserving ThoughtSignature)
- Include pre-tool-call content in the combined message for chat history
- Accumulate ReasoningContent (Items) across chunks
- Use final chunk's metadata for accurate usage stats and finish reason
- Use lazy initialization to avoid overhead when AutoInvoke is disabled

Fixes function calling with Gemini 2.5 Flash/Pro when thinkingConfig is set.
@roldengarm
Copy link
Contributor

@Cozmopolit just checking if you had a chance to look into this? Please bear in mind my code change was quickly tested and I haven't added/updated automated tests, but I'm happy to add that if you confirm the change is OK.

@Cozmopolit
Copy link
Contributor Author

@roldengarm There is a PR to your branch&fork waiting for your comment.

@Cozmopolit
Copy link
Contributor Author

@roldengarm

While I try to get this right and we wait for MS to react here, you might want to consider:
https://github.com/Cozmopolit/SemanticKernel.Connectors.GeminiDotnet

@roldengarm
Copy link
Contributor

@roldengarm There is a PR to your branch&fork waiting for your comment.

Thanks @Cozmopolit , looks good, approved 👍

@roldengarm
Copy link
Contributor

@rogerbarreto as you reviewed my previous PR regarding Gemini & Thinking, would this also be a PR you could review please?
right now, function calling with Gemini 3+ doesn't work

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

Labels

kernel Issues or pull requests impacting the core kernel .NET Issue or Pull requests regarding .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.Net: Bug: Gemini function calling fails with HTTP 400 when thinking is enabled (missing thoughtSignature support)

5 participants