I am currently trying to follow the example from the documents regarding tool-calling and generative UI
I would like to call the UI only without any additional text generated by the AI. The image shows a red square of the AI response which I don’t want (which happens after the UI was rendered)
My page.tsx
"use client";
import { useChat } from "@ai-sdk/react";
import AskForConfirmation from "./components/AskForConfirmation";
import GetLocation from "./components/GetLocation";
import GetWeatherInformation from "./components/GetWeatherInformation";
export default function Page() {
const { messages, input, handleInputChange, handleSubmit, addToolResult } =
useChat({
maxSteps: 5,
// run client-side tools that are automatically executed:
async onToolCall({ toolCall }) {
if (toolCall.toolName === "getLocation") {
const cities = [
"New York",
"Los Angeles",
"Chicago",
"San Francisco",
];
return cities[Math.floor(Math.random() * cities.length)];
}
},
});
return (
<div>
{messages.map((message) => (
<div key={message.id}>
<div>
{message.parts.map((part, index) => {
switch (part.type) {
case "text":
return <div key={index}>{part.text}</div>;
case "tool-invocation":
const callId = part.toolInvocation.toolCallId;
const { toolName, state, args } = part.toolInvocation;
switch (toolName) {
case "askForConfirmation":
return (
<AskForConfirmation
key={callId}
callId={callId}
message={args?.message ?? ""}
result={
part.toolInvocation.state === "result"
? part.toolInvocation.result
: undefined
}
state={state}
addToolResult={addToolResult}
/>
);
case "getLocation":
return (
<GetLocation
key={callId}
callId={callId}
result={
part.toolInvocation.state === "result"
? part.toolInvocation.result
: undefined
}
state={state}
/>
);
case "getWeatherInformation":
return (
<GetWeatherInformation
key={callId}
callId={callId}
city={args?.city ?? ""}
result={
part.toolInvocation.state === "result"
? part.toolInvocation.result
: undefined
}
state={state}
/>
);
}
break;
}
})}
</div>
</div>
))}
<form onSubmit={handleSubmit}>
<div className="flex gap-2">
<input
className="w-full border-2 border-gray-300 rounded-md p-2"
value={input}
onChange={handleInputChange}
placeholder="Type a message..."
/>
<button
type="submit"
className="bg-blue-500 text-white p-2 rounded-md"
>
Send
</button>
</div>
</form>
</div>
);
}
This is my route.ts
import { openai } from "@ai-sdk/openai";
import { streamText } from "ai";
import { z } from "zod";
export async function POST(request: Request) {
const { messages } = await request.json();
const result = streamText({
model: openai("gpt-4o"),
system: "You are a friendly assistant!",
toolCallStreaming: true,
messages,
maxSteps: 5,
tools: {
// server-side tool with execute function:
getWeatherInformation: {
description: "show the weather in a given city to the user",
parameters: z.object({ city: z.string() }),
execute: async ({}: { city: string }) => {
const weatherOptions = ["sunny", "cloudy", "rainy", "snowy", "windy"];
return weatherOptions[
Math.floor(Math.random() * weatherOptions.length)
];
},
},
// client-side tool that starts user interaction:
askForConfirmation: {
description: "Ask the user for confirmation.",
parameters: z.object({
message: z.string().describe("The message to ask for confirmation."),
}),
},
// client-side tool that is automatically executed on the client:
getLocation: {
description:
"Get the user location. Always ask for confirmation before using this tool.",
parameters: z.object({}),
},
},
});
return result.toDataStreamResponse();
}
I tried using the stop()
function from the useChat hook, but this sets the error
prop in the useChat hook.
Any insight is greatly appreciated.
Camilo