1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
17 small wins to finish your pathNext lesson →
Loop control: stopWhen and prepareStep
stopWhen decides when the loop ends; several conditions stop at the first that is true. prepareStep runs before every step and can change its settings.
import { ToolLoopAgent, hasToolCall, isStepCount } from "ai";
import { shopModel } from "./shop-model.ts";
import { lookupOrder } from "./tools.ts";
const agent = new ToolLoopAgent({
model: shopModel,
tools: { lookupOrder },
stopWhen: [isStepCount(3), hasToolCall("lookupOrder")],
prepareStep: async ({ stepNumber }) => {
console.log("preparing step", stepNumber);
return {};
},
});
const result = await agent.generate({ prompt: "Where is A-1001?" });
console.log(result.steps.length, JSON.stringify(result.text));npx tsx stop.tshasToolCall("lookupOrder") stopped the loop right after the tool ran, before the model could answer, so there is one step and no text. Useful when a tool's result is the answer, such as a final submitTicket tool. isStepCount(3) is the safety limit. Conditions are checked after steps that include tool results.
prepareStep ran once, for step 0. It can return a different model, activeTools, toolChoice or trimmed messages for that step, which is how agents switch to a stronger model after a failure or force a final tool.
Try it yourself
- Remove
hasToolCalland compare the steps. - Return
{ activeTools: [] }fromprepareStepfor step 0. - Write a custom condition that stops when
steps.at(-1)?.textis not empty.
Little by little, you're building something great.