Sprag

Claude Code statusline behind LiteLLM and other gateways

How the Sprag statusline reads spend, budgets and cache TTL when Claude Code runs through LiteLLM or another API gateway, and why the cache countdown can look frozen.

🌐 Behind a gateway (Bedrock / Vertex)

A gateway reports the cache-creation total but never the 5m/1h split. That left the tool unable to tell "nothing cached yet" from "this provider does not say", and the fallback assumed an hour — for a window that is really five minutes on Bedrock, overstating it twelvefold.

Since v3.26.0 the gateway is detected from the model ids in the transcript, which fixes:

If the detection is wrong, pin it with sprag mode ttl=5m (or ttl=1h). An explicit value outranks the measurement.

LiteLLM: your key budget stands in for the missing 5h/7d caps (v3.35.0)

Behind a LiteLLM proxy (Bedrock and friends), Claude Code's stdin never carries rate_limits, so the ✦ current / 📅 weekly gauges simply do not exist. LiteLLM does track per-key budgets, so the statusline draws a budget gauge in their place.

One related non-bug: if your session model is already sonnet, a sonnet-delegation (T1) rule can never save anything, because there is no price gap to capture. That is correct, but route-scan rules displayed it identically to "no delegations yet", so it now says outright that the rule does not apply at the current default model.

Pricing (Jul 2026)

Per million tokens (USD), as used by the cost estimator:

TierModelsInput5m Write1h WriteReadOutput
claude-fable-5Fable 5 / Mythos 5$10$12.50$20$1$50
claude-opus-newOpus 4.5 / 4.6 / 4.7 / 4.8$5$6.25$10$0.50$25
claude-opus-legacyOpus 4 / 4.1 / 3$15$18.75$30$1.50$75
claude-sonnetSonnet 3.7 / 4 / 4.5 / 4.6 / 5$3$3.75$6$0.30$15
claude-haiku-4-5Haiku 4.5$1$1.25$2$0.10$5

Source: Anthropic pricing docs. Sonnet 5 has an introductory $2/$10 rate through 2026-08-31; the estimator uses the standard sticker. Versions ≤ 2.16.x priced Fable 5 at the Sonnet tier (~3× under-estimate) — upgrade to 2.17.0+.

Cache TTL by plan

PlanTTLControlled by
Max ($100–200/mo)1h autotengu_prompt_cache_1h_config flag
Pro ($20/mo)5m fixednot configurable
API key5m default (1h via beta header)cache_control.ttl

FAQ

Is this the same tool as claude-token-saver? Yes. Sprag is the new name; the npm package is sprag-cli, and the claude-token-saver package keeps receiving the same releases so nothing breaks.

Does it call an LLM or need an API key? No. Everything is post-hoc analysis of the session logs Claude Code already writes on your machine. No extra model calls, no key, no telemetry leaves your computer.

Will it change how I prompt? No. It installs hooks and a statusline once, then works from what you already do. Rules, delegation, and warnings show up inside your normal sessions.

Where do the savings numbers come from? Each delegated run writes a ledger entry with the actual price difference. The tier criteria behind the routing are benchmarked on public data; the method is in docs/BENCHMARK.md.

How it works · Environment

Claude Code logs every API call to ~/.claude/projects/<dir>/<session>.jsonl. This tool dedupes streaming chunks by requestId and aggregates cache_read_input_tokens / cache_creation.ephemeral_5m/1h_input_tokens by day and session.

Node.js ≥ 18 · macOS / Linux / Windows / WSL · zero dependencies.

Known quirks · Migration · Background

IntelliJ Claude Code plugin — the statusline widget fuses frames at the character level when emoji are present (59:548 artifacts). v2.8.5+ detects TERMINAL_EMULATOR=JetBrains-JediTerm and falls back to text mode automatically.

If the countdown looks frozen: ticking while idle requires Claude Code to re-run the statusline command on a timer, controlled by statusLine.refreshInterval (seconds, Claude Code v2.1.97+) in ~/.claude/settings.json. Without it the line only redraws when the conversation updates. If behavior differs per terminal, check three things: ① that machine's Claude Code is ≥ 2.1.97; ② no project .claude/settings.json / settings.local.json overrides statusLine without a refreshInterval; ③ the statusline wrapper actually finds sprag on PATH instead of falling back to a multi-second npx run on every render (typical when nvm is not loaded in non-login shells). Re-running sprag install restores refreshInterval=5.

Migration from claude-cache-monitor:

npm uninstall -g claude-cache-monitor && npm i -g sprag-cli

Also update statusLine.command in ~/.claude/settings.json to sprag ….

Background: GitHub Issue #46829 (cache TTL regression) · HN discussion


More docs