fix(antigravity): strip Claude Code billing header from system prompts
This commit is contained in:
@@ -179,6 +179,10 @@ export const CLAUDE_SYSTEM_PROMPT = "You are Claude Code, Anthropic's official C
|
||||
export const ANTIGRAVITY_PROMPT_REWRITES = [
|
||||
{ from: "You are a Claude agent, built on Anthropic's Claude Agent SDK.", to: "" },
|
||||
{ from: /You are Hermes Agent,\s*(an intelligent AI assistant)(?: created by Nous Research)?\./gi, to: "You are Hermes Agent. You are $1." },
|
||||
// Claude Code prepends this line to its system prompt. The Claude-format translator strips it,
|
||||
// but OpenAI-format clients (e.g. proxies that convert Claude Code to /v1/chat/completions)
|
||||
// pass it through, and any system text containing it gets a fake 429 RESOURCE_EXHAUSTED.
|
||||
{ from: /^x-anthropic-billing-header:[^\n]*(?:\r?\n)*/gim, to: "" },
|
||||
{ from: /opencode/gi, to: (m) => (m === "OpenCode" ? "Antigravity" : m === "OPENCODE" ? "ANTIGRAVITY" : "antigravity") }
|
||||
];
|
||||
|
||||
|
||||
38
tests/unit/antigravity-billing-header-rewrite.test.js
Normal file
38
tests/unit/antigravity-billing-header-rewrite.test.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { AntigravityExecutor } from "../../open-sse/executors/antigravity.js";
|
||||
import { openaiToAntigravityRequest } from "../../open-sse/translator/request/openai-to-gemini.js";
|
||||
|
||||
const HEADER = "x-anthropic-billing-header: cc_version=2.1.275.f15; cc_entrypoint=cli;";
|
||||
|
||||
function systemTextSentToAntigravity(systemContent) {
|
||||
// OpenAI-format client (e.g. a proxy converting Claude Code to /v1/chat/completions).
|
||||
const body = openaiToAntigravityRequest("gemini-3.8-flash-tiered", {
|
||||
messages: [
|
||||
{ role: "system", content: systemContent },
|
||||
{ role: "user", content: "hi" },
|
||||
],
|
||||
}, true);
|
||||
const finalBody = new AntigravityExecutor().transformRequest("gemini-3.8-flash-tiered", body, true, {});
|
||||
return finalBody.request.systemInstruction.parts.map((p) => p.text).join("\n");
|
||||
}
|
||||
|
||||
describe("Antigravity strips the Claude Code billing header from system prompts", () => {
|
||||
it("removes the header line prepended by Claude Code", () => {
|
||||
const text = systemTextSentToAntigravity(`${HEADER}\n\nYou are Claude Code, Anthropic's official CLI for Claude.`);
|
||||
expect(text).not.toContain("x-anthropic-billing-header");
|
||||
expect(text).toContain("You are Claude Code, Anthropic's official CLI for Claude.");
|
||||
});
|
||||
|
||||
it("removes the header when it is not the first line", () => {
|
||||
const text = systemTextSentToAntigravity(`Some preamble\n${HEADER}\nRest of prompt`);
|
||||
expect(text).not.toContain("x-anthropic-billing-header");
|
||||
expect(text).toContain("Some preamble");
|
||||
expect(text).toContain("Rest of prompt");
|
||||
});
|
||||
|
||||
it("leaves prompts without the header untouched", () => {
|
||||
const text = systemTextSentToAntigravity("You are a helpful assistant.");
|
||||
expect(text).toContain("You are a helpful assistant.");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user