github mastra-ai/mastra @mastra/core@1.39.0
June 3, 2026

latest releases: mastracode@0.22.2, mastra@1.12.2, create-mastra@1.12.2...
6 hours ago

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 MessageFactory component to @mastra/react for rendering a MastraDBMessage with your own per-part components, and align its tripwire/task-verdict types with @mastra/core. (#17514)

    @mastra/react

    MessageFactory provides 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-only dynamic-tool and AI SDK v5 tool-${string} parts are covered by a dedicated DynamicTool renderer, 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 status prop with four strongly-typed slots that render from a message's metadata while keeping part renderers pure. Tripwire, Warning, and Error are replacement slots (rendered instead of the parts when metadata.status matches); Task is 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 invokes Task when suppressFeedback is true) — the consumer decides what to render or skip. Existing behavior is unchanged when status is 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, and SourceUrlPart, plus MessageFactoryPart (the exact union of part shapes MessageFactory can dispatch — the typed accumulator parts plus the runtime-only dynamic-tool / tool-${string} parts) for typing part arrays precisely instead of unknown[].

    MastraDBMessageMetadata.isTaskCompleteResult is now typed as the { passed?, suppressFeedback? } completion-verdict shape (matching completionResult) instead of boolean, so the Task slot resolves verdicts from either field without a cast.

    TripwireMetadata is now an alias of core's TripwirePayload, and the message accumulator persists the canonical shape. Two behavioral changes to persisted metadata.tripwire:

    • The tripwire reason is now persisted as tripwire.reason (previously it was only stored in the message text part).
    • The processor metadata field was renamed from tripwire.tripwirePayload to tripwire.metadata to match the canonical type.

    The MessageFactory Tripwire slot receives reason through props.tripwire.

    @mastra/core

    Exported the canonical IsTaskCompletePayload and TripwirePayload types from @mastra/core/stream so 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';
  • 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 structured metadata.notification signal 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_inbox tool 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 with agent.sendStateSignal(). The runtime tracks each lane by id, cacheKey, and mode, 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.useStateSignals opt-in. When set to true, working memory is delivered to the model as a state signal (via the new state-signals API) instead of being folded into the system message. Memory auto-attaches a WorkingMemoryStateProcessor that emits a signal with stateId: 'working-memory' and dedups via cacheKey. 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 as setWorkingMemory instead of updateWorkingMemory under this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (false) preserves the existing system-message behavior. useStateSignals is not supported with template working memory version: '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/dependents endpoint 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) with id + 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() and agent.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.useStateSignals opt-in. When set to true, working memory is delivered to the model as a state signal (via the new state-signals API) instead of being folded into the system message. Memory auto-attaches a WorkingMemoryStateProcessor that emits a signal with stateId: 'working-memory' and dedups via cacheKey. 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 as setWorkingMemory instead of updateWorkingMemory under this opt-in so legacy persistence/prompt strip filters naturally bypass it. The default (false) preserves the existing system-message behavior. useStateSignals is not supported with template working memory version: '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 MessageFactory component to @mastra/react for rendering a MastraDBMessage with your own per-part components, and align its tripwire/task-verdict types with @mastra/core. (#17514)

    @mastra/react

    MessageFactory provides 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-only dynamic-tool and AI SDK v5 tool-${string} parts are covered by a dedicated DynamicTool renderer, 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 status prop with four strongly-typed slots that render from a message's metadata while keeping part renderers pure. Tripwire, Warning, and Error are replacement slots (rendered instead of the parts when metadata.status matches); Task is 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 invokes Task when suppressFeedback is true) — the consumer decides what to render or skip. Existing behavior is unchanged when status is 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, and SourceUrlPart, plus MessageFactoryPart (the exact union of part shapes MessageFactory can dispatch — the typed accumulator parts plus the runtime-only dynamic-tool / tool-${string} parts) for typing part arrays precisely instead of unknown[].

    MastraDBMessageMetadata.isTaskCompleteResult is now typed as the { passed?, suppressFeedback? } completion-verdict shape (matching completionResult) instead of boolean, so the Task slot resolves verdicts from either field without a cast.

    TripwireMetadata is now an alias of core's TripwirePayload, and the message accumulator persists the canonical shape. Two behavioral changes to persisted metadata.tripwire:

    • The tripwire reason is now persisted as tripwire.reason (previously it was only stored in the message text part).
    • The processor metadata field was renamed from tripwire.tripwirePayload to tripwire.metadata to match the canonical type.

    The MessageFactory Tripwire slot receives reason through props.tripwire.

    @mastra/core

    Exported the canonical IsTaskCompletePayload and TripwirePayload types from @mastra/core/stream so 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';
  • 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/dependents endpoint 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) with id + 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:

Don't miss a new mastra release

NewReleases is sending notifications on new releases.