Show agent liveness, stuck/zombie detection and parse errors in admin

This commit is contained in:
Ian Gulliver
2026-10-14 22:35:53 -07:00
parent 33e682a9d5
commit 1dc09c77e0
21 changed files with 1072 additions and 114 deletions
+63 -1
View File
@@ -802,9 +802,19 @@ components:
Status:
type: object
required: [started_at, db_bytes, last_event_seq, projects, active_tasks, sse_clients, live_agents, running_turns, queued_turns, caps, rate_limits]
required: [started_at, db_bytes, last_event_seq, projects, active_tasks, sse_clients, live_agents, running_turns, queued_turns, caps, rate_limits, agent_processes, zombies, stuck_after_seconds, protocol_errors]
properties:
live_agents: { type: integer, description: Agent processes currently running. }
agent_processes:
type: array
description: Every agent process byre is tracking, idle sessions included.
items: { $ref: "#/components/schemas/AgentProcess" }
zombies:
type: array
description: Sessions marked running with no live process, and agent processes byre has no session for.
items: { $ref: "#/components/schemas/Zombie" }
stuck_after_seconds: { type: integer, description: How long a running turn may go without a stream event before it counts as stuck. }
protocol_errors: { $ref: "#/components/schemas/ProtocolErrors" }
running_turns:
type: array
description: Turns running now, oldest session first.
@@ -842,3 +852,55 @@ components:
session_id: { type: string }
task_id: { type: string }
vendor: { type: string }
AgentProcess:
type: object
required: [session_id, task_id, vendor, pid, state, last_event_at, health]
properties:
session_id: { type: string }
task_id: { type: string }
vendor: { type: string }
pid: { type: integer }
state: { type: string, description: The session's state, as on AgentSession. }
last_event_at: { type: string, format: date-time, description: When the process last wrote a line to its stream, or when it started. }
health:
type: string
enum: [ok, stuck, exited]
x-enum-varnames: [HealthOk, HealthStuck, HealthExited]
description: stuck means a turn is running and no stream event has arrived for stuck_after_seconds; exited means the process is gone.
Zombie:
type: object
required: [kind, detail]
properties:
kind:
type: string
enum: [running_without_process, process_without_session]
detail: { type: string }
session_id: { type: string }
task_id: { type: string }
pid: { type: integer }
ProtocolErrors:
type: object
required: [counts, recent]
properties:
counts:
type: object
description: Stream lines the adapter couldn't parse or didn't recognise since byre started, keyed by vendor.
additionalProperties: { type: integer }
recent:
type: array
description: The most recent ones, newest first.
items: { $ref: "#/components/schemas/ProtocolError" }
ProtocolError:
type: object
required: [vendor, session_id, at, reason, raw, size]
properties:
vendor: { type: string }
session_id: { type: string }
at: { type: string, format: date-time }
reason: { type: string }
raw: { type: string, description: The line as received, cut to its first 4 KiB. }
size: { type: integer, description: The line's full length in bytes. }