Agent Streaming (VNext)
Agents in Mastra support streaming responses for real-time interaction with clients. This enables progressive rendering of responses and better user experience.
Experimental API: The streamVNext
method shown in this guide is an experimental feature with enhanced streaming format support. It will replace the current stream()
method after additional testing and refinement. For production use, consider using the stable stream()
method until streamVNext
is finalized.
Usage
The experimental streaming protocol uses the streamVNext
method on an agent. This method now supports multiple output stream formats, for Mastra (default) and AI SDK v5.
Format Parameter
The format
parameter determines the output stream type:
'mastra'
(default): ReturnsMastraModelOutput
- Mastra’s native streaming format'aisdk'
: ReturnsAISDKV5OutputStream
- Compatible with AI SDK v5 interfaces like useChat.
// Mastra format (default)
const mastraStream = await agent.streamVNext("Hello");
// AI SDK v5 format
const aiSdkStream = await agent.streamVNext("Hello", {
format: 'aisdk'
});
Default Mastra Format
By default, streamVNext
returns a MastraModelOutput
stream:
const stream = await agent.streamVNext("Tell me a story.");
// Access the text stream
for await (const chunk of stream.textStream) {
console.log(chunk);
}
// Or get the full text after streaming
const fullText = await stream.text;
AI SDK v5 Compatibility
For integration with AI SDK v5, use the format: 'aisdk'
parameter to get an AISDKV5OutputStream
:
const stream = await agent.streamVNext("Tell me a story.", {
format: 'aisdk'
});
// The stream is now compatible with AI SDK v5 interfaces
for await (const chunk of stream.fullStream) {
// Process AI SDK v5 formatted chunks
console.log(chunk);
}
Stream Properties
Both stream formats provide access to various response properties:
stream.textStream
- A readable stream that emits text chunksstream.text
- Promise that resolves to the full text responsestream.finishReason
- The reason the agent stopped streamingstream.usage
- Token usage information
How to use the stream in a tool
Each tool gets a writer
argument, which is a writable stream with a custom write function. This write function is used to write the tool’s response to the stream.
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
export const weatherInfo = createTool({
id: "Get Weather Information",
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
conditions: z.string(),
temperature: z.number(),
}),
description: `Fetches the current weather information for a given city`,
execute: async ({ context: { city }, writer }) => {
writer.write({
type: "weather-data",
args: {
city
},
status: "pending"
})
// Tool logic here (e.g., API call)
console.log("Using tool to fetch weather information for", city);
writer.write({
type: "weather-data",
args: {
city
},
status: "success",
result: {
temperature: 20,
conditions: "Sunny"
}
})
return { temperature: 20, conditions: "Sunny" }; // Example return
},
});
To use streaming within an agent-based tool, call streamVNext
on the agent and pipe it to the writer:
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
export const weatherInfo = createTool({
id: "Get Weather Information",
description: `Fetches the current weather information for a given city`,
inputSchema: z.object({
city: z.string(),
}),
outputSchema: z.object({
text: z.string(),
}),
execute: async ({ context: { city }, writer, mastra }) => {
const agent = mastra.getAgent('weatherAgent')
const stream = await agent.streamVNext(`What is the weather in ${city}?`);
await stream.pipeTo(writer);
return {
text: await stream.text,
}
},
});
Piping the stream to the writer enables automatic aggregation of token usage across nested agent calls.