Skip to Content
DocsAgentsStreaming (vNext)exp.

Agent Streaming

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 that 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 returns a custom MastraAgentStream that extends ReadableStream with additional utilities.

const stream = await agent.streamVNext({ role: "user", content: "Tell me a story." }); for await (const chunk of stream) { console.log(chunk); }

Each chunk is a JSON object with the following properties:

{ type: string; runId: string; from: string; payload: Record<string, any>; }

The stream provides several utility functions for working with streaming responses:

  • stream.finishReason - The reason the agent stopped streaming.
  • stream.toolCalls - The tool calls made by the agent.
  • stream.toolResults - The tool results returned by the agent.
  • stream.usage - The total token usage of the agent, including agents/workflows as a tool.
  • stream.text - The full text of the agent’s response.
  • stream.object - The object of the agent’s response, if you use output or experimental output.
  • stream.textStream - A readable stream that will emit the text of the agent’s response.

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.

src/mastra/tools/test-tool.ts
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:

src/mastra/tools/test-tool.ts
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.