Highlights
Thread-Scoped Notification Signals + Persisted Inbox (Experimental)
New record-first notification signals add a thread-scoped inbox with agent.sendNotificationSignal(), priority-aware delivery (including due-notification dispatch and low-priority rollups), a structured metadata.notification contract, and a notification_inbox tool to list/read/dismiss/archive notifications.
Notification Inbox Storage Support Across Backends
Notification inbox persistence is now supported in multiple stores—Postgres (@mastra/pg), MongoDB (@mastra/mongodb), and LibSQL (@mastra/libsql)—so notification signals can reliably persist inbox records regardless of your storage choice.
Processor State Signals for Memory-Backed Thread Context
Processors can publish replayable, deduped state “lanes” via computeStateSignal() and external producers can update them with agent.sendStateSignal(), enabling efficient snapshot/delta state history and making browser context flow through the same thread state mechanism.
Working Memory Delivered as State Signals (Experimental Opt-in)
A new workingMemory.useStateSignals option sends working memory as state signals (instead of system-message injection), with automatic WorkingMemoryStateProcessor attachment, cache-key dedupe, and unified-diff deltas when smaller than snapshots (markdown mode).
Type-Safe Message Rendering with @mastra/react MessageFactory + Canonical Stream Types
@mastra/react adds a fully type-safe MessageFactory for per-part rendering (including dynamic tool parts) plus strongly-typed status slots (Tripwire/Warning/Error/Task), while @mastra/core/stream now exports canonical IsTaskCompletePayload and TripwirePayload types for consistent UI typing.
Breaking Changes
- None noted in this changelog.
Changelog
@mastra/core@1.39.0
Minor Changes
-
Add a type-safe
MessageFactorycomponent to@mastra/reactfor rendering aMastraDBMessagewith your own per-part components, and align its tripwire/task-verdict types with@mastra/core. (#17514)@mastra/react
MessageFactoryprovides optional, fully type-safe render functions for each kind of message part. Only the renderer matching a part's type runs, and each receives correctly narrowed props; missing renderers fall back gracefully. Runtime-onlydynamic-tooland AI SDK v5tool-${string}parts are covered by a dedicatedDynamicToolrenderer, and optional role wrappers let you frame parts per message role.import { MessageFactory } from '@mastra/react'; <MessageFactory message={message} Text={part => <p>{part.text}</p>} ToolInvocation={part => <ToolCard name={part.toolInvocation.toolName} />} DynamicTool={part => <ToolCard name={part.toolName} state={part.state} />} Data={part => <DataView type={part.type} data={part.data} />} roles={{ Signal: ({ children }) => <SignalFrame>{children}</SignalFrame> }} />;
It also accepts an optional
statusprop with four strongly-typed slots that render from a message's metadata while keeping part renderers pure.Tripwire,Warning, andErrorare replacement slots (rendered instead of the parts whenmetadata.statusmatches);Taskis an adjacent slot (rendered alongside the parts when a task-completion verdict exists). The factory only surfaces metadata to the slots and never filters it (for example, it still invokesTaskwhensuppressFeedbackis true) — the consumer decides what to render or skip. Existing behavior is unchanged whenstatusis omitted.<MessageFactory message={message} status={{ Error: ({ text }) => <ErrorNotice>{text}</ErrorNotice>, Task: ({ passed, suppressFeedback }) => (suppressFeedback ? null : <TaskVerdict passed={passed} />), }} {...renderers} />
The narrowed part types used by the renderers are exported so consumers can type their own components:
TextPart,ReasoningPart,FilePart,StepStartPart,ToolInvocationPart,SourceDocumentPart, andSourceUrlPart, plusMessageFactoryPart(the exact union of part shapesMessageFactorycan dispatch — the typed accumulator parts plus the runtime-onlydynamic-tool/tool-${string}parts) for typing part arrays precisely instead ofunknown[].MastraDBMessageMetadata.isTaskCompleteResultis now typed as the{ passed?, suppressFeedback? }completion-verdict shape (matchingcompletionResult) instead ofboolean, so theTaskslot resolves verdicts from either field without a cast.TripwireMetadatais now an alias of core'sTripwirePayload, and the message accumulator persists the canonical shape. Two behavioral changes to persistedmetadata.tripwire:- The tripwire
reasonis now persisted astripwire.reason(previously it was only stored in the message text part). - The processor metadata field was renamed from
tripwire.tripwirePayloadtotripwire.metadatato match the canonical type.
The
MessageFactoryTripwireslot receivesreasonthroughprops.tripwire.@mastra/core
Exported the canonical
IsTaskCompletePayloadandTripwirePayloadtypes from@mastra/core/streamso consumers can type their own task/completion and tripwire UI against them instead of redeclaring the shapes.import type { IsTaskCompletePayload, TripwirePayload } from '@mastra/core/stream';
- The tripwire
-
Add experimental record-first notification signals with thread-scoped inbox storage,
agent.sendNotificationSignal(), priority-aware notification delivery policies, due-notification dispatch, summary rollups for low-priority notifications, a structuredmetadata.notificationsignal contract, and a flexible notification inbox tool. (#17241)await agent.sendNotificationSignal( { source: 'github', kind: 'ci-status', priority: 'high', summary: 'CI failed on main', }, { resourceId: 'user-1', threadId: 'thread-1' }, );
Agents can then use the
notification_inboxtool to list, read, dismiss, or archive persisted inbox records. -
Add processor state signals for memory-backed thread context. (#17240)
Processors can now publish named state lanes with
computeStateSignal(), and external producers can update the same lanes withagent.sendStateSignal(). The runtime tracks each lane byid,cacheKey, andmode, so unchanged state is deduped and snapshot/delta history can be replayed efficiently.Browser context now uses this state-signal path, so browser state is represented as thread state instead of being injected as ad hoc context.
// External producer: push browser state outside a model run. await agent.sendStateSignal( { id: 'browser', cacheKey: 'tab-42:https://app.example.com/dashboard', mode: 'snapshot', contents: 'Browser is open on https://app.example.com/dashboard', value: { url: 'https://app.example.com/dashboard', title: 'Dashboard' }, }, { resourceId, threadId, ifIdle: { behavior: 'persist' } }, ); // Processor-owned state: compute state before the model request. const browserProcessor = { id: 'browser-state', stateId: 'browser', async computeStateSignal({ lastSnapshot }) { const nextBrowserState = await getBrowserState(); return { cacheKey: nextBrowserState.url, mode: 'snapshot', contents: `Browser is open on ${nextBrowserState.url}`, value: nextBrowserState, }; }, };
Patch Changes
-
Fixed CostGuardProcessor thread and resource scope resolution when running without auth middleware (e.g. Studio dev mode). The processor now falls back to the MastraMemory context on RequestContext to resolve threadId and resourceId, matching the pattern used by other processor helpers. (#17522)
-
Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
-
Improved notification delivery targeting and inbox search so notification records can be found and delivered to the intended thread. (#17447)
-
Fixed subscribed client tools so browser-executed tool results continue through the existing thread subscription instead of opening and canceling a second stream. This prevents closed-stream errors in apps like Agent Builder when multiple client tools run during one response. (#17532)
-
Added experimental
workingMemory.useStateSignalsopt-in. When set totrue, working memory is delivered to the model as astatesignal (via the new state-signals API) instead of being folded into the system message.Memoryauto-attaches aWorkingMemoryStateProcessorthat emits a signal withstateId: 'working-memory'and dedups viacacheKey. Subsequent turns emit unified-diff deltas against the prior snapshot when the diff is smaller than the snapshot (markdown mode only); schema mode and the fallback path always emit a full snapshot. The working-memory tool is registered assetWorkingMemoryinstead ofupdateWorkingMemoryunder this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (false) preserves the existing system-message behavior.useStateSignalsis not supported with template working memoryversion: 'vnext'. (#17497)import { Memory } from '@mastra/memory'; const memory = new Memory({ options: { workingMemory: { enabled: true, useStateSignals: true, }, }, });
@mastra/auth-better-auth@1.0.3
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/auth-cloud@1.1.3
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/auth-okta@0.0.4
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/auth-studio@1.2.3
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/auth-workos@1.5.1
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/client-js@1.23.0
Minor Changes
-
Added
GET /stored/agents/:storedAgentId/dependentsendpoint that lists agents (#17183)
referencing a stored agent as a sub-agent.const { dependents, hiddenCount } = await client.getStoredAgent(id).dependents(); // { dependents: [{ id: 'parent-1', name: 'Triager' }], hiddenCount: 2 }
dependents— caller-readable agents (public agents and the caller's own private
agents) withid+name.hiddenCount— cross-workspace dependents the caller cannot read, only surfaced
when the target agent is public.
Access mirrors
GET /stored/agents/:storedAgentId— 404 when the caller cannot
read the target. -
Add experimental
agent.sendMessage()andagent.queueMessage()helpers for the new message-first server routes. (#17238)
Patch Changes
-
Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. (#17208)
-
Fixed subscribed client tools so browser-executed tool results continue through the existing thread subscription instead of opening and canceling a second stream. This prevents closed-stream errors in apps like Agent Builder when multiple client tools run during one response. (#17532)
@mastra/deployer@1.39.0
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/libsql@1.12.1
Patch Changes
-
Added LibSQL support for the notifications storage domain so notification signals can persist thread-scoped inbox records. (#17241)
import { LibSQLStore } from '@mastra/libsql'; const storage = new LibSQLStore({ url: 'file:./mastra.db' });
-
Fixed LibSQL memory cleanup so in-memory stores initialize their tables before clearing data. This prevents reset flows from failing with missing table errors such as mastra_resources. (#17532)
@mastra/mcp@1.9.1
Patch Changes
- Removed Hono from @mastra/core and auth package runtime dependencies. Auth providers now receive framework-agnostic request types that support standard Request objects and Hono-compatible request shapes. MCP and deployer avoid relying on core-bundled Hono context types at package boundaries. (#17410)
@mastra/memory@1.20.2
Patch Changes
-
Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. (#17208)
-
Added experimental
workingMemory.useStateSignalsopt-in. When set totrue, working memory is delivered to the model as astatesignal (via the new state-signals API) instead of being folded into the system message.Memoryauto-attaches aWorkingMemoryStateProcessorthat emits a signal withstateId: 'working-memory'and dedups viacacheKey. Subsequent turns emit unified-diff deltas against the prior snapshot when the diff is smaller than the snapshot (markdown mode only); schema mode and the fallback path always emit a full snapshot. The working-memory tool is registered assetWorkingMemoryinstead ofupdateWorkingMemoryunder this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (false) preserves the existing system-message behavior.useStateSignalsis not supported with template working memoryversion: 'vnext'. (#17497)import { Memory } from '@mastra/memory'; const memory = new Memory({ options: { workingMemory: { enabled: true, useStateSignals: true, }, }, });
@mastra/mongodb@1.9.1
Patch Changes
-
Added notification inbox storage support for MongoDB stores. (#17241)
import { MongoDBStore } from '@mastra/mongodb'; const storage = new MongoDBStore({ url: process.env.MONGODB_URI!, dbName: 'mastra' });
Agents using this store can persist thread-scoped notification inbox records for notification signals.
@mastra/pg@1.12.1
Patch Changes
-
Added notification inbox storage support for Postgres stores. (#17241)
import { PostgresStore } from '@mastra/pg'; const storage = new PostgresStore({ connectionString: process.env.POSTGRES_URL! });
Agents using this store can persist thread-scoped notification inbox records for notification signals.
@mastra/playground-ui@32.0.0
Patch Changes
- Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. (#17208)
@mastra/react@0.5.0
Minor Changes
-
Add a type-safe
MessageFactorycomponent to@mastra/reactfor rendering aMastraDBMessagewith your own per-part components, and align its tripwire/task-verdict types with@mastra/core. (#17514)@mastra/react
MessageFactoryprovides optional, fully type-safe render functions for each kind of message part. Only the renderer matching a part's type runs, and each receives correctly narrowed props; missing renderers fall back gracefully. Runtime-onlydynamic-tooland AI SDK v5tool-${string}parts are covered by a dedicatedDynamicToolrenderer, and optional role wrappers let you frame parts per message role.import { MessageFactory } from '@mastra/react'; <MessageFactory message={message} Text={part => <p>{part.text}</p>} ToolInvocation={part => <ToolCard name={part.toolInvocation.toolName} />} DynamicTool={part => <ToolCard name={part.toolName} state={part.state} />} Data={part => <DataView type={part.type} data={part.data} />} roles={{ Signal: ({ children }) => <SignalFrame>{children}</SignalFrame> }} />;
It also accepts an optional
statusprop with four strongly-typed slots that render from a message's metadata while keeping part renderers pure.Tripwire,Warning, andErrorare replacement slots (rendered instead of the parts whenmetadata.statusmatches);Taskis an adjacent slot (rendered alongside the parts when a task-completion verdict exists). The factory only surfaces metadata to the slots and never filters it (for example, it still invokesTaskwhensuppressFeedbackis true) — the consumer decides what to render or skip. Existing behavior is unchanged whenstatusis omitted.<MessageFactory message={message} status={{ Error: ({ text }) => <ErrorNotice>{text}</ErrorNotice>, Task: ({ passed, suppressFeedback }) => (suppressFeedback ? null : <TaskVerdict passed={passed} />), }} {...renderers} />
The narrowed part types used by the renderers are exported so consumers can type their own components:
TextPart,ReasoningPart,FilePart,StepStartPart,ToolInvocationPart,SourceDocumentPart, andSourceUrlPart, plusMessageFactoryPart(the exact union of part shapesMessageFactorycan dispatch — the typed accumulator parts plus the runtime-onlydynamic-tool/tool-${string}parts) for typing part arrays precisely instead ofunknown[].MastraDBMessageMetadata.isTaskCompleteResultis now typed as the{ passed?, suppressFeedback? }completion-verdict shape (matchingcompletionResult) instead ofboolean, so theTaskslot resolves verdicts from either field without a cast.TripwireMetadatais now an alias of core'sTripwirePayload, and the message accumulator persists the canonical shape. Two behavioral changes to persistedmetadata.tripwire:- The tripwire
reasonis now persisted astripwire.reason(previously it was only stored in the message text part). - The processor metadata field was renamed from
tripwire.tripwirePayloadtotripwire.metadatato match the canonical type.
The
MessageFactoryTripwireslot receivesreasonthroughprops.tripwire.@mastra/core
Exported the canonical
IsTaskCompletePayloadandTripwirePayloadtypes from@mastra/core/streamso consumers can type their own task/completion and tripwire UI against them instead of redeclaring the shapes.import type { IsTaskCompletePayload, TripwirePayload } from '@mastra/core/stream';
- The tripwire
-
Use the message-first client helper for user-authored thread input while preserving fallback behavior for older servers that only support the legacy signal route. (#17238)
Patch Changes
- Improved agent message, stream, and observational-memory type handling across the client SDKs and playground UI. (#17208)
@mastra/server@1.39.0
Minor Changes
-
Added
GET /stored/agents/:storedAgentId/dependentsendpoint that lists agents (#17183)
referencing a stored agent as a sub-agent.const { dependents, hiddenCount } = await client.getStoredAgent(id).dependents(); // { dependents: [{ id: 'parent-1', name: 'Triager' }], hiddenCount: 2 }
dependents— caller-readable agents (public agents and the caller's own private
agents) withid+name.hiddenCount— cross-workspace dependents the caller cannot read, only surfaced
when the target agent is public.
Access mirrors
GET /stored/agents/:storedAgentId— 404 when the caller cannot
read the target.
Patch Changes
-
Fixed memory status incorrectly reporting memory as enabled for agents without memory configured. The /api/memory/status endpoint now returns false for a resolved agent that has no memory, even when the Mastra instance has storage configured. Previously, Studio would render memory UI for such agents. (#17506)
-
Fixed subscribed client tools so browser-executed tool results continue through the existing thread subscription instead of opening and canceling a second stream. This prevents closed-stream errors in apps like Agent Builder when multiple client tools run during one response. (#17532)
Other updated packages
The following packages were updated with dependency changes only:
- @mastra/agent-builder@1.0.40
- @mastra/deployer-cloud@1.39.0
- @mastra/deployer-cloudflare@1.1.40
- @mastra/deployer-netlify@1.1.16
- @mastra/deployer-vercel@1.1.34
- @mastra/editor@0.11.1
- @mastra/express@1.3.27
- @mastra/fastify@1.3.27
- @mastra/hono@1.4.22
- @mastra/koa@1.5.10
- @mastra/longmemeval@1.0.46
- @mastra/mcp-docs-server@1.1.43
- @mastra/nestjs@0.1.11
- @mastra/opencode@0.0.43
- @mastra/temporal@0.1.10