@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
234 lines • 8.92 kB
TypeScript
/**
* MastraSandbox Base Class
*
* Abstract base class for sandbox providers that want automatic logger integration.
* Extends MastraBase to receive the Mastra logger when registered with a Mastra instance.
*
* MountManager is automatically created if the subclass implements `mount()`.
* Use `declare readonly mounts: MountManager` to get non-optional typing.
*
* ## Lifecycle Management
*
* The base class provides race-condition-safe lifecycle wrappers:
* - `_start()` - Handles concurrent calls, status management, and mount processing
* - `_stop()` - Handles concurrent calls and status management
* - `_destroy()` - Handles concurrent calls and status management
*
* Subclasses override the plain `start()`, `stop()`, and `destroy()` methods
* to provide their implementation. Callers use the `_`-prefixed wrappers
* (or `callLifecycle()`) which add status tracking and race-condition safety.
*
* External providers can extend this class to get logger support, or implement
* the WorkspaceSandbox interface directly if they don't need logging.
*/
import { MastraBase } from '../../base.js';
import type { IMastraLogger } from '../../logger/index.js';
import type { WorkspaceFilesystem } from '../filesystem/filesystem.js';
import type { MountResult } from '../filesystem/mount.js';
import type { ProviderStatus } from '../lifecycle.js';
import { MountManager } from './mount-manager.js';
import type { SandboxProcessManager } from './process-manager/index.js';
import type { WorkspaceSandbox } from './sandbox.js';
import type { CommandResult, ExecuteCommandOptions, SandboxInfo } from './types.js';
/**
* Lifecycle hook that fires during sandbox state transitions.
* Receives the sandbox instance so users can call `executeCommand`, read files, etc.
*/
export type SandboxLifecycleHook = (args: {
sandbox: WorkspaceSandbox;
}) => void | Promise<void>;
/**
* Options for the MastraSandbox base class constructor.
* Providers extend this to add their own options while inheriting lifecycle hooks.
*/
export interface MastraSandboxOptions {
/** Called after the sandbox reaches 'running' status */
onStart?: SandboxLifecycleHook;
/** Called before the sandbox stops */
onStop?: SandboxLifecycleHook;
/** Called before the sandbox is destroyed */
onDestroy?: SandboxLifecycleHook;
/**
* Process manager for this sandbox.
*
* When provided, the base class automatically:
* 1. Sets the sandbox back-reference on the process manager
* 2. Exposes it via `this.processes`
* 3. Creates a default `executeCommand` implementation (spawn + wait)
*
* @example
* ```typescript
* class MySandbox extends MastraSandbox {
* constructor() {
* super({
* name: 'MySandbox',
* processes: new MyProcessManager({ env: myEnv }),
* });
* }
* }
* ```
*/
processes?: SandboxProcessManager;
}
/**
* Abstract base class for sandbox providers with logger support.
*
* Providers that extend this class automatically receive the Mastra logger
* when the sandbox is used with a Mastra instance. MountManager is also
* automatically created if the subclass implements `mount()`.
*
* @example
* ```typescript
* class MyCustomSandbox extends MastraSandbox {
* declare readonly mounts: MountManager; // Non-optional type
* readonly id = 'my-sandbox';
* readonly name = 'MyCustomSandbox';
* readonly provider = 'custom';
* status: ProviderStatus = 'pending';
*
* constructor() {
* super({
* name: 'MyCustomSandbox',
* processes: new MyProcessManager({ env: myEnv }),
* });
* }
*
* async start(): Promise<void> { /* startup logic *\/ }
* async mount(filesystem, mountPath) { ... }
* async unmount(mountPath) { ... }
* }
* ```
*/
export declare abstract class MastraSandbox extends MastraBase implements WorkspaceSandbox {
/** Unique identifier for this sandbox instance */
abstract readonly id: string;
/** Human-readable name (e.g., 'E2B Sandbox', 'Docker') */
abstract readonly name: string;
/** Provider type identifier */
abstract readonly provider: string;
/** Current status of the sandbox */
abstract status: ProviderStatus;
/**
* Execute a shell command and wait for completion.
*
* Method syntax (not property syntax) is intentional — it prevents
* `useDefineForClassFields` from emitting `this.executeCommand = undefined`
* which would shadow prototype methods defined by subclasses.
*/
executeCommand?(command: string, args?: string[], options?: ExecuteCommandOptions): Promise<CommandResult>;
/** Process manager */
readonly processes?: SandboxProcessManager;
/** Mount manager - automatically created if subclass implements mount() */
readonly mounts?: MountManager;
/** Optional mount method - implement to enable mounting support */
mount?(filesystem: WorkspaceFilesystem, mountPath: string): Promise<MountResult>;
/** Optional unmount method */
unmount?(mountPath: string): Promise<void>;
/** Get instructions describing how this sandbox works */
getInstructions?(): string;
/** Get sandbox status and metadata */
getInfo?(): SandboxInfo | Promise<SandboxInfo>;
/** Promise for _start() to prevent race conditions from concurrent calls */
protected _startPromise?: Promise<void>;
/** Promise for _stop() to prevent race conditions from concurrent calls */
protected _stopPromise?: Promise<void>;
/** Promise for _destroy() to prevent race conditions from concurrent calls */
protected _destroyPromise?: Promise<void>;
/** Lifecycle callbacks */
private readonly _onStart?;
private readonly _onStop?;
private readonly _onDestroy?;
constructor(options: {
name: string;
} & MastraSandboxOptions);
/**
* Start the sandbox (wrapper with status management and race-condition safety).
*
* This method is race-condition-safe - concurrent calls will return the same promise.
* Handles status management and automatically processes pending mounts after startup.
*
* Subclasses override `start()` to provide their startup logic.
*/
_start(): Promise<void>;
/**
* Internal start execution - handles status and mount processing.
*/
private _executeStart;
/**
* Override this method to implement sandbox startup logic.
*
* Called by `_start()` after status is set to 'starting'.
* Status will be set to 'running' on success, 'error' on failure.
*
* @example
* ```typescript
* async start(): Promise<void> {
* this._sandbox = await Sandbox.create({ ... });
* }
* ```
*/
start(): Promise<void>;
/**
* Ensure the sandbox is running.
*
* Calls `_start()` if status is not 'running'. Useful for lazy initialization
* where operations should automatically start the sandbox if needed.
*
* @throws {SandboxNotReadyError} if the sandbox fails to reach 'running' status
*
* @example
* ```typescript
* async executeCommand(command: string): Promise<CommandResult> {
* await this.ensureRunning();
* // Now safe to use the sandbox
* }
* ```
*/
ensureRunning(): Promise<void>;
/**
* Stop the sandbox (wrapper with status management and race-condition safety).
*
* This method is race-condition-safe - concurrent calls will return the same promise.
* Handles status management.
*
* Subclasses override `stop()` to provide their stop logic.
*/
_stop(): Promise<void>;
/**
* Internal stop execution - handles status.
*/
private _executeStop;
/**
* Override this method to implement sandbox stop logic.
*
* Called by `_stop()` after status is set to 'stopping'.
* Status will be set to 'stopped' on success, 'error' on failure.
*/
stop(): Promise<void>;
/**
* Destroy the sandbox and clean up all resources (wrapper with status management).
*
* This method is race-condition-safe - concurrent calls will return the same promise.
* Handles status management.
*
* Subclasses override `destroy()` to provide their destroy logic.
*/
_destroy(): Promise<void>;
/**
* Internal destroy execution - handles status.
*/
private _executeDestroy;
/**
* Override this method to implement sandbox destroy logic.
*
* Called by `_destroy()` after status is set to 'destroying'.
* Status will be set to 'destroyed' on success, 'error' on failure.
*/
destroy(): Promise<void>;
/**
* Override to propagate logger to MountManager.
* @internal
*/
__setLogger(logger: IMastraLogger): void;
}
//# sourceMappingURL=mastra-sandbox.d.ts.map