The bug
lib/ai-pricing.ts says it outright:
// Cache reads bill at the input rate here (we already fold cache_read/creation
// into `input` in user-ai.ts), which slightly over-estimates cached calls
"Slightly" is doing a lot of work. Anthropic bills cache reads at ~10% of the input rate and cache writes at 1.25×. Folding both into input at the full $3/M is a 10× overcharge on the read path.
Live 30d ledger, chat kind: input=4,796,074, of which cache_read=993,574. Those tokens are charged ~$2.98 and really cost ~$0.30 — about $2.68 overstated on one kind alone, ~7% of the reported total. The ratio gets worse as prompt caching does its job, so the error grows precisely as the platform gets more efficient.
Fix
- Stop folding
cache_read_input_tokens / cache_creation_input_tokens into input in user-ai.ts — carry them as their own fields.
- Add
cacheReadPerM / cacheWritePerM to the PRICES table (Anthropic: 0.1× and 1.25× of input).
- Price the three components separately.
- Storage:
ai_usage has input_tokens/output_tokens only. Add nullable cache_read_tokens/cache_write_tokens columns in a migration; existing rows stay NULL and keep their historical (over-stated) cost rather than being retro-corrected.
Acceptance
Note the sign: this makes reported cost go down. It does not offset #267, which makes it go up by more.
The bug
lib/ai-pricing.tssays it outright:"Slightly" is doing a lot of work. Anthropic bills cache reads at ~10% of the input rate and cache writes at 1.25×. Folding both into
inputat the full $3/M is a 10× overcharge on the read path.Live 30d ledger, chat kind:
input=4,796,074, of whichcache_read=993,574. Those tokens are charged ~$2.98 and really cost ~$0.30 — about $2.68 overstated on one kind alone, ~7% of the reported total. The ratio gets worse as prompt caching does its job, so the error grows precisely as the platform gets more efficient.Fix
cache_read_input_tokens/cache_creation_input_tokensintoinputinuser-ai.ts— carry them as their own fields.cacheReadPerM/cacheWritePerMto thePRICEStable (Anthropic: 0.1× and 1.25× of input).ai_usagehasinput_tokens/output_tokensonly. Add nullablecache_read_tokens/cache_write_tokenscolumns in a migration; existing rows stay NULL and keep their historical (over-stated) cost rather than being retro-corrected.Acceptance
Note the sign: this makes reported cost go down. It does not offset #267, which makes it go up by more.