streamingassistant

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.

'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.

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