Skip to content

Releases: mastra-ai/mastra

Mar 25, 2026

26 Mar 10:19

Choose a tag to compare

Highlights

Smarter Model Selection for Observational Memory

@mastra/memory now lets you route observer and reflector calls to different models based on input size using ModelByInputTokens. Short inputs can go to a fast, cheap model while longer ones get sent to a more capable one -- all configured declaratively with token thresholds. Tracing shows which model was selected and why.

MongoDB Support for Datasets and Experiments

@mastra/mongodb now stores versioned datasets with full item history and time-travel queries, plus experiment results and CRUD. If you're already using MongoDBStore, this works automatically with no extra setup.

Okta Auth and RBAC

New @mastra/auth-okta package brings SSO authentication and role-based access control via Okta. Map Okta groups to Mastra permissions, verify JWTs against Okta's JWKS endpoint, and manage sessions -- or pair Okta RBAC with a different auth provider like Auth0 or Clerk.

Breaking Changes

  • None called out in this changelog.

Changelog

@mastra/core@1.16.0

Minor Changes

  • Added dataset-agent association and experiment status tracking for the Evaluate workflow. (#14470)

    • Dataset targeting: Added targetType and targetIds fields to datasets, enabling association with agents, scorers, or workflows. Datasets can now be linked to multiple entities.
    • Experiment status: Added status field to experiment results ('needs-review', 'reviewed', 'complete') for review queue workflow.
    • Dataset experiment routes: Added API endpoints for triggering experiments from a dataset with configurable target type and target ID.
    • LLM data generation: Added endpoint for generating dataset items using an LLM with configurable count and prompt.
    • Failure analysis: Added endpoint for clustering experiment failures and proposing tags using LLM analysis.
  • Added agent version support for experiments. When triggering an experiment, you can now pass an agentVersion parameter to pin which agent version to use. The agent version is stored with the experiment and returned in experiment responses. (#14562)

    const client = new MastraClient();
    
    await client.triggerDatasetExperiment({
      datasetId: "my-dataset",
      targetType: "agent",
      targetId: "my-agent",
      version: 3, // pin to dataset version 3
      agentVersion: "ver_abc123" // pin to a specific agent version
    });
  • Added tool suspension handling to the Harness. (#14611)

    When a tool calls suspend() during execution, the harness now emits a tool_suspended event, reports agent_end with reason 'suspended', and exposes respondToToolSuspension() to resume execution with user-provided data.

    harness.subscribe((event) => {
      if (event.type === "tool_suspended") {
        // event.toolName, event.suspendPayload, event.resumeSchema
      }
    });
    
    // Resume after collecting user input
    await harness.respondToToolSuspension({ resumeData: { confirmed: true } });
  • Added agentId to the agent tool execution context. Tools executed by an agent can now access context.agent.agentId to identify which agent is calling them. This enables tools to look up agent metadata, share workspace configuration with sub-agents, or customize behavior per agent. (#14502)

  • Improved observability metrics and logs storage support. (#14607)

    • Added typed observability storage fields for shared correlation context and cost data.
    • Added storage-layer metric listing and richer metric aggregations that can return estimated cost alongside values.
    • Improved observability filter parity across log and metric storage APIs.
  • Add optional ?path= query param to workspace skill routes for disambiguating same-named skills. (#14430)

    Skill routes continue to use :skillName in the URL path (no breaking change). When two skills share the same name (e.g. from different directories), pass the optional ?path= query parameter to select the exact skill:

    GET /workspaces/:workspaceId/skills/:skillName?path=skills/brand-guidelines
    

    SkillMetadata now includes a path field, and the list() method returns all same-named skills for disambiguation. The client SDK's getSkill() accepts an optional skillPath parameter for disambiguation.

  • Added ModelByInputTokens in @mastra/memory for token-threshold-based model selection in Observational Memory. (#14614)

    When configured, OM automatically selects different observer or reflector models based on the actual input token count at the time the OM call runs.

    Example usage:

    import { Memory, ModelByInputTokens } from "@mastra/memory";
    
    const memory = new Memory({
      options: {
        observationalMemory: {
          model: new ModelByInputTokens({
            upTo: {
              10_000: "google/gemini-2.5-flash",
              40_000: "openai/gpt-4o",
              1_000_000: "openai/gpt-4.5"
            }
          })
        }
      }
    });

    The upTo keys are inclusive upper bounds. OM resolves the matching tier directly at the observer or reflector call site. If the input exceeds the largest configured threshold, OM throws an error.

    Improved Observational Memory tracing so traces show the observer and reflector spans and make it easier to see which resolved model was used at runtime.

Patch Changes

  • Update provider registry and model documentation with latest models and providers (68ed4e9)

  • Fixed Harness.destroy() to properly clean up heartbeats and workspace on teardown. (#14568)

  • Fixed null detection in tool input validation to check actual values at failing paths instead of relying on error message string matching. This ensures null values from LLMs are correctly handled even when validators produce error messages that don't contain the word "null" (e.g., "must be string"). Fixes #14476. (#14496)

  • Fixed missing tool lists in agent traces for streaming runs. Exporters like Datadog LLM Observability now receive the tools available to the agent. (#14550)

  • Fix consecutive tool-only loop iterations being merged into a single assistant message block. When the agentic loop runs multiple iterations that each produce only tool calls, the LLM would misinterpret them as parallel calls from a single turn. A step-start boundary is now inserted between iterations to ensure they are treated as sequential steps. (#14652)

  • Improved custom OpenAI-compatible model configuration guidance in the models docs. (#14594)

  • Added client/server body schemas for feedback and scores that omit the timestamp field, allowing it to be set server-side (#14470)

  • Workspace skills now surface all same-named skills for disambiguation. (#14430)

    When multiple skills share the same name (e.g., a local brand-guidelines skill and one from node_modules), list() now returns all of them instead of only the tie-break winner. This lets agents and UIs see every available skill, along with its path and source type.

    Tie-breaking behavior:

    • get(name) still returns a single skill using source-type priority: local > managed > external
    • If two skills share the same name and source type, get(name) throws an error — rename one or move it to a different source type
    • get(path) bypasses tie-breaking entirely and returns the exact skill

    Agents and UIs now receive all same-named skills with their paths, which improves disambiguation in prompts and tool calls.

    const skills = await workspace.skills.list();
    // Returns both local and external "brand-guidelines" skills
    
    const exact = await workspace.skills.get("node_modules/@myorg/skills/brand-guidelines");
    // Fetches the external copy directly by path
  • Fixed Anthropic 'tool_use ids were found without tool_result blocks immediately after' error. When client tools (e.g. execute_command) and provider tools (e.g. web_search) are called in parallel, the tool ordering in message history could cause Anthropic to reject subsequent requests, making the thread unrecoverable. Tool blocks are now correctly split to satisfy Anthropic's ordering requirements. (#14648)

  • Fix Zod v3 and Zod v4 compatibility across public structured-output APIs. (#14464)

    Mastra agent and client APIs accept schemas from either zod/v3 or zod/v4, matching the documented peer dependency range and preserving TypeScript compatibility for both Zod versions.

@mastra/ai-sdk@1.2.1

Patch Changes

Read more

March 17, 2026

19 Mar 10:48

Choose a tag to compare

Highlights

AI Gateway Tool Support in the Agentic Loop

@mastra/core now supports AI Gateway tools (e.g. gateway.tools.perplexitySearch()) as provider-executed tools: it infers providerExecuted, merges streamed provider results back into the originating tool calls, and skips local execution when the provider already returned a result.

More Reliable Observational Memory (Cache Stability + “As Of” Retrieval)

Observational memory persistence is more stable via dated message boundary delimiters and chunking, and @mastra/memory adds getObservationsAsOf() to retrieve the exact observation set active at a given message timestamp (useful for replay/debugging and consistent prompting).

MCP Client Diagnostics & Per-Server Control

@mastra/mcp adds per-server operational tooling—reconnectServer(serverName), listToolsetsWithErrors(), and getServerStderr(serverName)—to improve reliability and debugging of MCP stdio/server integrations.

Breaking Changes

  • None called out in this changelog.

Changelog

@mastra/core@1.14.0

Patch Changes

  • Update provider registry and model documentation with latest models and providers (51970b3)

  • Added dated message boundary delimiters when activating buffered observations for improved cache stability. (#14367)

  • Fixed provider-executed tool calls being saved out of order or without results in memory replay. (Fixes #13762) (#13860)

  • Fix generateEmptyFromSchema to accept both string and pre-parsed object JSON schema inputs, recursively initialize nested object properties, and respect default values. Updated WorkingMemoryTemplate type to a discriminated union supporting Record<string, unknown> content for JSON format templates. Removed duplicate private schema generator in the working-memory processor in favor of the shared utility. (#14310)

  • Fixed provider-executed tool calls (e.g. Anthropic web_search) being dropped or incorrectly persisted when deferred by the provider. Tool call parts are now persisted in stream order, and deferred tool results are correctly merged back into the originating message. (#14282)

  • Fixed replaceString utility to properly escape $ characters in replacement strings. Previously, patterns like $& in the replacement text would be interpreted as regex backreferences instead of literal text. (#14434)

  • Fixed tool invocation updates to preserve providerExecuted and providerMetadata from the original tool call when updating to result state. (#14431)

  • @mastra/core: patch (#14327)

    Added spanId alongside traceId across user-facing execution results that return tracing identifiers (including agent stream/generate and workflow run results) so integrations can query observability vendors by run root span ID

  • Add AI Gateway tool support in the agentic loop. (#14016)

    Gateway tools (e.g., gateway.tools.perplexitySearch()) are provider-executed but, unlike native provider tools (e.g., openai.tools.webSearch()), the LLM provider does not store their results server-side. The agentic loop now correctly infers providerExecuted for these tools, merges streamed provider results with their corresponding tool calls, and skips local execution when a provider result is already present.

    Fixes #13190

  • Fixed schema-based working memory typing so workingMemory.schema accepts supported schemas such as Zod and JSON Schema. (#14363)

  • Fixed workspace search being wiped when skills refresh. Previously, calling skills.refresh() or triggering a skills re-discovery via maybeRefresh() would clear the entire BM25 search index, including auto-indexed workspace content. Now only skill entries are removed from the index during refresh, preserving workspace search results. (#14287)

  • Added client/server body schemas for feedback and scores that omit the timestamp field, allowing it to be set server-side (#14270)

  • Fixed processor state not persisting between processOutputStream and processOutputResult when processors are wrapped in workflows. State set during stream processing is now correctly accessible in processOutputResult. (#14279)

  • Fixed type inference for requestContext schemas when using Zod v3 and v4. Agent and tool configurations now correctly infer RequestContext types from Zod schemas and other StandardSchema-compatible schemas. (#14363)

@mastra/ai-sdk@1.1.4

Patch Changes

  • Clarified that chatRoute() aborts generation on client disconnect and documented a custom route pattern that continues server-side generation with consumeStream(). (#14333)

@mastra/auth@1.0.2

Patch Changes

  • Fixed Studio showing unauthenticated state when using MastraJwtAuth with custom headers. MastraJwtAuth now implements the IUserProvider interface (getCurrentUser/getUser), so the Studio capabilities endpoint can resolve the authenticated user from the JWT Bearer token. (#14411)

    Also added an optional mapUser option to customize how JWT claims are mapped to user fields:

    new MastraJwtAuth({
      secret: process.env.JWT_SECRET,
      mapUser: payload => ({
        id: payload.userId,
        name: payload.displayName,
        email: payload.mail,
      }),
    });

    Closes #14350

@mastra/auth-studio@1.2.0

Minor Changes

  • Add configurable cookie domain support (#14285)
    • Add cookieDomain option to MastraAuthStudioOptions for explicit configuration
    • Support MASTRA_COOKIE_DOMAIN environment variable as fallback
    • Use hostname-based detection for auto-detecting .mastra.ai domain (prevents false positives from malicious URLs)
    • Maintain backward compatibility with existing .mastra.ai auto-detection

Patch Changes

@mastra/client-js@1.9.0

Minor Changes

  • Added new observability API endpoints and client methods for logs, scores, feedback, metrics (aggregate, breakdown, time series, percentiles), and discovery (metric names, label keys/values, entity types/names, service names, environments, tags) (#14270)

Patch Changes

@mastra/deployer@1.14.0

Patch Changes

  • Added MASTRA_HOST environment variable support for configuring the server bind address. Previously, the host could only be set via server.host in the Mastra config. Now it follows the same pattern as PORT: config value takes precedence, then env var, then defaults to localhost. (#14313)

  • Added a new MASTRA_TEMPLATES Studio runtime flag to control whether the Templates section appears in the sidebar. (#14309)

    • MASTRA_TEMPLATES=true now enables Templates navigation in Studio.
    • By default (false or unset), Templates is hidden.
    • Studio HTML injection now propagates this value in both CLI-hosted and deployer-hosted Studio builds.
    • Added tests covering environment variable injection for both paths.
  • Fixed tsconfig path aliases during build when imports use .js-style module specifiers. (#13998)

  • Fixed apiPrefix server option not being applied to the underlying Hono server instance. Routes, welcome page, Swagger UI, and studio HTML handler now all respect the configured apiPrefix instead of hardcoding /api. (#14325)

@mastra/deployer-cloudflare@1.1.12

Patch Changes

Read more

March 13, 2026

17 Mar 10:20

Choose a tag to compare

Highlights

Observability Storage Domain (schemas + in-memory implementations)

Mastra now ships zod-based storage schemas and in-memory implementations for all observability signals (scores, logs, feedback, metrics, discovery), with full type inference and a base ObservabilityStorage that includes default method implementations.

New persistent Workspace filesystem: @mastra/agentfs

The new AgentFSFilesystem workspace provider adds Turso/SQLite-backed, database-persistent file storage for agents across sessions via agentfs-sdk.

Observability pipeline upgrades: renamed types + EventBuffer batching

@mastra/observability exporters/event bus were updated to align with renamed core observability types, and an EventBuffer was added to batch non-tracing signals with configurable flush intervals.

Type-safe server route inference via @mastra/server/schemas

A new @mastra/server/schemas export provides utility types (RouteMap, InferPathParams, InferBody, InferResponse, etc.) that automatically infer request/response types from SERVER_ROUTES, including routes added via createRoute().

Lower token costs for long-running Observational Memory

Observational Memory adds observation.previousObserverTokens to truncate the “Previous Observations” context to a token budget (or omit/disable truncation), reducing observer prompt size in long conversations.

Breaking Changes

  • MetricType (counter/gauge/histogram) is deprecated — metrics are now raw events with aggregation at query time
  • Score schemas now use scorerId instead of scorerName
  • ObservabilityBus constructor now takes a config object (cardinalityFilter, autoExtractMetrics); setCardinalityFilter() and enableAutoExtractedMetrics() were removed

Changelog

@mastra/core@1.13.0

Minor Changes

  • Added observability storage domain schemas and implementations (#14214)

    Introduced comprehensive storage schemas and in-memory implementations for all observability signals (scores, logs, feedback, metrics, discovery). All schemas are zod-based with full type inference. The ObservabilityStorage base class includes default implementations for all new methods.

    Breaking changes:

    • MetricType (counter/gauge/histogram) is deprecated — metrics are now raw events with aggregation at query time
    • Score schemas use scorerId instead of scorerName for scorer identification

Patch Changes

  • Update provider registry and model documentation with latest models and providers (ea86967)

  • Fixed provider tools (e.g. openai.tools.webSearch()) being silently dropped when using a custom gateway that returns AI SDK v6 (V3) models. The router now remaps tool types from provider-defined to provider when delegating to V3 models, so provider tools work correctly through gateways. Fixes #13667. (#13895)

  • Fixed TypeScript type errors in onStepFinish and onFinish callbacks, and resolved compatibility issues with createOpenRouter() across different AI SDK versions. (#14229)

  • Fixed a bug where thread metadata (e.g. title, custom properties) passed via options.memory.thread was discarded when MASTRA_THREAD_ID_KEY was set in the request context. The thread ID from context still takes precedence, but all other user-provided thread properties are now preserved. (#13146)

  • Fixed workspace tools such as mastra_workspace_list_files and mastra_workspace_read_file failing with WorkspaceNotAvailableError in some execution paths. (#14228)

    Workspace tools now work consistently across execution paths.

  • Added observer context optimization for Observational Memory. The observation.previousObserverTokens field reduces Observer input token costs for long-running conversations: (#13568)

    • previousObserverTokens (default: 2000): Truncates the 'Previous Observations' section to a token budget, keeping the most recent observations and automatically replacing already-reflected lines with the buffered reflection summary. Set to 0 to omit previous observations entirely, or false to disable truncation and keep the full observation history.
    const memory = new Memory({
      options: {
        observationalMemory: {
          model: 'google/gemini-2.5-flash',
          observation: {
            previousObserverTokens: 10_000,
          },
        },
      },
    });

@mastra/agentfs@0.1.0

Minor Changes

  • Added AgentFSFilesystem workspace provider — a Turso/SQLite-backed filesystem via the agentfs-sdk that gives agents persistent, database-backed file storage across sessions. (#13450)

    Basic usage

    import { Workspace } from '@mastra/core/workspace';
    import { AgentFSFilesystem } from '@mastra/agentfs';
    
    const workspace = new Workspace({
      filesystem: new AgentFSFilesystem({
        agentId: 'my-agent',
      }),
    });

Patch Changes

@mastra/deployer@1.13.0

Patch Changes

  • Bump esbuild from ^0.25.10 to ^0.27.3 to resolve Go stdlib CVEs (CVE-2025-22871, CVE-2025-61729) flagged by npm audit in consumer projects. (#13124)

  • Fixed Agent-to-Agent requests to return a clear error message when the agent ID parameter is missing. (#14229)

  • Add dynamicPackages bundler config for runtime-loaded packages and auto-detect pino (#11779)

    Adds a new dynamicPackages bundler config option for packages that are loaded
    dynamically at runtime and cannot be detected by static analysis (e.g.,
    pino.transport({ target: "pino-opentelemetry-transport" })).

    Usage:

    import { Mastra } from '@mastra/core';
    
    export const mastra = new Mastra({
      bundler: {
        dynamicPackages: ['my-custom-transport', 'some-plugin'],
      },
    });

    Additionally, pino transport targets are now automatically detected from the
    bundled code, so most pino users won't need any configuration.

    This keeps externals for its intended purpose (packages to not bundle) and
    provides a clear mechanism for dynamic packages that need to be in the output
    package.json.

    Fixes #10893

@mastra/mcp@1.2.1

Patch Changes

  • Fixed TypeScript compilation errors when using MCP resource methods in projects with pnpm workspaces. (#14229)

@mastra/memory@1.8.0

Minor Changes

  • Added observer context optimization for Observational Memory. The observation.previousObserverTokens field reduces Observer input token costs for long-running conversations: (#13568)

    • previousObserverTokens (default: 2000): Truncates the 'Previous Observations' section to a token budget, keeping the most recent observations and automatically replacing already-reflected lines with the buffered reflection summary. Set to 0 to omit previous observations entirely, or false to disable truncation and keep the full observation history.
    const memory = new Memory({
      options: {
        observationalMemory: {
          model: 'google/gemini-2.5-flash',
          observation: {
            previousObserverTokens: 10_000,
          },
        },
      },
    });

Patch Changes

@mastra/observability@1.5.0

Minor Changes

  • Updated exporters and event bus to use renamed observability types from @mastra/core. Added EventBuffer for batching non-tracing signals with configurable flush intervals. (#14214)

    Breaking changes:

    • ObservabilityBus now takes a config object in its constructor (cardinalityFilter, autoExtractMetrics); setCardinalityFilter() and enableAutoExtractedMetrics() removed

Patch Changes

@mastra/playground-ui@16.1.0

Minor Changes

  • Added group-by-thread utility for the Observability tab. Traces can now be grouped by the...
Read more

March 12, 2026

16 Mar 14:36

Choose a tag to compare

Highlights

Cloudflare Durable Objects Storage Adapter

@mastra/cloudflare adds a new Durable Objects–backed storage implementation (in addition to KV), with SQLite persistence, batch operations, and table/column validation—enabling more robust stateful storage on Cloudflare.

Workspace Filesystem Path Resolution Now Matches Real Filesystem Semantics

LocalFilesystem no longer treats absolute paths like /file.txt as workspace-relative; absolute paths now resolve to real filesystem locations (with containment checks), relative paths resolve against basePath, and ~/ expands to the home directory.

Improved Observability for MCP Tooling and Agent/Workflow Execution

MCP tool calls are now traced with a dedicated MCP_TOOL_CALL span type (with server name/version metadata), Studio adds MCP-specific timeline styling, processor-triggered aborts are fully visible in traces, and workflow suspend/resume now preserves trace continuity under the original span.

More Reliable Agent Loops and Token Budgeting in Multi-step Runs

Fixes include the agent loop continuing correctly when onIterationComplete returns continue: true, and preventing exponential token growth by running token-based message pruning at every step (including tool call continuations).

Sandbox & Workspace Extensibility via Provider-specific Getters and String PIDs

Sandbox process IDs are now string-based (ProcessHandle.pid: string) to support session IDs across providers, and sandboxes/filesystems expose underlying SDK instances via new provider-specific getters (e.g., sandbox.daytona, sandbox.blaxel, filesystem.client for S3, filesystem.storage/bucket for GCS).

Breaking Changes

  • LocalFilesystem no longer treats absolute paths (e.g. /src/index.ts) as basePath-relative; update callers to pass relative paths when targeting the workspace.
  • ProcessHandle.pid changed from number to string; update any code that assumes numeric PIDs (including processes.get(...)).

Changelog

@mastra/core@1.12.0

Minor Changes

  • MCP tool calls now use MCP_TOOL_CALL span type instead of TOOL_CALL in traces. CoreToolBuilder detects mcpMetadata on tools and creates spans with MCP server name, version, and tool description attributes. (#13274)

  • Absolute paths now resolve to real filesystem locations instead of being treated as workspace-relative. (#13804)

    Previously, LocalFilesystem in contained mode treated absolute paths like /file.txt as shorthand for basePath/file.txt (a "virtual-root" convention). This could silently resolve paths to unexpected locations — for example, /home/user/.config/file.txt would resolve to basePath/home/user/.config/file.txt instead of the real path.

    Now:

    • Absolute paths (starting with /) are real filesystem paths, subject to containment checks
    • Relative paths (e.g., file.txt, src/index.ts) resolve against basePath
    • Tilde paths (e.g., ~/Documents) expand to the home directory

    Migration

    If your code passes paths like /file.txt to workspace filesystem methods expecting them to resolve relative to basePath, change them to relative paths:

    // Before
    await filesystem.readFile('/src/index.ts');
    
    // After
    await filesystem.readFile('src/index.ts');

    Also fixed:

    • allowedPaths resolving against the working directory instead of basePath, causing unexpected permission errors when basePath differed from cwd
    • Permission errors when accessing paths under allowedPaths directories that don't exist yet (e.g., during skills discovery)
  • Changed ProcessHandle.pid type from number to string to support sandbox providers that use non-numeric process identifiers (e.g., session IDs). (#13591)

    Before:

    const handle = await sandbox.processes.spawn('node server.js');
    handle.pid; // number
    await sandbox.processes.get(42);

    After:

    const handle = await sandbox.processes.spawn('node server.js');
    handle.pid; // string (e.g., '1234' for local, 'session-abc' for Daytona)
    await sandbox.processes.get('1234');

Patch Changes

  • Added a mastra/<version> User-Agent header to all provider API requests (OpenAI, Anthropic, Google, Mistral, Groq, xAI, DeepSeek, and others) across models.dev, Netlify, and Azure gateways for better traffic attribution. (#13087)

  • Update provider registry and model documentation with latest models and providers (9cede11)

  • Fixed processor-triggered aborts not appearing in traces. Processor spans now include abort details (reason, retry flag, metadata) and agent-level spans capture the same information when an abort short-circuits the agent run. This makes guardrail and processor aborts fully visible in tracing dashboards. (#14038)

  • Fix agent loop not continuing when onIterationComplete returns continue: true (#14170)

  • Fixed exponential token growth during multi-step agent workflows by implementing processInputStep on TokenLimiterProcessor and removing the redundant processInput method. Token-based message pruning now runs at every step of the agentic loop (including tool call continuations), keeping the in-memory message list within budget before each LLM call. Also refactored Tiktoken encoder to use the shared global singleton from getTiktoken() instead of creating a new instance per processor. (#13929)

  • Sub-agents with defaultOptions.memory configurations were having their memory settings overridden when called as tools from a parent agent. The parent unconditionally passed its own memory option (with newly generated thread/resource IDs), which replaced the sub-agent's intended memory configuration due to shallow object merging. (#11561)

    This fix checks if the sub-agent has its own defaultOptions.memory before applying parent-derived memory settings. Sub-agents without their own memory config continue to receive parent-derived IDs as a fallback.

    No code changes required for consumers - sub-agents with explicit defaultOptions.memory will now work correctly when used via the agents: {} option.

  • Fixed listConfiguredInputProcessors() and listConfiguredOutputProcessors() returning a combined workflow instead of individual processors. Previously, these methods wrapped all configured processors into a single committed workflow, making it impossible to inspect or look up processors by ID. Now they return the raw flat array of configured processors as intended. (#14158)

  • fetchWithRetry now backs off in sequence 2s → 4s → 8s and then caps at 10s. (#14159)

  • Preserve trace continuity across workflow suspend/resume for workflows run by the default engine, so resumed workflows appear as children of the original span in tracing tools. (#12276)

@mastra/blaxel@0.2.0

Minor Changes

  • Added provider-specific blaxel getter to access the underlying Blaxel SandboxInstance directly. Deprecated the generic instance getter in favor of the new blaxel getter for better IDE discoverability and consistency with other sandbox providers. (#14166)

    // Before
    const blaxelSandbox = sandbox.instance;
    
    // After
    const blaxelSandbox = sandbox.blaxel;

Patch Changes

  • Use provider-native string process IDs directly as ProcessHandle.pid, removing the previous parseInt() workaround. (#13591)

    const handle = await sandbox.processes.spawn('node server.js');
    handle.pid; // string — the Blaxel SDK's native process ID

@mastra/cloudflare@1.3.0

Minor Changes

  • feat: add Cloudflare Durable Objects storage adapter (#12366)

    Adds a new Durable Objects-based storage implementation alongside the existing KV store. Includes SQL-backed persistence via DO's SQLite storage, batch operations, and proper table/column validation.

Patch Changes

@mastra/cloudflare-d1@1.0.3

Patch Changes

  • Fixed D1 listMessages returning empty results when using semantic recall with perPage=0 and many include targets, by batching UNION ALL queries to avoid SQLite's compound SELECT limit (#14117)

[@mastra/daytona@0.2.0](https://github.com/mastra-ai/mastra/blob/@mastra/daytona@0...

Read more

March 11, 2026

16 Mar 14:35

Choose a tag to compare

Highlights

Dynamic Model Fallback Arrays (Runtime Routing)

Agents can now use model functions that return full fallback arrays (ModelWithRetries[]), enabling context-driven model routing (tier/region/etc.) with nested/async selection and proper maxRetries inheritance.

Standard Schema + Zod v4 Compatibility Layer

Mastra adds Standard Schema normalization (toStandardSchema, standardSchemaToJSONSchema) across Zod v3/v4, AI SDK Schema, and JSON Schema via @mastra/schema-compat, unifying schema handling and improving strict-mode provider compatibility.

Customizable Request Validation Errors Across All Server Adapters

New onValidationError hook on ServerConfig and createRoute() lets you control status codes and response bodies for Zod validation failures, supported consistently in Hono/Express/Fastify/Koa adapters.

RequestContext End-to-End (Tracing + Datasets/Experiments + Storage)

requestContext is now captured on tracing spans (and persisted in ClickHouse/PG/LibSQL/MSSQL span tables) and is supported on dataset items and experiments, allowing request-scoped metadata (tenant/user/flags) to flow through evaluation and observability.

Faster & More Flexible Storage: Recall Performance + PgVector Indexing + New Vector Types

Semantic recall is significantly faster across multiple adapters (notably Postgres for very large threads), PgVector adds metadataIndexes for btree indexing filtered metadata fields, and @mastra/pg now supports pgvector bit and sparsevec vector types.

Breaking Changes

  • Minimum Zod version is now ^3.25.0 (for v3) or ^4.0.0 (for v4 support).

Changelog

@mastra/core@1.11.0

Minor Changes

  • feat: support dynamic functions returning model fallback arrays (#11975)

    Agents can now use dynamic functions that return entire fallback arrays based on runtime context. This enables:

    • Dynamic selection of complete fallback configurations
    • Context-based model selection with automatic fallback
    • Flexible model routing based on user tier, region, or other factors
    • Nested dynamic functions within returned arrays (each model in array can also be dynamic)

    Examples

    Basic dynamic fallback array

    const agent = new Agent({
      model: ({ requestContext }) => {
        const tier = requestContext.get('tier');
        if (tier === 'premium') {
          return [
            { model: 'openai/gpt-4', maxRetries: 2 },
            { model: 'anthropic/claude-3-opus', maxRetries: 1 },
          ];
        }
        return [{ model: 'openai/gpt-3.5-turbo', maxRetries: 1 }];
      },
    });

    Region-based routing with nested dynamics

    const agent = new Agent({
      model: ({ requestContext }) => {
        const region = requestContext.get('region');
        return [
          {
            model: ({ requestContext }) => {
              // Select model variant based on region
              return region === 'eu' ? 'openai/gpt-4-eu' : 'openai/gpt-4';
            },
            maxRetries: 2,
          },
          { model: 'anthropic/claude-3-opus', maxRetries: 1 },
        ];
      },
      maxRetries: 1, // Agent-level default for models without explicit maxRetries
    });

    Async dynamic selection

    const agent = new Agent({
      model: async ({ requestContext }) => {
        // Fetch user's tier from database
        const userId = requestContext.get('userId');
        const user = await db.users.findById(userId);
    
        if (user.tier === 'enterprise') {
          return [
            { model: 'openai/gpt-4', maxRetries: 3 },
            { model: 'anthropic/claude-3-opus', maxRetries: 2 },
          ];
        }
        return [{ model: 'openai/gpt-3.5-turbo', maxRetries: 1 }];
      },
    });

    Technical Details

    • Functions can return MastraModelConfig (single model) or ModelWithRetries[] (array)
    • Models without explicit maxRetries inherit agent-level maxRetries default
    • Each model in returned array can also be a dynamic function for nested selection
    • Empty arrays are validated and throw errors early
    • Arrays are normalized to ModelFallbacks with all required fields filled in
    • Performance optimization: Already-normalized arrays skip re-normalization

    Fixes and Improvements

    • Dynamic model fallbacks now properly inherit agent-level maxRetries when not explicitly specified
    • getModelList() now correctly handles dynamic functions that return arrays
    • Added validation for empty arrays returned from dynamic functions
    • Added type guard optimization to prevent double normalization of static arrays
    • Preserved backward-compatible getLLM() and getModel() return behavior while adding dynamic fallback array support
    • Comprehensive test coverage for edge cases (async functions, nested dynamics, error handling)

    Documentation

    • Added dynamic fallback array example in Models docs under Model fallbacks

    Migration Guide

    No breaking changes. All existing model configurations continue to work:

    • Static single models: model: 'openai/gpt-4'
    • Static arrays: model: [{ model: 'openai/gpt-4', maxRetries: 2 }]
    • Dynamic single: model: ({ requestContext }) => 'openai/gpt-4'
    • Dynamic arrays (NEW): model: ({ requestContext }) => [{ model: 'openai/gpt-4', maxRetries: 2 }]

    Closes #11951

  • Added onValidationError hook to ServerConfig and createRoute(). When a request fails Zod schema validation (query parameters, request body, or path parameters), this hook lets you customize the error response — including the HTTP status code and response body — instead of the default 400 response. Set it on the server config to apply globally, or on individual routes to override per-route. All server adapters (Hono, Express, Fastify, Koa) support this hook. (#13477)

    const mastra = new Mastra({
      server: {
        onValidationError: (error, context) => ({
          status: 422,
          body: {
            ok: false,
            errors: error.issues.map(i => ({
              path: i.path.join('.'),
              message: i.message,
            })),
            source: context,
          },
        }),
      },
    });
  • Added requestContext field to tracing spans. Each span now automatically captures a snapshot of the active RequestContext, making request-scoped values like user IDs, tenant IDs, and feature flags available when viewing traces. (#14020)

  • Added allowedWorkspaceTools to HarnessSubagent. Subagents now automatically inherit the parent agent's workspace. Use allowedWorkspaceTools to restrict which workspace tools a subagent can see: (#13940)

    const subagent: HarnessSubagent = {
      id: 'explore',
      name: 'Explore',
      allowedWorkspaceTools: ['view', 'search_content', 'find_files'],
    };
  • Enabled tracing for tool executions through mcp server (#12804)

    Traces now appear in the Observability UI for MCP server tool calls

  • Added result to processOutputResult args, providing resolved generation data (usage, text, steps, finishReason) directly. This replaces raw stream chunks with an easy-to-use OutputResult object containing the same data available in the onFinish callback. (#13810)

    const usageProcessor: Processor = {
      id: 'usage-processor',
      processOutputResult({ result, messages }) {
        console.log(`Text: ${result.text}`);
        console.log(`Tokens: ${result.usage.inputTokens} in, ${result.usage.outputTokens} out`);
        console.log(`Finish reason: ${result.finishReason}`);
        console.log(`Steps: ${result.steps.length}`);
        return messages;
      },
    };
  • Added requestContext support for dataset items and experiments. (#13938)

    Dataset items now accept an optional requestContext field when adding or updating items. This lets you store per-item request context alongside inputs and ground truths.

    Datasets now support a requestContextSchema field to describe the expected shape of request context on items.

    Experiments now accept a requestContext option that gets passed through to agent.generate() during execution. Per-item request context merges with (and takes precedence over) the experiment-level context.

    // Add item with request context
    await dataset.addItem({
      input: messages,
      groundTruth: expectedOutput,
      requestContext: { userId: '123', locale: 'en' },
    });
    
    // Run experiment with global request context
    await runExperiment(mastra, {
      datasetId: 'my-dataset',
      targetType: 'agent',
      targetId: 'my-agent',
      requestContext: { environment: 'staging' },
    });
  • Add Zod v4 and Standard Schema support (#12238)

    Zod v4 Breaking Changes

    • Fix all z.record() calls to use 2-argument form (key + value schema) as required by Zod v4
    • Update ZodError.errors to ZodError.issues (Zod v4 API change)
    • Update @ai-sdk/provider versions for Zod v4 compatibility

    Standard Schema Integration

    • Add packages/core/src/schema/ module that re-exports from @mastra/schema-compat
    • Migrate codebase to use PublicSchema type for schema parameters
    • Use toStandardSchema() for normalizing schemas across Zod...
Read more

March 5, 2026

09 Mar 12:11

Choose a tag to compare

Highlights

Tool inputExamples to improve model tool-call accuracy

Tool definitions can now include inputExamples, which are passed through to models that support them (e.g., Anthropic’s input_examples) to demonstrate valid inputs and reduce malformed tool calls.

MCP client fetch hooks now receive RequestContext (auth/cookie forwarding)

@mastra/mcp adds requestContext support to custom fetch functions for MCP HTTP server definitions, enabling request-scoped forwarding of cookies/bearer tokens during tool execution while remaining backward compatible with (url, init) fetch signatures.

Reliability + DX fixes for agents, streaming, and memory cleanup

Provider stream errors are now consistently surfaced from generate()/resumeGenerate(), AI SDK errors are routed through the Mastra logger with structured context, client-side tools no longer lose history in stateless deployments, and memory.deleteThread()/deleteMessages() now automatically cleans up orphaned vector embeddings across supported vector stores.

Changelog

@mastra/core@1.10.0

Minor Changes

  • Add inputExamples support on tool definitions to show AI models what valid tool inputs look like. Models that support this (e.g., Anthropic's input_examples) will receive the examples alongside the tool schema, improving tool call accuracy. (#12932)

    • Added optional inputExamples field to ToolAction, CoreTool, and Tool class
    const weatherTool = createTool({
      id: "get-weather",
      description: "Get weather for a location",
      inputSchema: z.object({
        city: z.string(),
        units: z.enum(["celsius", "fahrenheit"])
      }),
      inputExamples: [{ input: { city: "New York", units: "fahrenheit" } }, { input: { city: "Tokyo", units: "celsius" } }],
      execute: async ({ city, units }) => {
        return await fetchWeather(city, units);
      }
    });

Patch Changes

  • dependencies updates: (#13209)

  • dependencies updates: (#13210)

  • Update provider registry and model documentation with latest models and providers (33e2fd5)

  • Fixed execute_command tool timeout parameter to accept seconds instead of milliseconds, preventing agents from accidentally setting extremely short timeouts (#13799)

  • Skill tools are now stable across conversation turns and prompt-cache friendly. (#13744)

    • Renamed skill-activateskill — returns full skill instructions directly in the tool result
    • Consolidated skill-read-reference, skill-read-script, skill-read-assetskill_read
    • Renamed skill-searchskill_search
    • <available_skills> in the system message is now sorted deterministically
  • Fixed Cloudflare Workers build failures when using @mastra/core. Local process execution now loads its runtime dependency lazily, preventing incompatible Node-only modules from being bundled during worker builds. (#13813)

  • Fix mimeTypemediaType typo in sendMessage file part construction. This caused file attachments to be routed through the V4 adapter instead of V5, preventing them from being correctly processed by AI SDK v5 providers. (#13833)

  • Fixed onIterationComplete feedback being discarded when it returns { continue: false } — feedback is now added to the conversation and the model gets one final turn to produce a text response before the loop stops. (#13759)

  • Fixed generate() and resumeGenerate() to always throw provider stream errors. Previously, certain provider errors were silently swallowed, returning false "successful" empty responses. Now errors are always surfaced to the caller, making retry logic reliable when providers fail transiently. (#13802)

  • Remove the default maxSteps limit so stopWhen can control sub-agent execution (#13764)

  • Fix suspendedToolRunId required error when it shouldn't be required (#13722)

  • Fixed subagent tool defaulting maxSteps to 50 when no stop condition is configured, preventing unbounded execution loops. When stopWhen is set, maxSteps is left to the caller. (#13777)

  • Fixed prompt failures by removing assistant messages that only contain sources before model calls. (#13790)

    • Fixed experiment pending count showing negative values when experiments are triggered from the Studio (#13831)
    • Fixed scorer prompt metadata (analysis context, generated prompts) being lost when saving experiment scores
  • Fixed RequestContext constructor crashing when constructed from a deserialized plain object. (#13856)

  • Fixed LLM errors (generateText, generateObject, streamText, streamObject) being swallowed by the AI SDK's default handler instead of being routed through the Mastra logger. Errors now appear with structured context (runId, modelId, provider, etc.) in your logger, and streaming errors are captured via onError callbacks. (#13857)

  • Fixed workspace tool output truncation so it no longer gets prematurely cut off when short lines precede a very long line (e.g. minified JSON). Output now uses the full token budget instead of stopping at line boundaries, resulting in more complete tool results. (#13828)

  • Fixed subagent tool to default maxSteps to 50 when no stopWhen condition is configured, preventing unbounded agent loops. When stopWhen is set, maxSteps remains unset so the stop condition controls termination. (#13777)

@mastra/agent-builder@1.0.10

Patch Changes

Read more

March 4, 2026

04 Mar 14:48

Choose a tag to compare

Highlights

Major Workspace & Sandbox upgrades (token-aware output, mounts, process control, LSP resolution)

Workspaces get significant capabilities: workspace tool output is now token-limited, ANSI-stripped for model context, and .gitignore-aware to reduce token usage. Sandbox commands support abortSignal for cancellation, plus background process streaming callbacks (onStdout/onStderr/onExit), and local symlink mounts in LocalSandbox. Tools can be exposed under custom names via WorkspaceToolConfig.name. LSP binary resolution is now configurable (binaryOverrides, searchPaths, packageRunner), making workspace diagnostics work reliably across monorepos, global installs, and custom setups.

End-to-end Auth + RBAC across Server, Studio, and Providers

Mastra now ships a pluggable auth system (@mastra/core/auth) plus server-side auth routes and convention-based route permission enforcement (@mastra/server + all server adapters). New auth provider packages (@mastra/auth-cloud, @mastra/auth-studio, @mastra/auth-workos) add OAuth/SSO, session management, and RBAC—Studio UI also gains permission-gated auth screens/components.

Workflow execution path tracking + concurrent-safe workflow snapshot updates

Workflow results now include stepExecutionPath (also available mid-execution and preserved across resume/restart), and execution logs are smaller by deduping payloads. Storage backends add atomic updateWorkflowResults/updateWorkflowState with a supportsConcurrentUpdates() check—enabling safer concurrent workflow updates (supported in e.g. Postgres/LibSQL/MongoDB/DynamoDB/Upstash; explicitly not supported in some backends like ClickHouse/Cloudflare/Lance).

Breaking Changes

  • harness.sendMessage() now uses files instead of images (supports any file type, preserves filenames, and auto-decodes text-based files).

Changelog

@mastra/core@1.9.0

Minor Changes

  • Added onStepFinish and onError callbacks to NetworkOptions, allowing per-LLM-step progress monitoring and custom error handling during network execution. Closes #13362. (#13370)

    Before: No way to observe per-step progress or handle errors during network execution.

    const stream = await agent.network('Research AI trends', {
      memory: { thread: 'my-thread', resource: 'my-resource' },
    });

    After: onStepFinish and onError are now available in NetworkOptions.

    const stream = await agent.network('Research AI trends', {
      onStepFinish: event => {
        console.log('Step completed:', event.finishReason, event.usage);
      },
      onError: ({ error }) => {
        console.error('Network error:', error);
      },
      memory: { thread: 'my-thread', resource: 'my-resource' },
    });
  • Add workflow execution path tracking and optimize execution logs (#11755)

    Workflow results now include a stepExecutionPath array showing the IDs of each step that executed during a workflow run. You can use this to understand exactly which path your workflow took.

    // Before: no execution path in results
    const result = await workflow.execute({ triggerData });
    // result.stepExecutionPath → undefined
    
    // After: stepExecutionPath is available in workflow results
    const result = await workflow.execute({ triggerData });
    console.log(result.stepExecutionPath);
    // → ['step1', 'step2', 'step4'] — the actual steps that ran

    stepExecutionPath is available in:

    • Workflow results (WorkflowResult.stepExecutionPath) — see which steps ran after execution completes
    • Execution context (ExecutionContext.stepExecutionPath) — access the path mid-execution inside your steps
    • Resume and restart operations — execution path persists across suspend/resume and restart cycles

    Workflow execution logs are now more compact and easier to read. Step outputs are no longer duplicated as the next step's input, reducing the size of execution results while maintaining full visibility.

    Key improvements:

    • Track which steps executed in your workflows with stepExecutionPath
    • Smaller, more readable execution logs with automatic duplicate payload removal
    • Execution path preserved when resuming or restarting workflows

    This is particularly beneficial for AI agents and LLM-based workflows where reducing context size improves performance and cost efficiency.

    Related: #8951

  • Added authentication interfaces and Enterprise Edition RBAC support. (#13163)

    New @mastra/core/auth export with pluggable interfaces for building auth providers:

    • IUserProvider — user lookup and management
    • ISessionProvider — session creation, validation, and cookie handling
    • ISSOProvider — SSO login and callback flows
    • ICredentialsProvider — username/password authentication

    Default implementations included out of the box:

    • Cookie-based session provider with configurable TTL and secure defaults
    • In-memory session provider for development and testing

    Enterprise Edition (@mastra/core/auth/ee) adds RBAC, ACL, and license validation:

    import { buildCapabilities } from '@mastra/core/auth/ee';
    
    const capabilities = buildCapabilities({
      rbac: myRBACProvider,
      acl: myACLProvider,
    });

    Built-in role definitions (owner, admin, editor, viewer) and a static RBAC provider are included for quick setup. Enterprise features require a valid license key via the MASTRA_EE_LICENSE environment variable.

  • Workspace sandbox tool results (execute_command, kill_process, get_process_output) sent to the model now strip ANSI color codes via toModelOutput, while streamed output to the user keeps colors. This reduces token usage and improves model readability. (#13440)

    Workspace execute_command tool now extracts trailing | tail -N pipes from commands so output streams live to the user, while the final result sent to the model is still truncated to the last N lines.

    Workspace tools that return potentially large output now enforce a token-based output limit (~3k tokens by default) using tiktoken for accurate counting. The limit is configurable per-tool via maxOutputTokens in WorkspaceToolConfig. Each tool uses a truncation strategy suited to its output:

    • read_file, grep, list_files — truncate from the end (keep imports, first matches, top-level tree)
    • execute_command, get_process_output, kill_process — head+tail sandwich (keep early output + final status)
    const workspace = new Workspace({
      tools: {
        mastra_workspace_execute_command: {
          maxOutputTokens: 5000, // override default 3k
        },
      },
    });
  • Workspace tools (list_files, grep) now automatically respect .gitignore, filtering out directories like node_modules and dist from results. Explicitly targeting an ignored path still works. Also lowered the default tree depth from 3 to 2 to reduce token usage. (#13724)

  • Added maxSteps and stopWhen support to HarnessSubagent. (#13653)

    You can now define maxSteps and stopWhen on a harness subagent so spawned subagents can use custom loop limits instead of relying only on the default maxSteps: 50 fallback.

    const harness = new Harness({
      id: 'dev-harness',
      modes: [{ id: 'build', default: true, agent: buildAgent }],
      subagents: [
        {
          id: 'explore',
          name: 'Explore',
          description: 'Inspect the codebase',
          instructions: 'Investigate and summarize findings.',
          defaultModelId: 'openai/gpt-4o',
          maxSteps: 7,
          stopWhen: ({ steps }) => steps.length >= 3,
        },
      ],
    });
  • Added OpenAI WebSocket transport for streaming responses with auto-close and manual transport access (#13531)

  • Added name property to WorkspaceToolConfig for remapping workspace tool names. Tools can now be exposed under custom names to the LLM while keeping the original constant as the config key. (#13687)

    const workspace = new Workspace({
      filesystem: new LocalFilesystem({ basePath: './project' }),
      tools: {
        mastra_workspace_read_file: { name: 'view' },
        mastra_workspace_grep: { name: 'search_content' },
        mastra_workspace_edit_file: { name: 'string_replace_lsp' },
      },
    });

    Also removed hardcoded tool-name cross-references from edit-file and ast-edit tool descriptions, since tools can be renamed or disabled.

  • Adds requestContext passthrough to Harness runtime APIs. (#13650)

    Added
    You can now pass requestContext to Harness runtime methods so tools and subagents receive request-scoped values.

  • Added binaryOverrides, searchPaths, and packageRunner options to LSPConfig to support flexible language server binary resolution. (#13677)

    Previously, workspace LSP diagnostics only worked when language server binaries were installed in the project's node_modules/.bin/. There was no way to use globally installed binaries or point to a custom install.

    New LSPConfig fields:

    • binaryOverrides: Override the binary command for a spe...
Read more

February 26, 2026

02 Mar 16:29

Choose a tag to compare

Highlights

Supervisor Pattern for Multi-Agent Coordination

A new supervisor pattern enables orchestrating multiple agents via stream() and generate(), with delegation hooks, iteration monitoring, completion scoring, memory isolation, tool approval propagation, context filtering, and a bail mechanism.

Metadata-Only Vector Queries (Optional queryVector)

Vector querying now supports metadata-only retrieval by making queryVector optional (with at least one of queryVector or filter required). @mastra/pg’s PgVector.query() explicitly supports filter-only queries, while other vector stores now throw a clear MastraError when metadata-only queries aren’t supported.

More Flexible Evaluations with runEvals Target Options

runEvals adds targetOptions to forward execution/run options into agent.generate() or workflow.run.start(), plus per-item startOptions for workflow-specific overrides (e.g., initialState) on each eval datum.

LSP Diagnostics After Workspace Edits

Workspace edit tools (write_file, edit_file, ast_edit) can now surface Language Server Protocol diagnostics immediately after edits (TypeScript, Python/Pyright, Go/gopls, Rust/rust-analyzer, ESLint), helping catch type/lint errors before the next tool call.

New Blaxel Cloud Sandbox Provider

@mastra/blaxel adds a Blaxel cloud sandbox provider, expanding deployment/runtime options for executing workspace tooling in a managed environment.

Breaking Changes

  • None noted in this changelog.

Changelog

@mastra/core@1.8.0

Minor Changes

  • Make queryVector optional in the QueryVectorParams interface to support metadata-only queries. At least one of queryVector or filter must be provided. Not all vector store backends support metadata-only queries — check your store's documentation for details. (#13286)

    Also fixes documentation where the query() parameter was incorrectly named vector instead of queryVector.

  • Added targetOptions parameter to runEvals that is forwarded directly to agent.generate() (modern path) or workflow.run.start(). Also added per-item startOptions field to RunEvalsDataItem for per-item workflow options like initialState. (#13366)

    New feature: targetOptions

    Pass agent execution options (e.g. maxSteps, modelSettings, instructions) through to agent.generate(), or workflow run options (e.g. perStep, outputOptions) through to workflow.run.start():

    // Agent - pass modelSettings or maxSteps
    await runEvals({
      data,
      scorers,
      target: myAgent,
      targetOptions: { maxSteps: 5, modelSettings: { temperature: 0 } },
    });
    
    // Workflow - pass run options
    await runEvals({
      data,
      scorers,
      target: myWorkflow,
      targetOptions: { perStep: true },
    });

    New feature: per-item startOptions

    Supply per-item workflow options (e.g. initialState) directly on each data item:

    await runEvals({
      data: [
        { input: { query: 'hello' }, startOptions: { initialState: { counter: 1 } } },
        { input: { query: 'world' }, startOptions: { initialState: { counter: 2 } } },
      ],
      scorers,
      target: myWorkflow,
    });

    Per-item startOptions take precedence over global targetOptions for the same key. Runeval-managed options (scorers, returnScorerData, requestContext) cannot be overridden via targetOptions.

  • Add supervisor pattern for multi-agent coordination using stream() and generate(). Includes delegation hooks, iteration monitoring, completion scoring, memory isolation, tool approval propagation, context filtering, and bail mechanism. (#13323)

  • Add LSP diagnostics to workspace edit tools (#13441)

    Language Server Protocol (LSP) diagnostics now appear after edits made with write_file, edit_file, and ast_edit.
    Seeing type and lint errors immediately helps catch issues before the next tool call.
    Edits still work without diagnostics when language servers are not installed.

    Supports TypeScript, Python (Pyright), Go (gopls), Rust (rust-analyzer), and ESLint.

    Example

    Before:

    const workspace = new Workspace({ sandbox, filesystem });

    After:

    const workspace = new Workspace({ sandbox, filesystem, lsp: true });

Patch Changes

  • Propagate tripwire's that are thrown from a nested workflow. (#13502)

  • Added isProviderDefinedTool helper to detect provider-defined AI SDK tools (e.g. google.tools.googleSearch(), openai.tools.webSearch()) for proper schema handling during serialization. (#13507)

  • Fixed ModelRouterEmbeddingModel.doEmbed() crashing with TypeError: result.warnings is not iterable when used with AI SDK v6's embedMany. The result now always includes a warnings array, ensuring forward compatibility across AI SDK versions. (#13369)

  • Fixed build error in ModelRouterEmbeddingModel.doEmbed() caused by warnings not existing on the return type. (#13461)

  • Fixed Harness.createThread() defaulting the thread title to "New Thread" which prevented generateTitle from working (see #13391). Threads created without an explicit title now have an empty string title, allowing the agent's title generation to produce a title from the first user message. (#13393)

  • Prevent unknown model IDs from being sorted to the front in reorderModels(). Models not present in the modelIds parameter are now moved to the end of the array. Fixes #13410. (#13445)

  • Include traceId on scores generated during experiment runs to restore traceability of experiment results (#13464)

  • Fixed skill-read-reference (and getReference, getScript, getAsset in WorkspaceSkillsImpl) to resolve file paths relative to the skill root instead of hardcoded subdirectories (references/, scripts/, assets/). (#13363)

    Previously, calling skill-read-reference with referencePath: "docs/schema.md" would silently fail because it resolved to <skill>/references/docs/schema.md instead of <skill>/docs/schema.md. Now all paths like references/colors.md, docs/schema.md, and ./config.json resolve correctly relative to the skill root. Path traversal attacks (e.g. ../../etc/passwd) are still blocked.

  • Fixed workspace listing to show whether each workspace is global or agent-owned. (#13468)
    Agent-owned workspaces now include the owning agent's ID and name so clients can distinguish them from global workspaces.

  • Fixed Observational Memory not working with AI SDK v4 models (legacy path). The legacy stream/generate path now calls processInputStep, enabling processors like Observational Memory to inject conversation history and observations. (#13358)

  • Added resolveWorkspace() so callers can access a dynamic workspace before the first request. (#13457)

  • Fixed abortSignal not stopping LLM generation or preventing memory persistence. When aborting a stream (e.g., client disconnect), the LLM response no longer continues processing in the background and partial/full responses are no longer saved to memory. Fixes #13117. (#13206)

  • Fixed observation activation to always preserve a minimum amount of context. Previously, swapping buffered observation chunks could unexpectedly drop the context window to near-zero tokens. (#13476)

  • Fixed a crash where the Node.js process would terminate with an unhandled TypeError when an LLM stream encountered an error. The ReadableStreamDefaultController would throw "Controller is already closed" when chunks were enqueued after a downstream consumer cancelled or terminated the stream. All controller.enqueue(), controller.close(), and controller.error() calls now check if the controller is still open before attempting operations. (#13107) (#13206)

  • Updated dependencies [8d14a59]:

    • @mastra/schema-compat@1.1.3

@mastra/agent-builder@1.0.8

Patch Changes

Read more

February 24, 2026

25 Feb 09:16

Choose a tag to compare

Highlights

Background Process Management in Workspaces & Sandboxes

Workspaces now support spawning and managing long-running background processes (via SandboxProcessManager / ProcessHandle), with new tools like execute_command (background: true), get_process_output, and kill_process plus improved streaming terminal-style UI.

Runtime Tool Configuration Updates via Workspace.setToolsConfig()

You can dynamically enable/disable tools at runtime on an existing workspace instance (including re-enabling all tools by passing undefined), enabling safer modes like plan/read-only without recreating the workspace.

Observational Memory Reliability & Introspection Improvements

Core adds Harness.getObservationalMemoryRecord() for public access to the full OM record for the current thread, while @mastra/memory fixes major OM stability issues (shared tokenizer to prevent OOM/memory leaks, plus PostgreSQL deadlock fixes and clearer errors when threadId is missing).

Changelog

@mastra/core@1.7.0

Minor Changes

  • Added getObservationalMemoryRecord() method to the Harness class. Fixes #13392. (#13395)

    This provides public access to the full ObservationalMemoryRecord for the current thread, including activeObservations, generationCount, and observationTokenCount. Previously, accessing raw observation text required bypassing the Harness abstraction by reaching into private storage internals.

    const record = await harness.getObservationalMemoryRecord();
    if (record) {
      console.log(record.activeObservations);
    }
  • Added Workspace.setToolsConfig() method for dynamically updating per-tool configuration at runtime without recreating the workspace instance. Passing undefined re-enables all tools. (#13439)

    const workspace = new Workspace({ filesystem, sandbox });
    
    // Disable write tools (e.g., in plan/read-only mode)
    workspace.setToolsConfig({
      mastra_workspace_write_file: { enabled: false },
      mastra_workspace_edit_file: { enabled: false },
    });
    
    // Re-enable all tools
    workspace.setToolsConfig(undefined);
  • Added HarnessDisplayState so any UI can read a single state snapshot instead of handling 35+ individual events. (#13427)

    Why: Previously, every UI (TUI, web, desktop) had to subscribe to dozens of granular Harness events and independently reconstruct what to display. This led to duplicated state tracking and inconsistencies across UI implementations. Now the Harness maintains a single canonical display state that any UI can read.

    Before: UIs subscribed to raw events and built up display state locally:

    harness.subscribe((event) => {
      if (event.type === 'agent_start') localState.isRunning = true;
      if (event.type === 'agent_end') localState.isRunning = false;
      if (event.type === 'tool_start') localState.tools.set(event.toolCallId, ...);
      // ... 30+ more event types to handle
    });

    After: UIs read a single snapshot from the Harness:

    import type { HarnessDisplayState } from '@mastra/core/harness';
    
    harness.subscribe(event => {
      const ds: HarnessDisplayState = harness.getDisplayState();
      // ds.isRunning, ds.tokenUsage, ds.omProgress, ds.activeTools, etc.
      renderUI(ds);
    });
  • Workspace instruction improvements (#13304)

    • Added Workspace.getInstructions(): agents now receive accurate workspace context that distinguishes sandbox-accessible paths from workspace-only paths.
    • Added WorkspaceInstructionsProcessor: workspace context is injected directly into the agent system message instead of embedded in tool descriptions.
    • Deprecated Workspace.getPathContext() in favour of getInstructions().

    Added instructions option to LocalFilesystem and LocalSandbox. Pass a string to fully replace default instructions, or a function to extend them with access to the current requestContext for per-request customization (e.g. by tenant or locale).

    const filesystem = new LocalFilesystem({
      basePath: './workspace',
      instructions: ({ defaultInstructions, requestContext }) => {
        const locale = requestContext?.get('locale') ?? 'en';
        return `${defaultInstructions}\nLocale: ${locale}`;
      },
    });
  • Added background process management to workspace sandboxes. (#13293)

    You can now spawn, monitor, and manage long-running background processes (dev servers, watchers, REPLs) inside sandbox environments.

    // Spawn a background process
    const handle = await sandbox.processes.spawn('node server.js');
    
    // Stream output and wait for exit
    const result = await handle.wait({
      onStdout: data => console.log(data),
    });
    
    // List and manage running processes
    const procs = await sandbox.processes.list();
    await sandbox.processes.kill(handle.pid);
    • SandboxProcessManager abstract base class with spawn(), list(), get(pid), kill(pid)
    • ProcessHandle base class with stdout/stderr accumulation, streaming callbacks, and wait()
    • LocalProcessManager implementation wrapping Node.js child_process
    • Node.js stream interop via handle.reader / handle.writer
    • Default executeCommand implementation built on process manager (spawn + wait)
  • Added workspace tools for background process management and improved sandbox execution UI. (#13309)

    • execute_command now supports background: true to spawn long-running processes and return a PID
    • New get_process_output tool to check output/status of background processes (supports wait to block until exit)
    • New kill_process tool to terminate background processes
    • Output truncation helpers with configurable tail lines
    • Sandbox execution badge UI: terminal-style output display with streaming, exit codes, killed status, and workspace metadata

Patch Changes

  • Fixed agents-as-tools failing with OpenAI when using the model router. The auto-injected resumeData field (from z.any()) produced a JSON Schema without a type key, which OpenAI rejects. Tool schemas are now post-processed to ensure all properties have valid type information. (#13326)

  • Fixed stopWhen callback receiving empty toolResults on steps. step.toolResults now correctly reflects the tool results present in step.content. (#13319)

  • Added hasJudge metadata to scorer records so the studio can distinguish code-based scorers (e.g., textual-difference, content-similarity) from LLM-based scorers. This metadata is now included in all four score-saving paths: runEvals, scorer hooks, trace scoring, and dataset experiments. (#13386)

  • Fixed a bug where custom output processors could not emit stream events during final output processing. The writer object was always undefined when passed to output processors in the finish phase, preventing use cases like streaming moderation updates or custom UI events back to the client. (#13454)

  • Added per-file write locking to workspace tools (edit_file, write_file, ast_edit, delete). Concurrent tool calls targeting the same file are now serialized, preventing race conditions where parallel edits could silently overwrite each other. (#13302)

@mastra/client-js@1.7.0

Patch Changes

@mastra/deployer@1.7.0

Patch Changes

  • Updated dependencies [24284ff, [f5097cc](https://github.com/mastra-ai/mastra/com...
Read more

February 23, 2026

24 Feb 16:55
@mastra/core@1.6.0
3083419

Choose a tag to compare

Highlights

AST-Based Workspace Edit Tool (mastra_workspace_ast_edit)

A new AST edit tool enables intelligent code transformations (rename identifiers, add/remove/merge imports, pattern-based replacements with metavariables) and is automatically available when @ast-grep/napi is installed, enabling robust refactors beyond string-based edits.

Harness UX + Built-ins: Streaming Tool Argument Previews and Task Tools

Tool renderers now stream argument previews in real time (including diffs for edits and streamed file content for writes) via partial JSON parsing, and task_write/task_check are now built-in Harness tools automatically injected into agent calls for structured task tracking.

Observational Memory Continuity Improvements (Suggested Continuation + Current Task)

Observational Memory now preserves suggestedContinuation and currentTask across activations (with storage adapter support), improving conversational continuity when the message window shrinks; activation/priority handling is improved to better hit retention targets and avoid runaway observer output.

Changelog

@mastra/core@1.6.0

Minor Changes

  • Added AST edit tool (workspace_ast_edit) for intelligent code transformations using AST analysis. Supports renaming identifiers, adding/removing/merging imports, and pattern-based find-and-replace with metavariable substitution. Automatically available when @ast-grep/napi is installed in the project. (#13233)

    Example:

    const workspace = new Workspace({
      filesystem: new LocalFilesystem({ basePath: '/my/project' }),
    });
    const tools = createWorkspaceTools(workspace);
    
    // Rename all occurrences of an identifier
    await tools['mastra_workspace_ast_edit'].execute({
      path: '/src/utils.ts',
      transform: 'rename',
      targetName: 'oldName',
      newName: 'newName',
    });
    
    // Add an import (merges into existing imports from the same module)
    await tools['mastra_workspace_ast_edit'].execute({
      path: '/src/app.ts',
      transform: 'add-import',
      importSpec: { module: 'react', names: ['useState', 'useEffect'] },
    });
    
    // Pattern-based replacement with metavariables
    await tools['mastra_workspace_ast_edit'].execute({
      path: '/src/app.ts',
      pattern: 'console.log($ARG)',
      replacement: 'logger.debug($ARG)',
    });
  • Added streaming tool argument previews across all tool renderers. Tool names, file paths, and commands now appear immediately as the model generates them, rather than waiting for the complete tool call. (#13328)

    • Generic tools show live key/value argument previews as args stream in
    • Edit tool renders a bordered diff preview as soon as old_str and new_str are available, even before the tool result arrives
    • Write tool streams syntax-highlighted file content in a bordered box while args arrive
    • Find files shows the glob pattern in the pending header
    • Task write streams items directly into the pinned task list component in real-time

    All tools use partial JSON parsing to progressively display argument information. This is enabled automatically for all Harness-based agents — no configuration required.

  • Added optional threadLock callbacks to HarnessConfig for preventing concurrent thread access across processes. The Harness calls acquire/release during selectOrCreateThread, createThread, and switchThread when configured. Locking is opt-in — when threadLock is not provided, behavior is unchanged. (#13334)

    const harness = new Harness({
      id: 'my-harness',
      storage: myStore,
      modes: [{ id: 'default', agent: myAgent }],
      threadLock: {
        acquire: threadId => acquireThreadLock(threadId),
        release: threadId => releaseThreadLock(threadId),
      },
    });
  • Refactored all Harness class methods to accept object parameters instead of positional arguments, and standardized method naming. (#13353)

    Why: Positional arguments make call sites harder to read, especially for methods with optional middle parameters or multiple string arguments. Object parameters are self-documenting and easier to extend without breaking changes.

    • Methods returning arrays use list prefix (listModes, listAvailableModels, listMessages, listMessagesForThread)
    • persistThreadSettingsetThreadSetting
    • resolveToolApprovalDecisionrespondToToolApproval (consistent with respondToQuestion / respondToPlanApproval)
    • setPermissionCategorysetPermissionForCategory
    • setPermissionToolsetPermissionForTool

    Before:

    await harness.switchMode('build');
    await harness.sendMessage('Hello', { images });
    const modes = harness.getModes();
    const models = await harness.getAvailableModels();
    harness.resolveToolApprovalDecision('approve');

    After:

    await harness.switchMode({ modeId: 'build' });
    await harness.sendMessage({ content: 'Hello', images });
    const modes = harness.listModes();
    const models = await harness.listAvailableModels();
    harness.respondToToolApproval({ decision: 'approve' });

    The HarnessRequestContext interface methods (registerQuestion, registerPlanApproval, getSubagentModelId) are also updated to use object parameters.

  • Added task_write and task_check as built-in Harness tools. These tools are automatically injected into every agent call, allowing agents to track structured task lists without manual tool registration. (#13344)

    // Agents can call task_write to create/update a task list
    await tools['task_write'].execute({
      tasks: [
        { content: 'Fix authentication bug', status: 'in_progress', activeForm: 'Fixing authentication bug' },
        { content: 'Add unit tests', status: 'pending', activeForm: 'Adding unit tests' },
      ],
    });
    
    // Agents can call task_check to verify all tasks are complete before finishing
    await tools['task_check'].execute({});
    // Returns: { completed: 1, inProgress: 0, pending: 1, allDone: false, incomplete: [...] }

Patch Changes

  • Fixed duplicate Vercel AI Gateway configuration that could cause incorrect API key resolution. Removed a redundant override that conflicted with the upstream models.dev registry. (#13291)

  • Fixed Vercel AI Gateway failing when using the model router string format (e.g. vercel/openai/gpt-oss-120b). The provider registry was overriding createGateway's base URL with an incorrect value, causing API requests to hit the wrong endpoint. Removed the URL override so the AI SDK uses its own correct default. Closes #13280. (#13287)

  • Fixed recursive schema warnings for processor graph entries by unrolling to a fixed depth of 3 levels, matching the existing rule group pattern (#13292)

  • Fixed Observational Memory status not updating during conversations. The harness was missing streaming handlers for OM data chunks (status, observation start/end, buffering, activation), so the TUI never received real-time OM progress updates. Also added switchObserverModel and switchReflectorModel methods so changing OM models properly emits events to subscribers. (#13330)

  • Fixed thread resuming in git worktrees. Previously, starting mastracode in a new worktree would resume a thread from another worktree of the same repo. Threads are now auto-tagged with the project path and filtered on resume so each worktree gets its own thread scope. (#13343)

  • Fixed a crash where the Node.js process would terminate with an unhandled TypeError when an LLM stream encountered an error. The ReadableStreamDefaultController would throw "Controller is already closed" when chunks were enqueued after a downstream consumer cancelled or terminated the stream. All controller.enqueue(), controller.close(), and controller.error() calls now check if the controller is still open before attempting operations. (#13107) (#13142)

  • Added suggestedContinuation and currentTask fields to the in-memory storage adapter's Observational Memory activation result, aligning it with the persistent storage implementations. (#13354)

  • Fixed provider-executed tools (e.g. Anthropic web_search) causing stream bail when called in parallel with regular tools. The tool-call-step now provides a fallback result for provider-executed tools whose output was not propagated, preventing the mapping step from misidentifying them as pending HITL interactions. Fixes #13125. (#13126)

  • Updated dependencies [7184d87]:

    • @mastra/schema-compat@1.1.2

@mastra/arize@1.0.4

Patch Changes

  • Updated dependencies [0d9efb4, ...
Read more