fix(claude): reserve cache breakpoint for thread continuation

- Decrement `maxBlocks` when a `thread` field is present in payload to reserve a cache breakpoint for Anthropic thread continuation

Closes: #6338
This commit is contained in:
Luis Pater
2026-10-04 21:00:20 +08:00
parent 5d890405b5
commit 26e5efbbdf
2 changed files with 27 additions and 0 deletions

View File

@@ -1876,6 +1876,12 @@ func enforceCacheControlLimit(payload []byte, maxBlocks int) []byte {
return payload
}
thread := gjson.GetBytes(payload, "thread")
if thread.Exists() && thread.Type != gjson.Null && maxBlocks > 0 {
// Anthropic reserves one cache breakpoint for thread continuation.
maxBlocks--
}
total := countCacheControls(payload)
if total <= maxBlocks {
return payload

View File

@@ -3240,6 +3240,27 @@ func TestEnforceCacheControlLimit_PreservesKeyOrderWhenModified(t *testing.T) {
}
}
func TestEnforceCacheControlLimit_ReservesThreadMarker(t *testing.T) {
payload := []byte(`{
"thread": {"type":"create"},
"tools": [{"name":"t1","cache_control":{"type":"ephemeral"}}],
"system": [
{"type":"text","text":"s1","cache_control":{"type":"ephemeral"}},
{"type":"text","text":"s2","cache_control":{"type":"ephemeral"}}
],
"messages": [{"role":"user","content":[
{"type":"text","text":"u1","cache_control":{"type":"ephemeral"}},
{"type":"text","text":"u2","cache_control":{"type":"ephemeral"}}
]}]
}`)
out := enforceCacheControlLimit(payload, 4)
if got := countCacheControls(out); got != 3 {
t.Fatalf("cache_control count = %d, want 3 when thread is present", got)
}
}
func TestEnforceCacheControlLimit_ToolOnlyPayloadStillRespectsLimit(t *testing.T) {
payload := []byte(`{
"tools": [