fix(deps): update dependency @mastra/core to v1#48
Open
renovate[bot] wants to merge 1 commit into
Open
Conversation
7b23759 to
4ca1f39
Compare
c64fbb8 to
c33d6c8
Compare
6ad1902 to
ef06b25
Compare
181489a to
7f2bbe9
Compare
9583e0f to
bf7edb0
Compare
ee1ce1f to
877ff2d
Compare
0eeb3ee to
aad6296
Compare
be8d060 to
3342730
Compare
7283845 to
351503f
Compare
a2ce468 to
44185ef
Compare
2121e8f to
c22e6ea
Compare
90f71f3 to
a7d4d63
Compare
60ada13 to
95f67b1
Compare
946963a to
1ba24e1
Compare
aac0766 to
eb03fc4
Compare
79e6253 to
24a3d87
Compare
24a3d87 to
5e11def
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
^0.12.1→^1.0.0Release Notes
mastra-ai/mastra (@mastra/core)
v1.43.0Compare Source
Minor Changes
Added harness modes that share a backing agent while applying mode-specific instructions, tools, and approval transitions. (#17892)
Added source-backed storage primitives for code-mode agent editing. (#17582)
Mastra now exposes a
SourceControlProviderinterface for hosted source-control-backed editor storage, andMastraEditorcan persist code-mode agent overrides through either local filesystem storage or a source provider.Code-defined agents still respect their
editorownership config, while source-backed storage can read, write, list history, and open change requests through a provider implementation.Removed the coalesced Harness display state subscription API. (#17989)
Before
After
Use
subscribe()withdisplay_state_changedevents andgetDisplayState()for UI rendering.Added support for Gateway embedding routing with
mastra/provider/modelIDs: (#17425)Add a native goal mechanism to the
Agent— a durable, thread-scoped objective that is judged in-loop and gates the agentic execution loop, mirroring theisTaskCompletestep. (#17889)Previously a "goal / Ralph loop" had to be built on top of the agent by re-invoking
agent.stream()between full turns and running a hand-rolled judge agent. That approach was consumer-specific and could not evaluate an objective mid-run (e.g. when asendMessagesignal was delivered into an already-running loop). Goals are now an Agent capability.A new
goalconfig is accepted on theAgent:The objective lives in the generic
threadStatestorage domain undertype: "goal"(reusing the domain introduced for task tools), so it persists across process restarts and is serializable mid-run. Programmatic control is via newAgentmethods:setObjective(objective, { threadId, resourceId?, judgeModelId?, maxRuns?, prompt? }),getObjective({ threadId }),clearObjective({ threadId }), andupdateObjectiveOptions({ threadId, judgeModelId?, maxRuns?, prompt? }). All no-op when the run is not memory-backed.Behavior:
isTaskCompleteStepin the agentic execution workflow, using the same gating asisTaskComplete(skips background-task / mid-tool-loop / working-memory-only iterations). On a candidate answer it scores the objective with an LLM-as-judge (the defaultcreateGoalScorer, acreateScoreranalyze → score → reason pipeline that returns1when the objective is achieved and0otherwise; a customgoal.scorercan be supplied instead), persistsrunsUsed, and gates the loop: pass →status: "done",isContinued = false; not passed within budget →isContinued = true(the goal gate wins overisTaskComplete);runsUsed >= maxRuns→ stop and keepstatus: "active".goalconfig → default (maxRuns50, a default judge prompt). If no judge model resolves from either the record orgoal.judge, the goal step is a complete no-op: no scoring, norunsUsedincrement, and nogoalchunk.goal.judgeaccepts a resolver function. In addition to a model id or model object,goal.judgemay be a({ requestContext, mastra }) => model | undefinedfunction so a consumer can inject provider credentials and read the current judge selection at runtime (returningundefinedkeeps the step a no-op). A bare model id (fromgoal.judgeor the per-objectivejudgeModelId) is resolved through the Mastra instance's model router/gateways when the default scorer is built, so provider credentials are applied rather than falling back to the default provider path.<current-objective>) by the newGoalStateProcessor, so the model sees it in context without invalidating the prompt-cache prefix.goalstream chunk is emitted on every evaluation (GoalEvaluationPayload: objective, iteration, maxRuns, passed, status, results, reason?, duration, timedOut, maxRunsReached, suppressFeedback) for consumers (TUI /@mastra/client-js).For the simplest setup, register
GoalSignalProvidervia the agent'ssignalsarray — whengoalconfig is present the Agent also auto-registersGoalStateProcessorif no goal provider is supplied.The goal primitives are co-located under
agent/goal(objective store, scorer, state processor, signal provider). The public export surface is unchanged:@mastra/core/toolsre-exportsGoalStateProcessor,DEFAULT_GOAL_JUDGE_PROMPT,DEFAULT_GOAL_MAX_RUNS, and the goal helpers/types (AgentGoalConfigDefaults, etc.);@mastra/core/signalsre-exportsGoalSignalProvider;@mastra/core/streamexportsGoalEvaluationPayload. New type on the thread-state domain:GoalObjectiveRecord. Thegoalarm is added to the publicChunkTypeunion. No breaking change toisTaskComplete.Docs: a new Goals page under
docs/agents/goals, and thegoalchunk is documented in the streamingChunkTypereference.Patch Changes
dependencies updates: (#17838)
fastq@^1.20.1↗︎ (from^1.19.1, independencies)dependencies updates: (#17846)
posthog-node@^5.37.0↗︎ (from^5.30.6, independencies)dependencies updates: (#17861)
fastq@^1.20.1↗︎ (from^1.19.1, independencies)jpeg-js@^0.4.4↗︎ (todependencies)dependencies updates: (#17961)
ajv@^8.20.0↗︎ (from^8.18.0, independencies)Added full Studio authentication support for Auth0 users. (#16658)
What's new:
/v2/logoutendpointSetup:
Note: This release includes updates to
@mastra/core(ISSOProvider interface now supports async getLoginUrl) and@mastra/server(handles async login URLs). All three packages should be updated together.Export the
Middlewaretype from@mastra/core/serverso server middleware can be declared in separate modules with contextual handler types. (#17882)Fixed signal providers losing memory access when harness forks agents per mode. Harness now propagates runtime services (memory, storage, etc.) to the base config agent during init so signal providers connected to it can deliver notifications. (#18008)
Added full Studio authentication support for Clerk users. (#16659)
What's new:
Setup:
Note: This release includes updates to
@mastra/core(ISSOProvider interface now supports async getLoginUrl) and@mastra/server(handles async login URLs). All three packages should be updated together.Multimodal content returned from
toModelOutput(e.g. images viatype: 'image-url') is now correctly preserved as native provider content instead of being stringified into a JSON string. Previously, tools returning{ type: 'content', value: [...] }with image parts would cause providers like OpenRouter and Mistral to receive a plain text string instead of multimodal content. (#17879)Fixed supervisor sub-agent tool preparation so memory tools are available when agents derive their thread and resource from default options. This prevents misleading "Skipping memory tools (no thread or resource context)" debug logs for correctly configured sub-agents. (#17175)
Republished clean patch versions after compromised npm releases were published outside of the trusted release workflow. (#18049)
These packages must be released as clean versions higher than the compromised versions currently present on npm so semver ranges resolve to trusted tarballs.
Fix multi-instance evented-mode hangs caused by transport edge cases. (#17860)
Four related fixes that stop
agent.generate()from hanging silently when multiple processes share a Unix socket pubsub broker:EEXIST):UnixSocketPubSub#start()now falls through to client mode whenlisten()throwsEEXISTon macOS for a path that already exists as a regular file, matching the existingEADDRINUSEfallback.#deliverLocalnow passes realack/nackcallbacks; nacked events are re-queued viasetTimeoutso consumer-side retries (e.g. SQLITE_BUSY backoff) can drain instead of being silently dropped.EPIPE):#sendToBrokerretries up to 3 times with re-election between attempts so an in-flight publish survives a broker crash and re-election rotation.WorkflowEventProcessor.handlenow tracks per-event delivery attempts and, after exhausting transport-level retries, publishesworkflow.failinstead of returning{ retry: true }forever. This unblocks any caller awaitingworkflows-finish(e.g.agent.generate()) so the original error reaches the user rather than hanging.'workflows'topic callback inMastranow callsnack()when the processor returns{ ok: false, retry: true }, enabling the transport-level redelivery loop above.Await
storage.init()before workers start instartWorkers(). (#17920)The scheduler worker runs an immediate warm-up tick on start, which can
dispatch an internal scheduled workflow (the notification dispatcher, enabled
by default) and persist a workflow snapshot. Without awaiting
storage.init()first, that write could race the lazy initialization that creates the
mastra_workflow_snapshottable, surfacing as repeatedSQLITE_ERROR: no such table: mastra_workflow_snapshoton SQL stores likelibSQL (#17905).
init()is idempotent and a no-op when storage init isdisabled.
Keep the agent loop alive after a tool suspension (e.g.
ask_user,request_access). (#17990)Two related fixes that stop the agent from appearing to quit mid-task right after a suspended tool resumes:
resumeStream()was called without a step budget, so a resumed run merged over the agent's small defaultmaxStepsand stopped after a single step. The harness now threads a shared set of run options (maxSteps,savePerStep,modelSettings, etc.) into both the initial stream and the resume via one helper, so the two paths can no longer drift.busy_timeoutsurvival: bump@libsql/clientto^0.17.4and add a configurable connection timeout soPRAGMA busy_timeoutsurvives connections created aftertransaction()(libsql-client-ts#288/#345). This reducesSQLITE_BUSYretry-exhaustion stalls under the evented engine's concurrent writes.Moved MastraCode model catalog and gateway-backed model resolution out of the core harness and into a class-backed MastraCode gateway, with model IDs resolving directly to gateway-created provider instances. (#17913)
Fixed LSP diagnostics always returning empty arrays on Windows when using
lsp: truein Workspace. (#17816)Previously,
waitForDiagnosticsreturned[]after the full timeout on Windows even when the language server published non-empty diagnostics. This affected any LSP server emitting VS Code-style URIs (e.g. lua-language-server). Now diagnostics are correctly returned regardless of how the language server encodes the file URI.Fixes #17813
Added gateway support to harness v0 model resolution, auth checks, and model discovery. (#17913)
Fixed workflow snapshot records leaking in storage for every agent run. Completed agent runs left behind stale "pending" or "suspended" records indefinitely. These internal records are now removed when an agent run finishes, fails, or is declined. A "suspended" status in workflow snapshot storage now reliably means the run is actually resumable. (#17858)
Fixed agent runs hanging or stopping silently when a model refuses a turn. Anthropic models such as claude-fable-5 can block a turn server-side and return a refusal, which the AI SDK surfaces as a
content-filterfinish reason. (#17893)Fixed the hang: the agentic loop treated
content-filteras "keep going", so it re-sent the same request and re-triggered the refusal on every step — looping untilmaxSteps, or forever whenmaxStepswas unset.content-filteris now treated as a terminal finish reason (alongsidestop,error, andlength), so the run stops instead of hanging.Surfaced a clear terminal state: when a run ends on
content-filter,error, orlength, it now finalizes into an explicit error state, emits an error event with diagnostic context (including the provider's stop details when available), and reportsagent_endwith reason'error'— instead of ending on an empty assistant message that looked like a silent stop.Avoided the refusal in the first place: when the harness runs
claude-fable-5, it now automatically enables Anthropic's server-side fallback toclaude-opus-4-8(providerOptions.anthropic.fallbacks). If fable-5's safety classifiers block a turn, Anthropic transparently retries it on the fallback model and returns that answer. If the whole chain still refuses, the run ends on the terminalcontent-filtererror state described above.Made the fallback visible: when a turn is served by a fallback model (reported via
fallback_messageentries inproviderMetadata.anthropic.iterations), the harness now emits aninfoevent naming the model that actually generated the response, so users know the selected model declined the turn.Attributed tracing to the serving model: the
MODEL_GENERATIONspan'sresponseModelattribute now reports the fallback model when a server-side fallback served the turn, so tracing exporters (Langfuse, etc.) attribute usage and cost to the model that actually generated the response instead of the requested model.Fixed harness modes so they can reuse configured agents and resolve their default models before running. (#17892)
Fixed base64-encoded images failing when sent to Gemini through withMastra. Images now reach the provider in the correct format, matching the behavior of calling generateText without withMastra. (#17976)
License validation for EE features (RBAC, ACL, FGA, SSO) now checks your license key against the Mastra license server instead of validating it locally. (#17859)
What changes for you
MASTRA_LICENSE_KEYto your license key.MASTRA_EE_LICENSEcontinues to work as a supported legacy alias, so existing deployments are unaffected.NODE_ENVnot set to production) are unaffected and keep full EE access without a license.Add alpha browser video recording primitives under
@mastra/core/browser. The new recording helper exposesbrowser_recordandbrowser_record_caption, captures browser screencast frames, burns in short captions, and saves Motion-JPEG AVI videos without requiringffmpeg. (#17028)Example:
Added validation for harness mode configuration so duplicate mode IDs, conflicting tool settings, and invalid transitions are rejected early. (#17892)
Fixed cross-instance output leaking between mastracode TUI tabs after /new. The /new command now fully unsubscribes from the old thread's PubSub topic instead of only aborting the current run, preventing another mc instance on the same thread from pushing events into the detached TUI. (#17883)
Fixed skill updates creating duplicate versions when a snapshot had not meaningfully changed. Comparison previously relied on
JSON.stringify, so reordered object keys (common with PostgreSQL JSONB) or optional fields round-tripping betweenundefinedandnulllooked like changes. Skill snapshots are now compared by value, so repeated no-op publish/update cycles no longer increment the version number. (#16811)Updated dependencies [
9b1adf7]:v1.42.0Compare Source
Minor Changes
You can now execute workflows, tools, and memory thread checks as a trusted actor, such as a background job or scheduled task. Pass an
actorobject to identify the system process making the call while keeping fine-grained authorization checks tenant-scoped. (#17484)Added an actor signal to core FGA checks for trusted server-side membership bypasses. (#17483)
Enabled persistent storage for durable harness sessions across storage backends. Harness v1 can now resolve its session store from a configured storage adapter. (#17712)
Added the
actoroption to agentgenerate()andstream()invocations so trusted background work can run without a JWT or human membership. (#17487)Mastra denies trusted actor FGA checks when the request context does not include an
organizationId.Added SignalProvider abstraction for building notification signal providers. Enables declarative signal wiring in Agent config with built-in subscription tracking, polling lifecycle, and webhook support. Includes WebhookSignalProvider as a proof-of-concept. (#17577)
Writing a signal provider:
Declarative wiring:
Added optional
getUsers(userIds)batch lookup method toIUserProvider. Auth providers can implement it to resolve multiple users in a single call; providers that don't implement it continue to work via per-idgetUserfallback. (#17205)Added MCP server Fine-Grained Authorization mapping overrides for tool authorization. (#17529)
Use the new
fgaoption onMCPServerto customize the resource and permission mappings used fortools/listandtools/callchecks without changing the Mastra instance-leveltoolmapping used by internal agent and workflow tool execution.Made the
ask_userbuilt-in tool agent-agnostic and removed the Harness question channel in favor of native tool suspension. (#17806)ask_usernow pauses through the same tool-suspension primitive used by every other interactive tool, so it works on any agent — not just inside a Harness. The Harness no longer has a separate question channel; instead it surfaces these pauses through the generictool_suspendedevent and resumes them withrespondToToolSuspension.Breaking changes
harness.respondToQuestion(...). Useharness.respondToToolSuspension(...)instead.ask_questionevent. Listen fortool_suspendedand read the question fromevent.suspendPayload.registerQuestionfromHarnessRequestContext, theHarnessDisplayState.pendingQuestionfield, and theHarnessQuestionAnswer,HarnessQuestionOption, andHarnessQuestionSelectionModetypes.HarnessDisplayState.pendingSuspension(a single object ornull) is nowHarnessDisplayState.pendingSuspensions, aMapkeyed bytoolCallId. This lets the display state hold several parked prompts at once, so resuming one parallelask_userno longer hides the others. Read a specific prompt withdisplayState.pendingSuspensions.get(toolCallId).respondToToolSuspensionaccepts an optionaltoolCallIdso concurrently suspended tools (for example, parallelask_usercalls) can each be answered independently.harness.abort()now clears any pending tool suspensions, so a run parked in asuspend()(e.g. an unansweredask_user) can be aborted instead of staying parked forever. A newharness.hasPendingSuspensions()method reports whether the harness is awaiting a resume — useful because a suspended run nulls its internal abort controller, soisRunning()returnsfalsewhile the run is still pending.Before
After
Made the
submit_planbuilt-in tool agent-agnostic and removed the Harness plan-approval channel in favor of native tool suspension. (#17817)submit_plannow pauses through the same tool-suspension primitive used by every other interactive tool, so it works on any agent — not just inside a Harness. A plain Agent (e.g. in Studio or a customer app) can render the plan and resume the tool withagent.resumeStream({ action, feedback }). The Harness surfaces the pause through the generictool_suspendedevent and resumes it withrespondToToolSuspension; on approval it additionally switches to its default (execution) mode.Breaking changes
harness.respondToPlanApproval(...). Resume a submitted plan withharness.respondToToolSuspension({ toolCallId, resumeData: { action, feedback } }).plan_approval_requiredandplan_approvedevents. Listen fortool_suspendedwithevent.toolName === 'submit_plan'and read{ title, plan }fromevent.suspendPayload.registerPlanApprovalfromHarnessRequestContextand theHarnessDisplayState.pendingPlanApprovalfield. A suspendedsubmit_plannow appears asHarnessDisplayState.pendingSuspensionlike any other suspended tool.Before
After
Add batching primitives to the PubSub abstraction. (#16482)
New options
SubscribeOptions.batch(SubscribeBatchOptions): opt in to coalesced delivery on a per-subscriber basis. Fields:maxSize,maxWaitMs,minIntervalMs,isImmediate,coalesce,maxBufferSize,overflow.EventEmitterPubSubconstructor accepts optionalEventEmitterPubSubOptionswith aloggerfor batched-delivery error diagnostics.Example
New exports
SubscribeBatchOptionstype.PubSub.supportsNativeBatching— advertises whether an adapter honorsoptions.batchinternally.Behavior
EventEmitterPubSub.supportsNativeBatching === true. Batched subscribers receive coalesced delivery driven by an in-memory buffer governed bymaxSize/maxWaitMs/minIntervalMs/isImmediate/coalesce/overflow/maxBufferSize.EventEmitterPubSub.flush()drains every batched subscriber buffer and waits for any pending nack redeliveries before resolving. Non-callback rejections surface through the configuredloggerinstead of being swallowed.CachingPubSubis transparent to batching: it forwardsoptions(includingbatch) to its inner PubSub and forwardssupportsNativeBatchingfrom the inner. Whether batching is honored depends entirely on the wrapped transport.Contract notes
SubscribeBatchOptions.coalescemust return a subset of its input array by reference identity. Returning freshly-constructedEventobjects (even with matchingid) is treated as a contract violation: the batching layer can't routeack/nackto original transport handles for manufactured events, so the entire batch is discarded and every original event is acked as dropped. If you need merged payloads, build them in the subscriber callback after delivery.flush()is best-effort: a successful resolution does not guarantee every subscriber callback succeeded. Per-event errors surface via the configured logger.Added agent and workspace tool hooks for applications that need to run logic before and after tool calls execute. Mastra Code now uses agent hooks so hook handlers run for built-in workspace tools as well as dynamic tools. (#17637)
Example
Added interface-first model gateways while keeping the existing
MastraModelGatewaybase class backwards compatible. (#17608)Added
MastraModelGatewayInterfacefor plain object/custom gateway implementations and optional gatewayresolveAuthhooks.Moved MastraCode gateway-routed OAuth model construction into a custom Mastra gateway so
ModelRouterLanguageModelcan route through gatewayresolveAuthand provider-specificresolveLanguageModelbehavior.Usage:
Additional changes in this release:
ModelRouterLanguageModel.resolveAuthand deprecate the standaloneresolveModelAuthhelper.defaultGatewaysdeduplication in theMastraclass to usegetGatewayId(gateway)instead of registry keys.resolveModelIdidentity function in mastracode in favor of direct usage.defaultNameGeneratorregex in_llm-recorderto anchor directory matches to path boundaries (prevents false matches like-authsuffixes).Make the task tools (
task_write,task_update,task_complete,task_check) agent-agnostic. (#17820)The task tools no longer depend on the Harness request context. The task list is now held in a generic, thread-scoped
threadStatestorage domain (ThreadStateStorage) — the source of truth — and projected onto the agent state-signal lane (stateId: "tasks") by the newTaskStateProcessor, so they work on anyAgentand not only inside the Harness.A new storage domain
threadStateis registered onMastraStorage(accessible viastorage.getStore("threadState")). It is keyed by(threadId, type)so it can hold any per-thread state; the task list lives undertype: "task"and the domain is intentionally generic so other agent-scoped state (e.g."goal") can reuse it. The composite store always wires anInMemoryThreadStateStorageby default, so task tracking works out of the box without configuring a backend, and a durable backend (@mastra/libsql'sThreadStateLibSQL) persists the list across process restarts. The tools read/write it within a run viacontext.mastra.getStorage().getStore("threadState"), scoped by the run'sthreadId.The state-signal projection is delta-first (modelled on working memory), cache-aware, and observational-memory-aware:
<current-task-list>snapshot; each later mutation emits a small<task-list-update>delta carrying only that turn's add/remove/update ops, so a large task list is not re-sent in full on every change.threadStatestore so the agent never loses track of its tasks.The task tools and the processor require a memory-backed thread. On a run that is not memory backed (no
threadId/resourceId), the task tools no-op and return a result explaining that task tracking requires agent memory.For the simplest setup, register
TaskSignalProvidervia the agent'ssignalsarray — it bundles the task tools and theTaskStateProcessorso they cannot get out of sync:The Agent merges the tools into its toolset and registers the processor automatically.
New exports from
@mastra/core/storage:ThreadStateStorage,InMemoryThreadStateStorage, and theTaskRecordtype. New exports from@mastra/core/tools:taskWriteTool,taskUpdateTool,taskCompleteTool,taskCheckTool,TaskStateProcessor, and the task helpers/types (assignTaskIds,summarizeTaskCheck,TaskItem,TaskItemSnapshot,TaskCheckSummary,TaskCheckResult, etc.). New export from@mastra/core/signals:TaskSignalProvider, alongside the other signal providers. The Harness continues to re-export the task tools, so existing imports and toolset identity are unchanged.Internal behavior change: the Harness no longer stores the task list in session state. Task mutations still emit the
task_updateddisplay event, so the Harness display snapshot and any pinned task UI are unaffected. To adopt the new behavior on a plain agent (withMemoryand a Mastrastorage), registernew TaskSignalProvider()insignals— or, for manual control, addnew TaskStateProcessor()toinputProcessorsalongside the task tools.Add workspace registry cleanup and shutdown destruction. (#17661)
Mastra now exposes
removeWorkspace(id, { destroy })for removing runtime workspaces from the registry. Whendestroyis true, the workspace is destroyed before removal and remains registered if destruction fails.mastra.shutdown()now destroys registered workspaces before closing storage and unregisters only the workspaces that clean up successfully. Workspace tool execution also updateslastAccessedAt, so runtime activity is tracked beyond search operations.Added two options to
ToolSearchProcessorfor cheaper, more cache-friendly tool discovery. (#17691)autoLoad: one-turn discoverySet
search.autoLoadso thatsearch_toolsactivates the matching tools immediately, removing the separateload_toolround-trip. The model searches once and can call a discovered tool on its next turn instead of searching, loading, then calling. This cuts one model turn (and a full prompt replay) per discovery.storage: opt-in'context'modeChoose where loaded-tool state lives. The default
'in-memory'keeps the original behavior. The new opt-in'context'mode derives loaded tools from the conversation messages, so it is restart-safe, needs no memory configuration, and de-loads a tool once its discovery result is no longer in the messages.Both modes are cache-friendly when loading tools, since loads are append-only and keep the cached prompt prefix stable. The default
'in-memory'store still shares a single'default'entry across anonymous (no thread ID) requests; usestorage: 'context'to keep anonymous requests isolated and derive loaded tools from the conversation messages.Patch Changes
Fixed ConsoleLogger.warn() to correctly call console.warn() instead of console.info(), ensuring warn-level logs are routed to stderr and properly classified by log backends (e.g. Datadog) (#17623)
Fixed silent error swallowing when agent.stream() fails during idle-start, continuation, or pending-idle signal processing. Errors now propagate to the subscription stream via a new run-failed event, so harness consumers (like MastraCode) surface proper error events instead of silently completing with no response. (#17727)
Added author enrichment to the stored-agents list and get handlers. When an auth provider is configured, each agent record now includes a resolved
authorobject alongside the existingauthorId: (#17205)Lookups are deduplicated per request and use the provider's
getUsersbatch method when available, falling back to per-idgetUsercalls otherwise. The field is omitted when no auth provider is configured or the ID can't be resolved, so existing clients keep working unchanged.Fixed ingestion of client-side tool tracing from AI SDK v6
toolMetadatawhen messages return through chatRoute. (#17202)Fixed durable and evented agent streams so tool-call steps continue to final text when maxSteps allows it. (#16679)
Clarified Studio config JSDoc to explain dual auth opt-in behavior. (#17722)
Fixed a multi-instance hang in evented execution mode. When two Mastra processes shared a UnixSocketPubSub broker, the agent's evented run could fail with
AGENT_GENERATE_MALFORMED_RESULT,condition is not a function, or hang silently with ECANCELED errors during shutdown. (#17788)What changed
parentWorkflow), per-run watch streams (workflow.events.v2.*), and scheduler-spawned background runs (sched_wf_*) are now delivered only inside the publishing process and no longer cross the unix socket.MastraModelOutputreturned by an agent run) are preserved instead of being stripped by JSON serialization on the broker round-trip.Why
Follow-up to the broker-side filter shipped in #17727. That filter ran after the publish frame had already been serialized, which stripped functions/streams from payloads and still fanned out cumulative
stepResultsblobs (often 9 MB+) to every connected client. Short-circuiting these publishes in-process removes the serialization round-trip entirely and lets the agent's run result survive intact.Added anonymous, aggregated model token usage telemetry. When a Mastra server starts and observability metrics are enabled, the input and output token totals per provider and model are sent to Mastra's telemetry. Only aggregate token counts are collected — never prompts, responses, or message content. Opt out by setting MASTRA_TELEMETRY_DISABLED=1. (#17750)
Plan due notification dispatches per thread from a single due snapshot so high-priority notifications that already emitted summaries are delivered in full before lower-priority notifications or summaries can wake the same thread.
Agent.sendNotificationSignalalso accepts an array of notification inputs so related notifications can be evaluated against the same initial thread state before any delivery wakes the thread. (#17590)storageis configured onMastra, and warn that it is not durable and a persistent storage adapter should be used in production.Prevented user-created filesystem stored agents from being treated as code agents when they are not declared in the code Mastra instance. (#17622)
Fixed per-item request context being dropped for inline experiment data. When running an experiment with inline
data, each item'srequestContextis now passed to the agent or workflow and merged over the global request context (per-item values win on key collisions), matching the behavior of storage-backed datasets. (#17597)Fixed thread subscribers so they can join an already-running remote stream and receive new output without waiting for the next run. (#17635)
Improved BM25 tokenization to support CJK (Japanese, Chinese, Korean) and other non-Latin languages. Added
TokenizeOptions.tokenizerfor plugging in custom tokenizers (e.g. n-gram, kuromoji). Workspacebm25config now acceptstokenizeoptions for full control over how text is split into search tokens. (#17640)Before: BM25 search returned no results for non-English content — CJK characters were silently stripped during tokenization.
After: Non-Latin characters are preserved by default. Users can also plug in a custom tokenizer:
Fixes #17636
Added OTel span instrumentation for the hardcoded 10-second rate-limit backpressure sleep, making it visible in traces as a 'rate-limit-sleep' span with remainingTokens and delayMs metadata (#17623)
Fixed medium-priority notification summaries so they wake idle agent threads when they are ready to deliver. (#17590)
Fixed message part timestamps affecting transcript ordering by ensuring only message-level timestamps advance the ordering watermark. (#17598)
Added a local development warning when Enterprise features are used without a valid license. (#17694)
Fix
response.modelIdbeing overwritten withundefinedinstep-finishchunks when the upstream model stream omitsmodelIdfromresponse-metadata. The explicit empty-string fallback was placed before a...otherMetadataspread that could overwrite it withundefined. Moved themodelIdassignment after the spread so the fallback always wins. (#17795)This restores consistent
response.modelId === ''behavior across both the direct and evented agentic-loop workflow paths.Fix
Cannot get workflow run. Mastra storage is not initializeddebug log spam on agents that use memory or any input/output processors. (#17571)#17344 fixed this for the internal
execution-workflow, but agents with memory/processors also build an internal processor workflow (Agent.combineProcessorsIntoWorkflow, run byProcessorRunner.executeWorkflowAsProcessor) that never received the parentMastrainstance — so itscreateRun()→getWorkflowRunById()saw no storage and logged the noise on every run. The processor workflow now receives the parentMastrainstance and opts out of snapshot persistence (shouldPersistSnapshot: () => false), mirroring the execution-workflow fix. Follow-up to #17137 / #17344.Fix
request_accessgranting a path but the file staying unreadable withEACCES. After approving access, the very next tool (e.g.view) could still be rejected for the path that was just granted. The grant now reliably applies to the filesystem the agent's tools actually read from, and persists before the run resumes, so reads of an approved path succeed. (#17806)Update ai-sdk deps (#17144)
Fixed browser state signals so they no longer show 'Browser is closed' before the browser is used. Added attribution for browser closes and active URL changes when the agent or user caused them. (#17631)
Added optional
authorfield onStoredAgentResponseso consumers can render the resolved author (name, email, avatar) returned by stored-agent list and detail endpoints. (#17205)Fixed Windows absolute paths breaking workspace skill discovery.
WorkspaceSkillssplit paths on/only, so a skill referenced by an absolute Windows path loaded with the wrong name (the full path string orunknown) or failed to load, and skills undernode_moduleswere misclassified as local instead of external. (#17671)Skills passed by absolute path now resolve the same way on Windows and POSIX:
v1.41.0Compare Source
Minor Changes
Workspace
sandboxnow accepts a resolver function for per-request sandboxes. (#16048)Before:
sandbox: WorkspaceSandbox(static, same sandbox for every request)After:
sandbox: WorkspaceSandbox | (({ requestContext }) => WorkspaceSandbox)(static or per-request)This enables per-request sandbox routing from a single Workspace — useful for multi-tenant deployments where each user/role needs an isolated working directory or different execution permissions.
When using a resolver, the caller owns the returned sandbox's lifecycle — the Workspace will not call
start()ordestroy()on it.mountsthrows anINVALID_CONFIGerror with a resolver, andlsp: trueis disabled with a warning because both require a concrete sandbox instance up front.Stable prompts by default
Building workspace instructions no longer calls a sandbox resolver. Resolver-backed sandboxes contribute stable placeholder text to the agent's system message, so constructing the prompt never provisions a caller-owned sandbox and the prompt stays cache-friendly. Opt into concrete per-request instructions with
instructions.dynamicSandbox:Background process continuity
Set
sandboxCacheKeyto keepexecute_command({ background: true }),get_process_output, andkill_processon the same sandbox across follow-up requests — continuity is keyed by a stable id rather than theRequestContextinstance:Failed sandbox resolver calls are removed from the cache so later calls can retry. Use
workspace.clearSandboxCache(cacheKey)to drop a keyed sandbox reference when your own lifecycle code has destroyed or replaced that sandbox.When background process tools cannot find a PID on a dynamic sandbox without
sandboxCacheKey, the tool output now points tosandboxCacheKeyso callers can fix continuity across follow-up requests.Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.