Your chatbot can already call tools, but we can make it more powerful. Right now, when you ask for weather in multiple cities, the model makes separate calls - let's enable it to handle multiple steps intelligently. And those tool results? We can render them as custom React components instead of debugging displays.
In this lesson, you'll enable multi-step conversations where the AI can chain multiple tool calls together, and generative UI where tool results render as custom React components instead of the Elements Tool components.
Try asking your current chatbot: "What's the weather in San Francisco and New York?"
You'll get weather data, but the flow feels incomplete. We can make this much more intelligent by allowing the AI to:
Good news: Your template already includes a polished Weather component ready to use! We'll integrate it to replace the tool debugging display.
Right now, if you ask "What's the weather in San Francisco and New York?", the AI makes tool calls but doesn't provide a natural language summary afterward. Let's fix that!
Without multi-step, the AI must choose ONE action per request:
This limitation means:
Multi-step conversations solve this by allowing the AI to take multiple "steps" where each step can:
Learn more about multi-step interfaces and stepCountIs in the documentation.
The key is adding stopWhen configuration to your API route:
typescript
Understanding stepCountIs
The
stepCountIs(5)allows up to 5 "steps" in the conversation. Here's what might happen:Example flow for "Weather in SF and NYC?":
- Step 1: AI calls
getWeather("San Francisco")andgetWeather("New York")in parallel- Step 2: AI receives both results and generates text response comparing them
Example flow for complex query:
- Step 1: AI calls first tool
- Step 2: Based on results, AI calls another tool
- Step 3: AI processes all data
- Step 4: AI generates final response
- Step 5: (Buffer for edge cases)
Use
stepCountIs(2)for simple tool + response,stepCountIs(5)for most cases, orstepCountIs(10)for complex multi-tool scenarios. Each step uses tokens, so balance capability with cost.
Save your changes to app/api/chat/route.ts
Restart your dev server if needed: pnpm dev
Navigate to http://localhost:3000/chat
Test these queries to see multi-step in action:
Single city (baseline): "What's the weather in Tokyo?"
Multiple cities: "What's the weather in San Francisco and New York?"
Complex query: "Compare the weather in London, Paris, and Berlin"

You should now see:
Learn More About Multi-Step Interfaces
For detailed information about multi-step interfaces and the
stopWhenconfiguration, see the Multi-step Interfaces documentation.
How Multi-Step Works
When the AI makes a tool call, the result automatically feeds back into the conversation context. The model then decides whether to:
- Make another tool call
- Provide a text response
- Both
This even works when tools fail! If a tool returns an error, the AI can acknowledge the failure and offer alternatives or retry suggestions.
Right now, tool results display using the Elements Tool component - which works great for debugging but isn't very user-friendly. Generative UI means rendering custom React components based on tool data. Instead of showing tool execution details, let's create visual weather cards that users actually want to see.
Generative UI Documentation
Learn more about Generative UI concepts and patterns in the Generative User Interfaces guide.
Your template includes app/(5-chatbot)/chat/weather.tsx - a pre-built Weather component. Let's understand what it provides:
typescript
This component:
WeatherData interface with city, temperature, weatherCode, and humidity that is used in the component propsNow let's integrate the Weather component. We need to:
TODO: Before looking at the solution below, try to:
import Weather from "./weather"; after your other imports (around line 24)case "tool-getWeather": section in your switch statementpart.state === "output-available" && part.output
<Weather weatherData={part.output} />💡 Hints if you're stuck
weatherDatapart.state === "output-available" to know when the tool succeededSolution:
typescript
The key changes you made:
Weather component from ./weathertool-getWeather case to:
part.state === "output-available" (tool completed successfully)Weather component with the dataTool component for loading/error statesThis conditional rendering pattern lets you show polished UI for success while maintaining debugging visibility for errors.
Try it: Ask "What's the weather in Tokyo?" and you should see a styled weather card instead of the tool display!

Preventing AI Overpromising
Notice in the screenshot the AI might offer "more details or a forecast"? Our system prompt in Step 1 helps prevent this by explicitly stating what the tool provides. If you still see overpromising, you can:
- Make the tool description more explicit:
description: "Returns ONLY current temperature, weather code, and humidity - no forecasts available"- Add validation in your tool's execute function to return clear capability messages
- Implement the additional features the AI keeps promising!
Perfect! Now you have polished weather cards that display instead of tool debugging info.
You've built a sophisticated chatbot with multi-step tool use and custom UI components:
stopWhen: stepCountIs(5) server-side to enable the AI to make multiple tool calls and synthesize results.part.state === 'output-available') instead of generic tool displays.message.parts array structure with typed tool parts like tool-getWeather.You've built a sophisticated chatbot with multi-step tool use and generative UI! It's time to wrap up.
This final lesson provides resources, next steps, and guidance for continuing your AI development journey with the AI SDK and beyond.
Mark this chapter as finished to continue
Mark this chapter as finished to continue