Skip to content

Align the Vercel UI message stream with the data stream protocol - #906

Merged
pushpak1300 merged 5 commits into
0.xfrom
vercel-stream-protocol
Aug 20, 2026
Merged

Align the Vercel UI message stream with the data stream protocol#906
pushpak1300 merged 5 commits into
0.xfrom
vercel-stream-protocol

Conversation

@pushpak1300

@pushpak1300 pushpak1300 commented Aug 20, 2026

Copy link
Copy Markdown
Member

Currently the Vercel protocol stream drops information the AI SDK client is built to consume. A completed run looks like this on the wire:

data: {"type":"start","messageId":"019..."}
data: {"type":"text-delta","id":"msg_1","delta":"Hello."}
data: {"type":"finish"}   // usage and finish reason are thrown away
data: [DONE]

And when a provider fails after streaming has started, the connection just drops, so useChat sits on a dead spinner with no error state.

After this PR, the same run emits every part the client processes, validated field by field against the UIMessageChunk schema in vercel/ai:

data: {"type":"start","messageId":"019..."}
data: {"type":"start-step"}
data: {"type":"text-delta","id":"msg_1","delta":"Hello."}
data: {"type":"finish-step"}
data: {"type":"finish","finishReason":"stop","messageMetadata":{"usage":{"prompt_tokens":10,...}}}
data: [DONE]

On the client that means message.metadata.usage is populated, finishReason lands in the chat state, and multi-step tool runs get proper step boundaries (start-step also makes the client insert its step-start parts, and finish-step resets its active text and reasoning state between steps, which guards against text block id reuse across steps).

A mid-stream failure now closes the stream properly instead of severing it:

data: {"type":"start","messageId":"019..."}
data: {"type":"text-delta","id":"msg_1","delta":"Hel"}
data: {"type":"error","errorText":"Provider connection lost."}   // client renders its error state
data: [DONE]

The exception is still reported to the handler, it just no longer escapes into an already-open response.

- Rename `toVercelProtocolLine()` to `toVercelProtocolFormat()` for
  clarity
- Distinguish between `StreamErrorException` (already surfaced by
  provider) and unexpected errors (should be reported)
- Flatten usage object in protocol to match Vercel AI SDK schema:
  `inputTokens`, `outputTokens`, `totalTokens`, `reasoningTokens`,
  `cachedInputTokens`
- Add test for unexpected exceptions after error parts
@pushpak1300
pushpak1300 marked this pull request as ready for review August 20, 2026 09:15
@pushpak1300
pushpak1300 merged commit a570c87 into 0.x Aug 20, 2026
8 checks passed
@pushpak1300
pushpak1300 deleted the vercel-stream-protocol branch August 20, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant