Stream Text with Chat Prompt

Learn how to generate text using the AI TOOLKIT and Next.js

2 min readnextstreamingchatView source

Chat completion can sometimes take a long time to finish, especially when the response is big. In such cases, it is useful to stream the chat completion to the client in real-time. This allows the client to display the new message as it is being generated by the model, rather than have users wait for it to finish. stream history={[ { role: 'User', content: 'How is it going?' }, { role: 'Assistant', content: 'All good, how may I help you?' }, ]} inputMessage={{ role: 'User', content: 'Why is the sky blue?' }} outputMessage={{ role: 'Assistant', content: 'The sky is blue because of rayleigh scattering.', }} />

Run it locally

$ npm install ai

Client

Let's create a React component that imports the useChat hook from the @ai-toolkit/react module. The useChat hook will call the /api/chat endpoint when the user sends a message. The endpoint will generate the assistant's response based on the conversation history and stream it to the client.

'use client';

import { useChat } from '@ai-toolkit/react';

import { DefaultChatTransport } from 'ai-toolkit';

import { useState } from 'react';

export default function Page() {

const [input, setInput] = useState('');

const { messages, sendMessage } = useChat({

transport: new DefaultChatTransport({

api: '/api/chat',

}),

});

return (

<div>

<input

value={input}

onChange={event => {

setInput(event.target.value);

}}

onKeyDown={async event => {

if (event.key === 'Enter') {

sendMessage({

parts: [{ type: 'text', text: input }],

});

}

}}

/>

{messages.map((message, index) => (

<div key={index}>

{message.parts.map(part => {

if (part.type === 'text') {

return <div key={${message.id}-text}>{part.text}</div>;

}

})}

</div>

))}

</div>

);

}

app/page.tsx
tsx
  1. 1'use client';
  2. 2import { useChat } from '@ai-toolkit/react';
  3. 3import { DefaultChatTransport } from 'ai-toolkit';
  4. 4import { useState } from 'react';
  5. 5export default function Page() {
  6. 6 const [input, setInput] = useState('');
  7. 7 const { messages, sendMessage } = useChat({
  8. 8 transport: new DefaultChatTransport({
  9. 9 api: '/api/chat',
  10. 10 }),
  11. 11 });
  12. 12 return (
  13. 13 <div>
  14. 14 <input
  15. 15 value={input}
  16. 16 onChange={event => {
  17. 17 setInput(event.target.value);
  18. 18 }}
  19. 19 onKeyDown={async event => {
  20. 20 if (event.key === 'Enter') {
  21. 21 sendMessage({
  22. 22 parts: [{ type: 'text', text: input }],
  23. 23 });
  24. 24 }
  25. 25 }}
  26. 26 />
  27. 27 {messages.map((message, index) => (
  28. 28 <div key={index}>
  29. 29 {message.parts.map(part => {
  30. 30 if (part.type === 'text') {
  31. 31 return <div key={`${message.id}-text`}>{part.text}</div>;
  32. 32 }
  33. 33 })}
  34. 34 </div>
  35. 35 ))}
  36. 36 </div>
  37. 37 );
  38. 38}

Server

Next, let's create the /api/chat endpoint that generates the assistant's response based on the conversation history.

import { convertToModelMessages, streamText, type UIMessage } from 'ai-toolkit';

export async function POST(req: Request) {

const { messages }: { messages: UIMessage[] } = await req.json();

const result = streamText({

model: 'openai/gpt-4o',

system: 'You are a helpful assistant.',

messages: await convertToModelMessages(messages),

});

return result.toUIMessageStreamResponse();

}

---

<GithubLink link="https://github.com/khulnasoft/ai-toolkit/blob/main/examples/next-openai-pages/pages/chat/stream-chat/index.tsx" />

app/api/chat/route.ts
typescript
  1. 1import { convertToModelMessages, streamText, type UIMessage } from 'ai-toolkit';
  2. 2export async function POST(req: Request) {
  3. 3 const { messages }: { messages: UIMessage[] } = await req.json();
  4. 4 const result = streamText({
  5. 5 model: 'openai/gpt-4o',
  6. 6 system: 'You are a helpful assistant.',
  7. 7 messages: await convertToModelMessages(messages),
  8. 8 });
  9. 9 return result.toUIMessageStreamResponse();
  10. 10}