@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
371 lines (240 loc) • 18.9 kB
Markdown
# Workspace class
**Added in:** `@mastra/core@1.1.0`
The `Workspace` class combines a filesystem and sandbox to provide agents with file storage and command execution capabilities. It also supports BM25 and vector search for indexed content.
## Usage example
```typescript
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'
const workspace = new Workspace({
id: 'my-workspace',
name: 'My Workspace',
filesystem: new LocalFilesystem({
basePath: './workspace',
}),
sandbox: new LocalSandbox({
workingDirectory: './workspace',
}),
bm25: true,
autoIndexPaths: ['docs'],
})
```
## Constructor parameters
**id** (`string`): Unique identifier for the workspace (Default: `Auto-generated`)
**name** (`string`): Human-readable name (Default: `workspace-{id}`)
**filesystem** (`WorkspaceFilesystem | WorkspaceFilesystemResolver`): Filesystem provider instance, or a resolver function that receives \`requestContext\` and returns a filesystem per request. See \[dynamic filesystem]\(/docs/workspace/filesystem#dynamic-filesystem).
**sandbox** (`WorkspaceSandbox`): Sandbox provider instance (e.g., LocalSandbox)
**bm25** (`boolean | BM25Config`): Enable BM25 keyword search. Pass true for defaults or a config object. (Default: `undefined`)
**vectorStore** (`MastraVector`): Vector store for semantic search
**embedder** (`Embedder`): Function that turns text into vectors. Required when \`vectorStore\` is set. Accepts either a single-text function \`(text: string) => Promise\<number\[]>\` or a batch-capable function \`(texts: string\[]) => Promise\<number\[]\[]>\` that has a \`batch: true\` property and an optional \`maxBatchSize\`. See \[Batch embedding]\(/docs/workspace/search#batch-embedding).
**autoIndexPaths** (`string[]`): Paths or glob patterns to auto-index on init(). Supports glob patterns like '\*\*/\*.md' for selective indexing.
**skills** (`string[] | ((context: SkillsContext) => string[] | Promise<string[]>)`): Paths where SKILL.md files are located. This can be a static array or an async function that resolves paths dynamically. Supports glob patterns like './\*\*/skills' for discovery.
**skillSource** (`SkillSource`): Custom skill source for skill discovery. When provided, this source is used instead of the workspace filesystem. Use VersionedSkillSource to serve published skill versions from a content-addressable blob store.
**onMount** (`OnMountHook`): Pre-mount hook called for each filesystem before mounting into a sandbox. Return false to skip mounting, or return { success: true } if the hook handled the mount. Return undefined to use the default mount behavior.
**searchIndexName** (`string`): Custom index name for the vector store. Must be a valid SQL identifier (start with a letter or underscore, contain only letters, numbers, or underscores, max 63 characters). Defaults to a sanitized version of '{id}\_search'.
**tools** (`WorkspaceToolsConfig`): Per-tool configuration for enabling tools and setting safety options
**tools.enabled** (`boolean`): Whether the tool is available to agents
**tools.requireApproval** (`boolean`): Whether the tool requires user approval before execution
**tools.name** (`string`): Custom name to expose this tool as. Replaces the default \`mastra\_workspace\_\*\` name. The config key must still use the original \`WORKSPACE\_TOOLS\` constant.
**tools.requireReadBeforeWrite** (`boolean`): For write tools: require reading the file first to prevent overwrites
**tools.maxOutputTokens** (`number`): Maximum tokens for tool output. Output exceeding this limit is truncated using tiktoken.
**operationTimeout** (`number`): Timeout for operations in milliseconds
## Tool configuration
The `tools` option accepts a `WorkspaceToolsConfig` object that controls which workspace tools are enabled and their safety settings.
```typescript
import { Workspace } from '@mastra/core/workspace'
import { WORKSPACE_TOOLS } from '@mastra/core/workspace'
const workspace = new Workspace({
id: 'my-workspace',
name: 'My Workspace',
tools: {
// Global defaults (apply to all tools)
enabled: true,
requireApproval: false,
// Per-tool overrides using WORKSPACE_TOOLS constants
[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: {
requireApproval: true,
},
},
})
```
The config object has two parts:
- **Global defaults** (`enabled`, `requireApproval`): Apply to all tools unless overridden
- **Per-tool overrides** - Use `WORKSPACE_TOOLS` constants as keys to configure individual tools
See [workspace overview](https://mastra.ai/docs/workspace/overview) for more examples.
### Tool name remapping
Rename workspace tools by setting the `name` property on individual tool configs. The config key remains the original constant — only the name exposed to the agent changes.
```typescript
import { Workspace } from '@mastra/core/workspace'
import { WORKSPACE_TOOLS } from '@mastra/core/workspace'
const workspace = new Workspace({
id: 'my-workspace',
name: 'My Workspace',
tools: {
[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: { name: 'view' },
[WORKSPACE_TOOLS.FILESYSTEM.GREP]: { name: 'search_content' },
},
})
```
Tool names must be unique across all workspace tools. Setting a custom name that conflicts with another tool's default or custom name throws an error.
## Properties
**id** (`string`): Workspace identifier
**name** (`string`): Workspace name
**status** (`WorkspaceStatus`): 'pending' | 'initializing' | 'ready' | 'paused' | 'error' | 'destroying' | 'destroyed'
**filesystem** (`WorkspaceFilesystem | undefined`): The static filesystem provider. Returns \`undefined\` when a resolver function is configured — use \`hasFilesystemConfig()\` to check availability.
**sandbox** (`WorkspaceSandbox | undefined`): The sandbox provider
**skills** (`WorkspaceSkills | undefined`): Skills interface for accessing SKILL.md files
**canBM25** (`boolean`): Whether BM25 search is available
**canVector** (`boolean`): Whether vector search is available
**canHybrid** (`boolean`): Whether hybrid search is available
## Methods
### Lifecycle
#### `init()`
Initialize the workspace and prepare resources.
```typescript
await workspace.init()
```
Calling `init()` is optional in most cases:
- **Sandbox**: Auto-starts on first `executeCommand()` call. Use `init()` to avoid first-command latency.
- **Filesystem**: Creates the base directory and runs any provider-specific setup. Some providers auto-create the directory on first operation.
- **Search**: Required only if using `autoIndexPaths` for auto-indexing.
Initialization performs:
- Starts the filesystem provider (creates base directory if needed)
- Starts the sandbox provider (creates working directory, sets up isolation if configured)
- Indexes files from `autoIndexPaths` for search
#### `destroy()`
Destroy the workspace and clean up resources.
```typescript
await workspace.destroy()
```
### Search operations
#### `index(path, content, options?)`
Index content for search.
```typescript
await workspace.index('/docs/guide.md', 'Guide content...')
```
#### `search(query, options?)`
Search indexed content.
```typescript
const results = await workspace.search('password reset', {
topK: 10,
mode: 'hybrid',
})
```
### Utility
#### `getInfo()`
Get workspace information.
```typescript
const info = await workspace.getInfo()
// { id, name, status, createdAt, lastAccessedAt, filesystem?, sandbox? }
```
#### `getInstructions(opts?)`
Returns combined instructions from the filesystem and sandbox providers. Injected into the agent's system message to help it understand the execution context.
```typescript
const instructions = workspace.getInstructions()
```
Pass `requestContext` to enable per-request customization when a provider's `instructions` option is a function:
```typescript
const instructions = workspace.getInstructions({ requestContext })
```
**Parameters:**
**opts.requestContext** (`RequestContext`): Forwarded to the \`instructions\` function on the filesystem or sandbox provider, if one is configured.
**Returns:** `string`
To override the default output, pass an `instructions` option to [LocalFilesystem](https://mastra.ai/reference/workspace/local-filesystem) or [LocalSandbox](https://mastra.ai/reference/workspace/local-sandbox).
#### `getToolsConfig()`
Get the current tools configuration.
```typescript
const config = workspace.getToolsConfig()
```
**Returns:** `WorkspaceToolsConfig | undefined`
#### `setToolsConfig(config?)`
Replace the per-tool configuration at runtime. This performs a full replacement — it doesn't merge with the previous config. Pass `undefined` to reset to defaults. Changes take effect on the next agent interaction (the next `createWorkspaceTools()` call).
```typescript
import { WORKSPACE_TOOLS } from '@mastra/core/workspace'
// Disable write tools for read-only mode
workspace.setToolsConfig({
[WORKSPACE_TOOLS.FILESYSTEM.WRITE_FILE]: { enabled: false },
[WORKSPACE_TOOLS.FILESYSTEM.EDIT_FILE]: { enabled: false },
})
// Reset to defaults
workspace.setToolsConfig(undefined)
```
**Parameters:**
**config** (`WorkspaceToolsConfig | undefined`): New tool configuration to apply. Pass undefined to reset to defaults.
### Dynamic filesystem
#### `hasFilesystemConfig()`
Check whether a filesystem is configured, either as a static instance or a resolver function. Use this instead of checking `workspace.filesystem` directly, because a resolver-based workspace returns `undefined` from the `filesystem` property.
```typescript
if (workspace.hasFilesystemConfig()) {
// Filesystem tools are available
}
```
**Returns:** `boolean`
#### `resolveFilesystem({ requestContext })`
Resolve the filesystem for a given request context. When a resolver function is configured, calls it with the provided `requestContext`. When a static filesystem is configured, returns it directly. Returns `undefined` if no filesystem is configured.
```typescript
import { RequestContext } from '@mastra/core/request-context'
const ctx = new RequestContext([['agent-role', 'admin']])
const fs = await workspace.resolveFilesystem({ requestContext: ctx })
```
**Parameters:**
**requestContext** (`RequestContext`): The request context to pass to the resolver function.
**Returns:** `Promise<WorkspaceFilesystem | undefined>`
## Agent tools
A workspace provides tools to agents based on what's configured.
### Filesystem tools
Added when a filesystem is configured:
| Tool | Description |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mastra_workspace_read_file` | Read file contents. Text files return as text (with optional line range). Images and PDFs return as native media parts the model can view directly. Other binaries return metadata only unless an explicit `encoding` is passed. |
| `mastra_workspace_write_file` | Create or overwrite a file with new content. Creates parent directories automatically. |
| `mastra_workspace_edit_file` | Edit an existing file by finding and replacing text. Useful for targeted changes without rewriting the entire file. |
| `mastra_workspace_list_files` | List directory contents as a tree structure. Supports recursive listing with depth limits, glob patterns, and `.gitignore` filtering (enabled by default). |
| `mastra_workspace_delete` | Delete a file or directory. Supports recursive deletion for directories. |
| `mastra_workspace_file_stat` | Get metadata about a file or directory including size, type, and modification time. |
| `mastra_workspace_mkdir` | Create a directory. Creates parent directories automatically if they don't exist. |
| `mastra_workspace_grep` | Search file contents using regex patterns. Supports glob filtering, context lines, and case-insensitive search. |
With a static filesystem, write tools (`write_file`, `edit_file`, `delete`, `mkdir`) are excluded when the filesystem is in read-only mode. With a [dynamic filesystem](https://mastra.ai/docs/workspace/filesystem), write tools are always included and read-only is enforced at runtime.
The `read_file` tool accepts `mediaTypes` and `maxMediaBytes` options to control which mime types are surfaced to the model as native media parts and how large those files can be:
**mediaTypes** (`string[] | ((mimeType: string) => boolean) | false`): Which mime types to surface to the model as media parts (file/image parts) rather than as text. Accepts an array of globs (e.g. \`\['image/\*']\`), a custom predicate function, or \`false\` to disable media detection. Defaults to the cross-provider-safe intersection of image formats plus PDF. Only applies when the caller doesn't pass an explicit \`encoding\`. (Default: `['image/png', 'image/jpeg', 'image/webp', 'application/pdf']`)
**maxMediaBytes** (`number`): Maximum file size (in bytes) to inline as a media part. Files larger than this fall back to metadata-only output rather than being fully base64-encoded into context and persisted in storage on rehydration. (Default: `10 * 1024 * 1024 (10 MiB)`)
```typescript
const workspace = new Workspace({
filesystem: new LocalFilesystem({ basePath: './workspace' }),
tools: {
[WORKSPACE_TOOLS.FILESYSTEM.READ_FILE]: {
// Broaden to any image (including SVG, BMP, HEIC) — may fail on some providers
mediaTypes: ['image/*'],
// Raise the inline-media cap to 25 MiB
maxMediaBytes: 25 * 1024 * 1024,
},
},
})
```
### Sandbox tools
Added when a sandbox is configured:
| Tool | Description |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `mastra_workspace_execute_command` | Execute a shell command. Returns stdout, stderr, and exit code. When the sandbox has a process manager, accepts `background: true` to spawn a long-running process and return a PID. |
| `mastra_workspace_get_process_output` | Get stdout, stderr, and status of a background process by PID. Accepts `tail` to limit output lines and `wait: true` to block until exit. Only available when the sandbox has a process manager. |
| `mastra_workspace_kill_process` | Kill a background process by PID. Returns the last 50 lines of output. Only available when the sandbox has a process manager. |
The `execute_command` tool accepts a `backgroundProcesses` option for lifecycle callbacks on background processes:
**backgroundProcesses** (`BackgroundProcessesConfig`): Configuration for handling background processes. Only applicable if the sandbox supports background execution.
**backgroundProcesses.onStdout** (`(data: string, meta: BackgroundProcessMeta) => void`): Callback for stdout chunks from background processes.
**backgroundProcesses.onStderr** (`(data: string, meta: BackgroundProcessMeta) => void`): Callback for stderr chunks from background processes.
**backgroundProcesses.onExit** (`(meta: BackgroundProcessExitMeta) => void`): Callback when a background process exits. Meta includes pid, exitCode, stdout, and stderr.
**backgroundProcesses.abortSignal** (`AbortSignal | null | false`): Abort signal for background processes. undefined (default) uses the agent's signal. null or false disables abort — processes persist after agent shutdown.
See [Background process callbacks](https://mastra.ai/docs/workspace/sandbox) for usage examples.
### Search tools
Added when BM25 or vector search is configured:
| Tool | Description |
| ------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `mastra_workspace_search` | Search indexed content using keyword (BM25), semantic (vector), or hybrid search. Returns ranked results with scores. |
| `mastra_workspace_index` | Index content for search. Associates content with a path for later retrieval. |
The `index` tool is excluded when the filesystem is in read-only mode.
### Skill tools
Added when skills are configured:
| Tool | Description |
| -------------- | --------------------------------------------------------------------------------------------------------- |
| `skill` | Activate a skill by name or path. Returns the skill's full instructions, references, scripts, and assets. |
| `skill_search` | Search across skill content. Accepts an optional list of skill names to filter and a `topK` parameter. |
| `skill_read` | Read a specific file (reference, script, or asset) from a skill directory. |
When multiple skills share the same name, `list()` returns all of them. `get()` with a name applies tie-breaking (local > managed > external). If two skills share the same name _and_ source type, `get()` throws an error. Pass a skill's full path to `get()` to bypass tie-breaking. See [Same-named skills](https://mastra.ai/docs/workspace/skills) for details.