fix(ui): include cache token columns in usage export - #32015
Conversation
Greptile SummaryThis PR fixes a bug where
Confidence Score: 5/5Safe to merge — changes are purely additive column additions to frontend export utilities with no backend or auth-path impact. All three export functions receive symmetric, consistent treatment: type declarations, initialisation, accumulation, and output rows are all updated together. The fallback || 0 pattern matches pre-existing handling of prompt_tokens and completion_tokens. The new regression tests cover the key correctness properties — per-entity per-day values, multi-day aggregation within the key export, multi-key summation within the model export, and zero defaults — and no existing assertions were weakened or removed. No files require special attention.
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.ts | Adds cache_read_input_tokens and cache_creation_input_tokens columns to all three export row builders; changes are additive, consistent with existing |
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts | New tests assert exact numeric cache token values for each export scope, including multi-day/multi-key aggregation and zero-default cases; no existing assertions weakened. |
Reviews (1): Last reviewed commit: "fix(ui): include cache token columns in ..." | Re-trigger Greptile
Greptile SummaryThis PR fixes missing cache token columns in the Usage page export by adding
Confidence Score: 5/5Safe to merge — the change is additive, touching only the export row builders in a single UI utility file with no server-side impact. Both changed files are confined to the frontend export utility. The additions follow the exact same defensive || 0 pattern already used for prompt_tokens and completion_tokens, the TypeScript type for the aggregation map is updated to match, and the new tests cover exact numeric values for all three export scopes including multi-entry aggregation. No existing assertions were weakened or removed. No files require special attention.
|
| Filename | Overview |
|---|---|
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.ts | Adds cache_read_input_tokens and cache_creation_input_tokens to all three export row builders, plus prompt/completion tokens to generateDailyWithModelsData; logic is consistent and defensive across all paths. |
| ui/litellm-dashboard/src/components/EntityUsageExport/utils.test.ts | Adds targeted regression tests for exact cache token values across all three export scopes, including aggregation cases and zero-default coverage; no existing assertions weakened. |
Reviews (2): Last reviewed commit: "fix(ui): include cache token columns in ..." | Re-trigger Greptile
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit fbca544. Configure here.
Relevant issues
Reported by a customer via support
Linear ticket
Resolves LIT-4011
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
@greptileaiand received a Confidence Score of at least 4/5 before requesting a maintainer reviewScreenshots / Proof of Fix
Everything below ran against a real proxy and the real Anthropic API; no mocks anywhere. Setup: a fresh git worktree of this repo, a brand new venv (
uv venv .venv-qathenuv pip install -e ".[proxy]" prisma), a dedicated Postgres database created only for this run (CREATE DATABASE litellm_qa_export_32015), and the proxy started on a randomly picked free port. Two chat completions were sent toanthropic/claude-haiku-4-5with an ephemeralcache_controlsystem block so the first call creates a cache entry and the second call reads it. After the daily spend flush landed, the actual export builders from the checked-out source (generateExportDatainui/litellm-dashboard/src/components/EntityUsageExport/utils.ts, serialized withPapa.unparse, which is exactly whathandleExportCSVdownloads) were run over the live/user/daily/activityresponse, first at the base commit and then at this PR's commit, using the identical commandPick a random free port and start the proxy;
.envprovidesANTHROPIC_API_KEYand theDATABASE_URLof the dedicated QA database (values never printed)Generate real cached traffic: the system block is ~9.5k tokens, well above the haiku cacheable minimum. First call creates the cache, second call reads it
The backend daily activity API carries both cache token fields for the bucket (requests land in UTC date buckets, hence 2026-07-03), so the data the export modal receives is complete; only the row builders drop it
The runner script imports the production builders from the checked-out source and prints the exact CSV the modal would download (the Usage page teams tab passes entity label "Team")
Before, at the base commit: the daily CSV stops at "Completion Tokens" and the models CSV has no token detail at all, so the cache tokens are silently dropped
Reconciling that export against published claude-haiku-4-5 prices (input 1e-06, output 5e-06 per token) fails; the exported columns cannot explain the exported spend
After, at this PR's commit, rerunning the identical command: both cache columns appear in both scopes with the real token counts, and the models scope also gains prompt and completion tokens
With the cache columns present the row reconciles exactly, to eight decimals, against the same price sheet (cache creation 1.25e-06, cache read 1e-07 per token)
Type
🐛 Bug Fix
Changes
The Export Data modal on the Usage page drops cache token metrics from both CSV and JSON exports. The daily activity API and the frontend aggregation both carry
cache_read_input_tokensandcache_creation_input_tokens, but the three row builders inui/litellm-dashboard/src/components/EntityUsageExport/utils.tsomitted them from the exported rows. This made exported spend impossible to reconcile against model prices: a real export row showed Spend $0.011054 with Prompt Tokens 16306 (which includes cache tokens) and Completion Tokens 8, yet 16306 x $1/M plus 8 x $5/M works out to $0.016346. With the previously hidden fields (24 regular input tokens, 8141 cache creation tokens at $1.25/M, 8141 cache read tokens at $0.10/M) the row reconciles exactly to $0.01105435This PR adds "Cache Read Input Tokens" and "Cache Creation Input Tokens" columns to all three export scopes.
generateDailyDatasources them from the entity metrics, andgenerateDailyWithKeysDataaccumulates them in its per-key aggregation before emitting the columns.generateDailyWithModelsDatapreviously only emitted "Total Tokens"; its per-model aggregation now also accumulates prompt, completion, and both cache token fields and emits them as columns, so per-model rows become reconcilable like the other scopes. The JSON export shares these row builders, so it picks up the same columns automaticallyRegression tests assert the exact numeric cache values per entity per day, per key (including aggregation across duplicate day entries for the same key), and per model (including summation across two keys that hit the same model), plus zero defaults when the backend omits the fields
Note
Low Risk
Dashboard-only export formatting with additive columns and unit tests; no API or billing logic changes.
Overview
Fixes Usage page CSV/JSON exports that already received
cache_read_input_tokensandcache_creation_input_tokensfrom daily activity but dropped them in the row builders.generateDailyDatanow emits Cache Read Input Tokens and Cache Creation Input Tokens from entity metrics (defaulting to 0 when absent).generateDailyWithKeysDatatracks those fields in per-date/entity/key aggregation and includes them on each row.generateDailyWithModelsDatanow sums prompt, completion, and both cache token types from each model’s per-key breakdown and exports them as columns (previously model rows only had total tokens), so spend can be reconciled against cache-aware pricing.JSON export uses the same builders, so it picks up the new columns automatically. Tests cover exact values, key-level aggregation across duplicate days, model-level summation across keys, and zero defaults when metrics are missing.
Reviewed by Cursor Bugbot for commit fbca544. Bugbot is set up for automated code reviews on this repo. Configure here.