The binding contract
A binding MUST provide:- Ordered, complete delivery of a run’s events, in the order the producer emitted them. The protocol’s order is arrival order; a transport that can reorder or drop events cannot carry AG-UI without a layer that restores both.
- Delivery of the
RunAgentInputthat opens the exchange, before any events. A stream that goes on to carry further runs — a replayed thread — delivers no further input for them: those runs are the producer restating history, and eachRUN_STARTEDMAY carry its owninputecho. - A termination signal a consumer can tell from truncation: a stream that ends cleanly after a terminal event is a closed run, and a connection that dies without one is a truncated run.
- An error path for rejected input — a structurally invalid
RunAgentInputis refused beforeRUN_STARTED, outside the stream.
Standard bindings
- HTTP + Server-Sent Events: the run input is an HTTP POST; the events stream back as SSE frames carrying JSON.
- HTTP + Protobuf: the same POST, negotiated to a binary response of length-prefixed protobuf frames.
Truncation
A consumer whose stream ends without a terminal event has a truncated run: the producer may have kept going, but this consumer will never see the rest. A truncated run has no outcome. A consumer MUST NOT synthesize aRUN_FINISHED
for it and MUST NOT report it as having succeeded; everything the run
delivered before the break remains delivered. Whether and how to surface the
truncation beyond that — leaving the run unresolved, or raising a synthetic
failure — is the consumer’s business; re-running is a new run with a new
runId.