diff --git a/src/agents/pi-embedded-runner/anthropic-stream-wrappers.cache-retention.test.ts b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.cache-retention.test.ts new file mode 100644 index 00000000000..38a54a6d044 --- /dev/null +++ b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.cache-retention.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, it } from "vitest"; +import { resolveCacheRetention } from "./anthropic-stream-wrappers.js"; + +describe("resolveCacheRetention", () => { + it("returns 'short' by default for anthropic provider", () => { + expect(resolveCacheRetention(undefined, "anthropic")).toBe("short"); + }); + + it("returns 'short' by default for cloudflare-ai-gateway provider", () => { + expect(resolveCacheRetention(undefined, "cloudflare-ai-gateway")).toBe("short"); + }); + + it("returns undefined for unrelated providers", () => { + expect(resolveCacheRetention(undefined, "openai")).toBeUndefined(); + expect(resolveCacheRetention(undefined, "openrouter")).toBeUndefined(); + }); + + it("returns explicit cacheRetention for cloudflare-ai-gateway", () => { + expect(resolveCacheRetention({ cacheRetention: "long" }, "cloudflare-ai-gateway")).toBe("long"); + expect(resolveCacheRetention({ cacheRetention: "none" }, "cloudflare-ai-gateway")).toBe("none"); + }); + + it("returns undefined for amazon-bedrock without explicit override", () => { + expect(resolveCacheRetention(undefined, "amazon-bedrock")).toBeUndefined(); + }); + + it("returns explicit cacheRetention for amazon-bedrock when overridden", () => { + expect(resolveCacheRetention({ cacheRetention: "short" }, "amazon-bedrock")).toBe("short"); + }); + + it("maps legacy cacheControlTtl values", () => { + expect(resolveCacheRetention({ cacheControlTtl: "5m" }, "anthropic")).toBe("short"); + expect(resolveCacheRetention({ cacheControlTtl: "1h" }, "anthropic")).toBe("long"); + expect(resolveCacheRetention({ cacheControlTtl: "5m" }, "cloudflare-ai-gateway")).toBe("short"); + }); +}); diff --git a/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts index 511b70d280d..f789ea43872 100644 --- a/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts +++ b/src/agents/pi-embedded-runner/anthropic-stream-wrappers.ts @@ -212,11 +212,14 @@ export function resolveCacheRetention( provider: string, ): CacheRetention | undefined { const isAnthropicDirect = provider === "anthropic"; + // Cloudflare AI Gateway proxies the Anthropic Messages API and passes + // cache_control through, so treat it like direct Anthropic (#46709). + const isCloudflareAnthropicProxy = provider === "cloudflare-ai-gateway"; const hasBedrockOverride = extraParams?.cacheRetention !== undefined || extraParams?.cacheControlTtl !== undefined; const isAnthropicBedrock = provider === "amazon-bedrock" && hasBedrockOverride; - if (!isAnthropicDirect && !isAnthropicBedrock) { + if (!isAnthropicDirect && !isCloudflareAnthropicProxy && !isAnthropicBedrock) { return undefined; } @@ -233,7 +236,7 @@ export function resolveCacheRetention( return "long"; } - return isAnthropicDirect ? "short" : undefined; + return isAnthropicDirect || isCloudflareAnthropicProxy ? "short" : undefined; } export function resolveAnthropicBetas(