feat(usage): Cost & token analytics dashboard - #560
Open
juanludataanalyst wants to merge 1 commit into
Open
Conversation
juanludataanalyst
force-pushed
the
feat/cost-analytics
branch
5 times, most recently
from
June 22, 2026 05:24
bba568f to
5e6b7ac
Compare
Adds a Usage tab to the Houston sidebar with real-time cost and token analytics across all agents. Closes gethouston#558. ### Frontend - `use-cost-analytics.ts` — loads all conversations via listAllConversations, batches loadChatHistory (concurrency 6), aggregates per session. Errors surface as toasts, never silently swallowed. - `cost-aggregate.ts` — pure aggregation logic (byAgent, byModel, byDay, byHour) extracted for testability and filter re-aggregation. - `usage-format.ts` — pure formatting utils (fmtCost, fmtTokens, shortModel) in a .ts file so unit tests can import without JSX overhead. - `token-pricing.ts` — OpenAI/Codex pricing table verified June 2026 at developers.openai.com/api/docs/pricing. Claude uses cost_usd from the CLI directly; Codex cost is computed from tokens + this table. - `date-utils.ts` — isoToLocalDate (UTC ISO to local YYYY-MM-DD) and streak helpers; fixes day-boundary skew for users in non-UTC timezones. - `usage-view.tsx` — KPI cards, filter dropdown (All / Agent / Model), by-model breakdown, by-agent with per-agent cache hit %, daily trend chart, activity-by-hour chart. All strings go through t(). - `usage-chart.tsx` — SVG bar chart with hover tooltips. Guards svg.isConnected before imperative DOM mutation to prevent the removeChild crash on unmount (React fiber tree conflict with imperative SVG children). - `usage-parts.tsx` — JSX helper components (KpiCard, Section, DataBar). - Locales en / es / pt — all keys added, check-locales passes. - Sidebar: Usage nav item. workspace-shell: renders UsageView on usage mode. ### Engine (Rust) - `session_runner.ts` — serialize_for_persist now accepts model: Option<&str> and injects it into the final_result JSON row so the frontend can compute cost for Codex sessions that do not report cost_usd themselves. Fully backwards-compatible: rows written before this change deserialize with model: null and fall back to token-only display. ### Tests - 39 frontend unit tests: token-pricing, date-utils, cost-aggregate, shortModel - 35 Rust tests: session_runner including 3 new model-persistence tests - Verified visually: data loads correctly, filter works, charts render in dark mode without crashes on mount/unmount
juanludataanalyst
force-pushed
the
feat/cost-analytics
branch
from
June 22, 2026 05:35
5e6b7ac to
cee359e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a Usage tab to the sidebar that shows cost and token consumption across all agents: KPI cards, a filter by agent or model, per-agent and per-model breakdowns with cache hit rate, a daily trend chart, and an activity-by-hour chart.
Cost is shown as the exact amount when Claude's CLI reports it (API-key billing), and as an estimate from each provider's official published pricing when it does not (Claude on a subscription, and Codex, which never report a cost). For subscription users this is an API-equivalent estimate of value rather than a literal charge, and the view states this clearly.
Closes #558
How cost is determined
Pricing was taken from the official sources, verified June 2026:
What's included
Frontend
use-cost-analytics.tscost-aggregate.tsusage-format.tstoken-pricing.tsdate-utils.tsusage-view.tsxusage-chart.tsxEngine (Rust)
session_runner.rs: the model is now recorded on each final-result row, so cost can be estimated for sessions whose CLI does not report one. Backwards compatible: rows written before this change deserialize with a null model and fall back to a token-only view.Data loading
Loading goes through TanStack Query (the project standard), so results are cached, de-duplicated, and refetched on window focus, keyed by the set of agent paths. The top-level conversation list uses the toast-on-error wrapper; individual history reads are resilient so one unreadable conversation cannot blank the dashboard.
Correctness notes
Tests
node --experimental-strip-types --test tests/*.test.ts.cargo test -p houston-agents-conversations.pnpm tsc --noEmitandpnpm check-localespass. Strings are localized in en, es, and pt.Test plan
UI
bg-card,border-border,text-foreground,text-muted-foreground, and friends), with no hardcoded colors, so it matches the rest of the app.Design notes
Screenshots