Skip to content

Conversation

@TejasGhatte
Copy link
Collaborator

@TejasGhatte TejasGhatte commented Dec 28, 2025

Summary

Refactored how thought signatures are handled for Gemini tool calls by moving them from ExtraContent to the ReasoningDetails structure with proper ID linking.

Changes

  • Removed thought signatures from tool call's ExtraContent map
  • Added ID field to ChatReasoningDetails struct to link reasoning details to specific tool calls
  • Modified the conversion logic to look up thought signatures in reasoning details using the tool call ID
  • Enhanced the reasoning details creation to include tool call IDs when applicable
  • Implemented a consistent ID format (tool_call_<callID>) for linking tool calls with their reasoning details

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

Test Gemini provider with tool calls to ensure thought signatures are properly preserved:

# Core/Transports
go version
go test ./core/providers/gemini/...

Breaking changes

  • Yes
  • No

Security considerations

This change maintains the same security properties for thought signatures but reorganizes how they're stored and retrieved in the data structures.

Checklist

  • I added/updated tests where appropriate
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 28, 2025

📝 Walkthrough

Summary by CodeRabbit

  • Refactor
    • Restructured how reasoning details are managed and stored, moving thought signature data to a dedicated reasoning details structure with improved organization and identifier tracking.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

The pull request refactors the storage and retrieval of thought signatures in the Gemini provider. Instead of storing signatures in ExtraContent, they are now persisted in ReasoningDetails with encrypted values and optional identifiers. This change affects both the composition of reasoning details during chat processing and the extraction of signatures from received data.

Changes

Cohort / File(s) Summary
Gemini Provider Logic
core/providers/gemini/chat.go, core/providers/gemini/utils.go
Modified thought signature handling: removed ExtraContent-based storage in favor of ReasoningDetails array. Chat handler now constructs ChatReasoningDetails entries with encrypted signatures and optional tool_call IDs. Utils handler now scans ReasoningDetails for matching entries and base64-decodes signatures from there.
Schema Definitions
core/schemas/chatcompletions.go
Removed ExtraContent field from ChatAssistantMessageToolCall struct. Added optional ID field to ChatReasoningDetails struct to support identifier tracking.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Thought signatures hop to a new home,
From ExtraContent to ReasoningDetails they roam,
With IDs and encryption in array arrays,
The Gemini provider reshapes its ways,
Cleaner schemas, smarter storage—hooray!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main refactoring change: moving thought signature handling in Gemini chat completion tool calls from ExtraContent to ReasoningDetails.
Description check ✅ Passed The description follows the template structure with all major sections completed including Summary, Changes, Type of change, Affected areas, How to test, Breaking changes, Security considerations, and Checklist.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 12-28-fix_thought_signature_handling_in_gemini_chat_completion_tool_call

📜 Recent review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 842e03a and 784c4f9.

📒 Files selected for processing (3)
  • core/providers/gemini/chat.go
  • core/providers/gemini/utils.go
  • core/schemas/chatcompletions.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
🧠 Learnings (3)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
📚 Learning: 2025-12-17T08:44:08.788Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1114
File: core/schemas/chatcompletions.go:224-228
Timestamp: 2025-12-17T08:44:08.788Z
Learning: In core/schemas/chatcompletions.go, ensure the schema structures mirror OpenAI's API specifications exactly. Use the valid values for fields like ChatAudioParameters.Format and ChatAudioParameters.Voice as defined by OpenAI's documentation, and avoid adding additional inline documentation or constants to maintain direct compatibility with OpenAI's API.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2025-12-19T09:26:54.961Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/providers/utils/utils.go:1050-1051
Timestamp: 2025-12-19T09:26:54.961Z
Learning: Update streaming end-marker handling so HuggingFace is treated as a non-[DONE] provider for backends that do not emit a DONE marker (e.g., meta llama on novita). In core/providers/utils/utils.go, adjust ProviderSendsDoneMarker() (or related logic) to detect providers that may not emit DONE and avoid relying on DONE as the sole end signal. Add tests to cover both DONE-emitting and non-DONE backends, with clear documentation in code comments explaining the rationale and any fallback behavior.

Applied to files:

  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
🧬 Code graph analysis (3)
core/schemas/chatcompletions.go (2)
core/providers/gemini/types.go (1)
  • Type (783-783)
