Agent.stream()
The .stream() method enables real-time streaming of responses from an agent with enhanced capabilities and format flexibility. This method accepts messages and optional streaming options, providing a current streaming experience with support for both Mastra's native format and AI SDK v5+ compatibility.
Usage exampleDirect link to Usage example
const stream = await agent.stream('message for agent')
Model Compatibility: This method is designed for V2 models. V1 models should use the .streamLegacy() method. The framework automatically detects your model version and will throw an error if there's a mismatch.
ParametersDirect link to Parameters
messages:
options?:
maxSteps?:
scorers?:
scorer:
sampling?:
type:
rate?:
onIterationComplete?:
context.iteration:
context.maxIterations:
context.text:
context.isFinal:
context.finishReason:
context.toolCalls:
context.messages:
return.continue?:
return.feedback?:
isTaskComplete?:
scorers:
strategy?:
onComplete?:
parallel?:
timeout?:
suppressFeedback?:
delegation?:
onDelegationStart?:
context.requestContext to add entries to the subagent run's request context.onDelegationComplete?:
bail() method to stop further execution, and you can return { feedback } to guide the supervisor's next action. Feedback is saved to supervisor memory as an assistant message.messageFilter?:
tracingContext?:
returnScorerData?:
onChunk?:
onError?:
onAbort?:
steps contains the steps that completed before the abort, and text contains the assistant text streamed so far for the step that was in flight.abortSignal?:
activeTools?:
prepareStep?:
context?:
structuredOutput?:
schema:
model?:
errorStrategy?:
fallbackValue?:
instructions?:
jsonPromptInjection?:
providerOptions?:
{ openai: { reasoningEffort: 'low' } }).outputProcessors?:
processOutputResult and processOutputStream functions.includeRawChunks?:
inputProcessors?:
processInput function.instructions?:
system?:
output?:
memory?:
thread:
id and optional metadata.resource:
options?:
onTitleGenerated?:
generateTitle is enabled in memory options and the thread has no existing title.onFinish?:
onStepFinish?:
telemetry?:
isEnabled?:
recordInputs?:
recordOutputs?:
functionId?:
modelSettings?:
temperature?:
maxOutputTokens?:
maxRetries?:
topP?:
topK?:
presencePenalty?:
frequencyPenalty?:
timeout?:
totalMs, the maximum duration of the entire agent run across every loop iteration, tool call and retry, and stepMs, the maximum duration of a single model call including the time spent consuming its stream. Exceeding either budget fails with a MastraTimeoutError. A totalMs timeout ends the run and does not try fallback models, because it is a hard deadline for the whole run. A stepMs timeout is not retried against the same model but does advance to the next entry in models when fallback models are configured.stopSequences?:
toolChoice?:
'auto':
'none':
'required':
{ type: 'tool'; toolName: string }:
toolsets?:
clientTools?:
hooks?:
beforeToolCall can return { proceed: false, output } to skip the tool call.savePerStep?:
requireToolApproval?:
tool-call-approval chunks and pause until approveToolCall() or declineToolCall() is called.autoResumeSuspendedTools?:
resumeData from the user's message based on the tool's resumeSchema. Requires memory to be configured.toolCallConcurrency?:
providerOptions?:
{ providerName: { optionKey: value } }. For example: { openai: { reasoningEffort: 'high' }, anthropic: { maxTokens: 1000 } }.openai?:
{ reasoningEffort: 'high' }anthropic?:
{ maxTokens: 1000 }google?:
{ safetySettings: [...] }[providerName]?:
runId?:
requestContext?:
tracingContext?:
currentSpan?:
tracingOptions?:
metadata?:
requestContextKeys?:
traceId?:
parentSpanId?:
tags?:
versions?:
agents?:
versionId?:
status?:
untilIdle?:
fullStream. Pass true for default settings (5 min idle timeout), or an object with maxIdleMs to configure. Requires memory. Replaces the standalone streamUntilIdle() method.maxIdleMs?:
ReturnsDirect link to Returns
stream:
traceId?:
spanId?:
Extended usage exampleDirect link to Extended usage example
Mastra Format (Default)Direct link to Mastra Format (Default)
import { stepCountIs } from 'ai-v5'
const stream = await agent.stream('Tell me a story', {
stopWhen: stepCountIs(3), // Stop after 3 steps
modelSettings: {
temperature: 0.7,
},
})
// Access text stream
for await (const chunk of stream.textStream) {
console.log(chunk)
}
// or access full stream
for await (const chunk of stream.fullStream) {
console.log(chunk)
}
// Get full text after streaming
const fullText = await stream.text
Limiting execution timeDirect link to Limiting execution time
Use modelSettings.timeout to bound how long a run may take. totalMs limits the entire run, including every loop iteration, tool call and retry. stepMs limits a single model call, covering both establishing the stream and consuming it.
const stream = await agent.stream('Tell me a story', {
modelSettings: {
timeout: {
totalMs: 30000, // fail the run if it takes longer than 30s
stepMs: 10000, // fail an individual model call after 10s
},
},
})
Exceeding either budget fails with a MastraTimeoutError, which carries a timeoutType of 'total' or 'step'. Each budget behaves differently when the agent is configured with fallback models:
- A
totalMstimeout ends the run immediately and doesn't try the next model, because it's a hard deadline for the run as a whole. - A
stepMstimeout isn't retried against the same model, but does advance to the next model, which makes it a way to fail over from a slow provider.
AI SDK v5+ FormatDirect link to AI SDK v5+ Format
To use the stream with AI SDK v5 (and later), you can convert it using our utility function toAISdkStream.
import { stepCountIs, createUIMessageStreamResponse } from 'ai'
import { toAISdkStream } from '@mastra/ai-sdk'
const stream = await agent.stream('Tell me a story', {
stopWhen: stepCountIs(3), // Stop after 3 steps
modelSettings: {
temperature: 0.7,
},
})
// In an API route for frontend integration
return createUIMessageStreamResponse({
stream: toAISdkStream(stream, { from: 'agent' }),
})
Using CallbacksDirect link to Using Callbacks
All callback functions are now available as top-level properties for a cleaner API experience.
const stream = await agent.stream('Tell me a story', {
onFinish: result => {
console.log('Streaming finished:', result)
},
onStepFinish: step => {
console.log('Step completed:', step)
},
onChunk: chunk => {
console.log('Received chunk:', chunk)
},
onError: ({ error }) => {
console.error('Streaming error:', error)
},
onAbort: ({ steps, text }) => {
console.log('Stream aborted after', steps.length, 'steps')
console.log('Partial text:', text)
},
})
// Process the stream
for await (const chunk of stream.textStream) {
console.log(chunk)
}
Advanced example with OptionsDirect link to Advanced example with Options
import { z } from 'zod'
import { stepCountIs } from 'ai'
await agent.stream('message for agent', {
stopWhen: stepCountIs(3), // Stop after 3 steps
modelSettings: {
temperature: 0.7,
},
memory: {
thread: 'user-123',
resource: 'test-app',
},
toolChoice: 'auto',
// Structured output with better DX
structuredOutput: {
schema: z.object({
sentiment: z.enum(['positive', 'negative', 'neutral']),
confidence: z.number(),
}),
model: 'openai/gpt-5.6-sol',
errorStrategy: 'warn',
},
// Output processors for streaming response validation
outputProcessors: [
new ModerationProcessor({ model: 'openrouter/openai/gpt-oss-safeguard-20b' }),
new BatchPartsProcessor({ maxBatchSize: 3, maxWaitTime: 100 }),
],
})
Responses WebSocket transportDirect link to Responses WebSocket transport
Opt into Responses WebSocket streaming with provider options. This only applies to streaming calls and is supported for direct OpenAI models and Azure OpenAI Responses deployments. If WebSocket streaming is unavailable, Mastra falls back to HTTP streaming. By default, Mastra closes the WebSocket when the stream finishes.
const stream = await agent.stream('Hello', {
providerOptions: {
openai: {
transport: 'websocket', // 'websocket' | 'fetch' | 'auto'
websocket: {
url: 'wss://api.openai.com/v1/responses',
closeOnFinish: true, // default
},
},
},
})
For Azure OpenAI, configure the gateway with useResponsesAPI: true, then use providerOptions.azure.transport.
const stream = await agent.stream('Hello', {
providerOptions: {
azure: {
transport: 'websocket',
store: false,
websocket: { closeOnFinish: true },
},
},
})
To keep the connection open after the stream finishes, set closeOnFinish: false and close it manually.
const stream = await agent.stream('Hello', {
providerOptions: {
openai: {
transport: 'websocket',
websocket: { closeOnFinish: false },
},
},
})
// Later, when you're done with the connection:
stream.transport?.close()
Responses WebSocket connections run one response at a time. Mastra rejects overlapping continuation requests that include previous_response_id on the same WebSocket transport. Wait for the active stream to finish before sending the next turn in the response chain.