For the complete documentation index, see llms.txt. This page is also available as Markdown.

Conversation lifecycle

What happens inside the engine on every turn: policy matching, routine advancement, tool execution, the iteration loop, and event emission.

Context — This page explains the engine loop that powers every agent turn. It assumes you know the component names from Architecture. Almost every behaviour you will observe — why a routine advanced or didn't, why a tool ran twice, why a turn ended early — traces back to this loop.

The unit of work: a turn

A turn starts when the engine is woken by an event:

  • a customer message (conversational mode), or

  • a system trigger (autonomous mode — see Autonomous routines).

A turn ends when the agent has produced its reply (conversational) or called built-in:emit_output (autonomous), or when the iteration cap is reached. One turn can contain many model calls and many tool calls; it produces a stream of typed events as it goes.

Anatomy of a turn

 incoming event


 ┌─────────────────────────────────────────────────────┐
 │ PREPARATION ITERATIONS  (at most max_engine_iterations, default 5)
 │                                                     │
 │  1. Policy matching      which policies apply now?  │
 │  2. Routine evaluation   which routine is active,   │
 │                          which node comes next?     │
 │  3. Tool / think calls   execute tool nodes and     │
 │                          think nodes; results join  │
 │                          the conversation history   │
 │                                                     │
 │  └── tools ran? ──► loop: re-evaluate with results  │
 │      nothing left to prepare? ──► exit loop         │
 └─────────────────────────────────────────────────────┘


 RESPONSE GENERATION   one chat-model call produces the reply,
                       honouring matched policies, the active
                       routine step, persona, and language


 EVENT EMISSION        message / tool / status events appended
                       to the session and streamed to consumers

1. Policy matching

Every turn begins by deciding which policies apply. Policies are evaluated in batches (policy_batch_size per model call, default 5) by the policy matcher — an internal evaluation-model call that reads each policy's condition against the current conversation and answers: does this apply right now?

  • Policies marked always_match: true skip the matcher and always apply.

  • Matched policies' action texts become binding instructions for the rest of the turn.

2. Routine evaluation

Next, the engine determines routine state:

  • Activation — a routine becomes active when one of its conditions matches the conversation (each condition is evaluated like a policy condition).

  • Advancement — for the active routine, the engine selects the next node by evaluating the current node's outbound transitions (their condition fields). Nodes and transition semantics are defined in Routines.

  • Backtracking — if the customer jumps back ("actually, change the pickup date"), the engine can re-enter an earlier node rather than ploughing forward.

These selection decisions are evaluation-model calls (see Models) — narrow, structured-output decisions the customer never sees.

3. Tool and think execution

If the selected node is a tool node or a think node, the engine executes it within the same turn:

  • Tool calls go to your MCP servers; results are appended to the conversation history as tool events.

  • Think nodes call the built-in built-in:reason tool: a model call that must return JSON matching the node's output_schema, stored under session.metadata.step_outputs[<node-id>].

After execution the loop iterates: routine evaluation runs again with the new results in context, and policies listing the executed tool in reevaluate_after get re-matched instead of staying decided. This is how a routine chains tool → tool → think → speak inside a single turn.

The iteration cap

The loop runs at most max_engine_iterations times (manifest field, default 5). When the cap is hit:

  • Conversational turns stop preparing and generate the best reply they can from what's gathered so far.

  • Autonomous runs that never reached emit_output fail with error code max_engine_iterations_reached in the callback, telling you to raise the cap or shorten the routine.

Raise the cap when a single turn legitimately needs longer chains of tool/think nodes. Don't raise it to paper over a routine that loops — see Troubleshooting.

Response generation

When nothing is left to prepare, one chat-model call produces the customer-facing message. The prompt assembles, in the agent's voice, roughly in this order:

  • the system prompt (persona, business rules),

  • context variables (the resolved per-customer values),

  • glossary terms,

  • the matched policies' actions and the active routine node's instruction (chat_state) — one combined instructions section,

  • the conversation history for this turn,

  • staged tool results, including retrieved knowledge-base snippets,

  • the language directive (see Prompts, language & preamble).

Two chat nodes can never run back-to-back in one turn — the first message ends the turn. The next customer message starts the next turn.

Preambles

While the engine is still preparing, the agent may emit a short preamble ("Let me check…") so the customer isn't staring at silence during tool calls. Preambles are configured in the manifest (context.preamble), are tagged distinctly in the event stream (kind: "preamble"), and should be rendered like a typing indicator with text — not as a final reply. On the first turn, a configured greeting (context.greeting) replaces the preamble entirely.

With context.preamble.announce_tools: true, the agent additionally emits a short status message right after each batch of tool calls completes ("I've checked your account") while the full reply is still being composed. These announcements arrive as kind: "preamble" events too — render them the same way. They never reveal tool names or final results, and they always precede the assistant_message.

What consumers observe

The turn produces an ordered stream of events on the session (each with a monotonically increasing offset):

Event kind
When

status: acknowledged

Engine received the message

status: typing / status: processing (with stage)

Preparation in progress

preamble

Optional filler message mid-turn

tool

A batch of tool calls completed (ids, arguments, results)

assistant_message

The reply

status: ready

Turn finished — clear indicators

status: error (with error_detail)

Turn failed

status: cancelled

A newer customer message superseded this turn

Exact wire shapes: Events & callbacks. Consumption patterns: Integrating the SDK.

Timing and failure characteristics

  • A new customer message cancels the in-flight turn for that session and starts a fresh one (consumers see status: cancelled).

  • Evaluation calls retry: each internal decision call attempts up to 3 times on the evaluation model, then up to 3 more on the bigger evaluation-fallback model before the turn errors. See Models.

  • Tool failures are visible to the model — a failed tool call lands in history and the agent can explain or retry per its instructions; it does not crash the turn.

  • Knowledge-base failures soft-fail — retrieval errors log a warning and the turn continues without retrieved context.

See also

  • Policies — what the matcher matches

  • Routines — step kinds and completion semantics

  • Models — which model serves which call

  • Observability — watching all of this in traces and logs

Last updated

Was this helpful?