Highlights
Durable Agents + Resumable Streams (crash/disconnect resilient execution)
New DurableAgent support lets agent streams resume after client disconnects and continue through server crashes/restarts by caching stream events and enabling reconnection via observe(runId, { offset }).
Workflow-backed “Durable Execution” (Evented + Inngest strategies)
Agents can now run outside the HTTP request using workflow execution (createEventedAgent for built-in evented engine, createInngestAgent for Inngest), enabling reliable long-running tool loops while clients subscribe to progress.
Pluggable PubSub + Cache infrastructure (Redis/Upstash-ready)
Durable streaming is backed by a PubSub + ServerCache layer (defaults: EventEmitterPubSub + InMemoryServerCache), with recommended production configs using Redis-backed implementations so any instance can serve reconnect/replay.
Improved A2A streaming artifacts in @mastra/server
A2A streaming now emits incremental artifact updates during the full agent stream while still preserving final structured output artifacts.
Observability noise/volume reduction by default
Cloud observability uploads now filter model chunk spans by default and raise the default observability log level to warn, reducing data volume and chatter.
Breaking Changes
- None called out in this changelog.
Changelog
@mastra/core@1.30.0
Minor Changes
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
Patch Changes
-
Fixed a regression in 1.29.0 where configuring an agent with channel adapters (e.g.
channels.adapters.slack) caused server startup to crash with a "Custom API route ... must not start with /api" error. The custom-route prefix validation now skips framework-generated webhook routes. (#15952) -
Update provider registry and model documentation with latest models and providers (
d587199) -
Fix MCP client support in the agent editor: (#15945)
- MCP client form dirty state: Save button now enables after adding/removing MCP clients
- MCP tool name matching: Both bare and namespaced tool names are matched correctly
- Auth token forwarding: Token from cookie or header is forwarded to auth-protected MCP servers
- String interpolation: Request context variables in system prompts now resolve correctly
@mastra/client-js@1.15.2
Patch Changes
-
Remove incorrect deprecation markers from
getTask()andcancelTask()in the Mastra A2A client. (#15941) -
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
@mastra/editor@0.7.22
Patch Changes
- Fix MCP client support in the agent editor: (#15945)
- MCP client form dirty state: Save button now enables after adding/removing MCP clients
- MCP tool name matching: Both bare and namespaced tool names are matched correctly
- Auth token forwarding: Token from cookie or header is forwarded to auth-protected MCP servers
- String interpolation: Request context variables in system prompts now resolve correctly
@mastra/hono@1.4.10
Patch Changes
- Fixed a regression in 1.29.0 where configuring an agent with channel adapters (e.g.
channels.adapters.slack) caused server startup to crash with a "Custom API route ... must not start with /api" error. The custom-route prefix validation now skips framework-generated webhook routes. (#15952)
@mastra/inngest@1.3.0
Minor Changes
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
-
Update peer dependencies to match core package version bump (1.0.5) (#12557)
Patch Changes
@mastra/memory@1.17.4
Patch Changes
- Fixed idle timeout and provider-change observation activations blocking on in-progress reflection buffering. These triggers now return immediately, letting the background reflection complete asynchronously. (#15937)
@mastra/observability@1.10.3
Patch Changes
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
-
Reduced default cloud observability volume by filtering model chunk spans from CloudExporter uploads by default and raising the default observability log level to
warn. (#15815)
@mastra/playground-ui@24.0.2
Patch Changes
-
Updated the look and motion of
Dialog. The surface is now lighter and translucent with a subtle backdrop blur, the typography is tighter, and the open/close animation feels snappier.SideDialogandAlertDialogpick up the refined ambient shadow as well, since they share the same shadow style. (#15958) -
Polished DataList visuals: removed the trailing "No more data to load" message and dropped the bottom border on the last row for a cleaner end-of-list appearance. (#15959)
-
Refined the DataPanel loading state with a smaller spinner and tightened layout for a less prominent appearance. (#15965)
@mastra/redis@1.1.0
Minor Changes
- Update peer dependencies to match core package version bump (1.0.5) (#12557)
Patch Changes
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
@mastra/server@1.30.0
Minor Changes
- Update peer dependencies to match core package version bump (1.0.5) (#12557)
Patch Changes
-
Fixed a regression in 1.29.0 where configuring an agent with channel adapters (e.g.
channels.adapters.slack) caused server startup to crash with a "Custom API route ... must not start with /api" error. The custom-route prefix validation now skips framework-generated webhook routes. (#15952) -
Fix MCP client support in the agent editor: (#15945)
- MCP client form dirty state: Save button now enables after adding/removing MCP clients
- MCP tool name matching: Both bare and namespaced tool names are matched correctly
- Auth token forwarding: Token from cookie or header is forwarded to auth-protected MCP servers
- String interpolation: Request context variables in system prompts now resolve correctly
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
-
Fix A2A streaming to emit incremental artifact updates from the agent full stream while preserving final structured output artifacts. (#15941)
@mastra/upstash@1.1.0
Minor Changes
- Update peer dependencies to match core package version bump (1.0.5) (#12557)
Patch Changes
-
Add durable agents with resumable streams (#12557)
Durable agents make agent execution resilient to disconnections, crashes, and long-running operations.
The Problem
Standard agent streaming has two fragility points:
- Connection drops - If a client disconnects mid-stream (network blip, browser refresh, mobile app backgrounded), all subsequent events are lost. The client has no way to "catch up" on what they missed.
- Long-running operations - Agent loops with tool calls can take minutes. Holding an HTTP connection open that long is unreliable. If the server restarts or the connection times out, the work is lost.
The Solution
Resumable streams solve connection drops. Every event is cached with a sequential index. If a client disconnects at event 5, they can reconnect and request events starting from index 6. They receive cached events immediately, then continue with live events as they arrive.
Durable execution solves long-running operations. Instead of executing the agent loop directly in the HTTP request, execution happens in a workflow engine (built-in evented engine or Inngest). The HTTP request just subscribes to events. If the connection drops, execution continues. The client can reconnect anytime to observe progress.
Usage
Wrap any existing
Agentwith durability using factory functions:import { Agent } from '@mastra/core/agent'; import { createDurableAgent } from '@mastra/core/agent/durable'; const agent = new Agent({ id: 'my-agent', model: openai('gpt-4'), instructions: 'You are helpful', }); const durableAgent = createDurableAgent({ agent });
Factory functions for different execution strategies:
Factory Execution Use Case createDurableAgent({ agent })Local, synchronous Development, simple deployments createEventedAgent({ agent })Fire-and-forget via workflow engine Long-running operations createInngestAgent({ agent, inngest })Inngest-powered Production, distributed systems Resumable Streams
// Start streaming const { runId, output } = await durableAgent.stream('Analyze this data...'); // Client disconnects at event 5... // Reconnect and resume from where we left off const { output: resumed } = await durableAgent.observe(runId, { offset: 6 }); // Receives events 6, 7, 8... from cache, then continues with live events
PubSub and Cache
Durable agents use two infrastructure components:
Component Purpose Default PubSub Real-time event delivery during streaming EventEmitterPubSubCache Stores events for replay on reconnection InMemoryServerCacheWhen
stream()is called, events flow through pubsub in real-time. The cache stores each event with a sequential index. Whenobserve()is called, missed events replay from cache before continuing with live events.Configure via Mastra instance (recommended):
const mastra = new Mastra({ cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), agents: { // Inherits cache and pubsub from Mastra myAgent: createDurableAgent({ agent }), }, });
Configure per-agent (overrides Mastra):
const durableAgent = createDurableAgent({ agent, cache: new RedisServerCache({ url: 'redis://...' }), pubsub: new RedisPubSub({ url: 'redis://...' }), });
Disable caching (streams won't be resumable):
const durableAgent = createDurableAgent({ agent, cache: false });
For single-instance deployments, the defaults work fine. For multi-instance deployments (load balancer, horizontal scaling), use Redis-backed implementations so any instance can serve reconnection requests.
Class Hierarchy
DurableAgentextendsAgent- base class with resumable streamsEventedAgentextendsDurableAgent- fire-and-forget executionInngestAgentextendsDurableAgent- Inngest-powered execution
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.0.32
- @mastra/arize@1.0.21
- @mastra/arthur@0.2.7
- @mastra/braintrust@1.0.21
- @mastra/datadog@1.0.21
- @mastra/deployer@1.30.0
- @mastra/deployer-cloud@1.30.0
- @mastra/deployer-cloudflare@1.1.29
- @mastra/deployer-netlify@1.1.5
- @mastra/deployer-vercel@1.1.23
- @mastra/express@1.3.15
- @mastra/fastify@1.3.15
- @mastra/koa@1.4.15
- @mastra/laminar@1.0.20
- @mastra/langfuse@1.2.3
- @mastra/langsmith@1.1.18
- @mastra/longmemeval@1.0.34
- @mastra/mcp-docs-server@1.1.31
- @mastra/opencode@0.0.31
- @mastra/otel-bridge@1.0.20
- @mastra/otel-exporter@1.0.20
- @mastra/posthog@1.0.21
- @mastra/react@0.2.32
- @mastra/sentry@1.0.20