Two shapes of the same stream
Inside the agent runtime, sessions emitAgentSessionEvent:
message_start— a new assistant message is beginningmessage_update— a partial assistant message (streaming text or a partial tool call)message_end— the message is completetool_execution_start— the agent invoked a tooltool_execution_update— the tool emitted progresstool_execution_end— the tool returned a result
web/server/src/event-mapper.ts) maps those to ChatStreamEvent on the wire, serialized as NDJSON:
Errors are events, not exceptions
The adapter never throws mid-stream. Failures encode asdone or error events so clients don’t need to distinguish between transport errors and agent errors — both arrive on the same channel.
Partial messages
While a model streams tokens, the runtime emitsmessage_update events carrying the accumulated streamingMessage. UIs render the partial message as it grows and swap it for the final AgentMessage on message_end.
Where clients live
- Web — the adapter emits NDJSON for chat and SSE for out-of-turn
AgentSessionEvent. Only the adapter imports agent packages; browsers consume the wire format. - CLI
json/rpcmodes — the CLI emits the same events as JSON per line so shell scripts can pipe them. - Daemon — clients (
DaemonClient) subscribe toAgentSessionEventdirectly over the daemon socket.