Description
Summary
The transformBody() function in transforms.ts discards cache_control when splitting the SYSTEM_IDENTITY block from the rest of the system prompt. This prevents Anthropic from caching the full system prompt consistently, reducing cache efficiency from ~66% ~38% in agentic multi-turn sessions.
Offending code
(transforms.ts, equivalent to ~line 569 in compiled output) const { cache_control: _cc, ...identityProps } = entryProps; // ← destructures AND discards cache_control splitSystem.push({ ...identityProps, text: SYSTEM_IDENTITY }); // ← new block has NO cache_control ## Impact (measured empirically, same traffic, claude-sonnet-5)
|
With bug |
Fixed (preserve cache_control) |
| Cache efficiency |
38.4% |
66.4% |
| Cost/generation |
$0.49 FULL 33% 12/20 (60%) |
|
Without fix, system prompt (~230K tokens) only partially cached (tool definitions 32K). With fix, full 262K+ cache_read works from first call.
Proposed fix
const { cache_control, ...identityProps } = entryProps; // preserve const identityBlock = { ...identityProps, text: SYSTEM_IDENTITY }; if (cache_control) identityBlock.cache_control = cache_control; // re-attach splitSystem.push(identityBlock);
Environment
- Plugin: v2.1.6
- Model:
anthropic/claude-sonnet-5 via LiteLLM proxy
- pattern: agentic multi-turn 76 tools, ~230K token system prompt
Steps to reproduce
Open OpenCode
Use the plugin to auth with claude
Operating system
Linux
Plugin version
v2.1.6
OpenCode version
1.18.14
Debug logs
Description
Summary
The
transformBody()function intransforms.tsdiscardscache_controlwhen splitting theSYSTEM_IDENTITYblock from the rest of the system prompt. This prevents Anthropic from caching the full system prompt consistently, reducing cache efficiency from ~66% ~38% in agentic multi-turn sessions.Offending code
(transforms.ts, equivalent to ~line 569 in compiled output) const { cache_control: _cc, ...identityProps } = entryProps; // ← destructures AND discards cache_control splitSystem.push({ ...identityProps, text: SYSTEM_IDENTITY }); // ← new block has NO cache_control ## Impact (measured empirically, same traffic,
claude-sonnet-5)Without fix, system prompt (~230K tokens) only partially cached (tool definitions 32K). With fix, full 262K+ cache_read works from first call.
Proposed fix
const { cache_control, ...identityProps } = entryProps; // preserve const identityBlock = { ...identityProps, text: SYSTEM_IDENTITY }; if (cache_control) identityBlock.cache_control = cache_control; // re-attach splitSystem.push(identityBlock);
Environment
anthropic/claude-sonnet-5via LiteLLM proxySteps to reproduce
Open OpenCode
Use the plugin to auth with claude
Operating system
Linux
Plugin version
v2.1.6
OpenCode version
1.18.14
Debug logs