Request streams report activity before delivering one terminal result.
Event envelope
Validate type, request, correlation, session, run, turn, sequence, and timestamp before updating application state. Ordering comes from the protocol sequence and replay cursor, not wall-clock arrival.
Public stream events
run.startedmarks the accepted run.run.progress,run.log, andrun.consoledescribe operational activity and should not be presented as agent-authored progress.run.model.reasoning.started,.delta,.completed,.failed, and.unavailablecarry labeled provider-returned summaries or visible thinking by attempt. They never carry encrypted continuation state or unavailable raw reasoning.run.agent_progresscarries a concise update only after the agent decision commits. It is safe to persist with ordinary conversation history.run.tool.started,run.tool.completed, andrun.tool.faileddescribe tool activity.task.updatedreports delegated task lifecycle.run.completed,run.failed, andrun.cancelledare terminal events.runner.errorreports a runner-level protocol or service problem.
Treat events as protocol data: validate the envelope before updating application state and correlate every event to its command, session, and run.
Group them in the interface by lifecycle, visible output, tools, waits/recovery, approvals, evaluation/budget signals, and terminal outcome. Provider reasoning and run.agent_progress remain different sources even when both are visible.
Persisted versus presentation events
Persist only events the protocol marks as durable and retain their canonical envelope. UI-only loading states, partially rendered deltas, and provider-private continuation data are not replay records.
Finish from the terminal event
Operational progress, provider reasoning, and agent progress may be useful to display, but they do not own the final answer. Provider deltas are live-only by default and should be discarded after the active run. Read assistantText, structured output, and any operator state from the terminal result.
A completed FinalizeAnswer tool event is a terminalization fence: clients may display the tool activity, but cancellation after that point must not prevent the original run from delivering run.completed. A run.cancel command issued after the fence receives runner.error with code RUN_ALREADY_FINALIZING; continue following the original run to its terminal event.
Reconnect rules
Resume from the last committed cursor, tolerate duplicate delivery, and apply events idempotently. A reconnect must not manufacture a new run or another terminal event.
Consumer checklist
- Handle every exported public event name and preserve unknown future names safely.
- Keep progress, tools, waits, approvals, and assistant text separate.
- Require exactly one terminal outcome per accepted run.
- Persist sequence/cursor state atomically with the consumer's application update.
- Correlate events before displaying, evaluating, or replaying them.