Skip to main content

Vercel UI Message Stream Adapter

What it is

Vercel’s AI SDK has become the de-facto standard streaming protocol for AI chat UIs in React. Its useChat, useAssistant, and useCompletion hooks consume a specific line-delimited JSON stream over HTTP — the UI Message Stream Protocol v1. Agentium ships an adapter that converts an agent.stream() async iterable into that exact protocol, so you can:
  • Drop an Agentium agent into a Vercel AI Chatbot template with zero React changes
  • Reuse any community ChatKit / shadcn AI chat component that targets the Vercel protocol
  • Future-proof against the inevitable consolidation of streaming protocols

Architecture

Two entry points

createAgentUIStreamResponse(agent, input, options?) — Web / Edge runtimes

Returns a standard fetch Response whose body streams UI message chunks. Use as the return value of a Next.js Route Handler, Hono handler, Cloudflare Worker, etc.
Client side (unchanged from the Vercel example):

pipeAgentUIStreamToResponse(agent, input, res, options?) — Node ServerResponse / Express

For Node’s classic http.ServerResponse shape (Express, Fastify with raw mode, etc.):

AgentUIStreamOptions

Both functions accept the same options:

Lower-level: agentUIStream(agent, input, options?)

Returns the raw ReadableStream<Uint8Array> if you want to wrap the response yourself (custom headers, intermediate transforms, multiplex with another stream):

Wire-level protocol

The adapter emits one SSE event per chunk in the form:
The full chunk vocabulary: The protocol matches AI SDK 5+ exactly. If you want to use it with the older AI SDK 3.x/4.x (“data stream protocol v0”), wrap the stream in your own transformer.

What chunks does the adapter need from agent.stream?

The adapter is loose about the agent’s internal chunk shape — it handles any of: If you build a custom Agent subclass with non-standard chunks, just teach it to emit one of the above shapes.

Headers

The adapter sets:
x-vercel-ai-ui-message-stream: v1 is what Vercel’s hooks look for to identify the protocol. Don’t strip it in a reverse proxy.

Compose with Resumable SSE

The UI Stream adapter is one-shot — if the client reconnects, they get a fresh stream. For full mobile-grade resumability (Last-Event-ID replay), use the lower-level defaultEventLog + formatSSEEvent instead of the UI stream adapter. The two can coexist: serve UI-stream-protocol from /api/chat for desktop browsers (Vercel hooks), and a separate /api/run endpoint with resumable SSE for mobile clients.

See also