ui/lib/types/logs.ts (1)
  • Function (152-157)
core/providers/gemini/utils.go (3)
core/schemas/chatcompletions.go (2)
  • ChatAssistantMessage (658-665)
  • BifrostReasoningDetailsTypeEncrypted (758-758)
ui/lib/types/logs.ts (1)
  • ReasoningDetails (127-134)
core/providers/gemini/types.go (1)
  • Type (783-783)
core/providers/gemini/chat.go (3)
core/schemas/chatcompletions.go (2)
  • ChatReasoningDetails (763-771)
  • BifrostReasoningDetailsTypeEncrypted (758-758)
core/providers/gemini/types.go (2)
  • Type (783-783)
  • FunctionCall (1202-1212)
core/schemas/utils.go (1)
  • Ptr (16-18)
🔇 Additional comments (4)
core/schemas/chatcompletions.go (2)

719-724: LGTM!

The removal of ExtraContent from ChatAssistantMessageToolCall aligns with the refactor to store thought signatures in ReasoningDetails instead. The remaining fields are appropriate for tool call representation.


764-764: LGTM!

The new optional ID field on ChatReasoningDetails enables linking reasoning details to specific tool calls via the tool_call_<callID> format. This is a clean approach for correlating encrypted signatures with their corresponding function calls.

core/providers/gemini/utils.go (1)

611-626: LGTM!

The logic correctly retrieves thought signatures from ReasoningDetails using the tool_call_<callID> lookup pattern. The implementation properly validates the ID match, type, and signature presence before decoding. The early break after finding the match is an appropriate optimization.

core/providers/gemini/chat.go (1)

136-154: LGTM!

The non-streaming path correctly creates the reasoning detail with the encrypted signature and sets the ID field to tool_call_<callID> when a FunctionCall is present on the same part. This enables proper lookup in utils.go during message conversion.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@github-actions
Copy link
Contributor

🧪 Test Suite Available

This PR can be tested by a repository admin.

Run tests for PR #1181

@TejasGhatte TejasGhatte marked this pull request as ready for review December 28, 2025 15:53
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
core/providers/gemini/chat.go (1)

287-295: Bug: Streaming path missing ID assignment for tool call signatures.

The non-streaming path (lines 145-151) sets reasoningDetail.ID when part.FunctionCall is present, but the streaming path does not. This will cause the thought signature lookup in utils.go (line 613) to fail for streaming responses because it searches for tool_call_<callID>.

🔎 Proposed fix
 			// Handle thought signature separately (not part of the switch since it can co-exist with other types)
 			if part.ThoughtSignature != nil {
 				thoughtSig := base64.StdEncoding.EncodeToString(part.ThoughtSignature)
-				reasoningDetails = append(reasoningDetails, schemas.ChatReasoningDetails{
+				reasoningDetail := schemas.ChatReasoningDetails{
 					Index:     len(reasoningDetails),
 					Type:      schemas.BifrostReasoningDetailsTypeEncrypted,
 					Signature: &thoughtSig,
-				})
+				}
+
+				// Set ID if this is a tool call signature
+				if part.FunctionCall != nil {
+					callID := part.FunctionCall.Name
+					if part.FunctionCall.ID != "" {
+						callID = part.FunctionCall.ID
+					}
+					reasoningDetail.ID = schemas.Ptr(fmt.Sprintf("tool_call_%s", callID))
+				}
+
+				reasoningDetails = append(reasoningDetails, reasoningDetail)
 			}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 842e03a and 784c4f9.

📒 Files selected for processing (3)
  • core/providers/gemini/chat.go
  • core/providers/gemini/utils.go
  • core/schemas/chatcompletions.go
🧰 Additional context used
📓 Path-based instructions (1)
**

⚙️ CodeRabbit configuration file

always check the stack if there is one for the current PR. do not give localized reviews for the PR, always see all changes in the light of the whole stack of PRs (if there is a stack, if there is no stack you can continue to make localized suggestions/reviews)

Files:

  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
🧠 Learnings (3)
📚 Learning: 2025-12-09T17:07:42.007Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/schemas/account.go:9-18
Timestamp: 2025-12-09T17:07:42.007Z
Learning: In core/schemas/account.go, the HuggingFaceKeyConfig field within the Key struct is currently unused and reserved for future Hugging Face inference endpoint deployments. Do not flag this field as missing from OpenAPI documentation or require its presence in the API spec until the feature is actively implemented and used. When the feature is added, update the OpenAPI docs accordingly; otherwise, treat this field as non-breaking and not part of the current API surface.

