Highlights
Azure Blob Storage workspace + blob store (@mastra/azure)
New @mastra/azure adds an Azure Blob Storage WorkspaceFilesystem provider (@mastra/azure/blob) and an AzureBlobStore content-addressable store for skill versioning, with support for connection string, account key, SAS token, DefaultAzureCredential, anonymous auth, prefix namespacing, and read-only mode.
Stream “until idle” to include background task results in the same turn
agent.streamUntilIdle() (plus POST /api/agents/:agentId/stream-until-idle) keeps SSE streaming open until all background tasks finish, then automatically re-invokes the agent so task results are incorporated without needing a second user message; client-js and React useChat now use this flow.
Resume suspended agent streams over HTTP (resume-stream)
Mastra Server adds POST /agents/:agentId/resume-stream and @mastra/client-js adds agent.resumeStream() so apps can resume a previously suspended run with custom data (e.g., approvals/choices) via the client SDK.
Forked subagents for isolated execution on a cloned thread
A new forked flag for HarnessSubagent (and the built-in subagent tool input) runs subagents on a cloned parent thread to preserve prompt-cache prefix while isolating writes; forks inherit parent tools/instructions, flush pending message saves before cloning, and are hidden from Harness.listThreads() by default unless explicitly included.
Cloudflare Workers / V8-isolate support for MCP JSON schema validation
@mastra/mcp adds a jsonSchemaValidator pass-through for MCPClient and MCPServer, enabling validators like CfWorkerJsonSchemaValidator so tools with outputSchema work in environments where Ajv’s new Function(...) compilation is blocked.
Breaking Changes
- None noted in this changelog.
Changelog
@mastra/core@1.29.0
Minor Changes
-
Added
prepareRunandfilterRunutilities for scorer input preparation, allowing scorers to filter and transform agent messages before scoring. Scorers can now declare aprepareRunhook or use thefilterRunbuilder to select specific message part types and tool names before scoring runs. (#15642)Added
getCurrentTraceId()to Harness, which captures the observability trace ID from agent stream responses. This allows callers to correlate feedback and other annotations to the correct trace. -
Added
progressThrottleMsto background task configuration so high-frequency progress output can be coalesced before it reaches pubsub and stream consumers. (#15829)const mastra = new Mastra({ backgroundTasks: { enabled: true, progressThrottleMs: 500, }, });
-
Added forked subagents: a new
forkedflag onHarnessSubagentdefinitions and the built-insubagenttool input. When set, the subagent runs on a clone of the parent thread using the parent agent's instructions and tools, preserving prompt-cache prefix while isolating writes from the main conversation. (#15695)
Patch Changes
-
Stop logging client-disconnect aborts as
Error in LLM executionat error level. The catch block inagentic-execution/llm-execution-step.tsnow checks forisAbortError(error)first and exits via adebug-level log + the existingonAbortflow before the upstream-error / generic-error branches run. Closes #15844. (#15847) -
Fixed Studio observability tabs so runtime-injected observability unlocks them. (#15821)
-
Update provider registry and model documentation with latest models and providers (
b510d36) -
Added a stream error retry processor with OpenAI Responses stream error matching. (#15760)
-
Enable ProviderHistoryCompat error processor by default in mastracode (#15730)
-
Fixed
AgentChannels.consumeAgentStreamsilently droppingtripwirechunks, which left channel users (Slack, Discord) with no response when astrategy: "block"processor fired. The chunk is now handled: whenretryisfalse/unset the block reason is posted to the channel (prefixed with theprocessorIdwhen present); whenretryistruethe chunk is skipped so the agent's retried output can flow through normally. (#15692) -
Fixed toModelOutput lookup for dynamically loaded tools via ToolSearchProcessor (#15452)
-
Replace wildcard
./*export with an explicit allowlist of 48 valid subpath exports. The wildcard combined with tsc emitting individual.d.tsfiles created phantom subpaths (e.g.@mastra/core/auth/ee/defaults) that compiled in TypeScript but crashed at runtime withMODULE_NOT_FOUND. The allowlist approach only exposes subpaths that have actual runtime JS, preventing phantom imports entirely. (#15794) -
fix(tools): preserve args for programmatic tool calls when merging synthetic tool-call (#15227)
Fixes an issue where programmatic tool calls (PTC) received empty
{}arguments during streaming.When a synthetic tool-call was created with empty args, the real tool-call event (containing actual args) was ignored. This change ensures that args from the real tool-call are merged into the synthetic one when missing.
-
Fixed agents forcing
temperature: 0when the user did not explicitly set it. Previously, everyagent.stream()/agent.generate()call silently injectedtemperature: 0into model settings, which broke models that restrict acceptable temperature values (for example Moonshot Kimi K2.5, which only acceptstemperature=1and rejects any other value with400 Bad Request). The model provider's own default is now used when the user does not configure a temperature. Users who explicitly settemperature(includingtemperature: 0for deterministic output) are unaffected. Fixes #15240. (#15611) -
Fix forked subagent fork threads starting with empty history. The parent stream's message saves are debounced through
SaveQueueManager, so a forked subagent that callsmemory.cloneThreadmid-stream used to clone from an empty store and lose the parent's user + assistant turn. The tool now drains the parent save queue via a newflushMessagescallback onAgentToolExecutionContextbefore cloning, so forks actually carry the prior conversation. (#15695) -
The internal
<subagent-meta />tag is no longer appended to subagent tool result content. The tag was previously visible to the parent model in the tool result, which could cause it to be echoed back as literal markup in the parent's assistant text on subsequent turns. Live UIs continue to receive model / duration / tool-call information via the structuredsubagent_*events; history UIs read the persistedtool_call.args.modelId.parseSubagentMetais retained so already-persisted threads carrying the legacy tag continue to render cleanly (and the tag is stripped before display in all cases). (#15695) -
Forked subagents now inherit the parent agent's toolsets (so harness-injected tools like
ask_user,submit_plan, and user-configured harness tools remain available inside a fork). Thesubagenttool entry is kept in the inherited toolset with its id, description, and schemas unchanged so the LLM request prefix stays byte-identical to the parent's and the prompt cache continues to hit; recursive forking is blocked at the runtime layer by replacing only the tool'sexecutewith a stub that returns a "tool unavailable inside a forked subagent" message. Forked runs allow follow-up steps so the model can recover and answer directly if it accidentally calls that stub. Fork threads are tagged withmetadata.forkedSubagent: trueandmetadata.parentThreadId, andHarness.listThreads()hides them by default so they don't surface in user-facing thread pickers; passincludeForkedSubagents: trueto opt back in for admin/debug tooling. (#15695)Mastra Code now renders forked subagent footers as
subagent fork <parent model id>, including persisted history reloaded after the live event metadata is gone. -
Added missing A2A vNext error variants for protocol 0.3 handling. (#15720)
-
Users now get a clear error when using Observational Memory with agent network. (#15808)
-
Improved skills discovery performance by parallelizing filesystem I/O operations. Discovery of multiple skills, subdirectory scanning, reference file reads, and staleness checks now run concurrently instead of sequentially. Also fixed a bug in CompositeVersionedSkillSource where the root directory stat always returned the current time, causing unnecessary re-discovery on every refresh cycle. (#14360)
-
Fixed tool
strict: truebeing silently dropped when routing through V2 (AI SDK v5) OpenAI providers. V2 providers use a globalstrictJsonSchemaprovider option instead of per-toolstrict, so Mastra now propagates the intent automatically — when any tool on a call hasstrict: true,providerOptions.openai.strictJsonSchemais set totruebefore the request is sent. Explicit user-suppliedstrictJsonSchemavalues are respected and never overridden. (#15450) -
Fixed execute_command timeout handling for models that send numeric values as strings. (#15765)
-
Fixed resourceId not being forwarded to createRun() in the agentic loop, which caused persistWorkflowSnapshot to receive resourceId: undefined. (#15742)
-
Fixed agent loops so truncated model responses stop instead of retrying pending tool calls until max steps. (#15788)
-
Fixed
dataset.startExperimentfor workflow targets to matchrunEvals. Previously, scorers running inside a persisted experiment could not access per-step input or output,requestContextconfigured on the experiment was not forwarded into the workflow run, and direct agent calls inside workflow steps could start detached traces instead of nesting under the workflow step span. Step-level data is now exposed to scorers viarun.targetMetadata.stepResultsandrun.targetMetadata.stepExecutionPath, the workflow's root span ID is available asrun.targetSpanId,requestContextpropagates into every step, and ambient workflow step tracing is used when creating nested spans. Fixes #15613. (#15792) -
Fixed
requireApprovalbeing silently ignored for tools loaded dynamically viaToolSearchProcessor. The approval gate now fires atool-call-approvalevent and pauses execution before running, matching the behaviour of tools registered directly on the agent. (#15782) -
Fixed AI SDK v5 message rehydration so suspended and approval tool state data parts are restored from persisted message metadata after reload. (#14246)
-
Fixed the TypeScript type for
requireApprovalon tools so it accepts a function in addition to a boolean. The runtime already supported per-call approval functions (added in #15346), but the type still requiredboolean, forcing anas anycast. You can now pass a sync or async predicate without a cast — the predicate receives the validated tool input and an optional{ requestContext, workspace }second argument. Fixes #15647. (#15783) -
Added ProviderHistoryCompat error processor that automatically sanitizes tool-call IDs when switching between LLM providers. When a provider rejects tool IDs from another provider's history (e.g. Anthropic enforces
^[a-zA-Z0-9_-]+$), the processor rewrites invalid characters and retries the request. (#15730) -
Add
agent.streamUntilIdle()and default sub-agents to run as background tasks. (#15686)streamUntilIdleA new agent streaming method that keeps the stream open until all background tasks dispatched during the turn complete. When a task finishes, the agent is re-invoked automatically so the result is processed in the same call — no second user turn required.
// Before — stream closes once the LLM returns. Background task // results are only processed on the next user message. const result = await agent.stream('Research quantum computing', { memory }); for await (const chunk of result.fullStream) { /* ... */ } // After — stream stays open through the background task completion // and the follow-up agent turn; the final answer arrives in the same call. const result = await agent.streamUntilIdle('Research quantum computing', { memory }); for await (const chunk of result.fullStream) { /* ... */ }
@mastra/auth-studio@1.2.2
Patch Changes
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
@mastra/azure@0.2.0
Minor Changes
-
Add
@mastra/azure, exporting an Azure Blob StorageWorkspaceFilesystemprovider via@mastra/azure/blobwith support for connection string, account key, SAS token,DefaultAzureCredential, and anonymous auth, plus prefix namespacing and read-only mode. (#15217) -
Added
AzureBlobStore, a content-addressable blob store backed by Azure Blob Storage for skill versioning. Available alongside the existingAzureBlobFilesystemfrom@mastra/azure/blob. (#15853)import { AzureBlobStore } from '@mastra/azure/blob'; const blobs = new AzureBlobStore({ container: 'my-skill-blobs', connectionString: process.env.AZURE_STORAGE_CONNECTION_STRING, });
Supports the same authentication methods as
AzureBlobFilesystem: connection string, account key, SAS token,DefaultAzureCredential, and anonymous access. A matchingazureBlobStoreProviderdescriptor is also exported for MastraEditor.
Patch Changes
@mastra/client-js@1.15.0
Minor Changes
-
Added support for resuming suspended agent streams over HTTP with custom data. This adds the
POST /agents/:agentId/resume-streamserver endpoint and the client SDKagent.resumeStream()method, so apps can continue a suspended agent run through the Mastra client. (#14579)Usage example (client SDK):
const agent = mastraClient.getAgent('my-agent'); // Resume a suspended agent stream with custom data const response = await agent.resumeStream( { approved: true, selectedOption: 'plan-b' }, { runId: 'previous-run-id', toolCallId: 'tool-123' }, ); await response.processDataStream({ onChunk: chunk => console.log(chunk), });
-
Improved the Mastra A2A client to feel closer to the official A2A SDK without introducing a breaking change. (#15720)
- Added official-style A2A methods such as
getAgentCard(),sendMessageStream(),getExtendedAgentCard(), andgetTaskPushNotificationConfig(). - Added typed A2A stream consumption for
sendMessageStream()andresubscribeTask(). - Kept older methods available as deprecated compatibility methods, including
getCard()andsendStreamingMessage().
- Added official-style A2A methods such as
Patch Changes
-
Fixed Studio observability tabs so runtime-injected observability unlocks them. (#15821)
-
Add
streamUntilIdleto the agent client, mirroring the new server route. The client keeps the SSE connection open through background task completion and the agent's follow-up turn, and preserves the/stream-until-idleendpoint across client-tool continuations. (#15686)const stream = await client.getAgent('my-agent').streamUntilIdle({ messages: 'Research quantum computing', }); for await (const chunk of stream) { /* ... */ }
@mastra/deployer@1.29.0
Patch Changes
-
Fixed slow or stuck
mastra devstartup in large monorepos when workspace packages share internal dependencies. (#12963)What changed
- Mastra now avoids repeating the same dependency analysis work during dev startup when multiple workspace packages depend on the same internal package.
- This reduces repeated startup work in large monorepos and helps the dev server reach a ready state more reliably.
Fixes #12843.
@mastra/express@1.3.13
Patch Changes
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
@mastra/fastify@1.3.13
Patch Changes
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
@mastra/hono@1.4.8
Patch Changes
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
-
Refactored Hono adapter's
registerCustomApiRoutes()to use the sharedbuildCustomRouteHandler()from the base class instead of duplicating route/handler resolution logic. AddedforwardCustomRouteRequest()to the base class for adapters that already have a rawRequestobject (avoiding unnecessary request reconstruction). (#15793)
@mastra/koa@1.4.13
Patch Changes
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
@mastra/mcp@1.6.0
Minor Changes
-
Added
jsonSchemaValidatorpass-through option onMCPClientserver entries andMCPServer. Forward this option from@modelcontextprotocol/sdkto opt into a non-default validator. PassCfWorkerJsonSchemaValidatorfrom@modelcontextprotocol/sdk/validation/cfworkerto make tools withoutputSchemawork in Cloudflare Workers / V8 isolates, where the default Ajv validator'snew Function(...)compile path is blocked. (#15866)import { MCPClient, MCPServer } from '@mastra/mcp'; import { CfWorkerJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/cfworker'; const mcp = new MCPClient({ servers: { upstream: { url: new URL('https://example/mcp'), jsonSchemaValidator: new CfWorkerJsonSchemaValidator(), }, }, }); const server = new MCPServer({ name: 'My Server', version: '1.0.0', tools: { ... }, jsonSchemaValidator: new CfWorkerJsonSchemaValidator(), });
Closes #15862.
Patch Changes
@mastra/memory@1.17.2
Patch Changes
- Fixed the recall tool so message browsing uses the current thread by default and explains when it does. (#15807)
@mastra/observability@1.10.1
Patch Changes
- Fixed requestContext filtering in span creation to prevent large objects from being serialized into trace data. (#15642)
@mastra/playground-ui@24.0.0
Minor Changes
-
Added shared
ThemeProvider,useTheme, andThemeToggleto unify theme management. (#15838)Added
ThemeProviderapplies the resolved theme class to<html>and persists the choice under the sharedmastra-themelocalStorage key, with a one-time migration from previously stored preferences.useTheme()works without a<ThemeProvider>ancestor: it returns a read-only fallback that tracks the OS color scheme and exposes a no-opsetTheme, so theme-aware leaf components (e.g.CodeDiff,CodeEditor) keep working when embedded standalone.ThemeTogglerenders a system/light/dark pill and supports both controlled and uncontrolled usage.
Patch Changes
-
Migrated color tokens to oklch() for perceptually uniform, wide-gamut (P3) ready colors. Light theme neutrals and surfaces no longer have a blue tint (slate → true gray). Dark theme is visually unchanged. (#15713)
-
Added shared Logs components and hooks under
@mastra/playground-ui. Consumers can now reuse the Logs page building blocks together with the data hooks and the URL-state / filter-persistence helpers instead of duplicating them per app. (#15723) -
Added shared metrics components and hooks under
@mastra/playground-ui. Consumers can now reuse the metrics dashboard building blocks (KPI, Latency, Scores, Token Usage, Trace Volume, Model Usage Cost cards), their data hooks, and theMetricsProvider/DateRangeSelectorprimitives instead of duplicating them per app. (#15705)New peer dependency:
@tanstack/react-query ^5.90.21. Add it alongside your existing playground-ui install. -
Added shared Traces components and hooks under
@mastra/playground-ui. Consumers can now reuse the Traces page building blocks together with the data hooks and the URL-state / filter-persistence helpers instead of duplicating them per app. (#15714) -
Fixed the logs date filter button height to match other filter controls. (#15801)
@mastra/posthog@1.0.19
Patch Changes
- Updated
posthog-nodefrom v4 to v5 to pick up the latest fixes and LLM analytics improvements. Resolves #15858. (#15867)
@mastra/react@0.2.30
Patch Changes
- The useChat hook stream now calls the new
agent.streamUntilIdlemethod and the background-task chunks are processed in toUIMessage. (#15686)
@mastra/redis@1.0.2
Patch Changes
- Fixed Redis package releases to include built files. (#15763)
@mastra/s3@0.5.0
Minor Changes
-
Added AWS credential provider chain support to S3Filesystem and S3BlobStore. You can now pass a
credentialsoption with a credential provider function (e.g.fromNodeProviderChain()) for auto-refreshing credentials on ECS, Lambda, SSO, or AssumeRole deployments. When all credential options are omitted, the AWS SDK default credential provider chain is used automatically instead of falling back to anonymous access. StaticaccessKeyId/secretAccessKeycredentials continue to work as before. (#15437)New
credentialsoptionimport { S3Filesystem } from '@mastra/s3'; import { fromNodeProviderChain } from '@aws-sdk/credential-providers'; // Auto-refreshing credentials (ECS task role, SSO, etc.) const fs = new S3Filesystem({ bucket: 'my-bucket', region: 'us-east-1', credentials: fromNodeProviderChain(), });
SDK default credential chain (no credentials needed)
// Credentials discovered from environment automatically const fs = new S3Filesystem({ bucket: 'my-bucket', region: 'us-east-1', });
Fixes #14289
Patch Changes
@mastra/server@1.29.0
Minor Changes
-
Added support for resuming suspended agent streams over HTTP with custom data. This adds the
POST /agents/:agentId/resume-streamserver endpoint and the client SDKagent.resumeStream()method, so apps can continue a suspended agent run through the Mastra client. (#14579)Usage example (client SDK):
const agent = mastraClient.getAgent('my-agent'); // Resume a suspended agent stream with custom data const response = await agent.resumeStream( { approved: true, selectedOption: 'plan-b' }, { runId: 'previous-run-id', toolCallId: 'tool-123' }, ); await response.processDataStream({ onChunk: chunk => console.log(chunk), });
Patch Changes
-
Fixed Studio observability tabs so runtime-injected observability unlocks them. (#15821)
-
Authentication now refreshes expired server-side sessions transparently, so recoverable token expiry no longer causes unexpected user sign-outs. Only truly expired sessions (e.g. refresh token dead) return a 401. (#15819)
Server adapters now forward refreshed session cookies consistently, and auth-studio logs session validation and refresh failures to improve diagnostics.
-
Updated the A2A server to match the v0.3 protocol shapes and methods. (#15720)
-
Refactored Hono adapter's
registerCustomApiRoutes()to use the sharedbuildCustomRouteHandler()from the base class instead of duplicating route/handler resolution logic. AddedforwardCustomRouteRequest()to the base class for adapters that already have a rawRequestobject (avoiding unnecessary request reconstruction). (#15793) -
Custom API routes now validate that their paths don't collide with the built-in route prefix. If a custom route path starts with the server's
apiPrefix(default/api), a descriptive error is thrown at startup. This prevents custom routes from shadowing built-in Mastra routes (e.g./api/agents,/api/tools). (#15743) -
Add
POST /api/agents/:agentId/stream-until-idleSSE route that mirrorsagent.streamUntilIdle(). The route keeps the SSE stream open through background task completion and the agent's follow-up turn, so clients receive the final answer in a single request. (#15686)
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.0.30
- @mastra/arize@1.0.19
- @mastra/arthur@0.2.5
- @mastra/braintrust@1.0.19
- @mastra/datadog@1.0.19
- @mastra/deployer-cloud@1.29.0
- @mastra/deployer-cloudflare@1.1.27
- @mastra/deployer-netlify@1.1.3
- @mastra/deployer-vercel@1.1.21
- @mastra/editor@0.7.20
- @mastra/laminar@1.0.18
- @mastra/langfuse@1.2.1
- @mastra/langsmith@1.1.16
- @mastra/longmemeval@1.0.32
- @mastra/mcp-docs-server@1.1.29
- @mastra/opencode@0.0.29
- @mastra/otel-bridge@1.0.18
- @mastra/otel-exporter@1.0.18
- @mastra/sentry@1.0.18