fix(decopilot): decode Gemini thought signatures out of tool-call ids#4005
Merged
Conversation
OpenAI-format gateways (LiteLLM et al.) fronting Gemini-thinking pack the
model's thoughtSignature into the tool-call id (`call_<base>__thought__<sig>`),
bloating it to multiple KB. That overflowed a Postgres btree key and broke the
chat UI's tool-call id matching ("No tool invocation found for tool call ID …").
A new language-model middleware strips the signature into
providerMetadata.google.thoughtSignature on the way in (matching the native
Google provider) and re-embeds it on the way out, gated to OpenAI-format
gateways (openai-compatible/openrouter/deco). Ids now reach storage and the UI
small, so this removes the #3973 storageKey sha256 hashing and hardens
dropRedundantStubs to match a stub by its part's toolCallId.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve async-research-jobs.ts conflict: keep main's v2 thread_message_parts polling-stub migration, drop the storageKey/sha256 hashing (this branch strips oversized tool-call ids upstream via the thought-signature middleware). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
decocms Bot
pushed a commit
that referenced
this pull request
Jun 22, 2026
PR: #4005 fix(decopilot): decode Gemini thought signatures out of tool-call ids Bump type: patch - decocms (apps/mesh/package.json): 3.37.9 -> 3.37.10 - @decocms/harness (packages/harness/package.json): 1.6.6 -> 1.6.7 Deploy-Scope: both
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is this contribution about?
OpenAI-format gateways (LiteLLM et al.) fronting Gemini-thinking pack the model's
thoughtSignatureinto the tool-call id (call_<base>__thought__<sig>), bloating it to multiple KB — which overflowed a Postgres btree key and broke the chat UI's tool-call id matching ("No tool invocation found for tool call ID …"). A new portable language-model middleware (thought-signature.ts) strips the signature intoproviderMetadata.google.thoughtSignatureon the way in — the same shape the native Google provider already emits andconversation.tspreserves — and re-embeds it into the id on the way out, gated to OpenAI-format gateways (openai-compatible/openrouter/deco) and a strict no-op for any id without the separator. Because ids now reach storage and the UI small, this removes the #3973storageKeysha256 hashing fromasync-research-jobs.tsand hardensdropRedundantStubsto match a stub by its part'stoolCallIdrather than the message-id suffix.Screenshots/Demonstration
N/A — no UI changes (fixes an error toast; no visual surface added).
How to Test
web_searchflow through a Gemini-thinking model behind a LiteLLM (OpenAI-compatible) gateway, so the upstreamtool_call_idiscall_<base>__thought__<multi-KB-sig>.async_research_jobsinsert + stub message succeed (no Postgres54000btree error) and the chat no longer throws "No tool invocation found for tool call ID …" on completion/refresh.bun test packages/harness/src/decopilot/thought-signature.test.tsandbun test apps/mesh/src/web/components/chat/store/thread-connection.test.tspass;bun run checkis green.Migration Notes
None — no schema or config changes. Short ids were already stored verbatim; oversized ids are now prevented upstream rather than hashed, so no data migration is required.
Review Checklist
Summary by cubic
Decode Gemini thought signatures out of gateway tool-call IDs and store them in metadata to keep IDs small. This prevents Postgres index overflows and fixes chat tool-call matching.
packages/harness/src/decopilot/thought-signature.tsto stripcall_<base>__thought__<sig>intoproviderMetadata.google.thoughtSignatureon inbound and re-embed on outbound; enabled foropenai-compatible,openrouter, anddeco.storageKeykeying and its tests; persist/query by the realtool_call_id, keep main’s v2thread_message_partspolling-stub migration, and key async stub messages by the raw id.dropRedundantStubsnow matches by a part’stoolCallId(covers legacy hashed stub ids); added a targeted test.Written for commit 6372833. Summary will update on new commits.