Applied to files:

  • core/schemas/chatcompletions.go
  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
📚 Learning: 2025-12-17T08:44:08.788Z
Learnt from: Pratham-Mishra04
Repo: maximhq/bifrost PR: 1114
File: core/schemas/chatcompletions.go:224-228
Timestamp: 2025-12-17T08:44:08.788Z
Learning: In core/schemas/chatcompletions.go, ensure the schema structures mirror OpenAI's API specifications exactly. Use the valid values for fields like ChatAudioParameters.Format and ChatAudioParameters.Voice as defined by OpenAI's documentation, and avoid adding additional inline documentation or constants to maintain direct compatibility with OpenAI's API.

Applied to files:

  • core/schemas/chatcompletions.go
📚 Learning: 2025-12-19T09:26:54.961Z
Learnt from: qwerty-dvorak
Repo: maximhq/bifrost PR: 1006
File: core/providers/utils/utils.go:1050-1051
Timestamp: 2025-12-19T09:26:54.961Z
Learning: Update streaming end-marker handling so HuggingFace is treated as a non-[DONE] provider for backends that do not emit a DONE marker (e.g., meta llama on novita). In core/providers/utils/utils.go, adjust ProviderSendsDoneMarker() (or related logic) to detect providers that may not emit DONE and avoid relying on DONE as the sole end signal. Add tests to cover both DONE-emitting and non-DONE backends, with clear documentation in code comments explaining the rationale and any fallback behavior.

Applied to files:

  • core/providers/gemini/utils.go
  • core/providers/gemini/chat.go
🧬 Code graph analysis (3)
core/schemas/chatcompletions.go (2)
core/providers/gemini/types.go (1)
  • Type (783-783)
ui/lib/types/logs.ts (1)
  • Function (152-157)
core/providers/gemini/utils.go (3)
core/schemas/chatcompletions.go (2)
  • ChatAssistantMessage (658-665)
  • BifrostReasoningDetailsTypeEncrypted (758-758)
ui/lib/types/logs.ts (1)
  • ReasoningDetails (127-134)
core/providers/gemini/types.go (1)
  • Type (783-783)
core/providers/gemini/chat.go (3)
core/schemas/chatcompletions.go (2)
  • ChatReasoningDetails (763-771)
  • BifrostReasoningDetailsTypeEncrypted (758-758)
core/providers/gemini/types.go (2)
  • Type (783-783)
  • FunctionCall (1202-1212)
core/schemas/utils.go (1)
  • Ptr (16-18)
🔇 Additional comments (4)
core/schemas/chatcompletions.go (2)

719-724: LGTM!

The removal of ExtraContent from ChatAssistantMessageToolCall aligns with the refactor to store thought signatures in ReasoningDetails instead. The remaining fields are appropriate for tool call representation.


764-764: LGTM!

The new optional ID field on ChatReasoningDetails enables linking reasoning details to specific tool calls via the tool_call_<callID> format. This is a clean approach for correlating encrypted signatures with their corresponding function calls.

core/providers/gemini/utils.go (1)

611-626: LGTM!

The logic correctly retrieves thought signatures from ReasoningDetails using the tool_call_<callID> lookup pattern. The implementation properly validates the ID match, type, and signature presence before decoding. The early break after finding the match is an appropriate optimization.

core/providers/gemini/chat.go (1)

136-154: LGTM!

The non-streaming path correctly creates the reasoning detail with the encrypted signature and sets the ID field to tool_call_<callID> when a FunctionCall is present on the same part. This enables proper lookup in utils.go during message conversion.

Copy link
Contributor

akshaydeo commented Dec 29, 2025

Merge activity

  • Dec 29, 3:27 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Dec 29, 3:27 AM UTC: @akshaydeo merged this pull request with Graphite.

@akshaydeo akshaydeo merged commit 9fabe38 into main Dec 29, 2025
11 checks passed
@akshaydeo akshaydeo deleted the 12-28-fix_thought_signature_handling_in_gemini_chat_completion_tool_call branch December 29, 2025 03:27
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.

3 participants