toAISdkStream()
Converts Mastra streams (agent, network, or workflow) to AI SDK-compatible streams. Use this function when you need to manually transform Mastra streams for use with AI SDK's createUIMessageStream() and createUIMessageStreamResponse().
This is useful when building custom streaming endpoints outside Mastra's provided route helpers such as chatRoute() or workflowRoute().
Usage exampleDirect link to Usage example
Next.js App Router example:
import { mastra } from "../../mastra";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream(messages);
const uiMessageStream = createUIMessageStream({
originalMessages: messages,
execute: async ({ writer }) => {
for await (const part of toAISdkStream(stream, { from: "agent" })) {
await writer.write(part);
}
},
});
return createUIMessageStreamResponse({
stream: uiMessageStream,
});
}
Pass messages to originalMessages in createUIMessageStream() to avoid duplicated assistant messages in the UI. See Troubleshooting: Repeated Assistant Messages for details.
ParametersDirect link to Parameters
The first parameter is the Mastra stream to convert. It can be one of:
MastraModelOutput- An agent stream fromagent.stream()MastraAgentNetworkStream- A network stream fromagent.network()MastraWorkflowStreamorWorkflowRunOutput- A workflow stream
The second parameter is an options object:
from:
lastMessageId?:
sendStart?:
sendFinish?:
sendReasoning?:
sendSources?:
includeTextStreamParts?:
messageMetadata?:
onError?:
ExamplesDirect link to Examples
Converting a workflow streamDirect link to Converting a workflow stream
import { mastra } from "../../mastra";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
export async function POST(req: Request) {
const { input } = await req.json();
const workflow = mastra.getWorkflow("myWorkflow");
const run = workflow.createRun();
const stream = await run.stream({ inputData: input });
const uiMessageStream = createUIMessageStream({
execute: async ({ writer }) => {
for await (const part of toAISdkStream(stream, { from: "workflow" })) {
await writer.write(part);
}
},
});
return createUIMessageStreamResponse({
stream: uiMessageStream,
});
}
Converting a network streamDirect link to Converting a network stream
import { mastra } from "../../mastra";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
export async function POST(req: Request) {
const { messages } = await req.json();
const routingAgent = mastra.getAgent("routingAgent");
const stream = await routingAgent.network(messages);
const uiMessageStream = createUIMessageStream({
execute: async ({ writer }) => {
for await (const part of toAISdkStream(stream, { from: "network" })) {
await writer.write(part);
}
},
});
return createUIMessageStreamResponse({
stream: uiMessageStream,
});
}
Converting an agent stream with reasoning enabledDirect link to Converting an agent stream with reasoning enabled
import { mastra } from "../../mastra";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
export async function POST(req: Request) {
const { messages } = await req.json();
const reasoningAgent = mastra.getAgent("reasoningAgent");
const stream = await reasoningAgent.stream(messages, {
providerOptions: {
openai: { reasoningEffort: "high" },
},
});
const uiMessageStream = createUIMessageStream({
originalMessages: messages,
execute: async ({ writer }) => {
for await (const part of toAISdkStream(stream, {
from: "agent",
sendReasoning: true,
})) {
await writer.write(part);
}
},
});
return createUIMessageStreamResponse({
stream: uiMessageStream,
});
}
Using messageMetadataDirect link to Using messageMetadata
import { mastra } from "../../mastra";
import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
export async function POST(req: Request) {
const { messages } = await req.json();
const myAgent = mastra.getAgent("weatherAgent");
const stream = await myAgent.stream(messages);
const uiMessageStream = createUIMessageStream({
originalMessages: messages,
execute: async ({ writer }) => {
for await (const part of toAISdkStream(stream, {
from: "agent",
messageMetadata: ({ part }) => ({
timestamp: Date.now(),
partType: part.type,
}),
})) {
await writer.write(part);
}
},
});
return createUIMessageStreamResponse({
stream: uiMessageStream,
});
}
Client-side stream transformationDirect link to Client-side stream transformation
If you're using the Mastra client SDK (@mastra/client-js) on the client side and want to convert streams to AI SDK format:
import { MastraClient } from "@mastra/client-js";
import { createUIMessageStream } from "ai";
import { toAISdkStream } from "@mastra/ai-sdk";
import type { ChunkType, MastraModelOutput } from "@mastra/core/stream";
const client = new MastraClient({
baseUrl: "http://localhost:4111",
});
const agent = client.getAgent("weatherAgent");
const response = await agent.stream("What is the weather in Tokyo?");
// Convert the client SDK stream to a ReadableStream<ChunkType>
const chunkStream = new ReadableStream<ChunkType>({
async start(controller) {
await response.processDataStream({
onChunk: async (chunk) => {
controller.enqueue(chunk);
},
});
controller.close();
},
});
// Transform to AI SDK format
const uiMessageStream = createUIMessageStream({
execute: async ({ writer }) => {
for await (const part of toAISdkStream(
chunkStream as unknown as MastraModelOutput,
{ from: "agent" }
)) {
await writer.write(part);
}
},
});
for await (const part of uiMessageStream) {
console.log(part);
}