I have a Next.js action that uses OpenAI to generate an answer :
export async function continueConversation(
messages: CoreMessage[],
data: PersonResponse,
prompt: string
) {
const { full_name, job_title, ...rest } = data
const result = await streamText({
system: `You are a ${job_title} and your name is ${full_name}. Answer the questions based on ${JSON.stringify(
rest
)}`,
model: openai("gpt-4o-2024-05-13"),
messages,
prompt,
})
const stream = createStreamableValue(result.textStream)
return stream.value
}
In the UI, I have this part of code:
{messages.map((m, i) => (
<div key={i} className="whitespace-pre-wrap flex flex-col px-8">
<div
className={cn(
"flex items-start",
m.role === "user" && "justify-end"
)}
>
{m.role === "assistant" && (
<Avatar className="w-8 h-8 mr-3 mt-1">
<AvatarImage
src={`https://${github_url}.png`}
alt={getInitials(full_name as string)}
/>
<AvatarFallback className="text-sm font-semibold tracking-[2px] bg-gradient-to-r from-[#ffaa40] via-[#9c40ff] to-[#ffaa40]">
{getInitials(full_name as string)}
</AvatarFallback>
</Avatar>
)}
<span
className={cn(
"my-2",
m.role === "user" &&
"bg-neutral-800 px-4 py-3 rounded-full"
)}
>
{m.content as string}
</span>
</div>
</div>
))}
In the output, I get the result as Markdown:
You can use react-markdown
package to display the markdown and the package size is only 45.4kb
npm install react-markdown
import Markdown from "react-markdown"
export default function Home(){
// api calls here
return (
{messages.map((m, i) => (
<div key={i} className="whitespace-pre-wrap flex flex-col px-8">
<div>
{m.role === "assistant" && (
<Avatar >
<AvatarImage
src={`https://${github_url}.png`}
alt={getInitials(full_name as string)}
/>
<AvatarFallback className="text-sm">
{getInitials(full_name as string)}
</AvatarFallback>
</Avatar>
)}
<span
className={cn(
"my-2",
m.role === "user" &&
"bg-neutral-800 px-4 py-3 rounded-full"
)}
>
<Markdown>{m.content}</Markdown>
</span>
</div>
</div>
))}
)
}