Skip to content

feat(mitm): translate Antigravity cloudcode end-to-end (Gap B) - #4299

Merged
diegosouzapw merged 1 commit into
release/v3.8.30from
fix/mitm-agentbridge-cloudcode
Jun 19, 2026
Merged

diegosouzapw merged 1 commit into
release/v3.8.30from
fix/mitm-agentbridge-cloudcode

Conversation

@diegosouzapw

Copy link
Copy Markdown
Owner

Summary

Closes Gap B from the live MITM validation. The Antigravity IDE speaks cloudcode (the Gemini payload wrapped under request) and expects a cloudcode reply ({response:{candidates}}). The AgentBridge proxy forwarded that envelope verbatim to /v1/chat/completions (OpenAI) → 400 'messages', so the IDE could be decrypted/intercepted but never routed to a provider.

The fix wires the inbound cloudcode path, reusing the already-registered bidirectional translators — no new translators:

  • provider.ts: detectFormatFromEndpoint classifies the /antigravity path as sourceFormat="antigravity" (mirrors /messages → claude). The pipeline then translates request antigravity→openai and response openai→antigravity (clientResponseFormat = sourceFormat).
  • /v1/antigravity route (new): cloudcode-compatible endpoint — just calls handleChat (mirrors /v1/messages).
  • server.cjs: routes cloudcode envelopes → /v1/antigravity and plain OpenAI bodies → /v1/chat/completions, via a testable shim.

Validation

  • mitm-forward-target.test.ts — cloudcode envelope → /v1/antigravity, OpenAI → /chat/completions, non-envelope guard — 4
  • antigravity-format-detection.test.ts — /antigravity path → antigravity, no disturbance to /messages //responses//chat/completions — 2
  • Translators already covered: translator-antigravity-to-openai, translator-resp-openai-to-antigravity
  • typecheck:core clean, lint clean
  • Live (lab VPS): real Antigravity IDE → MITM → glm-5.2 → cloudcode reply rendered in the IDE — pending the standalone deploy (this PR's provider.ts + route compile into .next; only server.cjs/forwardTarget.cjs are hot-deployable). This is the Rule fix(ci): add environment for npm token access #18 fire-test for the full flow.

Stacking

Stacked on #4285 (Gap A) — server.cjs here builds on the intercept() rewrite from Gap A. Base will retarget to release/v3.8.30 once #4285 merges.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for the Antigravity/cloudcode-compatible inbound endpoint. It adds path-based format detection for 'antigravity', a new /v1/antigravity API route, and MITM proxy forwarding logic to route cloudcode envelopes to this endpoint. Unit tests are also added to verify format detection and forwarding target resolution. The review feedback suggests making the translator initialization synchronous to prevent potential race conditions under concurrent startup requests.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +9 to +15
async function ensureInitialized() {
if (!initialized) {
await initTranslators();
initialized = true;
console.log("[SSE] Translators initialized for /v1/antigravity");
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since initTranslators is a synchronous function, wrapping it in an async function and using await introduces an unnecessary asynchronous gap (microtask yield) before initialized = true is set. If multiple requests hit this endpoint concurrently at startup, they can all pass the if (!initialized) check and call initTranslators() multiple times. Removing async/await makes the initialization completely synchronous and race-condition free.

Suggested change
async function ensureInitialized() {
if (!initialized) {
await initTranslators();
initialized = true;
console.log("[SSE] Translators initialized for /v1/antigravity");
}
}
function ensureInitialized() {
if (!initialized) {
initTranslators();
initialized = true;
console.log("[SSE] Translators initialized for /v1/antigravity");
}
}

Comment on lines +44 to +47
export async function POST(request: Request): Promise<Response> {
await ensureInitialized();
return await handleChat(request);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Since ensureInitialized is now synchronous, we can remove the await keyword when calling it.

Suggested change
export async function POST(request: Request): Promise<Response> {
await ensureInitialized();
return await handleChat(request);
}
export async function POST(request: Request): Promise<Response> {
ensureInitialized();
return await handleChat(request);
}

The Antigravity IDE speaks cloudcode (the Gemini payload wrapped under
`request`) and expects a cloudcode reply ({response:{candidates}}). The
AgentBridge proxy forwarded that envelope verbatim to /v1/chat/completions
(OpenAI), which 400s on the missing `messages` field — so the IDE could be
decrypted/intercepted but never actually routed to a provider.

Wire the inbound cloudcode path, reusing the already-registered bidirectional
translators (no new translators needed):

- provider.ts: detectFormatFromEndpoint classifies the /antigravity path as
  sourceFormat "antigravity" (mirrors /messages -> claude), so the pipeline
  translates request antigravity->openai and response openai->antigravity.
- /v1/antigravity route (new): cloudcode-compatible endpoint — just calls
  handleChat (mirrors /v1/messages).
- server.cjs: routes cloudcode envelopes to /v1/antigravity (translates both
  ways) and plain OpenAI bodies to /v1/chat/completions, via a testable shim.

Tests: forward-target shim (cloudcode vs openai routing) + endpoint format
detection. The antigravity<->openai translators are already covered by
translator-antigravity-to-openai / translator-resp-openai-to-antigravity.

Stacked on #4285 (Gap A). Full Antigravity-IDE e2e validates on the next
standalone deploy (provider.ts + the route compile into .next).
@diegosouzapw
diegosouzapw force-pushed the fix/mitm-agentbridge-cloudcode branch from 2f9ff38 to 96a939e Compare June 19, 2026 21:00
@diegosouzapw
diegosouzapw changed the base branch from fix/mitm-agentbridge-antigravity to release/v3.8.30 June 19, 2026 21:00
@diegosouzapw
diegosouzapw merged commit 0ab1876 into release/v3.8.30 Jun 19, 2026
4 checks passed
@diegosouzapw
diegosouzapw deleted the fix/mitm-agentbridge-cloudcode branch June 21, 2026 12:33
tkgo11 pushed a commit to tkgo11/OmniRoute that referenced this pull request Sep 23, 2026
…souzapw#4299)

The Antigravity IDE speaks cloudcode (the Gemini payload wrapped under
`request`) and expects a cloudcode reply ({response:{candidates}}). The
AgentBridge proxy forwarded that envelope verbatim to /v1/chat/completions
(OpenAI), which 400s on the missing `messages` field — so the IDE could be
decrypted/intercepted but never actually routed to a provider.

Wire the inbound cloudcode path, reusing the already-registered bidirectional
translators (no new translators needed):

- provider.ts: detectFormatFromEndpoint classifies the /antigravity path as
  sourceFormat "antigravity" (mirrors /messages -> claude), so the pipeline
  translates request antigravity->openai and response openai->antigravity.
- /v1/antigravity route (new): cloudcode-compatible endpoint — just calls
  handleChat (mirrors /v1/messages).
- server.cjs: routes cloudcode envelopes to /v1/antigravity (translates both
  ways) and plain OpenAI bodies to /v1/chat/completions, via a testable shim.

Tests: forward-target shim (cloudcode vs openai routing) + endpoint format
detection. The antigravity<->openai translators are already covered by
translator-antigravity-to-openai / translator-resp-openai-to-antigravity.

Stacked on diegosouzapw#4285 (Gap A). Full Antigravity-IDE e2e validates on the next
standalone deploy (provider.ts + the route compile into .next).
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.

1 participant