You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Admin][API] Agents & Instances — cross-tenant list + detail #31
[Admin][API] Agents & Instances — cross-tenant list + detail
Why
GET /v1/agents only returns published agents. Operators need to see all agents (incl. drafts, all owners) and all instances (subscriptions) across tenants for support/debugging.
Status update after code audit: partially shipped, keep open. Implemented: /v1/admin/agents, /v1/admin/agents/:id, /v1/admin/instances, and /v1/admin/instances/:id/detail exist with admin gating/tests. Remaining gaps vs acceptance: list filters are mostly search/pagination rather than full status/visibility/owner filtering, and instance detail shows runtime node rows but does not perform the relay live-check required by the ticket.
Most of this was already built and the issue had gone stale — /v1/admin/agents, /v1/admin/agents/:id, /v1/admin/instances and /v1/admin/instances/:id/detail all existed and were serving the admin SPA. What was missing was what makes them usable and honest:
Filters. The agents list took only search — an operator could not ask "show me the drafts", "show me the ones in status=error", "show me alice's". The instances list took nothing at all. Both now filter (visibility/status/owner and agent/owner/status; owner accepts a uid or a github_login, agent an id or a slug), all bound, never interpolated. The page and the COUNT now run the same predicate — when those drift, page 2 of a filtered list reports the unfiltered total and the UI pages into nothing.
Live runtime status (the AC that called this out). Instance detail was returning instance_runtime_nodes.status, which is never cleared on an unclean disconnect: it reads "online" for machines that have been off for days, so an operator debugging "why is nothing running" was told the runner was fine. Detail now returns runtimeConnected plus a per-node connected from the RelayDO (which holds the socket) alongside the DB's claim, so the two are comparable. The list does the same, capped at 50 relay round-trips per page — past the budget it reports null ("unknown"), never a fabricated false.
New fields: updated_at + owner_id + a capability summary (surfaces/runtime/workflow) on agent rows; agent_slug, user_id, display_name (the subscriber's own rename), updated_at, runtime_nodes, last_seen_at on instance rows.
Agent detail gains subscribers: {total, active} and recentActivity — the newest agent_events across every instance of the agent. The operator question is "is this agent working for anyone", which no per-tenant trace can answer.
Not done, deliberately:store_type from the scope list does not exist in the PAGS schema (that field is from the FAS/FGS reference, not this data model).
Tests: 28 new (lib/admin.test.ts, routes/admin-instance-detail.test.ts, plus route-level filter-passthrough in routes/admin.test.ts) covering drafts-are-included, filters-are-bound, list/count predicate parity, limit clamping, the live-vs-stale status contract, the fan-out cap, and 401/403 on every route.
Activity
feat(admin): Agents, Activity (errors+audit) views + richer Overview (#…
feat(admin): per-agent detail page + connectors per agent (#31/#84)
fix(console): add error boundary so a render crash can't white-screen…
serge-ivo commentedon Aug 6, 2026
Status update after code audit: partially shipped, keep open. Implemented: /v1/admin/agents, /v1/admin/agents/:id, /v1/admin/instances, and /v1/admin/instances/:id/detail exist with admin gating/tests. Remaining gaps vs acceptance: list filters are mostly search/pagination rather than full status/visibility/owner filtering, and instance detail shows runtime node rows but does not perform the relay live-check required by the ticket.
feat(admin): moderation levers + cross-tenant agent/instance filters (#…
serge-ivo commentedon Aug 6, 2026
Done in 5b7fe86.
Most of this was already built and the issue had gone stale —
/v1/admin/agents,/v1/admin/agents/:id,/v1/admin/instancesand/v1/admin/instances/:id/detailall existed and were serving the admin SPA. What was missing was what makes them usable and honest:search— an operator could not ask "show me the drafts", "show me the ones instatus=error", "show me alice's". The instances list took nothing at all. Both now filter (visibility/status/ownerandagent/owner/status;owneraccepts a uid or a github_login,agentan id or a slug), all bound, never interpolated. The page and theCOUNTnow run the same predicate — when those drift, page 2 of a filtered list reports the unfiltered total and the UI pages into nothing.instance_runtime_nodes.status, which is never cleared on an unclean disconnect: it reads "online" for machines that have been off for days, so an operator debugging "why is nothing running" was told the runner was fine. Detail now returnsruntimeConnectedplus a per-nodeconnectedfrom the RelayDO (which holds the socket) alongside the DB's claim, so the two are comparable. The list does the same, capped at 50 relay round-trips per page — past the budget it reportsnull("unknown"), never a fabricatedfalse.updated_at+owner_id+ a capability summary (surfaces/runtime/workflow) on agent rows;agent_slug,user_id,display_name(the subscriber's own rename),updated_at,runtime_nodes,last_seen_aton instance rows.subscribers: {total, active}andrecentActivity— the newestagent_eventsacross every instance of the agent. The operator question is "is this agent working for anyone", which no per-tenant trace can answer.Not done, deliberately:
store_typefrom the scope list does not exist in the PAGS schema (that field is from the FAS/FGS reference, not this data model).Tests: 28 new (
lib/admin.test.ts,routes/admin-instance-detail.test.ts, plus route-level filter-passthrough inroutes/admin.test.ts) covering drafts-are-included, filters-are-bound, list/count predicate parity, limit clamping, the live-vs-stale status contract, the fan-out cap, and 401/403 on every route.audit: silent-truncation fixes across tool/output paths (#898 T1–T16,…