Default mode: Reason-Act cycle.
Each iteration:
- Build a Request from current messages + tools + system prompt.
- Call the provider — uses
stream/3when the loop was started withon_event:set (so partial token deltas flow to the caller in real time), falls back to one-shotquery/2when no event callback is registered. - Extract tool calls (native, or TextTagged fallback via
ExAthena.ToolCalls). - If no tool calls: emit
{:content, text}, setfinish_reason: :stop, and halt. - If tool calls: run them (parallel-safe ones concurrently, mutating ones serially), append results, continue.
Budget + mistake-counter checks happen between iterations in the kernel. This mode only implements the turn-by-turn behaviour.