feat(claude): add ttl to cache_control with default 5m

Real Claude CLI traffic sends cache_control as
`{"type":"ephemeral","ttl":"1h"}`. Our previous payload only
sent `{"type":"ephemeral"}`, which is a bytewise mismatch with
the official CLI and one more third-party detection signal.

Policy: client-provided ttl is always passed through unchanged.
Proxy-generated cache_control blocks default to 5m (vs Parrot's 1h)
to avoid burning the 1h cache budget on automatic breakpoints while
still aligning with the `ttl` field being present.

  - claude/constants.go: DefaultCacheControlTTL = "5m"
  - apicompat/types.go: new AnthropicCacheControl type with TTL field;
    AnthropicTool gains optional CacheControl pointer so the mimicry
    path can attach a cache breakpoint to tools[-1] later.
  - service/gateway_service.go: anthropicCacheControlPayload gains TTL;
    marshalAnthropicSystemTextBlock and rewriteSystemForNonClaudeCode
    emit ttl=5m by default.
This commit is contained in:
keh4l
2026-04-24 23:16:32 +08:00
parent 165553cfb0
commit 66d6454535
3 changed files with 23 additions and 6 deletions
+6 -2
View File
@@ -850,6 +850,7 @@ func (s *GatewayService) hashContent(content string) string {
type anthropicCacheControlPayload struct {
Type string `json:"type"`
TTL string `json:"ttl,omitempty"`
}
type anthropicSystemTextBlockPayload struct {
@@ -898,7 +899,10 @@ func marshalAnthropicSystemTextBlock(text string, includeCacheControl bool) ([]b
Text: text,
}
if includeCacheControl {
block.CacheControl = &anthropicCacheControlPayload{Type: "ephemeral"}
block.CacheControl = &anthropicCacheControlPayload{
Type: "ephemeral",
TTL: claude.DefaultCacheControlTTL,
}
}
return json.Marshal(block)
}
@@ -3856,7 +3860,7 @@ func rewriteSystemForNonClaudeCode(body []byte, system any) []byte {
{
"type": "text",
"text": claudeCodeSystemPrompt,
"cache_control": map[string]string{"type": "ephemeral"},
"cache_control": map[string]string{"type": "ephemeral", "ttl": claude.DefaultCacheControlTTL},
},
}
out, ok := setJSONValueBytes(body, "system", claudeCodeSystemBlock)