pub async fn execute_loop<F>(
executor: Arc<dyn AgentExecutor>,
initial: Vec<AgentStepSpec>,
max_iterations: usize,
event_tx: Option<Sender<AgentEvent>>,
next: F,
) -> Vec<StepOutcome>Expand description
Run rounds until the predicate says Stop, a round is
asked to run no specs, or max_iterations is reached — whichever comes
first. Each round is a barrier (execute_steps_parallel); next receives
the just-completed round’s outcomes and decides whether (and with what) to
continue. Returns the last round’s outcomes (empty if initial was empty).
max_iterations is mandatory and a hard cap: it is clamped to at least
1, and once reached the loop stops even if the predicate returns
Continue. This is the guard that makes an
LLM-driven, unknown-length loop (e.g. loop-until-dry) safe — the predicate
must never be the only termination condition.
This is the “loop” shape from the orchestration grammar; like the other
combinators it is written purely against the AgentExecutor seam and adds
no scheduling of its own.