Skip to content

feat(protocols): Antigravity direct lane for Messages, on by default - #7081

Merged
lidge-jun merged 5 commits into
devfrom
feat/antigravity-direct-messages
Oct 14, 2026
Merged

lidge-jun merged 5 commits into
devfrom
feat/antigravity-direct-messages

Conversation

@lidge-jun

@lidge-jun lidge-jun commented Oct 13, 2026 •

Copy link
Copy Markdown
Owner

Summary

Refs #7079. Follows #7080 (the Chat half, now on dev).

Messages to Antigravity skips the internal Responses body. Before this PR, a /v1/messages request to a single Google Antigravity route was translated to a Responses body and parsed again: messages -> responses-internal -> ir -> other. Now it goes messages -> ir -> other, and the answer goes other -> ir -> messages through the existing PF-09 Messages encoder.

The Messages ingress picks its route from the translated body's resolved model, so the lane has to be planned before translation:

  • anthropicSettingsTranslation builds the bridge body's settings with input: []. One shared applyAnthropicSettings builds both bodies, so the resolved model, the prompt-cache key (still hashed from system text plus translated tools in wire order), sampling, tool choice, format, include and reasoning match.
  • The route is previewed on that resolved model and judged by antigravityMessagesDeclineReason. Only then does messagesConversationToIr (src/protocols/codecs/messages-ir.ts) decode the conversation into the IR.
  • Routing runs on the settings body, with evidence equal to what the bridge body would give. If the settled route (after the wire override) is not the planned eligible route, leaveDirectPlan swaps in the full translation before any route-specific shaping. The core seam from feat(protocols): Antigravity direct lane for Chat (no internal Responses hop) #7080 (directRequest, leaveDirectLaneIfRerouted, restore and the ambiguous-reset judgment) covers later reroutes.
  • A settings error, or an undecodable ocxr1 envelope (which the bridge retries through nativeAnthropicProjection), yields no plan. Those requests translate and refuse exactly as before. Any other decode error carries the translator walk's own message.

Reproduced, not declined: blocked-skill elision, the stabilizePromptCache relocation and its trailing notice, tool_result errors, images, documents and tool_reference markers, thinking and redacted thinking (envelopes encoded and charged against the translator budget as the translator does, then decoded as the parser does), and the native reasoning replay map.

Declined, keeping the bridge with a named reason: hosted-tool (a web_search_* tool or a forced WebSearch choice), vision-preprocessing, bridge-only-policy (the shadow intercept on the resolved model, a skills catalog in system text, a generated-image link in assistant history, an observing cache recorder) and combo-or-policy-route.

Default flipped (owner request): protocols.rollout.antigravityDirect now defaults on for both the Chat and Messages lanes. An explicit false turns it off, and a non-boolean value or a malformed protocols block fails closed. Every declined request still falls back to the bridge per request. The docs, the CLI help text and the generated skills/ocx map say so.

Route map for Messages, eligible concrete Antigravity route:

Before After
request messages -> responses-internal -> ir -> other messages -> ir -> other
answer other -> ir -> responses-internal -> messages (other -> ir -> messages only with directEncoders) other -> ir -> messages

Residual gaps:

  • The Google adapter still sends no Claude thinking text to Antigravity on either lane, only call-bound thoughtSignatures. Changing that is an adapter change and out of scope.
  • Combos, policies and Messages combos stay on the bridge.
  • As in feat(protocols): Antigravity direct lane for Chat (no internal Responses hop) #7080, _rawBody readers that matter only to other wires see an empty conversation, which is why the lane is limited to this route.

Verification

This host does not run tests locally (owner rule for this machine), so hosted CI is the test evidence. Commands run locally:

  • bun x tsc --noEmit: pass
  • bun run structure:check: pass (protocol-paths.md sits exactly at its 600-line budget)
  • bun run privacy:scan: pass
  • bun run skill:surface:check: pass

