Skip to content

gateway: agent-scoped "Recent runs" table with user, model and time - #1691

Merged
Evanfeenstra merged 1 commit into
mainfrom
gateway-agent-runs-table
Sep 15, 2026
Merged

Evanfeenstra merged 1 commit into
mainfrom
gateway-agent-runs-table

Conversation

@Evanfeenstra

Copy link
Copy Markdown
Collaborator

Problem

On /agents/:name the Recent runs table was derived from /histogram/cost?dimension=run-id, which has no agent filter and sorts series by spend. So selecting canvas-agent showed every agent's runs (repo-agent, logs-agent, …), ranked by cost, and the run you had just triggered was nowhere near the top.

Fix

Backend — new GET /_plugin/agents/:name/runs?window=&limit=&offset= (agentruns.go), dispatched from the existing /_plugin/agents/ subtree next to <name>/spend:

  • one row per run-id, scoped by metadata.agent-name, newest last_seen first (ties by run id for stable polling)
  • per run: user_id, models (most-used first), total_cost, total_tokens, request_count, first_seen, last_seen
  • total = run count before paging, so the UI can say "showing 50 of 120"
  • timestamps compared as parsed times, not strings (RFC3339Nano trims trailing zeros, which misorders …:00Z vs …:00.5Z lexicographically)
  • 404 without a logstore, 502 on upstream failure, 400 on bad window/limit — same contract as the sibling routes

UI — useAgentRuns hook (30s poll, the by-agent cadence). The table now shows:

Run User Model Spend Calls Last call
uuid, ellipsized at 200px, full id on hover first 8 chars, links to /people/:id, full id on hover most-used model, +N pill listing the rest on hover relative ("14m ago"), absolute on hover

Also: the cost chart now passes agent_name= so the server filters it (the hook already supported this), replacing the client-side series filter and the stale "phase-8 limitation" comment.

Tests

  • agentruns_test.go: scoping (another agent's run must not leak), newest-first order, models by call count, user from the first stamped row, orphan rows without run-id skipped, sub-second ordering, paging, 400/404/502.
  • go test ./internal/adminapi/ green; make tygo regenerated types.ts; tsc -b --noEmit and vite build clean.
  • Rendered against a Node mock of the gateway routes (no real Bifrost yet): rows truncate/link/pill as described at 1280px; no console errors from the page.

… user/model/time

The AgentDetail page built its Recent runs table from
/histogram/cost?dimension=run-id, which is not agent-scoped and orders
by spend: selecting canvas-agent listed every agent's runs, ranked by
cost, with the run just fired nowhere near the top.

New GET /_plugin/agents/:name/runs (agentruns.go): one row per run in
the window, filtered by metadata.agent-name, sorted by last activity
(newest first), with user_id, models (most-used first), spend, tokens,
call count and first/last seen. ?limit=/?offset= paging plus `total`
for the footer. Timestamps compare as times, not strings, so
sub-second RFC3339Nano trimming can't misorder rows.

UI: useAgentRuns hook; the table shows Run (ellipsized, full id on
hover), User (first 8 chars, links to /people/:id), Model (+N pill
when a run used more than one), Spend, Calls, Last call (relative,
absolute on hover). The cost chart now passes agent_name so the
server filters instead of the page; the stale "phase-8 limitation"
comment goes with it.
@Evanfeenstra
Evanfeenstra merged commit 3cf9539 into main Sep 15, 2026
9 checks passed
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