Skip to content

Commit 875bb70

Browse files
committed
fix(antigravity): switch User-Agent to IDE family to ungate gemini-3.7-flash
The Cloud Code Assist backend gates newer agent models (gemini-3.7-flash) by client family, returning 404 NOT_FOUND to CLI-shaped UAs (antigravity/cli/...) even with a valid OAuth token. Only antigravity/ide/<version> unlocks them. Switch antigravityUserAgent() from CLI to IDE shape (antigravity/ide/2.5.5). Pin the exact UA in the wire test so accidental drift cannot silently re-lock 3.7-flash. The GOOGLE_ANTIGRAVITY_USER_AGENT override still wins. Cherry-picked from PR #1646 (waw4303).
1 parent ea96fbd commit 875bb70

5 files changed

Lines changed: 28 additions & 19 deletions

File tree

‎src/adapters/client-fingerprint.ts‎

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,24 @@ export function claudeCodeSessionId(token: string | undefined): string {
4040
return `${h.slice(0, 8)}-${h.slice(8, 12)}-4${h.slice(13, 16)}-${variant}${h.slice(17, 20)}-${h.slice(20, 32)}`;
4141
}
4242

43-
// ── Antigravity CLI ──
44-
/** Pinned fallback Antigravity CLI version (real client fetches a manifest; we pin to avoid the network dependency). */
45-
export const ANTIGRAVITY_CLI_VERSION = "1.1.12";
46-
const ANTIGRAVITY_CLI_CLIENT_NAME = "aidev_client";
47-
const ANTIGRAVITY_CLI_PLATFORM = "darwin/arm64";
43+
// ── Antigravity IDE ──
44+
/** Pinned fallback Antigravity IDE language-server version (matches the bundled LS 2.5.5). */
45+
export const ANTIGRAVITY_IDE_VERSION = "2.5.5";
46+
const ANTIGRAVITY_IDE_CLIENT_NAME = "aidev_client";
47+
const ANTIGRAVITY_IDE_PLATFORM = "windows/amd64";
4848
/** Secondary Google API client UA the Antigravity client library reports. */
4949
export const ANTIGRAVITY_GOOG_API_CLIENT_UA = "google-api-nodejs-client/10.3.0";
5050