New or changed tests, left to CI:

  • tests/responses/protocol-messages-ir-parity.test.ts: the direct parse equals parseRequest(anthropicToResponsesTranslation(body).body) over a corpus covering media, tool results, every envelope kind (sig, txt, red, nat for own and other model, krc), skill elision, cache stabilization, the tool catalog and settings. Refusals match message for message. It also checks that the settings body equals the bridge body without its conversation, that routing evidence matches, and that feature effects are unchanged.
  • tests/responses/protocol-antigravity-direct-messages.test.ts: end to end against a fake Cloud Code Assist upstream. Requires the same wire body and the same answer, stream and non-stream, and the messages -> ir -> other trace. Also covers a declined case and an identical refusal.
  • protocol-antigravity-direct-eligibility.test.ts: Messages rules plus the new default. protocol-settings.test.ts: the default and fail-closed cases. Both e2e tests now turn the switch off explicitly for their bridge side.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review rounds

  • Round 1 (gpt-6.1-sol, at f362309): one P2. A direct decode abandoned over an undecodable envelope kept its retained reasoning charges, so the bridge's projection retry could answer 413 where it used to answer 400. Fixed in 34e1283: the decode records its retained charges, and the plan releases them on that fallback and when the ingress leaves it. Regression tests are at the end of protocol-messages-ir-parity.test.ts.
  • Round 2 (at 34e1283): round 1 resolved. One more P2: leaveDirectPlan never released the settings-only body's request_copies charge. Fixed in the next commit, which also drops the stale replay map. That ingress path (a preview that is Antigravity but settles on another wire) has no dedicated test; the fix is a two-line release beside the existing charge.
  • Hosted CI at f362309: all four test shards and every other required Ubuntu check passed. Exact-head CI for the latest head is tracked on this PR.

…routes

The Messages ingress plans the Antigravity direct lane before translating:
the settings-only body carries the resolved model, prompt-cache key and
reasoning settings, the route is previewed on that model, and the
conversation is decoded into the IR (messages-ir.ts) only for an eligible
route. Routing then settles on the same body; if it moves, the full bridge
translation replaces it. Refs #7079.
protocols.rollout.antigravityDirect now defaults on for the Chat and
Messages ingresses. An explicit false turns it off; a non-boolean value or
a malformed protocols block fails closed. Requests the eligibility rule
declines keep the bridge as before.
@coderabbitai

coderabbitai Bot commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the enhancement New feature or request label Oct 13, 2026
A plan the ingress abandons (an undecodable envelope the bridge retries, or
a settled route that moved) released none of the reasoning copies its decode
retained, so the bridge translation that followed could answer 413 where the
bridge alone fits. The decode now records its retained charges and the plan
releases them when it is left.
…the plan

leaveDirectPlan charged the full translation without handing back the
retained charge for the settings-only body it replaced, so a route that
settled off the plan (a per-model wire override, say) could answer 413 where
the bridge alone fits. It also dropped the stale replay map.
@lidge-jun
lidge-jun marked this pull request as ready for review October 14, 2026 02:13
@lidge-jun
lidge-jun requested a review from Ingwannu as a code owner October 14, 2026 02:13
@lidge-jun

Copy link
Copy Markdown
Owner Author

Maintainer integration into dev (MAINTAINERS.md dev-only exception), on behalf of @lidge-jun as part of the 2026-10-13 release train. Exact-head verification: all required PR checks passed on 65b535f172eed76449f4ca7524eb00dd597be0ac; macOS/Windows legs skipped per CI policy and will be covered by the post-merge manual cross-platform dispatch on dev.

@lidge-jun
lidge-jun merged commit 04b7d51 into dev Oct 14, 2026
33 of 35 checks passed
@lidge-jun
lidge-jun deleted the feat/antigravity-direct-messages branch October 14, 2026 02:13
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T02:18:41.387299Z 65b535f Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 65b535f172

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +185 to +186
bridgeConversation: () => {
bridge ??= messagesToResponsesTranslation(body, cc, budget).body;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Transfer decode charges when materializing the bridge

For a reasoning-heavy Messages request, planMessagesAntigravityDirect has already charged every encoded reasoning envelope through the recording budget, but this lazy fallback translates the same envelopes again and charges them a second time without calling plan.releaseDecodeCharges(). If the core invokes bridgeConversation() after a reroute or while judging an ambiguous pre-header reset, a request that fit through the old bridge can therefore exceed the 32 MiB translator budget and fail instead of rerouting/retrying. Transfer or release the direct decode's retained charges when the bridge representation becomes the retained owner, and cover the lazy fallback path with a near-limit regression test.

AGENTS.md reference: src/AGENTS.md:L17-L17

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant