Skip to content

fix(antigravity): send complete loadCodeAssist metadata (ideType/platform/pluginType as numeric enums) - #11969

Merged
diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.51from
rifqiawl:fix/antigravity-loadcodeassist-metadata
Aug 30, 2026
Merged

diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.51from
rifqiawl:fix/antigravity-loadcodeassist-metadata

Conversation

@rifqiawl

Copy link
Copy Markdown
Contributor

Summary

loadCodeAssist and onboardUser both returned 403 for every account on a live
deployment, even accounts that had completed Gemini Code Assist onboarding.

Root cause

Traced via a live log side-by-side (same Google account, same host) against the
sibling 9router project, which succeeds against the identical account:

  • OmniRoute — getAntigravityLoadCodeAssistMetadata() sent
    { ideType: "ANTIGRAVITY" }: ideType as a bare string, platform and
    pluginType omitted entirely.
  • 9router — sends { ideType: 9, platform: <os/arch enum>, pluginType: 2 }.

The metadata body on this endpoint is protobuf-JSON-shaped: ideType/pluginType
are int32 enums on the wire, not strings, and platform is expected. An
incomplete/malformed client identity reads to Google's backend as untrusted and
gets rejected outright rather than degrading gracefully.

Fix

Mirror 9router's LOAD_CODE_ASSIST_METADATA enum values and platform-detection
logic (darwin/linux/win32 × x64/arm64) exactly:

const ANTIGRAVITY_IDE_TYPE_ENUM = 9;
const ANTIGRAVITY_PLUGIN_TYPE_GEMINI_ENUM = 2;
// DARWIN_AMD64:1, DARWIN_ARM64:2, LINUX_AMD64:3, LINUX_ARM64:4, WINDOWS_AMD64:5

A prior version of this function carried the opposite claim in a comment
("Matches Antigravity-Manager quota.rs: only ideType — no platform, LINUX is
rejected"). That may have been true when it was written; it directly
contradicts today's live comparison, where the full-enum shape (including a
Linux platform value) succeeded from a Linux host. Left a note pointing at
this history in the code in case it resurfaces — worth a second look if
anyone reports a regression specifically tied to Linux hosts.

Honest caveat

In the specific deployment where this was found, the actual 403 root cause
for that operator turned out to be unrelated: a custom
ANTIGRAVITY_OAUTH_CLIENT_ID override pointing at a GCP project without the
private Cloud Code API enabled (Google's OAuth-client-identity check fails
before the request body/metadata shape would ever matter). This metadata fix
did not resolve that particular deployment's error on its own. It's
included here anyway because it's a real, independently verified correctness
bug — confirmed by a byte-for-byte comparison against 9router's identical,
live-working request shape — that could still cause failures for any account
using OmniRoute's default embedded OAuth client (not a custom override).

Validation

  • Updated tests/unit/antigravity-headers.test.ts's metadata-shape assertion
    (previously asserted the broken string-only shape as correct) — 6/6 passing.
  • 54 usage-service + 25 oauth-provider tests whose assertions already compare
    live output against this function — all still passing (no hardcoded
    duplicate of the old shape anywhere else).
  • npx tsc --noEmit -p tsconfig.typecheck-core.json: 0 errors.

I could not re-validate this specific fix against a live Google account
myself (no credentials here) — the live comparison that surfaced the bug was
done via the operator's production deployment logs, documented above.

⚠️ base-red inherited: #11874

…form/pluginType as numeric enums)

loadCodeAssist and onboardUser both returned 403 for every account on a
live deployment, even accounts with completed Gemini Code Assist
onboarding. Traced via live log comparison (same Google account, same
host) against the sibling 9router project, which succeeds against the
identical account: OmniRoute's getAntigravityLoadCodeAssistMetadata()
sent `{ ideType: "ANTIGRAVITY" }` — ideType as a bare string, with
platform and pluginType omitted entirely. 9router sends
`{ ideType: 9, platform: <os/arch enum>, pluginType: 2 }` — the field is
a protobuf-JSON int32 enum on the wire, not a string, and the API
apparently treats an incomplete/malformed identity as untrusted and
rejects it outright rather than degrading gracefully.

Fix: mirror 9router's LOAD_CODE_ASSIST_METADATA enum values and
platform-detection logic (darwin/linux/win32 x64/arm64) exactly.

