Loop tool results back

Set stopWhen so the model can answer with the tool result.

AI SDK docsai-sdk.dev
By default, stopWhen is set to isStepCount(1), which means generation stops after the first step when there are tool results.
Getting Started · Next.js App RouterRead docs ↗

From ai-sdk and the Tool Calling docs.

One step or two

Press Ask and follow the steps.

Default: 1 stepBad
0 msIdle
    streamText({ model, messages, tools })
    isStepCount(5)Good
    0 msIdle
      stopWhen: isStepCount(5)

      import { streamText, tool, isStepCount } from 'ai';
      import { z } from 'zod';
      
      const result = streamText({
        model: 'anthropic/claude-sonnet-5',
        messages: await convertToModelMessages(messages),
        stopWhen: isStepCount(5), // step 1 calls the tool, step 2 answers
        tools: {
          weather: tool({
            description: 'Get the weather in a location (fahrenheit)',
            inputSchema: z.object({ location: z.string() }),
            execute: async ({ location }) => getWeather(location),
          }),
        },
        onStepEnd: ({ toolResults }) => {
          console.log(toolResults);
        },
      });

      Why it matters, pros and cons

      Why it matters

      A tool call ends the step. Without another step the model never reads the result, so the reply has no text.

      Pros

      • The model turns tool output into an answer.
      • It can chain tools across steps.
      • The cap stops a runaway loop.

      Cons

      • Each step is another model call: time and tokens.
      • Structured output counts as a step too.
      • Reusable agents: use ToolLoopAgent instead.