Runtime Conversation Turn Coordinator (:gen_statem with [:handle_event_function, :state_enter])
synchronized with durable Fsmx tasks (SuperPi.Durable.TaskEngine) and the 12-hook
SuperPi.Extension pipeline (REQ-FSM-01..REQ-FSM-06, 09 - Data Flows and Extension Injection Points.md).
States
:recovering— RunsTaskEngine.reconcile_on_open!/1on startup and transitions to:idle.:idle— Acceptssubmit/3(:queue,:steer,:write) and manualcompact/2.:preparing_request— Runsbefore_agent_start, derives context (Context.derive/1), runsbefore_requestandbefore_provider_request.:streaming_llm— Streams or invokes the configuredllm_responderand normalizes events; handles mid-stream:steerpreemption.:executing_tools— Runs tool calls one at a time:before_toolin the machine, thenwrap_tool->SandboxRunner->after_toolin a task, so the machine still answerscancel,steerandget_statewhile a tool runs. Thenafter_tools. A:steerlets the running tool finish and skips the rest of the batch.:sleeping_backoff— Pauses turn execution when provider rate-limits/retries occur (TaskEngine.sleep_until/3).:awaiting_children— A tool result carried thecontroldirective%{"await" => ...}(delegate_subagent). The durable task iswaitingon its child tasks and the machine parks, like:sleeping_backoff, still answeringcancel,get_stateandcompact. A child that settles wakes the task and tells the machine ({:task_woken, task_id}, fromTaskEngine, on any node). A poll (config :super_pi, :await_poll_ms, default 5 s) covers a lost message. On wake the machine stores one user message per child with its summary and goes on at:preparing_request. Not a tool result: the tool call already has one (the acknowledgement), and a second result for one call id is refused by the providers.:compacting— Runsbefore_compactor default compaction and recordspi.compactionwithhead_entry_id.:settling_run— Runsafter_runverification gate; either loops back to:preparing_request({:continue, prompt}) or completes the durablepi.generationtask and returns to:idle.
Summary
Functions
Cancels the running turn: stops the LLM request or the running tool (with its OS processes),
records a "cancelled" result for every tool call without a result, marks the durable task
cancelled, replies {:error, :cancelled} to the waiting submit caller and returns to :idle.
Runs manual compaction. During a turn the request waits until the conversation is idle, so a
compaction never lands between a tool call and its result. opts[:timeout] (default 30 s)
bounds the wait. Returns {:ok, :noop}, {:ok, :cancelled} or {:ok, result}.
Returns the current {:state, data} snapshot of the :gen_statem.
Tells the machine that a pending pi.generation task was stored for it (a scheduled run, see
SuperPi.Schedule). An idle machine starts the task at once. A busy one starts it when its
turn ends. A machine that is still recovering finds the task itself.
submit/3 for entry points (gateway, RPC): a machine that exits or a call that times out is
{:error, reason}, not an exit of the caller.
Updates the active extension pipeline for the conversation machine.
Submits user input with mode :queue (default), :steer (preempts active tool batch/stream), or :write (passive append).
Functions
Cancels the running turn: stops the LLM request or the running tool (with its OS processes),
records a "cancelled" result for every tool call without a result, marks the durable task
cancelled, replies {:error, :cancelled} to the waiting submit caller and returns to :idle.
The subtree goes with it: the task's live children (subagents, also while the turn is parked in
:awaiting_children) are aborted bottom-up by TaskEngine.cancel_task/2, which calls
abort_task!/1 on each, and the machines of those children are cancelled.
Runs manual compaction. During a turn the request waits until the conversation is idle, so a
compaction never lands between a tool call and its result. opts[:timeout] (default 30 s)
bounds the wait. Returns {:ok, :noop}, {:ok, :cancelled} or {:ok, result}.
Returns the current {:state, data} snapshot of the :gen_statem.
Tells the machine that a pending pi.generation task was stored for it (a scheduled run, see
SuperPi.Schedule). An idle machine starts the task at once. A busy one starts it when its
turn ends. A machine that is still recovering finds the task itself.
submit/3 for entry points (gateway, RPC): a machine that exits or a call that times out is
{:error, reason}, not an exit of the caller.
Updates the active extension pipeline for the conversation machine.
Submits user input with mode :queue (default), :steer (preempts active tool batch/stream), or :write (passive append).