Skip to content

feat(gemini): add thought signature persistence for conversation replay#13100

Merged
EurFelux merged 9 commits intomainfrom
feat/gemini-thought-signuature
Mar 7, 2026
Merged

feat(gemini): add thought signature persistence for conversation replay#13100
EurFelux merged 9 commits intomainfrom
feat/gemini-thought-signuature

Conversation

@EurFelux
Copy link
Copy Markdown
Collaborator

@EurFelux EurFelux commented Feb 27, 2026

What this PR does

Persist Gemini thoughtSignature to MessageBlock metadata.

Before this PR:

  • The thoughtSignature in AI SDK providerMetadata was discarded during chunk processing
  • Cannot persist thoughtSignature

After this PR:

  • Extract and preserve providerMetadata.google.thoughtSignature in AiSdkToChunkAdapter
  • Pass through chunk pipeline to textCallbacks
  • Store in MessageBlock.metadata
  • Restore from metadata and add to text part when building API requests

Fixes #13002

Why we need it and why it was done in this way

Main reason: Gemini models require thoughtSignature to be passed for better performance. Without persistence, users lose the performance benefits when:

  • Reloading sessions (cached responses cannot be reused)
  • Continuing conversations (need to re-compute thought signature)

The thought signature persistence enables leveraging caching for improved performance.

The following tradeoffs were made:

  • Currently using getMainTextContent which merges multiple MainTextBlocks into a single text part
  • Only takes the first MainTextBlock's thoughtSignature

The following alternatives were considered:

  • Not merging discrete MainTextBlocks: More accurate but requires more changes to preserve exact thoughtSignature mapping

Breaking changes

None.

Special notes for your reviewer

This PR modifies:

  • Chunk types to carry providerMetadata
  • Message streaming callbacks to collect thoughtSignature
  • Message persistence to store thoughtSignature in metadata
  • Message converter to add thoughtSignature to text parts when building API requests

Known limitation: In multi-turn tool calling scenarios, there can be multiple text blocks each with its own thoughtSignature. The current implementation simplifies this by merging MainTextBlocks via getMainTextContent, thus only preserving the first block's thoughtSignature.

Note: Although this PR also modifies Agent Messages related processing logic, the Gemini thought signature currently only works when using the Google API directly. The Agent functionality uses Messages API, so the thought signature does not apply to agent-related functionality at this stage.

Checklist

This checklist is not enforcing, but it's a reminder of items that could be relevant to every PR.
Approvers are expected to review this list.

Release note

feat(gemini): persist thoughtSignature to MessageBlock metadata - Stores Gemini thought signature from AI SDK providerMetadata into MessageBlock for better performance via caching

EurFelux and others added 3 commits February 27, 2026 18:22
Implement Gemini thought signature persistence to solve the following issues:
1. Lost reasoning_content when reloading sessions
2. Error "thinking is enabled but reasoning_content is missing" on resend
3. Inability to leverage caching for performance

Changes:
- Extend chunk types with providerMetadata field to pass thoughtSignature
- Extract thoughtSignature from AI SDK providerMetadata in AiSdkToChunkAdapter
- Collect and store thoughtSignature in MessageBlock metadata during streaming
- Persist thoughtSignature to message providerMetadata in AgentMessageDataSource
- Restore thoughtSignature from metadata in skipGeminiThoughtSignaturePlugin

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Extract thoughtSignature from MainTextBlock.metadata and add it to
text part's providerOptions.google.thoughtSignature when converting
messages to SDK format. This ensures the thought signature is
properly passed to the API when sending requests.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- Remove message.providerMetadata usage for restoring thoughtSignature
- Keep only OpenAI-compatible tool-call handling
- text/reasoning parts now handled by messageConverter

Co-Authored-By: Claude Opus 4.6 <[email protected]>
}

// 0.7 Skip Gemini3 thought signature
// 0.7 Skip Gemini3 thought signature for OpenAI-compatible API
Copy link
Copy Markdown
Collaborator

@DeJeune DeJeune Feb 27, 2026

Choose a reason for hiding this comment

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

Note

This issue/comment/review was translated by Claude.

Check openrouter


Original Content 看下openrouter

Copy link
Copy Markdown
Collaborator Author

@EurFelux EurFelux Feb 27, 2026

Choose a reason for hiding this comment

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

Note

This issue/comment/review was translated by Claude.

Tested, openrouter tool calls no longer require thought signature, no errors. It's likely the server has implemented skipping validation


Original Content

测过,openrouter工具调用现在不需要thought signature了,不会报错。估计是服务端做了跳过验证

@EurFelux
Copy link
Copy Markdown
Collaborator Author

Thanks for reviewing this PR! I wanted to clarify one point:

Although this PR also modifies Agent Messages related processing logic (AgentMessageDataSource.ts), the Gemini thought signature currently only works when using the Google API directly. The Agent functionality uses Messages API, so the thought signature should not work with agent-related functionality at this stage.

This is a known limitation - the persistence layer is in place, but the actual usage for Agent scenarios would require additional integration work in the future.

