The gap
Live mode has two sources today:
kagent: full fidelity — per-actor runtime state (Resuming/Suspended) and worker assignments, read from ateapi via the kagent controller's /api/substrate/status.
crd: works on any Agent Substrate cluster via kubectl, but can only see WorkerPools, worker pods, and ActorTemplate phases. Which actor is on which worker right now is invisible, so the board can't animate restores and checkpoints.
A direct ateapi adapter would give every substrate cluster the full experience, no kagent required.
What exists upstream
ateapi's Control service already has everything Scope needs — see pkg/proto/ateapipb/ateapi.proto:
ListActors — per-actor status, template ref, assigned ateom pod
ListWorkers — one row per worker with the actor it currently hosts
ListActorTemplates, ListAtespaces
What the adapter needs
- gRPC client wiring (the server is currently zero-dependency;
@grpc/grpc-js + @grpc/proto-loader as optional deps, or shell out to grpcurl when present, are both acceptable — maintainer preference is the lightest thing that works).
- Auth: ateapi defaults to JWT backed by Kubernetes ServiceAccount tokens (substrate v0.0.6 chart). The adapter needs to mint/mount a token (
kubectl create token) and pass it as call credentials.
- Reachability: port-forward
svc/api in ate-system (the server already has a self-healing port-forward helper).
- Map the responses onto the snapshot shape
server.mjs already emits (workerPools, actorTemplates, actors, workers) — the frontend needs zero changes.
Definition of done
node server.mjs --live --source ateapi on a substrate cluster with no kagent shows live restore/checkpoint animation and worker assignments, identical to the kagent source minus chat ingestion.
The gap
Live mode has two sources today:
kagent: full fidelity — per-actor runtime state (Resuming/Suspended) and worker assignments, read from ateapi via the kagent controller's/api/substrate/status.crd: works on any Agent Substrate cluster via kubectl, but can only see WorkerPools, worker pods, and ActorTemplate phases. Which actor is on which worker right now is invisible, so the board can't animate restores and checkpoints.A direct ateapi adapter would give every substrate cluster the full experience, no kagent required.
What exists upstream
ateapi's
Controlservice already has everything Scope needs — seepkg/proto/ateapipb/ateapi.proto:ListActors— per-actor status, template ref, assigned ateom podListWorkers— one row per worker with the actor it currently hostsListActorTemplates,ListAtespacesWhat the adapter needs
@grpc/grpc-js+@grpc/proto-loaderas optional deps, or shell out togrpcurlwhen present, are both acceptable — maintainer preference is the lightest thing that works).kubectl create token) and pass it as call credentials.svc/apiinate-system(the server already has a self-healing port-forward helper).server.mjsalready emits (workerPools,actorTemplates,actors,workers) — the frontend needs zero changes.Definition of done
node server.mjs --live --source ateapion a substrate cluster with no kagent shows live restore/checkpoint animation and worker assignments, identical to the kagent source minus chat ingestion.