Skip to content

fix(usage): count cached tokens in every total — Codebase/Today/Yesterday were ~99% short - #152

Merged
ltmoerdani merged 2 commits into
ltmoerdani:mainfrom
Fahad090NP:fix/token-counting
Aug 14, 2026
Merged

fix(usage): count cached tokens in every total — Codebase/Today/Yesterday were ~99% short#152
ltmoerdani merged 2 commits into
ltmoerdani:mainfrom
Fahad090NP:fix/token-counting

Conversation

@Fahad090NP

Copy link
Copy Markdown
Contributor

What

The CLI's per-message tokens.input excludes cache reads, and the sums used for the usage rows and charts (input + output + reasoning) dropped cache.read entirely. DeepSeek V4 sessions routinely carry ~700K cached prompt tokens per message, so the displayed totals massively undercounted (verified: codebase showed ~6M tokens vs the real ~954M).

Fix

  • HistoryRow now carries a computed tokensTotal = input + output + reasoning + cache.read, verified against the DB's authoritative tokens.total (matches real rows exactly).
  • Every counting site uses it: sumDailyUsage (Today/Yesterday), buildUsageSeries (charts + Models tab), codebaseUsage (Codebase row).
  • Extension-tracked entries already included cached tokens in promptTokens, so the two sources are now consistent.

Audited and left as-is (already correct)

  • Requests — 1 per assistant message + 1 per extension-tracked entry (no overlap).
  • Price — CLI rows use the DB's own per-message cost (authoritative); extension-side billing uses billable = prompt − cached.

Verification

New regression test with a cache-heavy DeepSeek row; 277 unit tests, strict ESLint + tsc + prettier + markdownlint green, VSIX packages and installs cleanly.

…rday were ~99% short

The CLI's per-message tokens.input EXCLUDES cache reads; the sums used for
the rows and charts (input + output + reasoning) dropped cache.read
entirely. DeepSeek V4 sessions routinely carry ~700K cached prompt tokens
per message, so the displayed totals massively undercounted.

HistoryRow now carries a computed tokensTotal
(input + output + reasoning + cache.read), verified against the DB's
authoritative tokens.total, and every counting site
(sumDailyUsage / buildUsageSeries / codebaseUsage) uses it. The extension's
own tracked entries already included cached tokens in promptTokens, so the
two sources are now consistent. Requests (1 per assistant message) and
costs (CLI's own per-message field; billable = prompt - cached) were
already correct. New regression test with a cache-heavy row (277 tests).
@Fahad090NP

Copy link
Copy Markdown
Contributor Author

Hey @ltmoerdani One thing to flag, I noticed you mention this in your every message that you run tests locally and run linters, etc. Let me explain that the linter that I were implemented never allows developer to commit until the husky runs all linters, tests, and formatters.

@Fahad090NP

Copy link
Copy Markdown
Contributor Author

You can simply test the actual changes and do not worry about linters and tests.

@Fahad090NP

Copy link
Copy Markdown
Contributor Author

Conflicts resolved — merged the latest main (which now includes #150, #151 and #154) into fix/token-counting. The only conflict was the CHANGELOG (both the token-counting entry and the DeepSeek-thinking entry belong in [Unreleased]); both are kept. Branch is mergeable again — 281 tests, strict lint + tsc green.

@ltmoerdani

Copy link
Copy Markdown
Owner

This is a clean fix. I checked the diff, tokensTotal computed once in normalizeHistoryRows, then used across all 3 counting sites. Right approach, not scattered.

One small note: test fixtures now all need tokensTotal manually. Not a blocker, but if there are a lot of new tests down the road, a factory helper might save some boilerplate. Just a heads up, not for this PR.

Conflict resolution is solid both CHANGELOG entries (token-counting + DeepSeek thinking) kept. Checks 2/2 green.

@ltmoerdani
ltmoerdani merged commit 2c17f53 into ltmoerdani:main Aug 14, 2026
2 checks passed
@Fahad090NP
Fahad090NP deleted the fix/token-counting branch August 14, 2026 12:24
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