ai
ai copied to clipboard
Ending `textStream.done()` in `streamUI()` causes another render in component after version `>=3.2.6`
Description
Building on top of https://github.com/vercel/ai/issues/2183. It appears that any versions after [email protected] will cause an extra component rerender once textStream.done() is ran/when the stream ends after text generation. This bug is noticeable in [email protected]
Video demo with [email protected]
https://github.com/vercel/ai/assets/75579372/50d0b2b5-e930-4a7e-bd45-83bbadf86912
Video demo with [email protected]
https://github.com/vercel/ai/assets/75579372/b47108d1-769a-4aab-bb67-47f039ea66fa
Code example
Example code using streamUI() and textStream.done():
async function submitUserMessage(content: string) {
"use server"
const aiState = getMutableAIState<typeof AI>()
aiState.update({
...aiState.get(),
messages: [
...aiState.get().messages,
{
id: nanoid(),
role: "user",
content,
},
],
})
let textStream: undefined | ReturnType<typeof createStreamableValue<string>>
let textNode: undefined | React.ReactNode
const result = await streamUI({
model: openai("gpt-4o"),
initial: <SpinnerMessage />,
system: system_instructions,
messages: [
...aiState.get().messages.map((message: any) => ({
role: message.role,
content: message.content,
name: message.name,
})),
],
text: ({ content, done, delta }) => {
if (!textStream) {
textStream = createStreamableValue("")
textNode = <BotMessage content={textStream.value} />
}
if (done) {
textStream.done()
aiState.done({
...aiState.get(),
messages: [
...aiState.get().messages,
{
id: nanoid(),
role: "assistant",
content,
},
],
})
} else {
textStream.update(delta)
}
return textNode
},
onFinish: result => {
console.log(result.finishReason)
},
})
return {
id: nanoid(),
display: result.value,
}
}
Additional context
No response