Skip to content

feat(console): TPS instead of TPOT, agent-turns column reorder, sidebar logo#20

Merged
vaderyang merged 2 commits into
mainfrom
feat/ui-tps-and-column-reorder
May 21, 2026
Merged

feat(console): TPS instead of TPOT, agent-turns column reorder, sidebar logo#20
vaderyang merged 2 commits into
mainfrom
feat/ui-tps-and-column-reorder

Conversation

@vaderyang
Copy link
Copy Markdown
Collaborator

Three batched UI tweaks, no backend changes.

1. `Avg TPOT` → `Avg TPS` on Overview, and Models table

TPOT (time per output token, ms) is what the backend stores. Operators want to read generation speed — `1000 / tpot_avg` = tokens/sec — which is more intuitive at a glance. Render-time conversion only; no schema changes.

Where Before After
Overview KPI `Avg TPOT — 23.8 ms/tok` `Avg TPS — 42.0 tok/s`
Models table column `TPOT — 23.8 ms/tok` `Generation TPS — 42.0 tok/s`

The Models column still sorts by the underlying `tpot_avg` field, but `getSortValue` inverts to `1000 / tpot_avg` so clicking the header desc puts the fastest models first — matches what someone clicking "Generation TPS" expects.

2. Agent Turns column order

Rewritten around how operators triage a turn — identity first, then shape, then dimensions:

```
Time → Agent → Client → Calls → Status → In → Out → Model → Wire API → Server → Duration → User Input
```

Was previously `Time → Wire API → Model → Agent → Client → Server → Status → Calls → ...`, which buried Agent and Client behind two less-useful columns.

3. Sidebar logo

Replaces the bare panel-toggle button at the top-left of the sidebar with a TokenScope brand mark.

  • Expanded: wordmark on the left, collapse chevron on the right.
  • Collapsed: icon-only mark; clicking it expands the sidebar (icon doubles as the expand affordance).
  • Both variants share the same glyph — a rounded "scope" frame containing three decreasing token bars — so they line up visually as the sidebar opens/closes.
  • Stroke / fill use `currentColor` so dark-mode and theme inheritance work without extra CSS.

Verification

  • `bun test` — 97 pass
  • `npm run build` — green
  • Deployed to wuneng (bundle index-hFdRQt1S.js); verified KPI label and Models column visually, agent-turns column order, sidebar logo in both states.

Test plan

  • Overview: `Avg TPS` reads in tok/s; matches `1000 / TPOT` mentally
  • Models: `Generation TPS` column; click desc → fastest model first
  • Agent Turns: column order matches the spec above
  • Sidebar: wordmark visible expanded; clicking icon when collapsed expands; clicking chevron when expanded collapses
  • Dark mode: logo strokes stay legible

🤖 Generated with Claude Code

Vader Yang and others added 2 commits May 15, 2026 17:13
…ar logo

Three small UI changes batched into one branch — none of them touch
backend or data shapes:

* Overview "Avg TPOT" KPI surfaces as "Avg TPS" with units of tok/s
  (= 1000 / tpot_avg_ms). TPOT itself is what the backend stores;
  the conversion is one division at render time. "Generation speed"
  reads better in a glance than "milliseconds per token".

* Models table column "TPOT" → "Generation TPS", same unit swap.
  Sort key still points at tpot_avg under the hood but getSortValue
  inverts to 1000/tpot_avg so clicking the column desc gives
  fastest-first — matches what someone clicking "Generation TPS"
  expects.

* Agent Turns table column order rewritten around how operators
  actually triage a turn: Time, Agent, Client, Calls, Status, In,
  Out, then the less-frequently-scanned dimensions (Model, Wire
  API, Server, Duration) and the long User Input preview last.

* New TokenScope brand mark replaces the bare panel-toggle button
  at the top-left of the sidebar:
  - Expanded: wordmark on the left, collapse button on the right.
  - Collapsed: icon-only mark; click toggles to expand (the icon
    doubles as the expand affordance — discoverable, saves a row).
  Both variants share the same glyph (rounded "scope" frame
  containing three decreasing token bars) so they line up
  visually as the sidebar opens/closes. Stroke uses currentColor
  for dark-mode and theme inheritance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	console/src/components/layout/sidebar.tsx
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Agent run failed (exit 1). See workflow logs.


🤖 Reviewed by viviworkflow run

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I have enough context. Let me review the PR.

Summary

This PR batches three UI-only changes: (1) surface TPOT as "Generation TPS" (tokens/second = 1000/tpot_avg_ms) in overview KPI and models table, (2) reorder agent-turns columns for operator triage workflow, and (3) add a TokenScope brand logo to the sidebar. No backend changes, no schema changes. The TPS conversion is render-time only and guards against null/zero division. APPROVE — these are clean, low-risk UI polish changes with defensive edge-case handling.

Suggestions

  • console/src/pages/models.tsx:34-36 — The inverted sort (returning 1000/tpot_avg for the sort value) creates a subtle UX inconsistency: "TTFT avg" and "E2E avg" columns sort by raw ms values (desc = slower), while "Generation TPS" sorts by inverted value (desc = faster). This matches what a user clicking "TPS" expects (higher = faster), but differs from the latency-column convention. Consider documenting this intentional divergence in a comment for future maintainers.

  • console/src/components/ui/logo.tsx:58-68 — The wordmark uses SVG <text> with a system font stack (ui-sans-serif, system-ui, ...). The comment acknowledges cross-OS variance is acceptable, but note that fontWeight={600} (semi-bold) may render differently across Windows/macOS/Linux — on some systems it may look bolder or lighter than intended. If brand consistency matters, consider shipping a webfont or using a pre-rendered path instead of <text>.

  • console/src/pages/agent-turns.tsx:17-21 — The comment explaining column ordering is helpful, but could be slightly clearer: "Identity columns (Agent / Client)" — Agent is technically agent_kind (the agent type/profile), not the agent identity. Consider "Agent kind / Client" for precision.

Verified

  • Schema mirror: Checked MetricsSummary.tpot_avg (line 48) and MetricsModelRow.tpot_avg (line 80) in console/src/types/api.ts — both are number | null, matching Rust Option<f64> in ts-storage-duckdb/src/metrics.rs:500, 645.
  • Null/zero guards: All TPS conversions check tpot_avg != null && tpot_avg > 0 before dividing (overview:104-107, models:34-36, models:207-209). Prevents NaN/Infinity for edge cases.
  • No queryKey drift: The TPS change is render-time only; useMetricsSummary and useModels hooks have correct queryKey entries (start, end, filter params). No new API calls.
  • No route changes: All three files are page/component modifications — no new routes. app.tsx route registration unchanged.
  • Logo component: New file follows project conventions (Tailwind via cn(), @/lib/utils import). Exported correctly, imported only by sidebar.tsx:17.
  • Sidebar behavior: Toggle button logic uses existing useSidebarStore correctly. Expanded/collapsed states render different button arrangements but both call the same toggle() function.
  • Sort consistency: Reviewed models.tsx sort logic — getSortValue inverts tpot_avg for "Generation TPS" column; sorting by bv - av on desc correctly shows fastest-first when clicking the TPS header.

🤖 Reviewed by viviworkflow run

@vaderyang vaderyang merged commit aa3e7fc into main May 21, 2026
1 check passed
@vaderyang vaderyang deleted the feat/ui-tps-and-column-reorder branch May 21, 2026 05:08
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.

1 participant