cost-center
Add unit-of-measurement toggle to qdash `/cost` page — switch display between currency ($) and tokens
Why
The qdash /cost page reports all cost metrics in currency (dollars), but tokens are the more honest and immediate unit of LLM consumption. List-price conversions to USD are estimates; token counts are ground truth. A toggle lets users see through both lenses — currency for budget accountability, tokens for usage clarity and efficiency analysis.
Objective
Ship a working unit toggle on the /cost page that switches the display between currency and tokens without requiring a page refetch. First slice: toggle + supporting backend data only. Future slices (c66 follow-on): multi-currency support, token cost modeling, etc.
Scope
- Backend:
crates/qdash/src/web.rs— addtotal_tokens,input_tokens,output_tokensto/api/coststotals - Frontend:
crates/qdash/ui/app/pages/cost.vue— implement?unit=state viauseUrlState, addUxTabGrouptoggle, wire StatTiles/BarLists/chart to pick value/formatter per unit - Design repo: cycle tracking in
cycles/c66.cost-center/(per Mark's choice — global numbering here, implementation in qcontrol) - Deliberately out of scope: spend guardrail panel (inherently currency-based), token cost modeling, DataTables (already show both columns)
Key Changes
- Exploration & verdict (2026-08-14): Token data already exists in breakdown rows (
by_model/by_agent/by_user/by_team) and daily series; onlytotalslacks token counts. Filling it properly on the backend is cheap and clean — verdict: feasible + high-value first slice. - Backend (implemented 2026-08-14): Added accumulators
token_totandoutput_totto thecosts()loop; extended/api/coststotals JSON withtotal_tokens,input_tokens,output_tokens. - Frontend (implemented 2026-08-14):
- State:
const { period, unit } = useUrlState({ period: 'all', unit: 'cost' }) - Control: Added
UxTabGroupwith units[{ value: 'cost', label: '$' }, { value: 'tokens', label: 'Tokens' }]beside period switcher - StatTiles: Computed array swapping between cost-mode tiles (total/provider/estimated/cache%) and token-mode tiles (total/input/output/cache%)
- BarLists:
byAgent/byUserpickr.costvsr.tokens; titles and formatters follow unit - Chart:
spendSeriesmapsn: unit === 'cost' ? s.cost : s.tokens; series key auto-labels the legend - Caveat line: Hidden in token mode (currency-only)
- Known nit:
fmtN(0)renders"0"vsfmtC(0)renders"—"— acceptable for v1
- State:
- Cycle docs (design repo, 2026-08-14): Created
c66.cost-center/withinitial-prompt.md,CYCLE.md, andcost-unit-toggle-plan.md; updatedCYCLES.mdto index c66 - Pivot to mock-first (2026-08-14, same day): Mark reverted the qcontrol implementation (backend + frontend + dist, all restored to committed state) in favor of working out the details on the design site first. Built
/pages/cost-center-unit-toggle— a faithful/costreplica seeded with a live data snapshot (period=all, 2026-08-14) with the toggle fully wired: unit-driven tile remap, flipped Last-24h emphasis, unit-following table sort (remount trick forinitialSort), mixed-unit targets exempt, plus a design-notes panel. The qcontrol implementation above stands as the validated port path once the mock settles the design. - Data findings baked into the mock: the 2026-08-13 batch day (29.9M tokens, $143) flattens the token-mode chart — log-scale/dual-axis question; leaders flip between modes (gpt-5.6-sol #1 by tokens, #3 by cost) — possibly better told as a $/M-token unit-price column; token totals exclude cache reads (~96% cache rate), needs an "excl. cache" sub-label to read honestly.
Visual record
2 captures — heroes, page slices, and full-page renders. Click to view.


In the archive
Artifacts
- initial-prompt.md
- initial-prompt.md