Skip to content

Real-time throughput gauges and timeseries — tokens/sec, cost/sec, gas tank #1297

@jrf0110

Description

@jrf0110

Parent

Part of #204 (Phase 4: Hardening)

Problem

The town overview and observability tab have no real-time throughput metrics. Users can't tell how hard their town is working right now, how fast they're burning through their balance, or how productive the agents are. There's no visceral sense of "the machine is running."

Solution

Add real-time gauges and timeseries charts to the town overview and observability tab.

Gauges (town overview — live, updating every few seconds)

Gauge Unit Source
Tokens/sec tokens per second (aggregate across all agents) LLM gateway usage events or AgentDO streaming events (count message_part.updated token deltas)
Lines of code/sec LOC per second (across all polecats) Derived from commit diffs or agent tool call events (file_write, edit)
Cost/sec microdollars per second LLM gateway billing events or microdollar_usage deltas
Active agents count TownDO agent roster (status = 'working')
Gas tank account balance as a fuel gauge (empty → full) User/org microdollar_balance from the Kilo billing API

The gas tank gauge is the fun one — a visual fuel gauge that goes from empty (balance depleted) to full (freshly topped up). The needle drops in real time as agents consume tokens. Color transitions from green (plenty of gas) to yellow (getting low) to red (running on fumes). When it hits empty, agents stop (insufficient funds).

Timeseries charts (observability tab — historical data, zoomable)

Chart X-axis Y-axis Granularity
Token throughput Time Tokens/sec 5s buckets, 1h/6h/24h/7d windows
LOC throughput Time Lines changed/min 1m buckets
Cost over time Time Cumulative spend ($) 1m buckets, with rate-of-change overlay
Agent utilization Time Active/idle/total agent count (stacked area) 5s buckets
Bead velocity Time Beads opened/closed per hour 1h buckets
Review queue depth Time Pending/in-progress MR bead count 5s buckets

Data collection

Most of this data already flows through the system but isn't aggregated for display:

  • Token counts: AgentDO streaming events contain token usage. The alarm status WebSocket already pushes agent events to the browser. Aggregate client-side or add a server-side counter.
  • Cost: microdollar_usage table has per-request cost. The gateway already records this. Need a timeseries query or a rolling counter in TownDO.
  • LOC: Not currently tracked. Options: (a) count LOC in commit diffs when agents push (ties into Track commits in bead history with SCM links #1003), (b) count file_write/edit tool call events, (c) derive from git diff --stat output captured in bead events.
  • Balance: Already available from the billing API (getBalance tRPC procedure).

UI treatment

Overview page gauges: A strip of 4-5 gauges at the top of the overview page, above the existing stat cards. Each gauge is a compact radial or linear meter with a live-updating number. The gas tank is a literal fuel gauge icon with a needle.

Observability tab charts: Timeseries charts using a lightweight charting library (e.g., recharts, visx, or lightweight-charts). Each chart has zoom controls (1h/6h/24h/7d) and hover tooltips showing exact values. Charts update in real-time via the alarm status WebSocket.

The "gas tank" gauge specifically

┌─────────────────────┐
│     ⛽ Gas Tank      │
│                     │
│    ╭───────────╮    │
│   ╱      |      ╲   │  ← needle position = balance / max_balance
│  │   E   |   F   │  │
│   ╲      |      ╱   │
│    ╰───────────╯    │
│                     │
│   $47.23 remaining  │
│   ~3.2 hrs at pace  │
└─────────────────────┘

The "~3.2 hrs at pace" estimate uses the current cost/sec rate to project when the balance hits zero. This gives users a visceral sense of runway.

Acceptance Criteria

  • Tokens/sec gauge on town overview (live updating)
  • Cost/sec gauge on town overview (live updating)
  • Active agents gauge on town overview (live updating)
  • Gas tank gauge showing account balance as a fuel meter with time-remaining estimate
  • Token throughput timeseries chart on observability tab
  • Cost over time timeseries chart on observability tab
  • Agent utilization timeseries chart on observability tab
  • Bead velocity timeseries chart on observability tab
  • Charts support zoom (1h/6h/24h/7d windows)
  • Real-time updates via existing WebSocket infrastructure

Notes

  • No data migration needed
  • LOC/sec is the hardest metric to collect — it requires either commit diff analysis (Track commits in bead history with SCM links #1003) or tool call event counting. Could be a stretch goal while the other gauges ship first.
  • The timeseries data needs a storage strategy. Options: (a) aggregate in TownDO SQLite with periodic rollups, (b) use the AgentDO event stream with client-side aggregation, (c) push to an external timeseries store. Option (a) is simplest for the initial implementation.
  • The gas tank estimate ("~3.2 hrs at pace") should use a rolling average of cost/sec over the last 5 minutes, not the instantaneous rate (which would be too jumpy).
  • Depends on [Gastown] PR 22: Observability #228 (Observability) for the underlying metrics infrastructure. The gauges could ship ahead of the full observability system by using client-side aggregation of existing WebSocket events.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Post-launchenhancementNew feature or requestgt:observabilityLogging, metrics, Grafana, debugginggt:uiDashboard, settings, terminal, drawerskilo-auto-fixAuto-generated label by Kilokilo-triagedAuto-generated label by Kilo

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions