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