fabro/lib/crates/fabro-cli/src
Bryan Helmkamp e5f0290229
fix(llm): send cache_control breakpoints for Claude via OpenRouter
Anthropic prompt caching is opt-in per request: without explicit
ephemeral cache_control breakpoints in the body, no cache writes or
reads ever happen. The OpenAI-compatible codec never emitted them, so
every run on openrouter Claude models billed the full conversation at
the uncached input rate on every turn (0 cache tokens on the billing
page, confirmed by OpenRouter's activity portal).

- Add a `cache_control_breakpoints` model feature declaring that a
  route only caches when the request marks the cacheable prefix; set it
  on the builtin OpenRouter Claude rows. Catalog build rejects the flag
  without `prompt_cache`.
- Teach the Chat Completions wire shape a parts-form content variant so
  a message can carry the annotation; unmarked messages keep the
  plain-string form for compatibility with strict servers.
- Mark the last system message (covers tools + system upstream) and the
  second-to-last user turn, counting tool results as user turns —
  mirroring the anthropic codec's placement so agent loops get
  incremental cache hits.
- Extract the shared placement/opt-out policy into codec::cache and
  refactor the anthropic codec onto it; anthropic wire snapshots are
  unchanged.
- Honor `provider_options.<name>.auto_cache = false` as an opt-out and
  consume the control key instead of merging it into the body.
- Mirror the new feature through settings (fabro-config), the OpenAPI
  schema, and the generated TypeScript client.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 17:55:41 -04:00
..
commands fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
shared feat: make model aliases provider-aware 2026-07-23 10:12:25 -04:00
sleep_inhibitor fix sleep_inhibitor lints under --all-features clippy 2026-04-23 22:45:07 -04:00
args.rs Add fabro variable CLI namespace for server-managed variables (#434) 2026-05-27 13:57:25 -04:00
command_context.rs Clean up SQLite secrets migration and fix CLI env credential regression 2026-07-22 12:45:38 -04:00
gh.rs test(cli): trim slow integration fixture setup 2026-04-28 19:14:56 -07:00
landing.rs feat(cli): split run events and raw logs 2026-05-06 13:29:35 -04:00
local_server.rs Demote control-plane config to plain String; native FABRO_WEB_URL read (#510) 2026-06-18 10:03:14 -04:00
logging.rs fix(cli): keep run logs free of ANSI 2026-05-07 07:28:25 -07:00
main.rs Add fabro variable CLI namespace for server-managed variables (#434) 2026-05-27 13:57:25 -04:00
manifest_args.rs Replace run-scoped sandbox config with named environments (#360) 2026-05-23 13:03:21 -04:00
server_client.rs refactor(install): share persistence pipeline (#332) 2026-05-21 08:04:04 -04:00
server_runs.rs Simplify runs read model: single-source mappings, leaner queries 2026-07-22 13:55:22 -04:00
user_config.rs Demote control-plane config to plain String; native FABRO_WEB_URL read (#510) 2026-06-18 10:03:14 -04:00