Skip to content

feat(#822): warn when a run's prompts sit under the model's cache minimum - #983

Open
0frankie wants to merge 1 commit into
mainfrom
fix/822-cache-min-warning
Open

feat(#822): warn when a run's prompts sit under the model's cache minimum#983
0frankie wants to merge 1 commit into
mainfrom
fix/822-cache-min-warning

Conversation

@0frankie

@0frankie 0frankie commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

What

Decision 1 of #822: make a silently-uncacheable run announce itself instead of being distinguishable only by post-hoc token arithmetic.

Sample: prompt caching never engages for claude-haiku-4-5: median prompt 1500 tokens is under its 4096-token cache minimum

Web mirror rides along (carry onto prod)

test_live_ts_usage_summary_mirrors_the_usage_route drives the real route and requires live.ts's UsageSummary to name every wire field, so the type gains cache_warning?: string | null in this PR — the same documented exception as #979/#980. Flag for the next main→prod web sync.

Out of scope

The issue's decision 2 — padding the stable Haiku prefix past 4096 to buy cache eligibility — is a measurement experiment, deliberately not bundled with the warning.

Verification

  • TDD: 5 new tests in tests/test_usage.py, each watched failing (ImportError/AttributeError) before the implementation existed.
  • Engine suite: 1502 passed, 2 skipped. Backend suite: 971 passed (after the mirror fix; it was 970+1F before, which is what surfaced the live.ts requirement). black --check clean.
  • Known environmental failure only: test_godot_scenes_render times out in any fresh worktree (no imported .godot cache, [release] Retire restricted art before the public repo publish #876 assets absent) — pre-existing on the base commit, unrelated.

Closes #822 (decision 1; decision 2 tracked in the issue).

🤖 Generated with Claude Code

…imum

Anthropic's minimum cacheable prefix is model-dependent (Haiku 4.5:
4096 tokens, Sonnet/Opus 4.x: 1024, Opus 5: 512), and a prompt below it
silently never caches -- cache_creation_input_tokens stays 0 with no
error, which is how two runs and 981k input tokens read as 'caching is
dead' when the prompts were just under Haiku's bar (#822).

The ledger now says so: CACHE_MIN_PROMPT_TOKENS pins the per-model
minimums, UsageLedger.cache_warning() names each model whose median
real prompt (failed calls and zero-token mock rows excluded) sits under
its minimum with zero cache traffic, and summary() carries the string
as cache_warning -- so it reaches the RunLog footer, GET /usage, and
the run monitor through the existing seams. Models without a known
minimum (OpenAI, mock, unlisted) are never warned about, and any cache
traffic on a model silences its warning.

live.ts's UsageSummary names the new field -- the emitter-driven mirror
test (test_live_ts_usage_summary_mirrors_the_usage_route) requires the
union of wire fields, so the type rides this PR; carry it onto prod
with the next web sync, like #979/#980.

The issue's second question (pad the Haiku prefix past 4096 to buy
eligibility) stays open -- that's a measurement, not a warning.

TDD: 5 new tests in tests/test_usage.py, each watched failing
(ImportError/AttributeError) before implementation. Suites: engine
1502 passed / 2 skipped, backend 971 passed (godot scene smoke
deselected -- times out in any fresh worktree, pre-existing on base).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

Prompt caching never engages under Haiku: Penn prompts sit below its 4096-token cache minimum

1 participant