diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index c6bb020fe..8050ec83c 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Removed generated Cloudflare Workers AI `User-Agent` model headers so attribution can be controlled by callers. + ## [0.70.5] - 2026-04-27 ## [0.70.4] - 2026-04-27 diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 9ea228542..2c848ae43 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -64,10 +64,6 @@ const KIMI_STATIC_HEADERS = { "User-Agent": "KimiCLI/1.5", } as const; -const CLOUDFLARE_STATIC_HEADERS = { - "User-Agent": "pi-coding-agent", -} as const; - const AI_GATEWAY_MODELS_URL = "https://ai-gateway.vercel.sh/v1"; const AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh"; const ZAI_TOOL_STREAM_UNSUPPORTED_MODELS = new Set(["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v"]); @@ -403,7 +399,6 @@ async function loadModelsDevData(): Promise[]> { }, contextWindow: m.limit?.context || 4096, maxTokens: m.limit?.output || 4096, - headers: { ...CLOUDFLARE_STATIC_HEADERS }, compat: { sendSessionAffinityHeaders: true }, }); } diff --git a/packages/ai/src/models.generated.ts b/packages/ai/src/models.generated.ts index eddb394f7..b279d79dc 100644 --- a/packages/ai/src/models.generated.ts +++ b/packages/ai/src/models.generated.ts @@ -15381,7 +15381,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text", "image"], @@ -15400,7 +15399,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: false, input: ["text", "image"], @@ -15419,7 +15417,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text", "image"], @@ -15438,7 +15435,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text", "image"], @@ -15457,7 +15453,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text"], @@ -15476,7 +15471,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text"], @@ -15495,7 +15489,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text"], @@ -15514,7 +15507,6 @@ export const MODELS = { api: "openai-completions", provider: "cloudflare-workers-ai", baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", - headers: {"User-Agent":"pi-coding-agent"}, compat: {"sendSessionAffinityHeaders":true}, reasoning: true, input: ["text"], diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 5ecd8f4ca..512092c74 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed Cloudflare Workers AI attribution headers to honor the install telemetry setting. + ## [0.70.5] - 2026-04-27 ### Fixed diff --git a/packages/coding-agent/src/core/sdk.ts b/packages/coding-agent/src/core/sdk.ts index 5d31ab384..23ca07a34 100644 --- a/packages/coding-agent/src/core/sdk.ts +++ b/packages/coding-agent/src/core/sdk.ts @@ -125,21 +125,29 @@ function getDefaultAgentDir(): string { return getAgentDir(); } -function getOpenRouterAttributionHeaders( +function getAttributionHeaders( model: Model, settingsManager: SettingsManager, ): Record | undefined { if (!isInstallTelemetryEnabled(settingsManager)) { return undefined; } - if (model.provider !== "openrouter" && !model.baseUrl.includes("openrouter.ai")) { - return undefined; + + if (model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai")) { + return { + "HTTP-Referer": "https://pi.dev", + "X-OpenRouter-Title": "pi", + "X-OpenRouter-Categories": "cli-agent", + }; } - return { - "HTTP-Referer": "https://pi.dev", - "X-OpenRouter-Title": "pi", - "X-OpenRouter-Categories": "cli-agent", - }; + + if (model.provider === "cloudflare-workers-ai" || model.baseUrl.includes("api.cloudflare.com")) { + return { + "User-Agent": "pi-coding-agent", + }; + } + + return undefined; } /** @@ -316,7 +324,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} throw new Error(auth.error); } const providerRetrySettings = settingsManager.getProviderRetrySettings(); - const openRouterAttributionHeaders = getOpenRouterAttributionHeaders(model, settingsManager); + const attributionHeaders = getAttributionHeaders(model, settingsManager); return streamSimple(model, context, { ...options, apiKey: auth.apiKey, @@ -324,8 +332,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {} maxRetries: options?.maxRetries ?? providerRetrySettings.maxRetries, maxRetryDelayMs: options?.maxRetryDelayMs ?? providerRetrySettings.maxRetryDelayMs, headers: - openRouterAttributionHeaders || auth.headers || options?.headers - ? { ...openRouterAttributionHeaders, ...auth.headers, ...options?.headers } + attributionHeaders || auth.headers || options?.headers + ? { ...attributionHeaders, ...auth.headers, ...options?.headers } : undefined, }); },