Repository navigation
[Provider] repair orphaned and missing tool results in the Google / Claude-on-Antigravity adapter #2199
Description
Client or integration
Claude Code / Claude-on-Antigravity through the OpenCodex Google adapter
Provider or upstream service
Google Gemini / Claude-on-Antigravity gateway
OpenCodex version
v2.28.0 (upstream base 5840591; local validation patch c0dcef24)
Endpoint or capability
Anthropic messages translated to Gemini functionCall / functionResponse tool turns
Current behaviour
The Google adapter can emit a model turn containing one or more tool calls followed by a user turn containing tool results. In interrupted histories, a tool call can have no corresponding result; in replayed or duplicated histories, a result can have no adjacent call. Gemini/Claude-on-Antigravity rejects the resulting wire shape with HTTP 400 errors such as Invalid functionResponse or an unpaired tool call.
The upstream already has analogous protections for other transports (for example the merged Responses/Cursor work in #1912, #1990 and #2038), but the Google adapter path did not have the same adjacency contract.
Expected behaviour
For every model turn with tool calls, the immediately following user turn should contain exactly one response for each call in call order. If history is interrupted, the adapter should emit an explicit synthetic response such as [missing tool_result for this tool_use in history]. If a tool result has no adjacent matching call, it should be preserved as plain text with an explicit marker instead of being emitted as an unpaired functionResponse.
The repair must cover parallel calls, preserve stable call ids, and leave image-bearing tool results representable without manufacturing an image result.
Minimal redacted request or reproduction
- Send an Anthropic/Claude messages history through the Google adapter.
- Include a model turn with tool_use(call_1) and omit its later tool_result (simulating an interrupted turn), or include a standalone tool_result(call_orphan).
- Target a Claude-on-Antigravity model.
- Observe the translated Gemini request and the provider response.
No credentials or account identifiers are required for the reproduction.
Actual response or error
The provider rejects the translated request with HTTP 400: Invalid functionResponse / unpaired tool call (exact wording varies by gateway build). The request cannot be resumed until the history is manually repaired.
Upstream documentation
Anthropic tool-use message contract: https://docs.anthropic.com/en/docs/build-with-claude/tool-use
Gemini function calling: https://ai.google.dev/gemini-api/docs/function-calling
Suggested mapping or implementation notes
The attached local validation patch groups consecutive tool results after each model tool-call batch, synthesizes missing results in call order, and degrades orphan results to text. The relevant implementation shape is in src/adapters/google.ts around the tool-adjacency handling and is covered by the local adapter tests for missing, orphaned, duplicate, parallel, and image-bearing results. This is intentionally a wire-repair boundary; it does not fabricate successful tool output.
Additional context and attachments
Local v2.28.0 validation: typecheck exit 0; migration-focused suite 593 pass / 0 fail. The local patch is byte-for-byte validated against the installed package. Related upstream fixes: #1912, #1990, #2038.
This request is scoped to the Google/Claude-on-Antigravity adapter; it does not ask to duplicate the already-landed fixes for those other transports.
Activity
lidge-jun commentedon Aug 20, 2026
리뷰 · 우선순위 67 / 80
실화임. 지금 Google 어댑터가 툴 결과를 인접 계약 없이 하나씩 user 턴으로 밀어 넣음.
src/adapters/google.ts에서 assistant 툴콜은 model 턴으로 묶고 (:197-235),toolResult는 바로{ functionResponse }user 턴을 따로 만듦 (:237-251). 콜이 끊기거나 결과가 고아면 Gemini/Claude-on-Antigravity가 400 냄.Anthropic 쪽은 이미 같은 구멍을 막았음.
src/adapters/anthropic.ts:740-778이 툴콜 다음에 연속 toolResult를 묶고, 없는 건[missing tool_result for this tool_use in history]로 채우고, 고아는 텍스트로 내림. #1912/#1990/#2038이 그 선임. Google만 빠져 있음.이미지 결과는 지금
functionResponse옆에inline_data를 붙임 (:238-250). 합성 결과는 텍스트만 만들고 이미지 결과를 지어내면 안 됨. 이슈가 그거 맞음. call id는callIds.lookup이 콜 쪽 allocate를 재사용하게 되어 있음. 고아 lookup은 undefined라 id 없이 functionResponse가 나감. 그게 400임.types.ts/config.ts 스플릿이랑 상관 없음. 닫을 중복도 아님. #2125/#2198은 thought_signature 키 매칭이고 이건 결과 인접 계약임. 섞지 말 것.
해결방안: anthropic 그룹핑을 google contents 빌더에 포팅함. 모델 툴콜 배치 다음에 결과를 콜 순서로 붙이고, 없으면 그 마커로 합성, 고아는 텍스트 마커. 성공 출력을 지어내지 말 것. 병렬/중복/이미지 테스트는 이슈에 적힌 대로 가져오면 됨.
이 댓글은 grok-bot이 작성했습니다
Ingwannu commentedon Aug 20, 2026
Confirmed against current
dev(f2ebd3067). This is a real Google adapter wire-shape gap:messagesToGeminiFormatcurrently serializes eachtoolResultindependently and does not close an assistant tool-call batch before the next non-result turn. That can produce both unansweredfunctionCallparts and standalonefunctionResponseparts.I am taking this as a focused adapter fix. The implementation will repair only the Google/Gemini wire boundary: collect the result batch adjacent to each assistant tool-call turn, emit one ordered response per call, synthesize an explicit unknown/missing result for unanswered calls, and degrade genuinely orphaned results to marked user text rather than inventing a successful call. Image-bearing results will retain their sibling
inline_dataparts. I will add wire-level regressions for normal, missing, orphaned, duplicate, parallel, barrier, and image-bearing histories before proposing the PR.Ingwannu commentedon Aug 20, 2026
Implemented in #2207 against the current
devhead.The fix keeps the repair at the Google adapter wire boundary: adjacent tool-result batches are grouped, results are emitted in call order, missing results receive the explicit history marker, orphaned/duplicate results degrade to marked text, and image siblings remain visible as
inline_data.Verification completed locally: focused Google/Antigravity suites 179/179, typecheck, privacy scan, isolated bridge 16/16, clean-env Codex shim 69/69, GUI-importing root tests, and a 393-page docs build. The PR is intentionally left for another maintainer's review and exact-head CI; I have not self-approved or merged it.
Ingwannu commentedon Aug 21, 2026
Completed and merged into dev via #2207 (merge commit afd24bc). The Google adapter now repairs tool-result adjacency at the wire boundary while preserving ordered results, explicit missing-result markers, orphan/duplicate degradation, and image siblings. Closing this as completed.