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. ItsuseChat, 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.
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 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
- Resumable SSE — for mobile / flaky network resilience
- Vercel AI SDK docs — client-side hooks
- @agentium/transport — full transport package overview