Vercel AI SDKAI SDK 7 · TypeScript · Node.js 20+
0%
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.

Examplestop.ts
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));
Example
npx tsx stop.ts

hasToolCall("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 hasToolCall and compare the steps.
  • Return { activeTools: [] } from prepareStep for step 0.
  • Write a custom condition that stops when steps.at(-1)?.text is not empty.

Little by little, you're building something great.