Stream Assistant Response
Client
Let's create a simple chat interface that allows users to send messages to the assistant and receive responses. You will integrate the useAssistant
hook from ai/react
to stream the messages and status.
app/page.tsx
'use chat';
import { Message, useAssistant } from 'ai/react';
export default function Page() { const { status, messages, input, submitMessage, handleInputChange } = useAssistant({ api: '/api/assistant' });
return ( <div className="flex flex-col gap-2"> <div className="p-2">status: {status}</div>
<div className="flex flex-col p-2 gap-2"> {messages.map((message: Message) => ( <div key={message.id} className="flex flex-row gap-2"> <div className="w-24 text-zinc-500">{`${message.role}: `}</div> <div className="w-full">{message.content}</div> </div> ))} </div>
<form onSubmit={submitMessage} className="fixed bottom-0 p-2 w-full"> <input disabled={status !== 'awaiting_message'} value={input} onChange={handleInputChange} className="bg-zinc-100 w-full p-2" /> </form> </div> );}
Server
Next, you will create an API route for api/assistant
to handle the assistant's messages and responses. You will use the AssistantResponse
function from ai
to stream the assistant's responses back to the useAssistant
hook on the client.
app/api/assistant/route.ts
import OpenAI from 'openai';import { AssistantResponse } from 'ai';
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY || '',});
export async function POST(req: Request) { const input: { threadId: string | null; message: string; } = await req.json();
const threadId = input.threadId ?? (await openai.beta.threads.create({})).id;
const createdMessage = await openai.beta.threads.messages.create(threadId, { role: 'user', content: input.message, });
return AssistantResponse( { threadId, messageId: createdMessage.id }, async ({ forwardStream }) => { const runStream = openai.beta.threads.runs.stream(threadId, { assistant_id: process.env.ASSISTANT_ID ?? (() => { throw new Error('ASSISTANT_ID environment is not set'); })(), });
await forwardStream(runStream); }, );}
View Example on GitHub