content/docs/07-reference/01-ai-sdk-core/18-pipe-agent-ui-stream-to-response.mdx
pipeAgentUIStreamToResponseThe pipeAgentUIStreamToResponse function runs an Agent and streams the resulting UI message output directly to a Node.js ServerResponse object. This is ideal for building real-time streaming API endpoints (for chat, tool use, etc.) in Node.js-based frameworks like Express, Hono, or custom Node servers.
<Snippet
text={import { pipeAgentUIStreamToResponse } from "ai"}
prompt={false}
/>
import { pipeAgentUIStreamToResponse } from 'ai';
import { MyAgent } from './agent';
export async function handler(req, res) {
const { messages } = JSON.parse(req.body);
await pipeAgentUIStreamToResponse({
response: res, // Node.js ServerResponse
agent: MyAgent,
uiMessages: messages, // Required: array of input UI messages
// abortSignal: optional AbortSignal for cancellation
// status: 200,
// headers: { ... },
// ...other optional UI message stream options
});
}
<PropertiesTable
content={[
{
name: 'response',
type: 'ServerResponse',
isRequired: true,
description:
'The Node.js ServerResponse object to pipe UI message stream output into.',
},
{
name: 'agent',
type: 'Agent',
isRequired: true,
description:
'An agent instance implementing .stream({ prompt, ... }) and defining a tools property.',
},
{
name: 'uiMessages',
type: 'unknown[]',
isRequired: true,
description:
'Array of input UI messages sent to the agent (such as user/assistant message objects).',
},
{
name: 'abortSignal',
type: 'AbortSignal',
isRequired: false,
description:
'Optional abort signal to cancel streaming (e.g., on client disconnect). Supply an AbortSignal, for example from an AbortController.',
},
{
name: 'timeout',
type: 'number | { totalMs?: number }',
isRequired: false,
description:
'Timeout in milliseconds. Can be specified as a number or as an object with a totalMs property. The call will be aborted if it takes longer than the specified timeout. Can be used alongside abortSignal.',
},
{
name: 'options',
type: 'CALL_OPTIONS',
isRequired: false,
description:
'Optional agent call options, for agents configured with generic parameter CALL_OPTIONS.',
},
{
name: 'experimental_transform',
type: 'StreamTextTransform | StreamTextTransform[]',
isRequired: false,
description:
'Optional stream text transformation(s) applied to agent output.',
},
{
name: 'onStepFinish',
type: 'ToolLoopAgentOnStepFinishCallback',
isRequired: false,
description:
'Callback invoked after each agent step (LLM/tool call) completes. Useful for tracking token usage or logging intermediate steps.',
},
{
name: '...UIMessageStreamResponseInit & UIMessageStreamOptions',
type: 'object',
isRequired: false,
description:
'Options for streaming headers, status, SSE stream config, and additional UI message stream control.',
},
]}
/>
A Promise<void>. The function completes when the UI message stream has been fully sent to the provided ServerResponse.
import { pipeAgentUIStreamToResponse } from 'ai';
import { openaiWebSearchAgent } from './openai-web-search-agent';
app.post('/chat', async (req, res) => {
// Use req.body.messages as input UI messages
await pipeAgentUIStreamToResponse({
response: res,
agent: openaiWebSearchAgent,
uiMessages: req.body.messages,
// abortSignal: yourController.signal
// status: 200,
// headers: { ... },
// ...more options
});
});
.stream method with the provided UI messages and options, converting them into model messages as needed.ServerResponse, sending data via streaming HTTP responses (including appropriate headers).abortSignal is supplied, streaming is cancelled as soon as the signal is triggered (such as on client disconnect).Response, this function writes bytes directly to the ServerResponse and does not return a response object.AbortSignal (for example, wired to Express/Hono client disconnects) to ensure quick cancellation of agent computation and streaming.uiMessages (not messages) for consistency with SDK agent utilities.