From e0d75f566d7f2352b37e5c825f538fbbd07e06ba Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 27 Sep 2026 00:54:07 +0300 Subject: [PATCH 1/2] fix(antigravity): strip toolConfig from translated tools to prevent HTTP 400 --- tests/unit/antigravity-tool-config.test.ts | 28 ++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/unit/antigravity-tool-config.test.ts diff --git a/tests/unit/antigravity-tool-config.test.ts b/tests/unit/antigravity-tool-config.test.ts new file mode 100644 index 000000000000..6c26b4fd25d1 --- /dev/null +++ b/tests/unit/antigravity-tool-config.test.ts @@ -0,0 +1,28 @@ +import assert from "node:assert/strict"; +import test from "node:test"; +import { antigravityToOpenAIRequest } from "../../open-sse/translator/request/antigravity-to-openai.ts"; + +test("antigravityToOpenAIRequest strips toolConfig from translated tools", () => { + const body = { + request: { + contents: [{ role: "user", parts: [{ text: "Hello" }] }], + tools: [ + { + functionDeclarations: [ + { + name: "get_weather", + description: "Get weather", + parameters: { type: "OBJECT", properties: { location: { type: "STRING" } } } + } + ] + } + ], + toolConfig: { functionCallingConfig: { mode: "VALIDATED" } } + } + }; + + const res = antigravityToOpenAIRequest("gemini-2.5-flash", body, false); + assert.equal(res.toolConfig, undefined); + assert.equal(Array.isArray(res.tools), true); + assert.equal(res.tools?.length, 1); +}); From f361d336e7bf210e69697412186771573b9ae5db Mon Sep 17 00:00:00 2001 From: Denis Date: Sun, 27 Sep 2026 00:54:12 +0300 Subject: [PATCH 2/2] fix(antigravity): scrub x-goog-user-project header to prevent HTTP 403 --- open-sse/services/antigravityHeaderScrub.ts | 2 ++ tests/unit/antigravity-headers.test.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/open-sse/services/antigravityHeaderScrub.ts b/open-sse/services/antigravityHeaderScrub.ts index 985e3fe757e6..2a6eb1591dd5 100644 --- a/open-sse/services/antigravityHeaderScrub.ts +++ b/open-sse/services/antigravityHeaderScrub.ts @@ -41,6 +41,8 @@ const HEADERS_TO_REMOVE = [ // Encoding: Antigravity (Node.js) sends "gzip, deflate, br" by default; // Electron clients add "zstd" which is a fingerprint mismatch. "accept-encoding", + // Google Cloud project header — Antigravity backend throws HTTP 403 when present + "x-goog-user-project", ]; /** diff --git a/tests/unit/antigravity-headers.test.ts b/tests/unit/antigravity-headers.test.ts index efb64adc3b04..d8f248f4234b 100644 --- a/tests/unit/antigravity-headers.test.ts +++ b/tests/unit/antigravity-headers.test.ts @@ -10,6 +10,7 @@ import { getAntigravityLoadCodeAssistMetadata, getAntigravityOAuthUserAgent, } from "../../open-sse/services/antigravityHeaders.ts"; +import { scrubProxyAndFingerprintHeaders } from "../../open-sse/services/antigravityHeaderScrub.ts"; import { clearAntigravityVersionCaches, seedAntigravityCliVersionCache, @@ -65,12 +66,23 @@ test("IDE and CLI content headers use independent cached versions", () => { "x-vscode-sessionid", "X-Goog-Api-Client", "Client-Metadata", + "x-goog-user-project", ]) { assert.equal(headers.get(absent), null, `${absent} must be absent from content headers`); } } }); +test("scrubProxyAndFingerprintHeaders strips x-goog-user-project header", () => { + const input = { + "Content-Type": "application/json", + "x-goog-user-project": "my-project-123", + Authorization: "Bearer token", + }; + const scrubbed = scrubProxyAndFingerprintHeaders(input); + assert.equal(scrubbed["x-goog-user-project"], undefined); +}); + test("IDE Node OAuth and onboarding headers use the captured Google Node identity", () => { seedAntigravityIdeVersionCache("2.1.1"); const headers = new Headers(getAntigravityIdeNodeHeaders("token"));