The life of a run
Introduction
Section titled “Introduction”A run is one execution of an agent on a conversation. This page follows one from the composer to the last event, so you know which package does what and where to look when something goes wrong.
From send to answer
Section titled “From send to answer” client server runtime | run:start -----------> | | | | validate, RUN_STARTED | | | -------------------------> | build or reuse the graph | | <-------- events --------- | model + tools | <------ run:event ------ | number, broadcast, buffer | | ... | | | <--- RUN_FINISHED ----- | |- The chat UI renders the composer.
chat-corerecords the message under an id it mints itself and checks that a command can still reach the server before it consumes the draft. chat-coresendsrun:startthrough the transport the app provided.- The gateway validates the command against
chat-protocol. It rejects a duplicate message or an unknown conversation, names the conversation from its first message, and joins the sender’s socket to the thread room. - The gateway emits
RUN_STARTEDand hands the run toagent-runtime. - The runtime finds the agent definition and the profile it names, keeps the tools the agent lists that are registered, mounts its skills and builds the graph. The graph is cached per tenant and agent, and rebuilt when the definition, the profile or a subagent changes.
- The graph runs. Text deltas and tool calls are drained concurrently, so parallel tool calls stay parallel.
- The gateway gives each event the run’s next sequence number, wraps it in an envelope that names the thread, broadcasts it to the room and appends it to a replay buffer.
chat-corevalidates every envelope and folds it into the view model. An event type it does not know is counted and ignored.- The run ends with
RUN_FINISHED,RUN_CANCELLEDorRUN_ERROR. The checkpoint has already stored the messages, so nothing is saved twice.
Opening a conversation mid-run
Section titled “Opening a conversation mid-run”A second window, or a reload, asks for thread:messages. It receives the checkpointed history plus the replay of the run in flight, and joins the thread room. The next envelope it receives continues the last one it was given, so the screen is whole without a special case.
Pausing for a decision
Section titled “Pausing for a decision”A run can stop and wait: for a human to approve an action, or for a blocking client tool to answer. The gateway emits INTERRUPT then RUN_PAUSED. The client shows the question and answers with run:resume, and the same run carries on.
Subagents in the background
Section titled “Subagents in the background”When an orchestrator delegates with the task tool, the server runs the subagent on a child conversation with the same owner. Opening the child is like switching to another thread: history, replay and live run.
- When a task nobody is awaiting finishes, the parent gets a turn nobody typed, marked as a task result.
- On a thread where a run is writing, a new
run:startis queued and starts when the run is done. - Tasks left running when the server restarts become interrupted and are reported to their parent.
The conversation list hides child conversations. Deleting the parent deletes its children.
Next steps
Section titled “Next steps”- Wire protocol lists every command and event.
- Subagents shows how to define an orchestrator.
- Packages and boundaries explains who owns each step.