From bf96e704ff43c78ccc2fe3561136f5fd62288ff7 Mon Sep 17 00:00:00 2001 From: diegosouzapw Date: Mon, 4 May 2026 23:26:55 -0300 Subject: [PATCH] test(antigravity): update claude bridge tests for native payload structure --- open-sse/executors/default.ts | 9 ++- .../translator/request/openai-to-gemini.ts | 13 ++++ tests/unit/sse-auth.test.ts | 24 ++++--- .../unit/translator-openai-to-gemini.test.ts | 63 +++++++++---------- 4 files changed, 63 insertions(+), 46 deletions(-) diff --git a/open-sse/executors/default.ts b/open-sse/executors/default.ts index 3a98034ecc..21a9ef7d9e 100644 --- a/open-sse/executors/default.ts +++ b/open-sse/executors/default.ts @@ -410,9 +410,12 @@ export class DefaultExecutor extends BaseExecutor { // #1961: Map max_tokens -> max_completion_tokens for recent OpenAI models if (getTargetFormat(this.provider, credentials?.providerSpecificData) === "openai") { const isRecentOpenAI = /^(o1|o3|gpt-5)/i.test(model); - if (isRecentOpenAI && "max_tokens" in withDefaults) { - withDefaults.max_completion_tokens = withDefaults.max_tokens; - delete withDefaults.max_tokens; + if (isRecentOpenAI && withDefaults && typeof withDefaults === "object") { + const defaultsRecord = withDefaults as Record; + if ("max_tokens" in defaultsRecord) { + defaultsRecord.max_completion_tokens = defaultsRecord.max_tokens; + delete defaultsRecord.max_tokens; + } } } } diff --git a/open-sse/translator/request/openai-to-gemini.ts b/open-sse/translator/request/openai-to-gemini.ts index 1947c702d6..4af955986d 100644 --- a/open-sse/translator/request/openai-to-gemini.ts +++ b/open-sse/translator/request/openai-to-gemini.ts @@ -489,6 +489,17 @@ function wrapInCloudCodeEnvelopeForClaude( const cleanModel = model.includes("/") ? model.split("/").pop()! : model; + // Keep Antigravity's default and caller-provided system rules + let systemText = ANTIGRAVITY_DEFAULT_SYSTEM; + if (claudeRequest.system) { + if (Array.isArray(claudeRequest.system)) { + const texts = claudeRequest.system.map((b) => b.text).filter(Boolean); + if (texts.length > 0) systemText += "\n" + texts.join("\n"); + } else if (typeof claudeRequest.system === "string") { + systemText += "\n" + claudeRequest.system; + } + } + const envelope: CloudCodeEnvelope = { project: projectId, model: cleanModel, @@ -497,6 +508,8 @@ function wrapInCloudCodeEnvelopeForClaude( requestType: "agent", request: { ...claudeRequest, + system: systemText, + max_tokens: getAntigravityClaudeOutputTokens(sourceBody), sessionId: generateSessionId(), }, }; diff --git a/tests/unit/sse-auth.test.ts b/tests/unit/sse-auth.test.ts index b3fc656f92..7ac60df468 100644 --- a/tests/unit/sse-auth.test.ts +++ b/tests/unit/sse-auth.test.ts @@ -27,7 +27,7 @@ function futureIso(ms = 60_000) { return new Date(Date.now() + ms).toISOString(); } -async function seedConnection(provider, overrides = {}) { +async function seedConnection(provider: string, overrides: any = {}) { return providersDb.createProviderConnection({ provider, authType: overrides.authType || "apikey", @@ -176,7 +176,7 @@ test("getProviderCredentialsWithQuotaPreflight skips exhausted preflight account const selected = await auth.getProviderCredentialsWithQuotaPreflight("openai"); - assert.equal(selected.connectionId, healthy.id); + assert.equal((selected as any).connectionId, healthy.id); }); test("getProviderCredentials includes per-account maxConcurrent caps", async () => { @@ -229,7 +229,7 @@ test("getProviderCredentialsWithQuotaPreflight returns allRateLimited when a for })); const selected = await auth.getProviderCredentialsWithQuotaPreflight("openai", null, null, null, { - forcedConnectionId: blocked.id, + forcedConnectionId: (blocked as any).id, }); assert.equal(selected.allRateLimited, true); @@ -293,7 +293,7 @@ test("evaluateQuotaLimitPolicy aggregates reasons and keeps the earliest valid f daily: { remainingPercentage: 90, resetAt: futureIso(180_000) }, }); - const evaluation = auth.evaluateQuotaLimitPolicy("openai", connection); + const evaluation = auth.evaluateQuotaLimitPolicy("openai", connection as any); assert.equal(evaluation.blocked, true); assert.deepEqual(evaluation.reasons, ["weekly usage 80%", "session usage 95%"]); @@ -352,7 +352,7 @@ test("getProviderCredentials honors allowedConnections filters", async () => { apiKey: "sk-selected", }); - const selected = await auth.getProviderCredentials("openai", null, [selectedConn.id]); + const selected = await auth.getProviderCredentials("openai", null, [(selectedConn as any).id]); assert.equal(selected.connectionId, selectedConn.id); assert.equal(selected.apiKey, "sk-selected"); @@ -372,7 +372,7 @@ test("getProviderCredentials honors forcedConnectionId even when another account }); const selected = await auth.getProviderCredentials("openai", null, null, null, { - forcedConnectionId: forcedConn.id, + forcedConnectionId: (forcedConn as any).id, }); assert.equal(selected.connectionId, forcedConn.id); @@ -389,9 +389,15 @@ test("getProviderCredentials intersects forcedConnectionId with allowedConnectio apiKey: "sk-blocked", }); - const selected = await auth.getProviderCredentials("openai", null, [allowedConn.id], null, { - forcedConnectionId: blockedConn.id, - }); + const selected = await auth.getProviderCredentials( + "openai", + null, + [(allowedConn as any).id], + null, + { + forcedConnectionId: (blockedConn as any).id, + } + ); assert.equal(selected, null); }); diff --git a/tests/unit/translator-openai-to-gemini.test.ts b/tests/unit/translator-openai-to-gemini.test.ts index 843444e3d7..afac00bd68 100644 --- a/tests/unit/translator-openai-to-gemini.test.ts +++ b/tests/unit/translator-openai-to-gemini.test.ts @@ -659,33 +659,28 @@ test("OpenAI -> Antigravity uses the Claude bridge for Claude-family models", () assert.equal(result.project, "proj-claude"); assert.equal(result.userAgent, "antigravity"); - assert.equal((result as any).request?.systemInstruction.role, "system"); - assert.equal( - (result as any).request?.systemInstruction.parts[0].text, - ANTIGRAVITY_DEFAULT_SYSTEM - ); - assert.equal((result as any).request?.systemInstruction.parts[1].text, "Project rules"); - assert.equal((result as any).request?.generationConfig.maxOutputTokens, 16384); - assert.equal((result as any).request?.generationConfig.temperature, 1); - assert.equal((result as any).request?.generationConfig.thinkingConfig, undefined); + assert.ok((result as any).request?.system.includes(ANTIGRAVITY_DEFAULT_SYSTEM)); + assert.ok((result as any).request?.system.includes("Project rules")); + assert.equal((result as any).request?.max_tokens, 16384); - const modelTurn = result.request.contents.find( - (content) => content.role === "model" && content.parts.some((part) => part.functionCall) + const modelTurn = result.request.messages.find( + (msg) => msg.role === "assistant" && msg.content.some((block) => block.type === "tool_use") ); assert.ok(modelTurn, "expected a Claude-bridged model turn"); - const bridgeFunctionCall = getFunctionCall(modelTurn.parts[0]); + const bridgeFunctionCall = modelTurn.content.find((block) => block.type === "tool_use"); assert.equal(bridgeFunctionCall.name, "read_file"); - assert.deepEqual(bridgeFunctionCall.args, { path: "/tmp/demo" }); + assert.deepEqual(bridgeFunctionCall.input, { path: "/tmp/demo" }); - const toolTurn = result.request.contents.find( - (content) => content.role === "user" && content.parts.some((part) => part.functionResponse) + const toolTurn = result.request.messages.find( + (msg) => msg.role === "user" && msg.content.some((block) => block.type === "tool_result") ); assert.ok(toolTurn, "expected a Claude-bridged tool response turn"); - assert.equal(getFunctionResponse(toolTurn.parts[0]).id, "call_1"); - assert.equal((result as any).request?.tools[0].functionDeclarations[0].name, "read_file"); + const toolResultBlock = toolTurn.content.find((block) => block.type === "tool_result"); + assert.equal(toolResultBlock.tool_use_id, "call_1"); + assert.equal((result as any).request?.tools[0].name, "read_file"); }); -test("OpenAI -> Antigravity Claude bridge sanitizes long names and preserves restore map", () => { +test("OpenAI -> Antigravity Claude bridge preserves tool names (Claude supports longer names)", () => { const longToolName = "ns:mcp__filesystem__read_multiple_files_with_validation_and_metadata_bundle"; const result = openaiToAntigravityRequest( @@ -727,26 +722,26 @@ test("OpenAI -> Antigravity Claude bridge sanitizes long names and preserves res { projectId: "proj-claude-map" } as any ); - const sanitizedToolName = (result as any).request?.tools[0].functionDeclarations[0].name; - assert.equal(sanitizedToolName.length, 64); - assert.match(sanitizedToolName, /^[a-zA-Z0-9_]+$/); - assert.equal((result as any)._toolNameMap.get(sanitizedToolName), longToolName); + const sanitizedToolName = (result as any).request?.tools[0].name; + assert.equal(sanitizedToolName, longToolName); - const modelTurn = result.request.contents.find( - (content) => content.role === "model" && content.parts.some((part) => part.functionCall) + const modelTurn = result.request.messages.find( + (msg) => msg.role === "assistant" && msg.content.some((block) => block.type === "tool_use") ); assert.ok(modelTurn, "expected a model turn"); - assert.equal(getFunctionCall(modelTurn.parts[0]).name, sanitizedToolName); + const toolUseBlock = modelTurn.content.find((block) => block.type === "tool_use"); + assert.equal(toolUseBlock.name, sanitizedToolName); - const toolTurn = result.request.contents.find( - (content) => content.role === "user" && content.parts.some((part) => part.functionResponse) + const toolTurn = result.request.messages.find( + (msg) => msg.role === "user" && msg.content.some((block) => block.type === "tool_result") ); assert.ok(toolTurn, "expected a tool response turn"); - assert.equal(getFunctionResponse(toolTurn.parts[0]).name, sanitizedToolName); - assert.deepEqual(getFunctionResponse(toolTurn.parts[0]).response, { result: { ok: true } }); + const toolResultBlock = toolTurn.content.find((block) => block.type === "tool_result"); + assert.equal(toolResultBlock.tool_use_id, "call_long_2"); + assert.ok(toolResultBlock.content.includes("ok")); }); -test("OpenAI -> Antigravity Claude bridge applies Antigravity output cap without forwarding thinking", () => { +test("OpenAI -> Antigravity Claude bridge applies Antigravity output cap but forwards thinking", () => { const result = openaiToAntigravityRequest( "claude-3-7-sonnet", { @@ -758,8 +753,8 @@ test("OpenAI -> Antigravity Claude bridge applies Antigravity output cap without { projectId: "proj-claude-thinking" } as any ); - assert.equal((result as any).request?.generationConfig.maxOutputTokens, 16384); - assert.equal((result as any).request?.generationConfig.thinkingConfig, undefined); + assert.equal((result as any).request?.max_tokens, 16384); + assert.deepEqual((result as any).request?.thinking, { type: "enabled", budget_tokens: 131072 }); }); test("OpenAI -> Antigravity Claude bridge preserves lower requested output despite reasoning effort", () => { @@ -774,6 +769,6 @@ test("OpenAI -> Antigravity Claude bridge preserves lower requested output despi { projectId: "proj-claude-short" } as any ); - assert.equal((result as any).request?.generationConfig.maxOutputTokens, 1000); - assert.equal((result as any).request?.generationConfig.thinkingConfig, undefined); + assert.equal((result as any).request?.max_tokens, 1000); + assert.deepEqual((result as any).request?.thinking, { type: "enabled", budget_tokens: 131072 }); });