You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] Gemini/Antigravity tool call loses thoughtSignature during Codex continuation #1735
#430 - fix(google): never emit empty or malformed content parts (#420) [open] #1266 - fix(google): replay Vertex thought signatures [merged] #1411 - fix(command-code): pair tool results and synthesize missing-result errors [merged] #1434 - fix(google-antigravity): persist thought-signature replay across restarts [open] #1499 - fix(deepseek): keep parallel reasoning replay on continuation [open]
📝 Issue Planner
Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.
Create Plan
🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your .coderabbit.yaml:
issue_enrichment:
auto_enrich:
enabled: false
💬 Have feedback or questions? Drop into our discord!
Reproduced through a third-party OpenAI Responses client (Survey Workbench) against http://localhost:10100/v1/responses using google/gemini-3.6-flash and OpenCode @bitkyc08/opencodex 2.15.0 on macOS.
The client is stateless and correctly sends the full current tool turn as:
user message
assistant function_call
function_call_output
Observed behavior:
The first streamed Responses result contains a function_call, but its exposed keys are only arguments, call_id, id, name, status, and type. It has no extra_content, thought_signature, or thoughtSignature.
The next request fails upstream with Gemini 400: Function call is missing a thought_signature in functionCall parts (for default_api:articles_read).
Manually adding extra_content.google.thought_signature with Google's documented compatibility sentinel skip_thought_signature_validator still yields the same missing-signature 400, indicating the Responses gateway parser/adapter drops or does not replay this metadata before it reaches Gemini.
I also tested two consecutive requests with a stable x-codex-parent-thread-id; the first tool request succeeds (200) and the continuation still fails (400), so the gateway replay cache does not currently rescue this Responses flow.
Expected: /v1/responses should either expose and accept/replay function_call.extra_content.google.thought_signature losslessly, or have its internal Gemini replay cache inject the real signature for the continuation. Current external clients cannot preserve a signature they never receive.
No API keys, prompts, tool arguments, or tool output are included in this report.
Confirmed as a real Responses compatibility gap on current dev.
The Google adapter observes the upstream Gemini thoughtSignature and stores it in the internal Antigravity replay cache, but the outward bridge cannot expose it to a stateless Responses client: the shared tool_call_start event carries only id and name, the emitted function_call item has no extra_content, and the inbound Responses schema/parser likewise do not accept or restore extra_content.google.thought_signature into OcxToolCall.thoughtSignature.
That explains both reported observations: the first response gives the client no signature to retain, and a later stateless continuation cannot repair a field it never received. A stable thread/session may use the internal replay cache in some managed flows, but it is not a substitute for a lossless Responses wire contract.
The fix needs to be end-to-end rather than a parser-only patch:
carry a validated opaque signature from the Google adapter through the tool-call event;
emit it on the matching Responses function_call.extra_content.google.thought_signature;
accept the same field on inbound history and map it back to OcxToolCall.thoughtSignature;
preserve call order/id and keep the existing validation that refuses foreign item ids as signatures;
add stateless two-request and managed replay regressions.
I am keeping this issue open while that cross-layer contract is implemented and tested.
The signature now travels with the individual tool call at every hop — adapter event, Responses function_call item (extra_content.google.thought_signature), parser, and the rebuilt Google part — so a history-driven or previous_response_id turn keeps continuity without the same-process replay cache. That cache is why this looked intermittent: it covered streaming turns and nothing else.
Both synthetic loops (web search, images) now copy the metadata per call, so a batched or parallel response cannot share or swap a signature between calls. Values stay opaque — never parsed, merged, re-encoded, or synthesized — and are refused above the same 64 KiB ceiling the replay cache already enforces.
Verified on the remote validation host: 176 pass / 0 fail, 534 expect() calls across google-provider-metadata-roundtrip, google-signature-history-roundtrip, google-vertex-thought-signature, google-antigravity-wire, bridge, and web-search. The new cold-replay test warms no cache.
Two adjacent defects found during review are recorded in devlog/_plan/260815_roadmap_closeout/050_gemini_thought_signature.md rather than bundled in: Google-issued functionCall.id is still replaced by a synthetic call_* (the ids match each other, so pairing works), and the web-search loop interleaves parallel calls as FC1, FR1, FC2, FR2 where Google wants FC1, FC2, FR1, FR2.
Thanks @chilung-cgu — your #1772 identified the defect and is credited as co-author.
Activity
coderabbitai commentedon Aug 15, 2026
🔗 Related PRs
#430 - fix(google): never emit empty or malformed content parts (
#420) [open]#1266 - fix(google): replay Vertex thought signatures [merged]
#1411 - fix(command-code): pair tool results and synthesize missing-result errors [merged]
#1434 - fix(google-antigravity): persist thought-signature replay across restarts [open]
#1499 - fix(deepseek): keep parallel reasoning replay on continuation [open]
📝 Issue Planner
Check the box below or use the
@coderabbitai plancommand to generate an implementation plan and prompts that you can use with your favorite coding assistant.🧪 Issue enrichment is currently in open beta.
To disable automatic issue enrichment, add the following to your
.coderabbit.yaml:💬 Have feedback or questions? Drop into our discord!
github-actions commentedon Aug 15, 2026
Maintainer decision respected
A maintainer has reopened this issue. The automated closure has been deactivated.
fhh2626 commentedon Aug 15, 2026
AaronConlon commentedon Aug 15, 2026
Reproduced through a third-party OpenAI Responses client (Survey Workbench) against
http://localhost:10100/v1/responsesusinggoogle/gemini-3.6-flashand OpenCode@bitkyc08/opencodex2.15.0 on macOS.The client is stateless and correctly sends the full current tool turn as:
function_callfunction_call_outputObserved behavior:
function_call, but its exposed keys are onlyarguments,call_id,id,name,status, andtype. It has noextra_content,thought_signature, orthoughtSignature.Function call is missing a thought_signature in functionCall parts(fordefault_api:articles_read).extra_content.google.thought_signaturewith Google's documented compatibility sentinelskip_thought_signature_validatorstill yields the same missing-signature 400, indicating the Responses gateway parser/adapter drops or does not replay this metadata before it reaches Gemini.x-codex-parent-thread-id; the first tool request succeeds (200) and the continuation still fails (400), so the gateway replay cache does not currently rescue this Responses flow.Expected:
/v1/responsesshould either expose and accept/replayfunction_call.extra_content.google.thought_signaturelosslessly, or have its internal Gemini replay cache inject the real signature for the continuation. Current external clients cannot preserve a signature they never receive.No API keys, prompts, tool arguments, or tool output are included in this report.
Ingwannu commentedon Aug 15, 2026
Confirmed as a real Responses compatibility gap on current
dev.The Google adapter observes the upstream Gemini
thoughtSignatureand stores it in the internal Antigravity replay cache, but the outward bridge cannot expose it to a stateless Responses client: the sharedtool_call_startevent carries onlyidandname, the emittedfunction_callitem has noextra_content, and the inbound Responses schema/parser likewise do not accept or restoreextra_content.google.thought_signatureintoOcxToolCall.thoughtSignature.That explains both reported observations: the first response gives the client no signature to retain, and a later stateless continuation cannot repair a field it never received. A stable thread/session may use the internal replay cache in some managed flows, but it is not a substitute for a lossless Responses wire contract.
The fix needs to be end-to-end rather than a parser-only patch:
function_call.extra_content.google.thought_signature;OcxToolCall.thoughtSignature;I am keeping this issue open while that cross-layer contract is implemented and tested.
fix(google): carry Gemini thought signatures through the Responses ro…
fix(google): carry Gemini thought signatures through the Responses ro…
lidge-jun commentedon Aug 15, 2026
Fixed on
devas 4b95010 (PR #1781).The signature now travels with the individual tool call at every hop — adapter event, Responses
function_callitem (extra_content.google.thought_signature), parser, and the rebuilt Google part — so a history-driven orprevious_response_idturn keeps continuity without the same-process replay cache. That cache is why this looked intermittent: it covered streaming turns and nothing else.Both synthetic loops (web search, images) now copy the metadata per call, so a batched or parallel response cannot share or swap a signature between calls. Values stay opaque — never parsed, merged, re-encoded, or synthesized — and are refused above the same 64 KiB ceiling the replay cache already enforces.
Verified on the remote validation host: 176 pass / 0 fail, 534 expect() calls across
google-provider-metadata-roundtrip,google-signature-history-roundtrip,google-vertex-thought-signature,google-antigravity-wire,bridge, andweb-search. The new cold-replay test warms no cache.Two adjacent defects found during review are recorded in
devlog/_plan/260815_roadmap_closeout/050_gemini_thought_signature.mdrather than bundled in: Google-issuedfunctionCall.idis still replaced by a syntheticcall_*(the ids match each other, so pairing works), and the web-search loop interleaves parallel calls asFC1, FR1, FC2, FR2where Google wantsFC1, FC2, FR1, FR2.Thanks @chilung-cgu — your #1772 identified the defect and is credited as co-author.
fix(google): complete replay thought signature coverage for tool_sear…
fix(google): carry Gemini thought signatures through the Responses ro…
fix(google): complete replay thought signature coverage for tool_sear…