fabro/lib/crates
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
..
build-support fix(build): refresh embedded git sha on branch commits 2026-05-09 14:10:04 -04:00
fabro-acp Resolve run.prepare.steps env and interpolation at the run boundary (#530) 2026-07-01 10:31:26 -04:00
fabro-agent fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-api fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-auth refactor(llm): simplify session trace header plumbing 2026-07-23 13:38:18 -04:00
fabro-automation Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-checkpoint Demote non-interpolating config fields to plain String (#492) 2026-06-16 13:16:31 -04:00
fabro-cli fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-client feat: make model aliases provider-aware 2026-07-23 10:12:25 -04:00
fabro-config fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-core Replace bare unwrap() with documented expect() across production runtim… (#415) 2026-05-26 17:46:39 -04:00
fabro-db Simplify runs read model: single-source mappings, leaner queries 2026-07-22 13:55:22 -04:00
fabro-dev feat: make model aliases provider-aware 2026-07-23 10:12:25 -04:00
fabro-dump feat(web): add server-managed Environments CRUD settings UI (#462) 2026-06-13 08:44:38 -04:00
fabro-environment Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-github fix(github): refresh installation tokens during workflows 2026-05-06 07:15:18 -04:00
fabro-graphviz fabro(01KY7Y01REECZ24XXTMBZ3PPV9): simplify_fable (succeeded) 2026-07-23 19:10:39 +00:00
fabro-hooks feat: make model aliases provider-aware 2026-07-23 10:12:25 -04:00
fabro-http refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
fabro-install Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-interview Replace stdin JSONL control pipe with WebSocket worker control bus (#440) 2026-05-27 20:24:25 -04:00
fabro-llm fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-macros refactor(dev): simplify generated docs tooling 2026-04-24 18:41:00 -04:00
fabro-manifest Demote non-interpolating config fields to plain String (#492) 2026-06-16 13:16:31 -04:00
fabro-mcp fix(mcp): honor inline enabled=false and per-server tool_timeout (#520) 2026-06-24 16:17:27 -04:00
fabro-mcp-server feat: Add approve/deny run controls to MCP and CLI (#400) 2026-05-25 15:49:57 -04:00
fabro-mcp-store Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-model fix(llm): send cache_control breakpoints for Claude via OpenRouter 2026-07-23 17:55:41 -04:00
fabro-oauth Replace bare unwrap() with documented expect() across production runtim… (#415) 2026-05-26 17:46:39 -04:00
fabro-options-metadata refactor(dev): simplify generated docs tooling 2026-04-24 18:41:00 -04:00
fabro-proc refactor(static): centralize env var names 2026-04-24 12:29:51 -04:00
fabro-redact feat(llm): add Poolside Laguna models 2026-07-22 18:49:16 -04:00
fabro-sandbox feat(workflow): keep push credentials fresh across long ACP turns 2026-07-11 02:47:31 +02:00
fabro-server fix(test): replay SSE events before asserting stage types 2026-07-23 14:58:01 -04:00
fabro-slack Replace vague expect/panic messages with invariant-explaining messages (#422) 2026-05-27 10:38:20 -04:00
fabro-spa Fix web app load performance: caching, compression, and eager chunk loading (#550) 2026-07-02 16:58:47 -04:00
fabro-static fix(test): strip inherited color-forcing env vars in brew upgrade tests 2026-07-23 11:19:01 -04:00
fabro-store fix(server): make generated title updates atomic 2026-07-23 14:18:04 -04:00
fabro-telemetry Replace vague expect/panic messages with invariant-explaining messages (#422) 2026-05-27 10:38:20 -04:00
fabro-template Hooks: typed end-to-end interpolation, narrow header tokens, fail-closed resolution (#528) 2026-06-30 17:07:11 -04:00
fabro-test fix(test): eliminate install and session-root races 2026-07-23 16:46:40 -04:00
fabro-tool feat(web): add server-managed Environments CRUD settings UI (#462) 2026-06-13 08:44:38 -04:00
fabro-tracker fix(github): refresh installation tokens during workflows 2026-05-06 07:15:18 -04:00
fabro-types fix: preserve provider pins during model routing 2026-07-23 13:11:49 -04:00
fabro-util Resolve run.prepare.steps env and interpolation at the run boundary (#530) 2026-07-01 10:31:26 -04:00
fabro-validate Merge remote-tracking branch 'origin/main' into fabro/run/01KY7Y01REECZ24XXTMBZ3PPV9 2026-07-23 20:29:21 +00:00
fabro-variable Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-vault Simplify SQLite stores after review pass 2026-07-22 13:37:31 -04:00
fabro-workflow Merge pull request #601 from fabro-sh/fabro/run/01KY7Y01REECZ24XXTMBZ3PPV9 2026-07-23 17:14:51 -04:00