Skip to content

[Admin][API] Agents & Instances — cross-tenant list + detail #31

Closed

Description

@serge-ivo

[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.

Scope

  • GET /v1/admin/agents (paginated, searchable, filter by status/visibility/owner): id, slug, name, owner (login), category, store_type, visibility, status, model, capabilities, instance count, created/updated.
  • GET /v1/admin/agents/:id — detail incl. owner, config/capabilities, subscriber count, recent activity.
  • GET /v1/admin/instances (paginated, filter by agent/owner/status): id, agent, owner, display name, status, runtime-connected?, created; and GET /v1/admin/instances/:id — detail (state summary, runtime nodes, recent tasks/board items, recent errors).
  • Read-only here; mutations (unpublish/cancel) live in the Moderation issue.

Acceptance criteria

  • Lists include drafts and all owners; pagination + filters work.
  • Instance detail shows live runtime status (reuse the relay live-check, not the stale status column).
  • Non-admin → 403; tests for gate + pagination.

Relevant code

  • Tables: agents, agent_instances, instance_runtime_nodes, agent_events
  • Reuse lib/agent-capabilities.ts; relay live-check in relay routes/DO.

References

  • FAS /v1/admin/apps with session counts (content-admin.ts), FGS Games list.

Part of the PAGS Admin Portal epic. Depends on Foundation.

Activity

  1. serge-ivo commented on Aug 6, 2026

    @serge-ivo
    ContributorAuthor

    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.

  2. serge-ivo commented on Aug 6, 2026

    @serge-ivo
    ContributorAuthor

    Done in 5b7fe86.

    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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    admin-portalPAGS admin/operator portalenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions