Skip to main content
This page lists the state tracked at each control level. For the order of a turn, see The Runtime Loop. Every turn runs a deterministic-first loop:
  1. Execute deterministic steps first: ordered-block steps that need no model call (execute_tool:, noop:, set_memory:, action:, and collect: steps whose value is already known). The framework also narrows what the LLM may do next, filtering routable skills by requires: and hiding gated tools, though the routing choice itself is made by the LLM in step 3.
  2. Build a scoped prompt from live state: the active skill’s instructions filtered by if: markers, the tools whose requires: conditions currently hold, and the memory values readable in scope.
  3. Call the LLM.
  4. If the LLM returns a tool call: dispatch it, apply any memory writes the tool makes as it runs, check for newly-available deterministic steps, and loop back to step 1.
  5. Otherwise: send any text. Then either wait for the user or loop back to step 1. See When the engine waits.
One user message can go around this loop several times.

When the engine waits

The engine waits for the next user message when:
  • The stack is empty after a delivered response (the skill or block finished).
  • An engaged collect: needs the user’s answer.
  • An ordered-block action: action_listen step runs.
  • The LLM calls listen() alone (not mixed with text or other tools).
The listen tool lets the LLM end its turn silently after it already asked a question and now needs the user’s answer. It sends no message, makes no stack or memory change, and has no side effects. It is a reserved framework tool name; builder tools cannot be defined with that name. The engine offers listen on main LLM calls. It withholds listen on guided collect rephrase calls, on the answer call that runs after search_knowledge, and while a tool confirmation is pending. The engine resolves mixed model outputs as follows:
  • listen alone: the turn ends in silence.
  • Text plus listen: the text wins. The engine sends the text and drops listen.
  • listen alongside other tool calls: the engine drops listen and runs the other tools.

State tracked per control level

These coexist. A hybrid skill, meaning prose with if: markers that also references an ordered block, tracks both a step pointer and memory state at once.

Tool execution

A tool may be invoked by the LLM (a tool call) or by the framework (an execute_tool: step). The function does not know or care which. tool_constraints are checked in both cases, and in two places:
  • when the tool schema is built, deciding whether the LLM sees the tool at all
  • again at dispatch, before the function runs
Both fail closed. A requires: condition that cannot be evaluated hides and blocks the tool rather than allowing it.

Knowledge search changes the loop

When search_knowledge runs during a turn, the tool list for the remainder of that turn collapses to activate, search_knowledge, and cannot_help, plus resolve_tool_confirmation when a confirmation is pending so the pending gate is never stranded. The active skill’s lifecycle, collect, builder, and listen tools are dropped so a grounded answer neither re-drives the skill nor ends silently before presenting the retrieved information. They return on the next turn. Relatedly, cannot_help is withheld until a search has run whenever a knowledge base is configured, so the model cannot decline before retrieval could have answered. If the model still mixes listen with a user-facing answer after a search, the engine ignores listen and treats the text as the grounded reply.

Where conditions are evaluated

See Conditions.

Tracker events

Mantle appends these events to the conversation tracker. They are what Inspector and Copilot read; you do not author them in YAML. Skill-level flow_* events are still written beside skill_*. Internals and ordered blocks emit flow_* only. Each tool run also appends mcp_tool_executed (same name, arguments, result, and error fields; that copy has no replay metadata). Each memory write also appends slot_set with the same key and value. Session-start metadata uses slot_set only. Trackers that stored MCP tool runs or slot_set memory still replay.

See also