Bug Report
OpenClaw version: 2026.3.28
Provider: anthropic (direct)
Model: anthropic/claude-sonnet-4-6
Summary
Prompt caching (\cache_control: { type: ephemeral }) is applied to system messages on the OpenRouter provider path via \createOpenRouterSystemCacheWrapper, but is NOT applied on the direct Anthropic provider path. This results in \cacheRead=0\ on every turn for users using the direct Anthropic API, causing significant unnecessary cost.
Root Cause (from source analysis of pi-embedded-BaSvmUpW.js)
The function \createOpenRouterSystemCacheWrapper\ correctly wraps system prompt content with \cache_control: { type: ephemeral }\ but is gated behind \isOpenRouterAnthropicModel(). The direct Anthropic path (\provider === anthropic) goes through
esolveCacheRetention()\ which sets TTL duration but does NOT inject the \cache_control\ marker on the message content — the actual mechanism Anthropic uses to establish a cache entry.
Impact
- \cacheRead=0\ on every turn for direct Anthropic users
- Full input token cost on every turn for repeated system prompt content
- On a long working session (100k+ token system prompt, 100+ turns): ~10x higher cost than expected
- Real-world example: single 14-hour session cost .89 due to this issue
Expected Behavior
Direct Anthropic provider path should apply \cache_control: { type: ephemeral }\ to system prompt messages, consistent with OpenRouter path behavior.
Workaround
Routing through \openrouter/auto\ activates the cache wrapper but introduces uncontrolled model selection (routes to Opus instead of Sonnet despite account-level defaults), negating cost savings. No clean workaround exists.
Request
Apply equivalent \cache_control\ injection to the direct Anthropic provider path, or expose a config option to explicitly enable it.
Bug Report
OpenClaw version: 2026.3.28
Provider: anthropic (direct)
Model: anthropic/claude-sonnet-4-6
Summary
Prompt caching (\cache_control: { type: ephemeral }) is applied to system messages on the OpenRouter provider path via \createOpenRouterSystemCacheWrapper, but is NOT applied on the direct Anthropic provider path. This results in \cacheRead=0\ on every turn for users using the direct Anthropic API, causing significant unnecessary cost.
Root Cause (from source analysis of pi-embedded-BaSvmUpW.js)
The function \createOpenRouterSystemCacheWrapper\ correctly wraps system prompt content with \cache_control: { type: ephemeral }\ but is gated behind \isOpenRouterAnthropicModel(). The direct Anthropic path (\provider === anthropic) goes through
esolveCacheRetention()\ which sets TTL duration but does NOT inject the \cache_control\ marker on the message content — the actual mechanism Anthropic uses to establish a cache entry.
Impact
Expected Behavior
Direct Anthropic provider path should apply \cache_control: { type: ephemeral }\ to system prompt messages, consistent with OpenRouter path behavior.
Workaround
Routing through \openrouter/auto\ activates the cache wrapper but introduces uncontrolled model selection (routes to Opus instead of Sonnet despite account-level defaults), negating cost savings. No clean workaround exists.
Request
Apply equivalent \cache_control\ injection to the direct Anthropic provider path, or expose a config option to explicitly enable it.