@EurFelux EurFelux changed the title feat(gemini): add thought signature persistence for session replay feat(gemini): add thought signature persistence for conversation replay Feb 27, 2026
@DeJeune DeJeune added this to the v1.7.22 milestone Feb 28, 2026
Copy link
Copy Markdown
Collaborator

@GeorgeDong32 GeorgeDong32 left a comment

Choose a reason for hiding this comment

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

Note

This review was translated by Claude.

📋 Code Review Report

✅ Overall Assessment: Approve to Merge

This is a high-quality PR with reasonable architectural design, clear code, implementing the Gemini thoughtSignature persistence feature.


🎯 Feature Analysis

The data flow design is reasonable:

AI SDK providerMetadata → Chunk → textCallbacks → MessageBlock.metadata → messageConverter → API Request

✅ Strengths

  1. Reasonable Architecture Design: Passes providerMetadata through existing chunk pipelines with minimal intrusion
  2. Clear Separation of Concerns: Data extraction, transmission, storage, and recovery are clearly divided
  3. Simplified skipGeminiThoughtSignaturePlugin: Removed duplicate text/reasoning processing logic
  4. All CI Passed: Basic guarantee of code quality

⚠️ Suggested Improvements (Non-blocking)

1. Type Safety Issue

File: src/renderer/src/services/StreamProcessingService.ts:86-92

Uses (data as any).providerMetadata instead of type-safe access. Suggest using type guards or safely accessing after checking chunk type:

case ChunkType.TEXT_DELTA: {
  const textChunk = data as TextDeltaChunk
  if (callbacks.onTextChunk) callbacks.onTextChunk(textChunk.text, textChunk.providerMetadata)
  break
}

2. Insufficient Test Coverage

File: src/renderer/src/aiCore/prepareParams/__tests__/message-converter.test.ts

The newly added findMainTextBlocks mock returns an empty array and does not test the thoughtSignature recovery logic. Suggest adding test cases.

3. Multiple Text Block Limitation (Already documented in PR description)

Multi-round tool calling scenarios may have multiple text blocks, and the current implementation only keeps the first thoughtSignature.


🔒 Security Review

  • ✅ No hardcoded sensitive information
  • ✅ No direct injection of user input
  • ✅ Data is only stored in local metadata

Overall Assessment: 🟢 Approved to Merge

Suggest supplementing test cases and optimizing type safety in subsequent iterations.

@EurFelux EurFelux merged commit b848580 into main Mar 7, 2026
7 checks passed
@EurFelux EurFelux deleted the feat/gemini-thought-signuature branch March 7, 2026 07:09
@kangfenmao kangfenmao mentioned this pull request Mar 13, 2026
6 tasks
kangfenmao added a commit that referenced this pull request Mar 13, 2026
### What this PR does

Before this PR:
- Version is 1.7.24

After this PR:
- Version is 1.7.25
- Release notes updated in `electron-builder.yml`

### Why we need it and why it was done in this way

Standard release workflow: collect commits since v1.7.24, generate
bilingual release notes, bump version.

The following tradeoffs were made:
N/A

The following alternatives were considered:
N/A

### Breaking changes

**Action Required**: The built-in filesystem MCP server now requires
manual approval for write/edit/delete operations by default.

### Special notes for your reviewer

**Included commits since v1.7.24:**

✨ New Features:
- feat(websearch): add Querit search provider (#13050)
- feat(minapp,provider): add MiniMax Agent, IMA mini apps and MiniMax
Global, Z.ai providers (#13099)
- feat(provider): add agent support filter for provider list (#11932)
- feat(agent): add custom environment variables to agent configuration
(#13357)
- feat: add GPT-5.4 support (#13293)
- feat(gemini): add thought signature persistence (#13100)

🐛 Bug Fixes:
- fix: secure built-in filesystem MCP root handling (#13294)
- fix: check underlying tool permissions for hub invoke/exec (#13282)
- fix: remove approval countdown timers and add system notifications
(#13281)
- fix: agent tool status not stopping on abort (#13111)
- fix: resolve spawn ENOENT on Windows for Code Tools (#13405)
- fix: Use default assistant for topic auto-renaming (#13387)
- fix(backup): defer auto backup during streaming response (#13307)
- fix(ui): fix Move To submenu overflow (#13399)
- fix: render xml fenced svg blocks as svg previews (#13431)
- fix: correct Gemini reasoning params (#13388)
- fix: improve Qwen 3.5 reasoning model detection (#13235)
- fix: upgrade xAI web search to Responses API (#12812)
- fix(api-server): relax chat completion validation (#13279)
- fix: install or uninstall button state issues (#13114)
- fix: improve update dialog behavior (#13363)
- fix: auto-convert reasoning_effort to reasoningEffort (#12831)

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: Write code that humans can understand and Keep it simple
- [x] Refactor: You have left the code cleaner than you found it (Boy
Scout Rule)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [x] Documentation: A user-guide update was considered and is present
(link) or not required.
- [x] Self-review: I have reviewed my own code before requesting review
from others

### Release note

```release-note
See release notes in electron-builder.yml
```

---------

Signed-off-by: kangfenmao <[email protected]>
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.

[Feature]: Persist Gemini thoughtSignature to MessageBlock metadata

3 participants