SIGN IN SIGN UP

fix(third-party): strip undocumented cache_control subfields for custom upstreams (#297)

* fix(third-party): strip undocumented cache_control subfields for custom upstreams

Claude Code sends a scope subfield inside cache_control that Anthropic
accepts but strict Anthropic-compatible backends reject with 400 unknown
parameter, breaking every request once such an account is selected.
Forward only the documented type/ttl there; Anthropic legs pass through
byte-identical.

* fix(third-party): forward only cache_control type to custom upstreams

Probed against api.meta.ai: scope is an unknown parameter and ttl:1h is
not supported; bare type:ephemeral and type+ttl:5m both return 200. Since
5m is the default window, dropping ttl is lossless except on backends
with 1h windows — and requests there still succeed.

* fix(third-party): make the cache_control strip opt-in, keep ttl, walk only breakpoints

Three changes from review:

- `ttl` is documented by Anthropic ("5m" | "1h") and a mirror that honours
  "1h" must keep it, so it is no longer dropped by default.
- Nothing is dropped unless the account opts in, like every other body rewrite
  keyed on `upstream`: `stripRequestFields` accepts `"cache_control.<sub>"`
  entries (e.g. `["cache_control.scope"]`), and only those subfields go. A
  first-party relay or regional mirror pointed at by `upstream` loses nothing.
- Only the documented breakpoint positions are walked — the root, `system[]`,
  `messages[].content[]` (and a tool_result's own content blocks), `tools[]`.
  A `cache_control` key inside a `tool_use.input`, a `tool_result` payload or
  `metadata` is data, not a cache hint, and is left byte-identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Mark Karpeles <magicaltux@gmail.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
A
aram.eth committed
344ff383efca1791703fef920882a6619b7c43be
Parent: 73dc784
Committed by GitHub <noreply@github.com> on 9/8/2026, 2:57:21 PM