3 · Two protocols
Public client surface vs private worker surface — different jobs, different shapes.
Agent Protocol (client → plane)
Public HTTP API (plus SSE / WebSocket for streaming). Same conceptual surface many Agent Protocol clients already expect: threads, runs, stream, cancel, resume, store. It never exposes reclaim generations, runner kinds, or queue internals.
- HTTP — create/get/search, store access
- SSE — one-way token/event stream to the client
- WebSocket — bidirectional streaming + in-band commands
Runner Protocol (plane ↔ runner)
Private gRPC contract for workers. Long-poll for work, stream events, report status, heartbeat, watch cancels. Small RPC surface on purpose; resources during a run (connectors, store, vectors) go over short-lived HTTP to the plane’s internal routes, run-bound.
- GetJob — long-poll assignment
- StreamEvents — progress back to the plane
- ReportStatus — terminal outcome
- Heartbeat — liveness + superseded signal
- WatchCancels — cancel stream
Why not one protocol?
Clients need a portable, SDK-friendly runs API. Runners need leases, fencing, and connector minting. Collapsing them either leaks internals to clients or starves workers of the lifecycle primitives a control plane must own. See why Agent Protocol on the front.
Also: opaque checkpoints (ThreadState ≠ LangGraph checkpointer) · generation fencing