April 23, 2026
@mastra/core and the new @mastra/browser-viewer package add end-to-end browser automation for CLI-based agent workflows. BrowserViewer launches Chrome via Playwright with remote debugging, and a new BrowserCliHandler automatically detects browser CLIs (agent-browser, browser-use, browse) and injects the CDP URL into commands — no manual wiring needed. Browser sessions are thread-isolated with automatic lifecycle management, and live screencasts stream directly to Studio. External CDP endpoints (e.g. browser-use cloud) are also supported: the system detects them, skips injection, and connects for screencast.
Workspace packages (@mastra/s3, @mastra/daytona, @mastra/e2b, and @mastra/blaxel) now support mounting an S3 subdirectory via a prefix option, so sandboxes can expose only a folder within a bucket instead of the entire bucket.
foreachFixes a workflow snapshot/resume bug where parallel foreach iterations could lose their suspendPayload when a sibling iteration resumed—important for HITL/tool-approval flows that rely on preserved per-iteration stream state.
Adds opt-in temporal-gap markers (observationalMemory.temporalMarkers: true) to inject persisted <system-reminder type="temporal-gap"> when users return after 10+ minutes, and fixes duplication/conflicts by force-disabling savePerStep when observational memory is enabled.
@mastra/tavilyNew integration package wrapping @tavily/core as first-class Mastra tools — createTavilySearchTool, createTavilyExtractTool, createTavilyCrawlTool, and createTavilyMapTool — with full Zod input/output schemas, lazy client initialization, and a convenience createTavilyTools() that returns all four with shared config. API key resolves from config or TAVILY_API_KEY env var.
Added support for CLI-driven browser automation with screencast support in @mastra/core, including automatic CDP injection for browser CLIs. (#15415)
Fixed local process spawning so workspace-relative cwd values no longer get duplicated.
Update provider registry and model documentation with latest models and providers (f112db1)
Fixed foreach parallel iterations losing their suspendPayload when a sibling iteration was resumed. Previously, every result entry written back to the workflow snapshot had its suspendPayload cleared, so iterations that were still suspended (e.g. parallel tool-call approvals each carrying an agent's __streamState) lost the context they needed to resume correctly. Suspended iterations now retain their suspendPayload across resume cycles; completed iterations still have it cleared to keep snapshots small. (#15551)
const approvalWorkflow = createWorkflow({ id: "approve" }).foreach(approveToolStep, { concurrency: 5 }).commit();
// Before: resuming the first approval wiped streamState on the others,
// so subsequent resumes lost conversation context.
// After: each suspended iteration keeps its suspendPayload (including
// streamState) until it is individually resumed.
Fixed interaction between savePerStep and observational memory that caused message duplication. The saveStepMessages method redundantly re-added response messages to the message list on every step, duplicating them. Additionally, savePerStep is now force-disabled when observational memory is enabled, since OM handles its own per-step persistence and the two features conflict. (#15652)
Added opt-in temporal-gap markers for observational memory. When enabled via observationalMemory.temporalMarkers: true, the agent receives a <system-reminder type="temporal-gap"> before any user message that arrives more than 10 minutes after the previous one, so it can anchor responses in real elapsed time. Markers are persisted, surfaced to the observer, and rendered by the MastraCode TUI on reload. (#15605)
mastra dev startup (that was previously already hidden but got exposed again by a recent change) (#15616)Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the prefix option on your S3 filesystem. (#15171)
Example:
const fs = new S3Filesystem({
bucket: "my-bucket",
region: "us-east-1",
prefix: "workspace/data",
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!
});
When mounted in a sandbox, only the contents under workspace/data/ in the bucket will be visible at the mount path. This uses the s3fs bucket:/path syntax under the hood.
Closes #15147.
Initial release of @mastra/browser-viewer (#15415)
Playwright-based browser viewer for CLI providers that enables screencast visualization in Studio. Supports thread-isolated browser sessions and automatic CDP connection management.
import { BrowserViewer } from "@mastra/browser-viewer";
const workspace = new Workspace({
sandbox: new LocalSandbox({ cwd: "./workspace" }),
browser: new BrowserViewer({
cli: "agent-browser",
headless: false
})
});
Fixed mastra dev repeatedly reporting MIGRATION REQUIRED on ClickHouse Cloud after mastra migrate had already run successfully. The observability migration check now recognizes the engine-name variants that ClickHouse Cloud and replicated clusters use in place of ReplacingMergeTree. (#15623)
Improved ClickHouse v-next observability initialization errors to include the underlying ClickHouse message in the standard error text. This makes init failures actionable in loggers that only print error.message. (#15588)
Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the prefix option on your S3 filesystem. (#15171)
Example:
const fs = new S3Filesystem({
bucket: "my-bucket",
region: "us-east-1",
prefix: "workspace/data",
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!
});
When mounted in a sandbox, only the contents under workspace/data/ in the bucket will be visible at the mount path. This uses the s3fs bucket:/path syntax under the hood.
Closes #15147.
Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the prefix option on your S3 filesystem. (#15171)
Example:
const fs = new S3Filesystem({
bucket: "my-bucket",
region: "us-east-1",
prefix: "workspace/data",
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!
});
When mounted in a sandbox, only the contents under workspace/data/ in the bucket will be visible at the mount path. This uses the s3fs bucket:/path syntax under the hood.
Closes #15147.
tools (e.g. POST /stored/agents, POST /stored/workspaces). The adapter now exposes registered tools as registeredTools in handler params, matching the Express and Hono adapters and the @mastra/server handler contract. (#15635)observationalMemory.temporalMarkers: true, the agent receives a <system-reminder type="temporal-gap"> before any user message that arrives more than 10 minutes after the previous one, so it can anchor responses in real elapsed time. Markers are persisted, surfaced to the observer, and rendered by the MastraCode TUI on reload. (#15605)no low surrogate in string, causing observer runs to fail. (#15634)Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the prefix option on your S3 filesystem. (#15171)
Example:
const fs = new S3Filesystem({
bucket: "my-bucket",
region: "us-east-1",
prefix: "workspace/data",
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!
});
When mounted in a sandbox, only the contents under workspace/data/ in the bucket will be visible at the mount path. This uses the s3fs bucket:/path syntax under the hood.
Closes #15147.
Forward requestContext from the /approve-tool-call, /decline-tool-call, /approve-tool-call-generate and /decline-tool-call-generate REST handlers to agent.approveToolCall(...) / declineToolCall(...) / approveToolCallGenerate(...) / declineToolCallGenerate(...). (#15620)
Previously requestContext was destructured from the handler arguments but never passed through. On resume, dynamicInstructions ran with requestContext: undefined, so any value placed on the per-request RequestContext by upstream middleware (or by body.requestContext auto-merge) was lost for the rest of the turn. Agents whose prompt assembly depends on request-scoped data (e.g. read-only state from the frontend) produced blank or placeholder responses after the user approved a HITL tool call. Other agent entry points (stream, generate) already forwarded requestContext correctly; this brings the approval routes in line.
Fixed screencast panel staying "Live" after browser closes due to an error. The ViewerRegistry now broadcasts browser_closed status when a screencast stream emits an error, not just when it stops cleanly. (#15415)
ERR_MODULE_NOT_FOUND for @tavily/core by making it a direct dependency. Consumers no longer need to install @tavily/core manually. (#15628)The following packages were updated with dependency changes only:
Fetched April 24, 2026
Highlights Azure Blob Storage workspace + blob store ( ) New adds an Azure Blob Storage provider ( ) and an content-addressable store for s…
Highlights Background Process Management in Workspaces & Sandboxes Workspaces now support spawning and managing long-running background pro…