Events

A session is an event log. The engine appends an event before it acts, and streams every event to any client that is watching.

Use events to render a conversation, to follow a turn, and to monitor a run.

The stream

GET /api/client/sessions/{session_id}/events/stream

The response is text/event-stream. Each frame carries three fields.

Frame fieldHolds
idThe event's seq.
eventThe event type.
dataAn Event object.
id: 7
event: message.new
data: {"session_id":"0193a1","seq":7,"occurred_at":"2026-07-14T10:00:03Z","payload":{"type":"message.new","message":{"id":"m2","role":"assistant","content":"Hi"}}}

To resume after a drop, pass ?after_seq=<n>. EventSource does this for you. On reconnect the browser sends the last frame id in a Last-Event-ID header, which wins over the query parameter.

Each stream covers one session. A sub-agent is its own session with its own stream. Open a second stream with the child's id to watch it.

Event shape

type Event = {
    session_id: string
    seq: number
    occurred_at: string         // RFC 3339
    turn_id?: string            // the turn running when this happened
    payload: EventPayload       // tagged by `type`
}

seq orders the log. It starts at 1 and never repeats.

Conversation

Render a chat from these.

EventPayload
session.createdThe session exists.
message.newA message joined the tree: { message, parent_id? }.
head.movedThe active leaf changed. A client branched or edited.
turn.startedA turn began: { turn_id }.
turn.completedA turn ended, with its cost and output.
session.doneThe session finished its work.
session.cancelledThe session was cancelled.

Model calls

EventMeaning
llm.call.requestedA call was recorded.
llm.call.dispatchedThe call went out.
llm.call.completedThe call returned.
llm.call.erroredThe call failed.

Partial output arrives between events as llm.token.delta frames.

event: llm.token.delta
data: {"type":"llm.token.delta","session_id":"0193a1","call_id":"llm-1","seq":3,"text":"Hi"}

These carry a StreamDelta. They are not recorded in the log.

Tool calls

EventMeaning
tool.call.requestedThe model asked for a tool: { id, name }.
tool.call.dispatchedThe call went to its handler.
tool.call.completedThe call returned: { id, result }.
tool.call.erroredThe call failed: { id, error }.

Sub-agents

EventMeaning
sub_agent.requestedThe model called a child agent.
sub_agent.dispatchedThe spawn went out.
sub_agent.startedThe child session exists.
sub_agent.turn_completedThe child's turn ended.
sub_agent.erroredThe child failed.

The id on each of these is the child session. Open a stream with it to watch the child.

Connectors

EventMeaning
connector.sync.requestedThe engine is fetching a connection's tools.
connector.sync.completedThe tools arrived.
connector.sync.erroredThe fetch failed. The turn runs without those tools.

Interrupts

EventPayload
session.interrupted{ interrupt_id, origin, reason, payload, anchor? }. anchor is the head it pauses. Without it, every branch pauses.
session.interrupt_resumed{ interrupt_id, payload }.

State and config

EventMeaning
worker.state.updatedA decision wrote new state.
agent.updatedA decision wrote a new config.
channels.updatedA decision wrote a frontend view.

Decisions

Engine bookkeeping. Useful for monitoring.

EventMeaning
decision.queuedA decision is waiting for the slot.
decision.dispatchedThe request went to the worker.
decision.completedThe worker answered.
decision.erroredThe decision failed.
decision.droppedThe decision was abandoned.
call.voidedA call was cancelled before it settled.
session.message_requestedA message.send targeted another session.

AG-UI

The AG-UI endpoints send AG-UI protocol events instead of these. See AG-UI.

Next