A prior version of this function carried the opposite claim in a
comment ("Matches Antigravity-Manager quota.rs: only ideType — no
platform, LINUX is rejected"). That may have been true when written;
it directly contradicts today's live comparison, where the full-enum
shape (including a Linux platform value) succeeded from a Linux host.
Left a note pointing at this history in case it resurfaces.

Updated tests/unit/antigravity-headers.test.ts's metadata-shape
assertion accordingly — it previously asserted the broken string-only
shape as correct.

Validation
- New/updated unit test in tests/unit/antigravity-headers.test.ts
  (6/6 passing) plus 54 usage-service + 25 oauth-provider tests whose
  assertions already compare against this function's own output —
  all passing.
- npx tsc --noEmit -p tsconfig.typecheck-core.json: 0 errors.

Note: in the specific deployment where this was found, the actual
403 root cause turned out to be a separate issue (a custom
ANTIGRAVITY_OAUTH_CLIENT_ID override pointing at a GCP project without
the private Cloud Code API enabled) — this metadata fix did not
resolve that deployment's error on its own, since Google's error
surfaces before the metadata shape would matter for a client-identity
rejection. It's included here because it's a real, independently
verified correctness bug (9router's identical live-working shape vs.
OmniRoute's incomplete one) that could still cause failures for
accounts using OmniRoute's default embedded OAuth client.
@rifqiawl
rifqiawl requested a review from diegosouzapw as a code owner August 29, 2026 03:28
@diegosouzapw
diegosouzapw merged commit 56dddfc into cheaper-inference:release/v3.8.51 Aug 30, 2026
14 of 15 checks passed
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…form/pluginType as numeric enums) (cheaper-inference#11969)

Envia metadata completo do loadCodeAssist (ideType/platform/pluginType como enums numéricos) para o Antigravity, com teste de regressão atualizado. Validado no worktree combinado. Obrigado!
Witroch4 pushed a commit to Witroch4/OmniRoute that referenced this pull request Oct 24, 2026
…the wire

agy/antigravity connections presented a fingerprint no official client uses:
`Antigravity/4.2.0 (X11; Linux x86_64) Chrome/142 Electron/39` (4.2.0 came from
a third-party tool, Antigravity-Manager; the IDE never shipped it) plus
x-client-name, x-client-version, x-machine-id and x-vscode-sessionid on every
content request.

Ground truth (2026-10-24): the official `agy` 1.4.7 was run behind a local TLS
capture proxy that answered every request itself, so nothing reached Google.
All six daily-cloudcode-pa v1internal calls observed carried exactly:

  User-Agent: antigravity/cli/1.4.7 (aidev_client; os_type=linux; arch=amd64; cl=1006008713; auth_method=consumer)
  Authorization, Content-Type: application/json, Accept-Encoding: gzip

with loadCodeAssist metadata {"ideType":"ANTIGRAVITY"}; its Go OAuth calls use
Go-http-client/1.1. Neither the CLI nor the installed IDE 2.5.5 (language
server binary and JS) contains x-client-name/x-machine-id/x-vscode-sessionid
or an Electron UA. Both binaries embed the OAuth client id these connections
use, so the CLI identity matches their tokens. Upstream's cheaper-inference#8013/cheaper-inference#11969/cheaper-inference#16559
format (darwin/arm64 pinned, no cl=, numeric loadCodeAssist enums) also differs
from the real client, so it is deliberately not ported.

Changes:
- open-sse/config/antigravityCliClient.ts (leaf): the CLI build (version +
  changelist pinned as a pair; ANTIGRAVITY_CLI_VERSION + ANTIGRAVITY_CLI_CHANGELIST
  override only together), real host os_type/arch, Cloud Code headers in wire
  order, OAuth token headers, loadCodeAssist metadata.
- Client profile "cli" (legacy stored "harness"/"sdk" read as cli) is now the
  default; "ide" stays as an opt-in legacy profile with its version floor fixed
  to the IDE's real ideVersion 2.5.5 (was 4.2.0).
- Every outbound path uses it: executor buildHeaders + per-attempt profile
  headers (rebuilt to exactly the CLI set), project bootstrap (no longer
  hard-defaults to "ide"; the executor passes the connection profile), token
  refresh (executor + shared refreshGoogleToken for agy/antigravity), OAuth code
  exchange + userinfo, model discovery, quota probes (loadCodeAssist now on the
  daily host the CLI uses, not the sandbox), image generation, registry headers.
- Docs/.env.example: new vars documented; ANTIGRAVITY_USER_AGENT marked as not
  applied by the Antigravity executor (the example had it active).

Known gaps (not header-level): undici fetch still adds accept-language and
sec-fetch-mode, and TLS/HTTP version (HTTP/1.1 vs the CLI's HTTP/2) differ.
The streamGenerateContent request itself was not captured (the CLI needs a
real model catalog to get there); it is inferred from the six uniform calls.

Tests: antigravity-cli-client (new) + 577 across 75 Antigravity/OAuth/usage/
discovery/image suites; translate-path golden regenerated (only the 6
Antigravity UA lines changed; os/arch normalized).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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