Call Tools
Learn how to call tools using the AI TOOLKIT and React Server Components.
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. history={[ { role: 'User', content: 'How is it going?' }, { role: 'Assistant', content: 'All good, how may I help you?' }, ]} inputMessage={{ role: 'User', content: 'What is 24 celsius in fahrenheit?', }} outputMessage={{ role: 'Assistant', content: '24°C is 75.20°F', }} />
Run it locally
$ npm install aiClient
Let's create a simple conversation between a user and model and place a button that will call continueConversation.
'use client';
import { useState } from 'react';
import { Message, continueConversation } from './actions';
// Allow streaming responses up to 30 seconds
export const maxDuration = 30;
export default function Home() {
const [conversation, setConversation] = useState<Message[]>([]);
const [input, setInput] = useState<string>('');
return (
<div>
<div>
{conversation.map((message, index) => (
<div key={index}>
{message.role}: {message.content}
</div>
))}
</div>
<div>
<input
type="text"
value={input}
onChange={event => {
setInput(event.target.value);
}}
/>
<button
onClick={async () => {
const { messages } = await continueConversation([
...conversation,
{ role: 'user', content: input },
]);
setConversation(messages);
}}
>
Send Message
</button>
</div>
</div>
);
}
- 1'use client';
- 2import { useState } from 'react';
- 3import { Message, continueConversation } from './actions';
- 4// Allow streaming responses up to 30 seconds
- 5export const maxDuration = 30;
- 6export default function Home() {
- 7 const [conversation, setConversation] = useState<Message[]>([]);
- 8 const [input, setInput] = useState<string>('');
- 9 return (
- 10 <div>
- 11 <div>
- 12 {conversation.map((message, index) => (
- 13 <div key={index}>
- 14 {message.role}: {message.content}
- 15 </div>
- 16 ))}
- 17 </div>
- 18 <div>
- 19 <input
- 20 type="text"
- 21 value={input}
- 22 onChange={event => {
- 23 setInput(event.target.value);
- 24 }}
- 25 />
- 26 <button
- 27 onClick={async () => {
- 28 const { messages } = await continueConversation([
- 29 ...conversation,
- 30 { role: 'user', content: input },
- 31 ]);
- 32 setConversation(messages);
- 33 }}
- 34 >
- 35 Send Message
- 36 </button>
- 37 </div>
- 38 </div>
- 39 );
- 40}
Server
Now, let's implement the continueConversation action that uses generateText to generate a response to the user's question. We will use the `tools` parameter to specify our own function called celsiusToFahrenheit that will convert a user given value in celsius to fahrenheit.
We will use zod to specify the schema for the celsiusToFahrenheit function's parameters.
'use server';
import { generateText } from 'ai-toolkit';
import { openai } from '@ai-toolkit/openai';
import { z } from 'zod';
export interface Message {
role: 'user' | 'assistant';
content: string;
}
export async function continueConversation(history: Message[]) {
'use server';
const { text, toolResults } = await generateText({
model: openai('gpt-3.5-turbo'),
system: 'You are a friendly assistant!',
messages: history,
tools: {
celsiusToFahrenheit: {
description: 'Converts celsius to fahrenheit',
inputSchema: z.object({
value: z.string().describe('The value in celsius'),
}),
execute: async ({ value }) => {
const celsius = parseFloat(value);
const fahrenheit = celsius * (9 / 5) + 32;
return ${celsius}°C is ${fahrenheit.toFixed(2)}°F;
},
},
},
});
return {
messages: [
...history,
{
role: 'assistant' as const,
content:
text || toolResults.map(toolResult => toolResult.result).join('\n'),
},
],
};
}
- 1'use server';
- 2import { generateText } from 'ai-toolkit';
- 3import { openai } from '@ai-toolkit/openai';
- 4import { z } from 'zod';
- 5export interface Message {
- 6 role: 'user' | 'assistant';
- 7 content: string;
- 8}
- 9export async function continueConversation(history: Message[]) {
- 10 'use server';
- 11 const { text, toolResults } = await generateText({
- 12 model: openai('gpt-3.5-turbo'),
- 13 system: 'You are a friendly assistant!',
- 14 messages: history,
- 15 tools: {
- 16 celsiusToFahrenheit: {
- 17 description: 'Converts celsius to fahrenheit',
- 18 inputSchema: z.object({
- 19 value: z.string().describe('The value in celsius'),
- 20 }),
- 21 execute: async ({ value }) => {
- 22 const celsius = parseFloat(value);
- 23 const fahrenheit = celsius * (9 / 5) + 32;
- 24 return `${celsius}°C is ${fahrenheit.toFixed(2)}°F`;
- 25 },
- 26 },
- 27 },
- 28 });
- 29 return {
- 30 messages: [
- 31 ...history,
- 32 {
- 33 role: 'assistant' as const,
- 34 content:
- 35 text || toolResults.map(toolResult => toolResult.result).join('\n'),
- 36 },
- 37 ],
- 38 };
- 39}