Per-run orchestration blackboard.
One Coordinator GenServer observes one top-level run: it ingests loop
events for the main agent and every subagent (attributed via
notify/3), folds them through the pure AgentInfo reducers, and
broadcasts batched snapshots to subscribed hosts. It is observational
only — control flow stays in the agent loop:
- All loop → coordinator traffic is
cast; a coordinator crash can never stall or kill a run. - Runs never read coordinator state; hosts do, via
snapshot/1/subscribe/2(a real call API — never:sys.get_state/1).
Supervision & naming
Started on demand under ExAthena.Orchestrator.Supervisor
(DynamicSupervisor) with restart: :temporary, named
{:via, Registry, {ExAthena.Orchestrator.Registry, session_id}}.
Subscribers & batching
Subscribers are monitored pids receiving
{:orchestrator_update, session_id, snapshot} via plain send/2
(Phoenix.PubSub only exists under mix athena.web; send keeps the
coordinator host-agnostic). Event ingest marks the state dirty and
arms a 100 ms flush timer — hosts see at most ~10 snapshots/s no matter
how fast deltas arrive (per-delta fan-out freezes LiveView sockets).
Run lifecycle
attach_run/2 monitors the run process: on :DOWN, every non-terminal
agent is marked :failed and a retention timer starts (default 5 min)
so hosts can still inspect the final snapshot before the coordinator
retires with :normal.
Summary
Functions
Monitor the run process so agent statuses track its fate.
Returns a specification to start this module under a supervisor.
Ingest one event for agent_id (:main or a subagent id). Fire-and-forget
cast — safe to call against a dead coordinator.
Current snapshot of the run's observable state.
Start (or return) the coordinator for session_id.
Subscribe pid to batched {:orchestrator_update, session_id, snapshot}
messages. Subscribe-then-snapshot in one call, so no update can fall in
between. The subscriber is monitored and dropped on exit.
Pid of the coordinator for session_id, or nil.
Functions
Monitor the run process so agent statuses track its fate.
Returns a specification to start this module under a supervisor.
See Supervisor.
Ingest one event for agent_id (:main or a subagent id). Fire-and-forget
cast — safe to call against a dead coordinator.
Besides ExAthena.Loop.Events tuples, two coordinator-internal shapes are
accepted: {:todos, list} (todo-list rewrite from a todo_writer
side-channel) and {:agent_meta, %{prompt:, name:, linked_todo_id:}}
(enrichment emitted by SpawnAgent before the subagent runs).
Current snapshot of the run's observable state.
Start (or return) the coordinator for session_id.
Subscribe pid to batched {:orchestrator_update, session_id, snapshot}
messages. Subscribe-then-snapshot in one call, so no update can fall in
between. The subscriber is monitored and dropped on exit.
Pid of the coordinator for session_id, or nil.