> ## Documentation Index
> Fetch the complete documentation index at: https://maestro.rasa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The Runtime Loop

> What Maestro does on every turn, step by step.

Every turn runs the same loop, and the order is the point: the **framework acts
first**, and only calls the LLM for what genuinely needs judgment. That's what
"deterministic-first" means.

## Each turn, in order

1. **The framework acts first.** It runs whatever is already determined, such as
   the next steps in an active [ordered block](/build-guide/ordered-blocks),
   without calling the LLM. It also narrows what the LLM may do next: which
   skills are routable (by `requires:`) and which tools are visible.
2. **It builds a focused prompt.** Only the active skill's instructions, the
   tools currently allowed, and the memory values that matter. See
   [Context Management](/maestro/context).
3. **It calls the LLM.** The model replies, calls a tool, or switches skills,
   but only within what the framework already allowed. Choosing a skill is the
   model's call; the framework decides which skills were eligible to choose
   from.
4. **Tool calls run back through the framework.** Constraints and confirmations
   are checked before the tool runs, then the loop repeats from step 1.

One user message can loop several times. Call a tool, settle the result, call
another. The framework is in the path every time, not just at the start.

```mermaid theme={null}
flowchart TD
    A[User message] --> B[Framework runs first]
    B --> C{Can the framework<br/>settle this itself?}
    C -->|Yes| D[Act without the LLM]
    D --> C
    C -->|No. Needs judgment| E[Build a focused prompt]
    E --> F[Call the LLM]
    F --> G{What did it do?}
    G -->|Called a tool| H[Run the tool]
    H --> B
    G -->|Replied or asked| I[Send message, wait for user]
```

## Why deterministic-first

Anything the framework can settle on its own is faster, cheaper, and can't be
talked out of. The next deterministic step in an
[ordered block](/build-guide/ordered-blocks) is resolved without a model call.
The LLM is reserved for what actually needs reasoning, and even then it acts
only inside the boundaries the framework has already set. See
[Guarantees & Guardrails](/maestro/guarantees).

## Running tools

A skill can call two kinds of tools: its own, auto-discovered from the skill's
`tools.py` or `tools/` folder, and shared tools it imports from the agent root.
On a name collision the skill-local tool wins. This precedence is resolved when
the model loads, not looked up per call.

When the LLM calls a tool, its [constraints](/build-guide/tool-constraints) are
checked first: a tool whose `requires:` condition is unmet is never offered to
the LLM at all. A tool can also write to memory as it runs, so acting and
recording happen in one step.

The same function can be run directly by an ordered-block `execute_tool:` step.
The block controls when the step is reached, and the same `requires:` gate is
checked before the function runs. See [Tools](/concepts/tools) for the full
contract.

## When a turn is cancelled

A turn can end before every in-flight step finishes, whether from a voice
barge-in, a session timeout, or a dropped connection. The runtime races
cancellation against LLM
calls, tool dispatch, and skill advancement: when cancel wins, in-flight work is
aborted promptly (with a short grace window for teardown) and the turn returns
as cancelled rather than as an error.

For tool authors, the important part is what happens inside a running tool:
`asyncio.CancelledError` at the current `await`, no call record if the tool was
mid-`await`, memory already written is kept, and the step can run again next
turn. See [Cancellation](/reference/tools#cancellation) for `context.is_cancelled`,
cleanup, and idempotency patterns.

## Reference

For the loop expressed as a terse spec, plus what state the framework tracks at
each control level, see the [Execution Loop reference](/reference/execution-loop).
