February 24, 2026
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.
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.
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).
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)
Workspace.getInstructions(): agents now receive accurate workspace context that distinguishes sandbox-accessible paths from workspace-only paths.WorkspaceInstructionsProcessor: workspace context is injected directly into the agent system message instead of embedded in tool descriptions.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_processhandle.reader / handle.writerexecuteCommand 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 PIDget_process_output tool to check output/status of background processes (supports wait to block until exit)kill_process tool to terminate background processesFixed 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)
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
Fixed getInstructions() to report sandbox-level facts only (working directory, provider type) instead of counting all mount entries regardless of state. Added instructions option to E2BSandbox to override or extend default instructions. (#13304)
Added E2BProcessManager for background process management in E2B cloud sandboxes. (#13293)
Wraps E2B SDK's commands.run() with background: true and commands.connect() for reconnection. Processes spawned in E2B sandboxes are automatically cleaned up on stop() and destroy().
Bumps @mastra/core peer dependency to >=1.7.0-0 (requires SandboxProcessManager from core).
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
Fixed non-deterministic query ordering by adding secondary sort on id for dataset and dataset item queries. (#13399)
Updated dependencies [24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
3af89bb, 551dc24, e8afc44, 24284ff, f5097cc, 71e237f, c2e02f1, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
Fixed memory leak in Observational Memory (#13425)
Fixed several memory management issues that could cause OOM crashes in long-running processes with Observational Memory enabled:
cleanupStaticMaps.Fixed PostgreSQL deadlock when parallel agents with different threadIds share the same resourceId while using Observational Memory. Thread scope now requires a valid threadId and throws a clear error if one is missing. Also fixed the database lock ordering in synchronous observation to prevent lock inversions. (#13436)
Updated dependencies [24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
551dc24, e8afc44, 24284ff, f5097cc, 71e237f, c2e02f1, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
Fixed non-deterministic query ordering by adding secondary sort on id for dataset and dataset item queries. (#13399)
Updated dependencies [24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
Improved comparison selection behavior: selecting a third item now replaces the most recent selection instead of being blocked. Applies to dataset version, item version, and dataset item comparison flows. (#13406)
Improved the score dialog to show "N/A" with an explanation instead of "null" for empty scorer fields. Code-based scorers show "N/A — code-based scorer does not use prompts" and LLM scorers with unconfigured steps show "N/A — step not configured". Detection uses the hasJudge metadata flag with a heuristic fallback for older data. (#13386)
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 PIDget_process_output tool to check output/status of background processes (supports wait to block until exit)kill_process tool to terminate background processesUpdated dependencies [24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
zeroentropy@0.1.0-alpha.7 ↗︎ (from 0.1.0-alpha.6, in dependencies)24284ff, f5097cc, 71e237f, 13a291e, 397af5a, d4701f7, 2b40831, 6184727, 0c338b8, 6f6385b, 14aba61, dd9dd1c]:
2b40831]:
Fetched April 7, 2026