Files
openclaw/src/agents/anthropic-payload-policy.test.ts
André Santos eb0f367e00 fix(cache): enable prompt cache retention for Anthropic Vertex AI (#60888)
* fix(cache): enable prompt cache retention for Anthropic Vertex AI

* fix(cache): add anthropic-vertex to isAnthropicFamilyCacheTtlEligible

* fix(cache): use hostname parsing for long-TTL endpoint eligibility

* docs(changelog): note anthropic vertex cache ttl fix

---------

Co-authored-by: affsantos <andreffsantos91@gmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-04-05 08:07:02 +01:00

228 lines
6.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
applyAnthropicPayloadPolicyToParams,
resolveAnthropicPayloadPolicy,
} from "./anthropic-payload-policy.js";
import { SYSTEM_PROMPT_CACHE_BOUNDARY } from "./system-prompt-cache-boundary.js";
type TestPayload = {
messages: Array<{ role: string; content: unknown }>;
service_tier?: string;
system?: unknown;
};
describe("anthropic payload policy", () => {
it("applies native Anthropic service tier and cache markers without widening cache scope", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic",
api: "anthropic-messages",
baseUrl: "https://api.anthropic.com/v1",
cacheRetention: "long",
enableCacheControl: true,
serviceTier: "standard_only",
});
const payload: TestPayload = {
system: [
{ type: "text", text: "Follow policy." },
{ type: "text", text: "Use tools carefully." },
],
messages: [
{
role: "assistant",
content: [{ type: "text", text: "Working." }],
},
{
role: "user",
content: [
{ type: "text", text: "Hello" },
{ type: "tool_result", tool_use_id: "tool_1", content: "done" },
],
},
],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload.service_tier).toBe("standard_only");
expect(payload.system).toEqual([
{
type: "text",
text: "Follow policy.",
cache_control: { type: "ephemeral", ttl: "1h" },
},
{
type: "text",
text: "Use tools carefully.",
cache_control: { type: "ephemeral", ttl: "1h" },
},
]);
expect(payload.messages[0]).toEqual({
role: "assistant",
content: [{ type: "text", text: "Working." }],
});
expect(payload.messages[1]).toEqual({
role: "user",
content: [
{ type: "text", text: "Hello" },
{
type: "tool_result",
tool_use_id: "tool_1",
content: "done",
cache_control: { type: "ephemeral", ttl: "1h" },
},
],
});
});
it("denies proxied Anthropic service tier and omits long-TTL upgrades for custom hosts", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic",
api: "anthropic-messages",
baseUrl: "https://proxy.example.com/anthropic",
cacheRetention: "long",
enableCacheControl: true,
serviceTier: "auto",
});
const payload: TestPayload = {
system: [{ type: "text", text: "Follow policy." }],
messages: [{ role: "user", content: "Hello" }],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload).not.toHaveProperty("service_tier");
expect(payload.system).toEqual([
{
type: "text",
text: "Follow policy.",
cache_control: { type: "ephemeral" },
},
]);
expect(payload.messages[0]).toEqual({
role: "user",
content: [{ type: "text", text: "Hello", cache_control: { type: "ephemeral" } }],
});
});
it("splits cached stable system content from uncached dynamic content", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic",
api: "anthropic-messages",
baseUrl: "https://api.anthropic.com/v1",
cacheRetention: "long",
enableCacheControl: true,
});
const payload: TestPayload = {
system: [
{
type: "text",
text: `Stable prefix${SYSTEM_PROMPT_CACHE_BOUNDARY}Dynamic lab suffix`,
},
],
messages: [{ role: "user", content: "Hello" }],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload.system).toEqual([
{
type: "text",
text: "Stable prefix",
cache_control: { type: "ephemeral", ttl: "1h" },
},
{
type: "text",
text: "Dynamic lab suffix",
},
]);
});
it("applies 1h TTL for Vertex AI endpoints with long cache retention", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic-vertex",
api: "anthropic-messages",
baseUrl: "https://us-east5-aiplatform.googleapis.com",
cacheRetention: "long",
enableCacheControl: true,
});
const payload: TestPayload = {
system: [
{ type: "text", text: "Follow policy." },
{ type: "text", text: "Use tools carefully." },
],
messages: [{ role: "user", content: "Hello" }],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload.system).toEqual([
{
type: "text",
text: "Follow policy.",
cache_control: { type: "ephemeral", ttl: "1h" },
},
{
type: "text",
text: "Use tools carefully.",
cache_control: { type: "ephemeral", ttl: "1h" },
},
]);
expect(payload.messages[0]).toEqual({
role: "user",
content: [{ type: "text", text: "Hello", cache_control: { type: "ephemeral", ttl: "1h" } }],
});
});
it("applies 5m ephemeral cache for Vertex AI endpoints with short cache retention", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic-vertex",
api: "anthropic-messages",
baseUrl: "https://us-east5-aiplatform.googleapis.com",
cacheRetention: "short",
enableCacheControl: true,
});
const payload: TestPayload = {
system: [{ type: "text", text: "Follow policy." }],
messages: [{ role: "user", content: "Hello" }],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload.system).toEqual([
{
type: "text",
text: "Follow policy.",
cache_control: { type: "ephemeral" },
},
]);
});
it("strips the boundary even when cache retention is disabled", () => {
const policy = resolveAnthropicPayloadPolicy({
provider: "anthropic",
api: "anthropic-messages",
baseUrl: "https://api.anthropic.com/v1",
cacheRetention: "none",
enableCacheControl: true,
});
const payload: TestPayload = {
system: [
{
type: "text",
text: `Stable prefix${SYSTEM_PROMPT_CACHE_BOUNDARY}Dynamic lab suffix`,
},
],
messages: [{ role: "user", content: "Hello" }],
};
applyAnthropicPayloadPolicyToParams(payload, policy);
expect(payload.system).toEqual([
{
type: "text",
text: "Stable prefix\nDynamic lab suffix",
},
]);
});
});