Skip to content

feat: model-aware pricing with per-model cost breakdown - #39

Open
long-910 wants to merge 1 commit into
claude/perf-mtime-skip-y9ahrwfrom
claude/feat-model-pricing-y9ahrw
Open

long-910 wants to merge 1 commit into
claude/perf-mtime-skip-y9ahrwfrom
claude/feat-model-pricing-y9ahrw

Conversation

@long-910

@long-910 long-910 commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Stacked on #38 (which is stacked on #37) — all three touch the same reader code. Merge order: #37#38 → this. GitHub retargets the base automatically as each parent merges.

Summary

Costs were computed with one flat rate — the Sonnet-based claudeStatus.pricing.* defaults — regardless of which model produced each entry. That overestimates Haiku 4.5 usage ~3× and underestimates Opus usage up to 5×. Every JSONL entry carries message.model, so this PR prices each entry by its model.

Changes

Built-in per-model rates (resolveModelPricing() in jsonlReader.ts, first match wins, per 1M tokens; cache read = 0.1× input, cache write = 1.25× input per Anthropic's published pricing):

Match Family Input / Output
fable, mythos Fable 5 / Mythos 5 $10 / $50
claude-3-opus, opus-4-0/1, opus-4-2025 Legacy Opus ≤ 4.1 $15 / $75
opus Opus 4.5+ $5 / $25
haiku Haiku $1 / $5
sonnet Sonnet $3 / $15
  • New setting claudeStatus.pricing.useModelPricing (boolean, default true). Unrecognized models (e.g. <synthetic>) — and every entry when disabled — fall back to the manual claudeStatus.pricing.* rates, so the old behavior is one toggle away.
  • All cost consumers unified on CostOptions: readAllUsage, projectCost, prediction, heatmap now take config.costOptions. This also fixes a pre-existing inconsistency: prediction and heatmap previously ignored the user's pricing.* settings and always used the hardcoded defaults.
  • Dashboard: the token breakdown card gains a "By model (5h)" list (sonnet-4-5: $0.42, haiku-4-5: $0.03), fed by a new costByModel5h aggregate.
  • l10n: setting description and dashboard label in EN / JA / ZH (package.nls* + l10n/bundle.l10n.*).
  • Docs: docs/DATA.md (model-aware + manual pricing tables), docs/SETTINGS.md, README settings tables (EN / JA / ZH), CHANGELOG.

Tests

New suites cover rate resolution per family (including the legacy-Opus-before-generic-Opus ordering), fallback for unknown/missing models, the useModelPricing toggle in entryCost, and model parsing in readUsageEntries. npm run lint ✅, npm run compile ✅, unit suites (43 tests) ✅ via mocha; @vscode/test-electron cannot download VS Code in this sandbox — please rely on CI for the extension-host suites.

Note: since costs are estimates, displayed totals will change for users mixing models (they become more accurate). Called out in the CHANGELOG.

🤖 Generated with Claude Code

https://claude.ai/code/session_012ZLCLQeudf1LQBnBSyyr4f


Generated by Claude Code

Cost was previously computed with a single flat rate (Sonnet-based
claudeStatus.pricing.* defaults) regardless of which model produced each
entry, overestimating Haiku usage ~3x and underestimating Opus usage up
to 5x. Each JSONL entry carries message.model, so price entries by it.

- jsonlReader: built-in per-model rate table (Fable/Mythos 5, legacy
  Opus <=4.1, Opus 4.5+, Haiku, Sonnet) with resolveModelPricing() and
  entryCost(); UsageEntry gains a model field
- New setting claudeStatus.pricing.useModelPricing (default true);
  unknown models and disabled mode fall back to manual pricing.* rates
- All cost consumers (readAllUsage, projectCost, prediction, heatmap)
  now take CostOptions from config; prediction and heatmap previously
  ignored user pricing settings entirely and always used defaults
- AggregatedUsage gains costByModel5h; dashboard token breakdown lists
  per-model 5h cost
- l10n: EN/JA/ZH for the setting description and dashboard label
- Docs: DATA.md pricing tables, SETTINGS.md, README (EN/JA/ZH), CHANGELOG
- Tests: rate resolution, fallback, entryCost toggle, model parsing

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012ZLCLQeudf1LQBnBSyyr4f
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.

2 participants