Skip to content

fix(chat): inject cache breakpoints in marker-less claude passthrough - #18025

Draft
patrykkopycinski wants to merge 2 commits into
cheaper-inference:mainfrom
patrykkopycinski:fix/passthrough-cache-breakpoints
Draft

patrykkopycinski wants to merge 2 commits into
cheaper-inference:mainfrom
patrykkopycinski:fix/passthrough-cache-breakpoints

Conversation

@patrykkopycinski

Copy link
Copy Markdown
Contributor

What this fixes

Marker-less Anthropic-format clients (e.g. Cursor) send zero cache_control markers through the pure claude→claude passthrough branch, so every turn re-bills the full prompt prefix. On one gateway this measured 678M uncached prompt tokens/week on provider=claude.

Change

ensurePassthroughCacheBreakpoints (new helper in claudeHelper.ts) now runs in the plain passthrough branch of chatCore/claudePassthroughBody.ts for Anthropic-native upstreams (claude + anthropic-compatible-*):

  • Injects only when the body carries no markers anywhere — a client managing its own breakpoints passes through byte-untouched
  • Placement mirrors the standard heuristic: system tail ttl=1h, second-to-last user message + last assistant message plain ephemeral
  • The CC semantic-passthrough branch keeps its own contract (ensureCacheControlOnLastUserMessage)
  • extended-cache-ttl beta is already in ANTHROPIC_BETA_BASE, so ttl=1h markers are accepted upstream

Tests

  • tests/unit/claude-passthrough-cache-rescue.test.ts — helper contract (inject-on-marker-less, zero-injection on client-managed)
  • tests/unit/claude-passthrough-cache-wiring.test.ts — handleChatCore-level wiring test with mocked upstream; includes a mutation arm (call disabled → test red)
  • Full passthrough-family regression: 307/307 pass on this base

Anthropic-format requests forwarded through the non-CC pure passthrough
branch reached upstream with zero cache_control markers whenever the
client shipped none (e.g. Cursor) — re-billing the full prompt prefix
every turn (678M uncached prompt tokens/week observed on one gateway).

ensurePassthroughCacheBreakpoints now runs in the plain passthrough
branch for Anthropic-native upstreams (claude + anthropic-compatible-*)
and injects the standard breakpoint set only when the body carries no
markers anywhere: system tail ttl=1h, second-to-last user message and
last assistant message plain ephemeral. A client that manages its own
markers stays byte-untouched. The CC semantic-passthrough branch keeps
its own contract (ensureCacheControlOnLastUserMessage).

Wiring is pinned by a handleChatCore-level test with a mocked upstream:
injection asserted on the marker-less body, zero-injection on the
client-managed body, and a mutation arm (call disabled → test red)
proved the wiring bites. extended-cache-ttl beta is already in
ANTHROPIC_BETA_BASE, so ttl=1h markers are accepted upstream.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant