Repository navigation
feat: dashboard rework with eleven ranged pages and honest pricing - #51
KurutoDenzeru wants to merge 22 commits into
Conversation
Dashboard rework: payload, tokens-per-second, and the last freezeFour fixes on top of
Verification: Note on the residual tokens/s gap versus OMP: OMP counts cache-read and cache-write in throughput; tersio counts output only. TTFT matches to the decimal. |
|
Superseded by #53, which is the same work carried to its conclusion. Closed rather than merged.
The behaviour fixes behind the architecture all survive, each reimplemented against omp's own database rather than Tersio's ledger:
Two things here were deliberately dropped rather than replaced: the Usage page and its ledger-only surface, and the |
Description
Rebuilds the dashboard into a navigable page set and reworks the pricing ledger so every reported number traces to a recorded value.
The dashboard was one vertical scroll of components. It is now a sidebar shell with hash routing and eleven range-aware pages: Overview, Models, Providers, Costs, Requests, Errors, Traces, Tools, Frustration, Projects, Gain. Range picker in the header,
1–6hotkeys,g+ letter jumps.The pricing ledger blended a default price into totals when it could not match a model id, so a single unknown model silently priced the whole account at Sonnet rates. A model id now resolves to its canonical vendor and provider, and three numbers are reported separately and never blended: measured (vendor-reported), API-equivalent (public rates), and cache savings. API-equivalent totals state coverage (
N/M models priced) instead of hiding it. On this machine the API-equivalent total moved from $339.63 to $86.84 with39/52 models pricedand the 13 unpriced models named.Related Issue
None. This branch started as a port of the omp-stats dashboard page set.
Type of Change
Changes Made
1h,24h(default),7d,30d,90d,all. A short range filters recent rows by exact timestamp and buckets them (5minside the hour,1hinside the day); a day range reads the payload's day tables. One payload serves every range.GET /sessions,/session/trace,/session/entryparse span timelines from the pi/omp transcripts (turns, model calls, tools, subagent tracks, markers, per-tool stats) with mtime and ETag caching. The Traces page renders a searchable session list, a per-track waterfall, and a span drawer with the raw transcript row. Every span comes from a recorded timestamp.rangeViewreturned a fresh object each render, so every memo below it missed on each click and re-aggregated every day table on each expand, tab, and drawer. The view is now memoized on its inputs. The Models detail panel also mounted a recharts chart per expanded row; it now draws its day bars with plain elements.windowPartialcounted any full recent list as a truncated window, so the default 24h range showed a false "lower bound" note on five pages. A window is truncated only when the list is full and every row in it falls inside the window.usage.dbmigrations guard against a truncated re-parse: a rebuild that keeps under half the rows restores the pre-migration backup rather than publishing the loss.Screenshots/Recordings
Visual verification during development was done against the omp-stats instance at
127.0.0.1:3847on dark and light themes. Not captured here.Testing
bun run verify(frozen lockfile + build + test) is what CI runs: 62 files, 445 tests, all passing.New coverage:
test/shared/session-trace.test.ts(parser: omp rows, pi fallbacks, unterminated calls, child-track linking, pricing, directory shape) anddashboard/app/test/for pages, routing, traces, theme, and settings.dashboard/app/test/interaction-cost.test.tsxspies on the aggregation and fails if a second fold runs inside a click, which is the regression guard for the freeze above.Also verified: a served instance returning 200 with a
/data.jsoncarrying every field; the cap note appearing on30d/90d/alland absent on1h/24h.Checklist
Additional Notes
Lint reports warnings that predate this branch (
react-hooks/exhaustive-depson models,unicorn/no-array-sort, nested cell components); no new classes.Labels applied:
bug,enhancement,documentation,tests. There is nostylelabel on this repo, so the UI part is covered byenhancement— say the word and I will create astyle/UIlabel.Two limits worth stating. Providers' "Subscription windows" and "Window utilization" sections are honest notes rather than empty tables: each needs per-account plan, quota, reset, and rate-limit data that the transcripts do not carry. And tokens-per-second is not reported, because dividing tokens by elapsed wall clock would conflate tool time with model speed.