5151
/**
52-
* The real Antigravity CLI User-Agent, e.g.
53-
* `antigravity/cli/1.1.12 (aidev_client; os_type=darwin; arch=arm64)`.
52+
* The real Antigravity IDE User-Agent, e.g.
53+
* `antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)`.
54+
*
55+
* Must be the IDE client family, NOT `antigravity/cli/...`: the Cloud Code Assist backend gates
56+
* newer agent models (e.g. `gemini-3.7-flash`) by User-Agent and answers 404 NOT_FOUND to
57+
* CLI-shaped UAs even with a valid OAuth token. Only `antigravity/ide/<ver>` unlocks them.
5458
* A `GOOGLE_ANTIGRAVITY_USER_AGENT` override (set by the caller) takes precedence upstream.
5559
*/
56-
export function antigravityUserAgent(version = ANTIGRAVITY_CLI_VERSION): string {
57-
const [osType, arch] = ANTIGRAVITY_CLI_PLATFORM.split("/");
58-
return `antigravity/cli/${version} (${ANTIGRAVITY_CLI_CLIENT_NAME}; os_type=${osType}; arch=${arch})`;
60+
export function antigravityUserAgent(version = ANTIGRAVITY_IDE_VERSION): string {
61+
const [osType, arch] = ANTIGRAVITY_IDE_PLATFORM.split("/");
62+
return `antigravity/ide/${version} (${ANTIGRAVITY_IDE_CLIENT_NAME}; os_type=${osType}; arch=${arch})`;
5963
}

‎src/adapters/google-antigravity-wire.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import type { OcxContentPart, OcxParsedRequest } from "../types";
33
import { antigravityUserAgent } from "./client-fingerprint";
44

55
/**
6-
* Antigravity request User-Agent. Mirrors the real Antigravity CLI UA
7-
* (`antigravity/cli/{ver} (aidev_client; os_type=darwin; arch=arm64)`) so the request fingerprint
6+
* Antigravity request User-Agent. Mirrors the real Antigravity IDE UA
7+
* (`antigravity/ide/{ver} (aidev_client; os_type=windows; arch=amd64)`) so the request fingerprint
88
* matches the OAuth credential — the prior literal `"antigravity"` was a giveaway no real client
9-
* sends. A `GOOGLE_ANTIGRAVITY_USER_AGENT` override still wins.
9+
* sends. The IDE client family is also required to unlock newer agent models (the backend 404s
10+
* CLI-shaped UAs for `gemini-3.7-*`). A `GOOGLE_ANTIGRAVITY_USER_AGENT` override still wins.
1011
*/
1112
export const ANTIGRAVITY_REQUEST_UA = process.env.GOOGLE_ANTIGRAVITY_USER_AGENT || antigravityUserAgent();
1213

‎src/adapters/google.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ export function createGoogleAdapter(provider: OcxProviderConfig): ProviderAdapte
469469
const envelope = {
470470
model: wireModelId,
471471
// The envelope's `userAgent` field is a protocol constant ("antigravity"), distinct from
472-
// the HTTP `User-Agent` header (the real CLI UA). CLIProxyAPI `geminiToAntigravity` hardcodes
472+
// the HTTP `User-Agent` header (the real IDE UA). CLIProxyAPI `geminiToAntigravity` hardcodes
473473
// the body field; only the header carries the versioned client string.
474474
userAgent: "antigravity",
475475
requestType: "agent",

‎tests/client-fingerprint.test.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, expect, test } from "bun:test";
22
import {
3-
ANTIGRAVITY_CLI_VERSION,
3+
ANTIGRAVITY_IDE_VERSION,
44
ANTIGRAVITY_GOOG_API_CLIENT_UA,
55
CLAUDE_CODE_HEADERS,
66
antigravityUserAgent,
@@ -19,14 +19,14 @@ function parsed(): OcxParsedRequest {
1919
}
2020

2121
describe("client fingerprint — helpers", () => {
22-
test("antigravity UA has the real CLI shape, never the literal giveaway", async () => {
22+
test("antigravity UA has the real IDE shape, never the literal giveaway", async () => {
2323
const ua = antigravityUserAgent();
24-
expect(ua).toBe("antigravity/cli/1.1.12 (aidev_client; os_type=darwin; arch=arm64)");
24+
expect(ua).toBe(`antigravity/ide/${ANTIGRAVITY_IDE_VERSION} (aidev_client; os_type=windows; arch=amd64)`);
2525
expect(ua).not.toBe("antigravity");
2626
});
2727

2828
test("antigravity UA honors an explicit version override", async () => {
29-
expect(antigravityUserAgent("9.9.9")).toBe("antigravity/cli/9.9.9 (aidev_client; os_type=darwin; arch=arm64)");
29+
expect(antigravityUserAgent("9.9.9")).toBe("antigravity/ide/9.9.9 (aidev_client; os_type=windows; arch=amd64)");
3030
});
3131

3232
test("GOOGLE_ANTIGRAVITY_USER_AGENT env override wins over the default UA", async () => {

‎tests/google-antigravity-wire.test.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ describe("antigravity CCA envelope", () => {
5656
expect(env.request.model).toBeUndefined();
5757
expect(env.request.safetySettings).toBeUndefined();
5858
expect(req.headers["Authorization"]).toBe("Bearer ya29.token");
59-
expect(req.headers["User-Agent"]).toMatch(/^antigravity\/cli\/[\d.]+ \(aidev_client; os_type=\w+; arch=\w+\)$/);
59+
// The exact default must not drift: Google gates models by family AND version,
60+
// so any change to version/platform could silently re-lock gemini-3.7-flash.
61+
expect(req.headers["User-Agent"]).toBe(
62+
"antigravity/ide/2.5.5 (aidev_client; os_type=windows; arch=amd64)",
63+
);
6064
// The literal "antigravity" giveaway UA must no longer be sent.
6165
expect(req.headers["User-Agent"]).not.toBe("antigravity");
6266
// x-goog-api-client is NOT sent on runtime requests (CLIProxyAPI only uses it during onboarding).

0 commit comments

Comments
 (0)