pub fn dispatch_tools(
agents: Query<'_, '_, (Entity, &AgentState, &StageInference, &InferenceResult, &mut ContextWindow, Option<&ToolResultRoutingComponent>, Option<&ToolSensitivities>, Option<&mut TaintGate>, Option<&GateResolved>, Option<&GateAutoApprove>, Option<&InFlightWork>, Option<&StageCursor>, Option<&RunMetadata>), With<ReadyForTools>>,
service: Res<'_, ToolServiceRes>,
stage: Res<'_, ToolStage>,
policy: Option<Res<'_, PolicyGate>>,
script_rules: Option<Res<'_, GateScriptRules>>,
hub: Option<Res<'_, InteractionHub>>,
gate_stage: Option<Res<'_, GatePromptStage>>,
persist: Option<Res<'_, PersistenceStage>>,
sink: Option<Res<'_, WorldEventSink>>,
commands: Commands<'_, '_>,
)Expand description
Tool-dispatch system: for each ReadyForTools agent, apply its context_*
tool calls inline (they mutate the ECS window) and hand the rest to the
sequential tool lane, moving it to AwaitingTools. If a batch is all
context tools there is nothing for the lane, so the results are applied
immediately and the agent loops straight back to ReadyToInfer. The lane
serializes execution, so there is no permit gate - every ready agent is
enqueued in turn.
A persisted agent’s batch is journaled at dispatch: a ToolBatch record
(inline results pre-filled, lane calls pending) goes to the persistence lane
with an ack the exec waits on, and a per-call ToolProgress journals each
completion as a ToolCallDone. On a crash mid-batch, recovery replays the
recorded results instead of re-running their side effects (issue #96).