fix(cc-compatible): keep cache ttl ordering valid (#948)

This commit is contained in:
Randi
2026-04-03 09:17:21 -04:00
committed by GitHub
parent 082cb86a23
commit be2f7cb3e5
2 changed files with 56 additions and 18 deletions

View File

@@ -397,8 +397,14 @@ function buildClaudeCodeCompatibleSystemBlocks({
}) {
const customSystemBlocks =
Array.isArray(systemBlocks) && systemBlocks.length > 0
? systemBlocks
? systemBlocks.map((block) => ({ ...block }))
: extractCustomSystemBlocks(messages);
const useLongSystemTtl =
!preserveCacheControl ||
customSystemBlocks.some((block) => readCacheControlTtl(block) === "1h");
const systemCacheControl = useLongSystemTtl
? { type: "ephemeral", ttl: "1h" }
: { type: "ephemeral" };
const dateText = formatDate(now);
const blocks: Array<Record<string, unknown>> = [
@@ -409,17 +415,21 @@ function buildClaudeCodeCompatibleSystemBlocks({
{
type: "text",
text: "You are a Claude agent, built on Anthropic's Claude Agent SDK.",
cache_control: { type: "ephemeral" },
cache_control: { ...systemCacheControl },
},
{
type: "text",
text: `You are Claude Code, Anthropic's official CLI for Claude.\n\nCWD: ${cwd}\nDate: ${dateText}`,
cache_control: { type: "ephemeral" },
cache_control: { ...systemCacheControl },
},
];
for (const systemBlock of customSystemBlocks) {
blocks.push(systemBlock);
const preparedBlock = { ...systemBlock };
if (!preserveCacheControl || useLongSystemTtl) {
preparedBlock.cache_control = { ...systemCacheControl };
}
blocks.push(preparedBlock);
}
if (
@@ -427,8 +437,8 @@ function buildClaudeCodeCompatibleSystemBlocks({
customSystemBlocks.length > 0 &&
!customSystemBlocks.some((block) => hasCacheControl(block))
) {
const lastCustomSystemBlock = customSystemBlocks[customSystemBlocks.length - 1];
lastCustomSystemBlock.cache_control = { type: "ephemeral", ttl: "1h" };
const lastCustomSystemBlock = blocks[blocks.length - 1];
lastCustomSystemBlock.cache_control = { ...systemCacheControl };
}
return blocks;
@@ -650,7 +660,7 @@ function convertClaudeCodeCompatibleClaudeMessage(
function extractCustomSystemBlocks(messages: MessageLike[] | undefined) {
if (!Array.isArray(messages)) return [];
const blocks = messages
return messages
.filter((message) => {
const role = String(message?.role || "").toLowerCase();
return role === "system" || role === "developer";
@@ -660,14 +670,7 @@ function extractCustomSystemBlocks(messages: MessageLike[] | undefined) {
.map((text) => ({
type: "text",
text,
cache_control: { type: "ephemeral" },
}));
if (blocks.length > 0) {
blocks[blocks.length - 1].cache_control = { type: "ephemeral", ttl: "1h" };
}
return blocks;
}
function applyClaudeCodeCompatibleMessageCacheStrategy(
@@ -762,6 +765,10 @@ function hasCacheControl(value: unknown) {
return !!readRecord(value)?.cache_control && typeof readRecord(value)?.cache_control === "object";
}
function readCacheControlTtl(value: unknown) {
return toNonEmptyString(readRecord(readRecord(value)?.cache_control)?.ttl);
}
function findLastCacheableToolIndex(tools: Array<Record<string, unknown>>) {
for (let i = tools.length - 1; i >= 0; i--) {
if (!tools[i].defer_loading) {

View File

@@ -109,6 +109,9 @@ test("buildClaudeCodeCompatibleRequest keeps prior role history while dropping t
assert.deepEqual(payload.messages[2].content.at(-1).cache_control, { type: "ephemeral" });
assert.equal(payload.system.length, 4);
assert.equal(payload.system.at(-1).text, "sys");
assert.deepEqual(payload.system[1].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[2].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[3].cache_control, { type: "ephemeral", ttl: "1h" });
assert.equal(payload.tools.length, 1);
const { cache_control, ...toolWithoutCacheControl } = payload.tools[0];
assert.deepEqual(toolWithoutCacheControl, {
@@ -230,9 +233,38 @@ test("buildClaudeCodeCompatibleRequest supplements missing Claude cache markers
assert.deepEqual(payload.messages[0].content[0].cache_control, { type: "ephemeral" });
assert.deepEqual(payload.messages[1].content[0].cache_control, { type: "ephemeral" });
assert.deepEqual(payload.messages[2].content[0].cache_control, { type: "ephemeral" });
assert.deepEqual(payload.system.at(-1).cache_control, { type: "ephemeral" });
assert.deepEqual(payload.tools[0].cache_control, { type: "ephemeral", ttl: "1h" });
});
test("buildClaudeCodeCompatibleRequest upgrades built-in system cache markers when preserved system uses 1h", () => {
const payload = buildClaudeCodeCompatibleRequest({
sourceBody: {
max_tokens: 64,
},
normalizedBody: {
max_tokens: 64,
messages: [{ role: "user", content: "fallback" }],
},
claudeBody: {
system: [
{ type: "text", text: "prefix", cache_control: { type: "ephemeral" } },
{ type: "text", text: "stable", cache_control: { type: "ephemeral", ttl: "1h" } },
],
messages: [{ role: "user", content: [{ type: "text", text: "u1" }] }],
tools: [],
},
model: "claude-sonnet-4-6",
sessionId: "session-preserve-system-upgrade",
preserveCacheControl: true,
});
assert.deepEqual(payload.system[1].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[2].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[3].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[4].cache_control, { type: "ephemeral", ttl: "1h" });
});
test("buildClaudeCodeCompatibleRequest marks final user turn and 1h system cache in non-preserve mode", () => {
const largeUserPrompt = Array.from(
{ length: 200 },
@@ -257,10 +289,9 @@ test("buildClaudeCodeCompatibleRequest marks final user turn and 1h system cache
preserveCacheControl: false,
});
assert.deepEqual(payload.system.at(-1).cache_control, {
type: "ephemeral",
ttl: "1h",
});
assert.deepEqual(payload.system[1].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[2].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.system[3].cache_control, { type: "ephemeral", ttl: "1h" });
assert.deepEqual(payload.messages[0].content[0].cache_control, { type: "ephemeral" });
assert.deepEqual(payload.messages[1].content[0].cache_control, { type: "ephemeral" });
assert.deepEqual(payload.messages[2].content[0].cache_control, { type: "ephemeral" });