Skip to content
Merged
14 changes: 11 additions & 3 deletions packages/ai/src/activities/chat/stream/processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* @see docs/chat-architecture.md β€” Canonical reference for AG-UI chunk ordering,
* adapter contract, single-shot flows, and expected UIMessage output.
*/
import { generateMessageId, uiMessageToModelMessages } from '../messages.js'
import { generateMessageId, modelMessageToUIMessage, uiMessageToModelMessages } from '../messages.js'
import { normalizeToolResult } from '../../../utilities/tool-result'
import { defaultJSONParser } from './json-parser'
import {
Expand Down Expand Up @@ -870,8 +870,16 @@ export class StreamProcessor {
chunk: Extract<StreamChunk, { type: 'MESSAGES_SNAPSHOT' }>,
): void {
this.resetStreamState()
// AG-UI Message[] is compatible with UIMessage[] at runtime
this.messages = [...chunk.messages] as Array<UIMessage>
// Normalize AG-UI messages to UIMessage[] to ensure each message has
// a `parts` array. AG-UI snapshot messages carry `content` but no
// `parts`, so casting them directly as UIMessage[] is unsafe and causes
// "Cannot read properties of undefined (reading 'find')" when any code
// later accesses message.parts (e.g. onToolCallStateChange devtools handler).
this.messages = chunk.messages.map((msg) =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've replaced one cast with another. Our initial cast was incorrect, so lets find a way to fix it without casting again. Please remove as any casting. I think you're missing createdAt as well. Can you find a better way to do this?

'parts' in msg
? (msg as UIMessage)
: modelMessageToUIMessage(msg as any, generateMessageId()),
)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
this.emitMessagesChange()
}

Expand Down