diff --git a/src/adapters/client-fingerprint.ts b/src/adapters/client-fingerprint.ts index ca090c5669..91a51ea39a 100644 --- a/src/adapters/client-fingerprint.ts +++ b/src/adapters/client-fingerprint.ts @@ -40,20 +40,24 @@ export function claudeCodeSessionId(token: string | undefined): string { return `${h.slice(0, 8)}-${h.slice(8, 12)}-4${h.slice(13, 16)}-${variant}${h.slice(17, 20)}-${h.slice(20, 32)}`; } -// ── Antigravity CLI ── -/** Pinned fallback Antigravity CLI version (real client fetches a manifest; we pin to avoid the network dependency). */ -export const ANTIGRAVITY_CLI_VERSION = "1.1.12"; -const ANTIGRAVITY_CLI_CLIENT_NAME = "aidev_client"; -const ANTIGRAVITY_CLI_PLATFORM = "darwin/arm64"; +// ── Antigravity IDE ── +/** Pinned fallback Antigravity IDE language-server version (matches the bundled LS 2.5.5). */ +export const ANTIGRAVITY_IDE_VERSION = "2.5.5"; +const ANTIGRAVITY_IDE_CLIENT_NAME = "aidev_client"; +const ANTIGRAVITY_IDE_PLATFORM = "windows/amd64"; /** Secondary Google API client UA the Antigravity client library reports. */ export const ANTIGRAVITY_GOOG_API_CLIENT_UA = "google-api-nodejs-client/10.3.0"; /** - * The real Antigravity CLI User-Agent, e.g. - * `antigravity/cli/1.1.12 (aidev_client; os_type=darwin; arch=arm64)`. + * The real Antigravity IDE User-Agent, e.g. + * `antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)`. + * + * Must be the IDE client family, NOT `antigravity/cli/...`: the Cloud Code Assist backend gates + * newer agent models (e.g. `gemini-3.7-flash`) by User-Agent and answers 404 NOT_FOUND to + * CLI-shaped UAs even with a valid OAuth token. Only `antigravity/ide/` unlocks them. * A `GOOGLE_ANTIGRAVITY_USER_AGENT` override (set by the caller) takes precedence upstream. */ -export function antigravityUserAgent(version = ANTIGRAVITY_CLI_VERSION): string { - const [osType, arch] = ANTIGRAVITY_CLI_PLATFORM.split("/"); - return `antigravity/cli/${version} (${ANTIGRAVITY_CLI_CLIENT_NAME}; os_type=${osType}; arch=${arch})`; +export function antigravityUserAgent(version = ANTIGRAVITY_IDE_VERSION): string { + const [osType, arch] = ANTIGRAVITY_IDE_PLATFORM.split("/"); + return `antigravity/ide/${version} (${ANTIGRAVITY_IDE_CLIENT_NAME}; os_type=${osType}; arch=${arch})`; } diff --git a/src/adapters/google-antigravity-wire.ts b/src/adapters/google-antigravity-wire.ts index 7c7a7714f6..e516b64c63 100644 --- a/src/adapters/google-antigravity-wire.ts +++ b/src/adapters/google-antigravity-wire.ts @@ -3,10 +3,11 @@ import type { OcxContentPart, OcxParsedRequest } from "../types"; import { antigravityUserAgent } from "./client-fingerprint"; /** - * Antigravity request User-Agent. Mirrors the real Antigravity CLI UA - * (`antigravity/cli/{ver} (aidev_client; os_type=darwin; arch=arm64)`) so the request fingerprint + * Antigravity request User-Agent. Mirrors the real Antigravity IDE UA + * (`antigravity/ide/{ver} (aidev_client; os_type=windows; arch=amd64)`) so the request fingerprint * matches the OAuth credential — the prior literal `"antigravity"` was a giveaway no real client - * sends. A `GOOGLE_ANTIGRAVITY_USER_AGENT` override still wins. + * sends. The IDE client family is also required to unlock newer agent models (the backend 404s + * CLI-shaped UAs for `gemini-3.7-*`). A `GOOGLE_ANTIGRAVITY_USER_AGENT` override still wins. */ export const ANTIGRAVITY_REQUEST_UA = process.env.GOOGLE_ANTIGRAVITY_USER_AGENT || antigravityUserAgent(); diff --git a/src/adapters/google.ts b/src/adapters/google.ts index 9ccba7f33d..9a074c0506 100644 --- a/src/adapters/google.ts +++ b/src/adapters/google.ts @@ -469,7 +469,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte const envelope = { model: wireModelId, // The envelope's `userAgent` field is a protocol constant ("antigravity"), distinct from - // the HTTP `User-Agent` header (the real CLI UA). CLIProxyAPI `geminiToAntigravity` hardcodes + // the HTTP `User-Agent` header (the real IDE UA). CLIProxyAPI `geminiToAntigravity` hardcodes // the body field; only the header carries the versioned client string. userAgent: "antigravity", requestType: "agent", diff --git a/tests/client-fingerprint.test.ts b/tests/client-fingerprint.test.ts index cf155df948..9e30d494ef 100644 --- a/tests/client-fingerprint.test.ts +++ b/tests/client-fingerprint.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from "bun:test"; import { - ANTIGRAVITY_CLI_VERSION, + ANTIGRAVITY_IDE_VERSION, ANTIGRAVITY_GOOG_API_CLIENT_UA, CLAUDE_CODE_HEADERS, antigravityUserAgent, @@ -19,14 +19,14 @@ function parsed(): OcxParsedRequest { } describe("client fingerprint — helpers", () => { - test("antigravity UA has the real CLI shape, never the literal giveaway", async () => { + test("antigravity UA has the real IDE shape, never the literal giveaway", async () => { const ua = antigravityUserAgent(); - expect(ua).toBe("antigravity/cli/1.1.12 (aidev_client; os_type=darwin; arch=arm64)"); + expect(ua).toBe(`antigravity/ide/${ANTIGRAVITY_IDE_VERSION} (aidev_client; os_type=windows; arch=amd64)`); expect(ua).not.toBe("antigravity"); }); test("antigravity UA honors an explicit version override", async () => { - expect(antigravityUserAgent("9.9.9")).toBe("antigravity/cli/9.9.9 (aidev_client; os_type=darwin; arch=arm64)"); + expect(antigravityUserAgent("9.9.9")).toBe("antigravity/ide/9.9.9 (aidev_client; os_type=windows; arch=amd64)"); }); test("GOOGLE_ANTIGRAVITY_USER_AGENT env override wins over the default UA", async () => { diff --git a/tests/google-antigravity-wire.test.ts b/tests/google-antigravity-wire.test.ts index a5427c5584..5ea15eff2a 100644 --- a/tests/google-antigravity-wire.test.ts +++ b/tests/google-antigravity-wire.test.ts @@ -56,7 +56,11 @@ describe("antigravity CCA envelope", () => { expect(env.request.model).toBeUndefined(); expect(env.request.safetySettings).toBeUndefined(); expect(req.headers["Authorization"]).toBe("Bearer ya29.token"); - expect(req.headers["User-Agent"]).toMatch(/^antigravity\/cli\/[\d.]+ \(aidev_client; os_type=\w+; arch=\w+\)$/); + // The exact default must not drift: Google gates models by family AND version, + // so any change to version/platform could silently re-lock gemini-3.7-flash. + expect(req.headers["User-Agent"]).toBe( + "antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)", + ); // The literal "antigravity" giveaway UA must no longer be sent. expect(req.headers["User-Agent"]).not.toBe("antigravity"); // x-goog-api-client is NOT sent on runtime requests (CLIProxyAPI only uses it during onboarding).