Learn how to call tools using the AI SDK and Next.js
Some models allow developers to provide a list of tools that can be called at any time during a generation. This is useful for extending the capabilities of a language model to either use logic or data to interact with systems external to the model.
Let's create a React component that imports the useChat hook from the @ai-sdk/react module. The useChat hook will call the /api/chat endpoint when the user sends a message. The endpoint will generate the assistant's response based on the conversation history and stream it to the client. If the assistant responds with a tool call, the hook will automatically display them as well.
You will create a new route at /api/chat that will use the streamText function from the ai module to generate the assistant's response based on the conversation history.
You will use the tools parameter to specify a tool called celsiusToFahrenheit that will convert a user given value in celsius to fahrenheit.
You will also use zod to specify the schema for the celsiusToFahrenheit function's parameters.
app/api/chat/route.ts
import { type InferUITools, type ToolSet, type UIDataTypes, type UIMessage, convertToModelMessages, stepCountIs, streamText, tool,} from 'ai';import { z } from 'zod';const tools = { getWeather: tool({ description: 'Get the weather for a location', inputSchema: z.object({ city: z.string().describe('The city to get the weather for'), unit: z .enum(['C', 'F']) .describe('The unit to display the temperature in'), }), execute: async ({ city, unit }) => { const weather = { value: 24, description: 'Sunny', }; return `It is currently ${weather.value}°${unit} and ${weather.description} in ${city}!`; }, }),} satisfies ToolSet;export type ChatTools = InferUITools<typeof tools>;export type ChatMessage = UIMessage<never, UIDataTypes, ChatTools>;export async function POST(req: Request) { const { messages }: { messages: ChatMessage[] } = await req.json(); const result = streamText({ model: 'openai/gpt-4o', system: 'You are a helpful assistant.', messages: convertToModelMessages(messages), stopWhen: stepCountIs(5), tools, }); return result.toUIMessageStreamResponse();}