Expand description
Streaming sink registry — per-session lookup table for the WebSocket streaming path.
§Why this exists
The agent runtime’s AgentEvent::TextChunk callback fires per text delta
during run_streaming. The Web UI needs each delta as a live token
chunk. Without plumbing streaming_sink: Option<...> through every layer
between the gateway and the runtime callback (Supervisor trait, AgentApi,
AgentTool, AgentLifecycleManager, Orchestrator, AgentRuntime), we use a
session-keyed registry:
- The gateway creates
mpsc::unbounded()+ a collector task right before invoking the orchestrator. The collector holds the strongArc<UnboundedSender<StreamDelta>>for the duration of the turn (withtarget_conn_id = Some(conn_id)on every partialOutgoingMessage, mirroringgateway.rs:491). The gateway also stores aWeakundersession_idin this registry. - The runtime callback looks up the registry by
session_id(which it already has viatransparency_session) and sendsStreamDelta::Textdirectly into the channel — no plumbing through intermediate layers. - When the collector task completes, the strong
Arcdrops.Weak::upgradeon the next runtime lookup returnsNoneand the registry lookup cleanly misses — no explicit unregister required, no stale entries.
§Design rationale (vs threaded Option<StreamingSinkTx> params)
run_with_directive is a Supervisor trait method with concrete impls
on BasicSupervisor and NoOpSupervisor, and dyn Supervisor is held
by AgentLifecycleManager, AgentApi, and AgentTool. Threading the
sink through there would touch every impl + every holder. The registry
avoids all of that because the runtime callback already has the
session_id it needs to look up the sink — no new arguments required.
§Concurrency
The registry is Send + Sync (it owns a Mutex<HashMap<...>> of Weaks,
neither contains interior mutability beyond the mutex itself). Lookup is
O(n) where n = active turns; in practice n ≤ a few during normal use, so
a HashMap is fine. A DashMap would be a one-line swap if load grows.
Structs§
- Streaming
Sink Registry - Per-session lookup table. Shared via
Arcbetween the kernel handle, the agent runtime, and the gateway dispatch layer.
Type Aliases§
- Streaming
Sink Sender - Strong sender side, wrapped in
Arcso the runtime callback can clone cheaply on every lookup. Re-exported here so callers don’t have to know the runtime’s internal type.