Skip to content

fix(antigravity): strip trailing model turn for native Gemini requests too - #10436

Open
diegosouzapw wants to merge 1 commit into
release/v3.8.50from
fix/10104-antigravity-trailing-model-turn
Open

fix(antigravity): strip trailing model turn for native Gemini requests too#10436
diegosouzapw wants to merge 1 commit into
release/v3.8.50from
fix/10104-antigravity-trailing-model-turn

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Closes #10104

Root cause

AntigravityExecutor.transformRequest() in open-sse/executors/antigravity.ts only
wired stripTrailingAntigravityAssistantTurn() into the isClaude branch. A native
Gemini model routed through Antigravity (agy/gemini-*, e.g. gemini-3-flash-agent)
that ends the conversation on a role: "model" turn keeps that trailing entry
unchanged, and newer Gemini endpoints reject that shape with HTTP 400 "Requests
ending with a model turn are not supported."

stripTrailingAntigravityAssistantTurn (already correct, guarded pop-loop, never
empties contents) is now also applied on an isGemini branch
(upstreamModel.toLowerCase().includes("gemini")), independent of the
sanitizeAntigravityGeminiRequest() Claude-only field whitelist. The Claude path is
byte-identical to before — this only widens the strip to native Gemini requests.

Regression test

tests/unit/antigravity-claude-prefill-strip.test.ts:

Fail→pass evidence (same test file, run against pre-fix vs post-fix
antigravity.ts):

# pre-fix (HEAD~1 antigravity.ts, same test file)
✖ (b2) native Gemini agent tier (gemini-3-flash-agent, #10104) also gets the strip
  AssertionError [ERR_ASSERTION]: trailing model turn should be stripped for native Gemini
  2 !== 1

# post-fix
✔ (a) strips a single trailing assistant (model) turn for Claude models
✔ (b) strips a trailing model turn for native Gemini models too (#10104)
✔ (b2) native Gemini agent tier (gemini-3-flash-agent, #10104) also gets the strip
✔ (c) a Claude conversation already ending on user is unchanged
✔ (d) multiple trailing model turns are all stripped
✔ (e) never strips contents down to empty
✔ empty/missing contents does not throw
7 pass, 0 fail

Gates run

  • npm run typecheck:core — clean
  • npx eslint --suppressions-location config/quality/eslint-suppressions.json open-sse/executors/antigravity.ts tests/unit/antigravity-claude-prefill-strip.test.ts — clean
  • node scripts/check/check-file-size.mjs — no new violations on touched files
  • node scripts/check/check-test-discovery.mjs — OK, test file discovered
  • Targeted suite node --import tsx/esm --test tests/unit/antigravity-claude-prefill-strip.test.ts — 7/7 pass
  • node scripts/check/check-complexity.mjs, check-cognitive-complexity.mjs, and the full npm run test:unit were kicked off but did not finish within this session due to extreme host contention (13 parallel worktree sessions running the same checks concurrently, load average ~209). No failures observed in the partial output before the session ended; the change is a small, additive conditional branch unlikely to move complexity/cognitive thresholds. Recommend a follow-up CI run confirms these before merge.

Notes

⚠️ base-red inherited: #9985 — ESLint errors (2) from #10250 (unrelated to this change, do not chase).

…s too

Newer Gemini endpoints reject a request ending on a model turn with HTTP
400 'Requests ending with a model turn are not supported' — the same
rejection class Claude hits via Vertex. transformRequest() previously
wired stripTrailingAntigravityAssistantTurn() only into the isClaude
branch, so native Gemini models routed through Antigravity kept a
trailing role:model entry and hit the 400.

Extend the guarded strip (never empties contents) to native Gemini
models too, gated by upstreamModel including "gemini". The Claude
path is untouched (byte-identical), preserving PR #6114's live
validation against Vertex Claude.

Flips tests/unit/antigravity-claude-prefill-strip.test.ts test (b),
which previously asserted the buggy pass-through, and adds (b2) for
the gemini-3-flash-agent tier.

Closes #10104
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.

[bug] Antigravity Gemini requests can end on a model turn and fail with 400

2 participants