Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

State Machine

The agent loop has six states. A transition handler runs the work for each state and chooses the next one.

States

StateWorkNext state
thinkingCheck loop limits, clear older tool results when needed, prepare the prompt and tool schemas, and start a model call.streaming, or done if a limit is reached
streamingStream text and collect requested tool calls. Eligible read-only tools can start during streaming.executing when tools were requested; otherwise done
executingValidate and execute tools, then append results to the conversation.executing, confirming, compacting, thinking, or done
confirmingWait for the user's approval of a tool call.executing when approved; otherwise thinking with a denial result
compactingSummarize older messages and retain recent turns.thinking
doneRecord the completion reason and accumulated usage.None

Limits, cancellation, and errors can end the loop between transitions. Subagent dispatch runs as a tool inside executing; each specialist has its own loop.

Streaming

Clients receive text deltas while the model generates them. Tool-start, progress, and subagent events can also be emitted while a tool is running. Final tool results are added to conversation history for the next model call.

State handlers share mutable execution context, including messages, usage, tools, and cancellation state. They can call providers and tools; they are not pure functions.

The ordinary chat endpoint sends these events as SSE data frames. See Runtime Server for the wire format and client integration.

Confirmation

A tool that requires approval emits confirmation_required. The client sends the decision to /chat/sessions/:id/ask-user-response using the event's correlation ID.

Ordinary chat confirmation waits within the active request. Durable workflows have separate approval and resume endpoints; see Agent Workflows.

Done reasons

ReasonMeaning
model_stopThe model finished without requesting more tools, or a tool ended execution.
max_turnsThe model-turn limit was reached.
user_abortThe request was cancelled.
errorAn unrecoverable error ended the loop.
budget_exceededAccumulated session tokens reached maxSessionTokens. This is checked between transitions and can overshoot.
loop_detectedOptional repeated-tool detection reached its limit.

Normal completion emits a done event with usage and the reason. A disconnected client cannot rely on receiving it; use persisted session history to inspect the result of an interrupted request.

Implementation

The loop lives in packages/runtime/src/agent/loop.ts. loop-types.ts defines the states and shared context; states/ contains the handlers. The transition dispatcher uses an exhaustive TypeScript switch so an added state must have a handler.

See The Core Loop for the user-level sequence and Context Management for compaction and loop detection.