Skip to content

fix: pass tool result content through as string in OpenAI/Claude -> Gemini translation - #11624

Merged
diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.51from
Hsia97:fix/antigravity-tool-result-json-string
Aug 26, 2026
Merged

diegosouzapw merged 1 commit into
diegosouzapw:release/v3.8.51from
Hsia97:fix/antigravity-tool-result-json-string

Conversation

@Hsia97

@Hsia97 Hsia97 commented Aug 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Tool results that are themselves valid JSON (e.g. a WebFetch payload {"title": ..., "summary": ...}) were JSON.parse'd and nested into functionResponse.response.result as a structured object by both Gemini request translators. Antigravity rejects that shape with HTTP 400 "upstream error".

This change stops parsing tool result content entirely: the raw string is passed through unchanged as response.result, and plain-text results are no longer double-wrapped as { result: { result: ... } }.

  • open-sse/translator/request/openai-to-gemini.ts — drop the tryParseJSON dance on tool result content; emit response: { result: resp }.
  • open-sse/translator/request/claude-to-gemini.ts — same for tool_result content; remove the now-unused tryParseJSON import.
  • openai-to-gemini.ts keeps parsing function call arguments (fn.arguments) — that path is untouched.

Related Issues

  • No issue was filed for this regression; reported directly with a local reproduction.

Validation

Change type: other (request-translator conversion)

  • Change type: other (request-translator conversion)
  • Focused tests and category gates from the golden path — translator unit suites + new regression suite below
  • npm run lint — full lint runs in CI; the changed files are eslint-clean (--max-warnings 0, exit 0)
  • Reconciled with the current active release base: branch cut from release/v3.8.51 tip e0ea3f9; focused checks rerun after the change
  • Production-code changes include a new or updated automated test in this PR

Evidence — translator suites (includes the new regression tests):

ℹ tests 68
ℹ pass 68
ℹ fail 0
✔ OpenAI -> Gemini keeps a JSON-string tool result as a raw string
✔ OpenAI -> Gemini keeps a plain-text tool result as a raw string (no double wrap)
✔ OpenAI -> Antigravity keeps a JSON-string tool result as a raw string
✔ Claude -> Gemini keeps a JSON-string tool_result as a raw string
✔ Claude -> Gemini keeps a plain-text tool_result as a raw string (no double wrap)

Evidence — open-sse typecheck gate and test discovery (the local runner is Windows 24 where npx.cmd spawnSync is EINVAL — same class of issue the repo's Windows build scripts already accommodate — so tsc was invoked directly with identical flags and the same baseline diff):

LIVE-ERRORS=5
NO-REGRESSIONS (all live errors within frozen baseline)
[test-discovery] OK — 5182 arquivos de teste, 31 collectors, 13 órfão(s) congelado(s)

Tests Added Or Updated

  • tests/unit/translator-tool-result-json-passthrough.test.ts (new): JSON-string and plain-text tool results stay raw strings through OpenAI→Gemini, OpenAI→Antigravity (Cloud Code envelope) and Claude→Gemini request translation.
  • tests/unit/translator-openai-to-gemini.test.ts: 3 expectations updated to the new shape ({"temp":20} stays a string; "The answer is capybara-4729." is no longer double-wrapped; '{"ok":true}' stays a string).
  • tests/unit/translator-claude-to-gemini.test.ts: 1 expectation updated ("20C" is no longer double-wrapped).

Coverage Notes

  • The change is confined to open-sse/translator/request/ conversion. The two translator suites plus the new passthrough suite assert the exact emitted functionResponse.response shape on both the OpenAI and Claude input paths, including the Cloud Code envelope used for Antigravity.
  • The deleted parse branches were removed, not replaced — no coverage regression.
  • The emitted response: { result: <string> } shape is exactly what the response-direction translators already consume (gemini-to-openai-function-response.test.ts uses response: { result: "b done" }), so round-trips are consistent.

Reviewer Notes

…emini translation

Tool results that are themselves valid JSON (e.g. a WebFetch payload) were
JSON.parse'd and nested into functionResponse.response.result as an object,
which Antigravity rejects with HTTP 400 'upstream error'.

Stop parsing tool result content in openai-to-gemini.ts and
claude-to-gemini.ts: the raw string is now passed through unchanged as
response.result, and a plain-text result no longer gets double-wrapped as
{ result: { result: ... } }.
@Hsia97
Hsia97 requested a review from diegosouzapw as a code owner August 26, 2026 09:37
@diegosouzapw
diegosouzapw merged commit 0481f61 into diegosouzapw:release/v3.8.51 Aug 26, 2026
10 of 16 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…emini translation (diegosouzapw#11624)

Merged via /merge-batch (lote 2026-08-26 batch 2, v3.8.51). Boarded no worktree combinado junto com outras ~20 PRs; validação única: typecheck/complexity/cognitive-complexity/changelog-integrity verdes, file-size rebaseado onde necessário (crescimento legítimo), lint com os mesmos 228 achados pré-existentes confirmados via sonda contra o tip puro (não introduzidos por este lote), e 292 testes focados (unit) + 18 (vitest) passando. Obrigado pela contribuição.
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.

2 participants