> Discover all available pages from the documentation index: https://mastra.zisheng.pro/llms.txt # RailwaySandbox 在临时、隔离的 [Railway](https://docs.railway.com/sandboxes) Sandbox 中执行命令。每个 Sandbox 都是通过 Railway TypeScript SDK 按需配置的隔离 Debian Linux VM。支持执行命令并以 streaming 方式传输输出、命令超时、可配置的空闲超时、`ISOLATED`/`PRIVATE` 网络隔离、通过 Railway template builder 使用自定义基础镜像、基于 checkpoint 的恢复、fork 正在运行的 Sandbox,以及按 ID 重新连接到现有 Sandbox。有关接口详情,请参阅 [WorkspaceSandbox 接口](https://mastra.zisheng.pro/reference/workspace/sandbox)。 ## 安装 **npm**: ```bash npm install @mastra/railway ``` **pnpm**: ```bash pnpm add @mastra/railway ``` **Yarn**: ```bash yarn add @mastra/railway ``` **Bun**: ```bash bun add @mastra/railway ``` 可通过以下三种方式之一设置 Railway 凭据。 **Shell 导出**: ```bash export RAILWAY_API_TOKEN=your-api-token export RAILWAY_ENVIRONMENT_ID=your-environment-id ``` **.env 文件**: ```bash RAILWAY_API_TOKEN=your-api-token RAILWAY_ENVIRONMENT_ID=your-environment-id ``` **构造函数**: ```typescript new RailwaySandbox({ token: 'your-api-token', environmentId: 'your-environment-id', }) ``` ## 用法 将 `RailwaySandbox` 添加到 Workspace,并将其分配给 Agent: ```typescript import { Agent } from '@mastra/core/agent' import { Workspace } from '@mastra/core/workspace' import { RailwaySandbox } from '@mastra/railway' const workspace = new Workspace({ sandbox: new RailwaySandbox({ // token + environmentId read from RAILWAY_API_TOKEN / RAILWAY_ENVIRONMENT_ID idleTimeoutMinutes: 30, }), }) const agent = new Agent({ id: 'code-agent', name: 'Code Agent', instructions: 'You are a coding assistant working in this workspace.', model: 'anthropic/claude-sonnet-4-6', workspace, }) const response = await agent.generate( 'Print "Hello, world!" and show the current working directory.', ) console.log(response.text) ``` ### 私有网络 加入环境的私有网络,以访问其他 Railway 服务(例如 `postgres.railway.internal`): ```typescript const workspace = new Workspace({ sandbox: new RailwaySandbox({ networkIsolation: 'PRIVATE', env: { NODE_ENV: 'production' }, }), }) ``` 默认的 `ISOLATED` 模式仅允许访问外部互联网,不允许连接私有网络。 ### 自定义基础镜像(template) 预先安装软件包并运行设置步骤,让每个 Sandbox 启动后即可使用。传入 Railway template builder 的 builder 回调;template 会在首次调用 `start()` 时构建一次: ```typescript const workspace = new Workspace({ sandbox: new RailwaySandbox({ template: t => t.withPackages('git', 'curl').run('npm i -g pnpm').workdir('/app'), }), }) ``` 也可以传入预先构建的 `SandboxTemplate`,在多个 Sandbox 之间复用而无需重新构建。设置 `sandboxId` 时会忽略 template,因为重新连接会使用现有 Sandbox 的文件系统。 ### Fork 正在运行的 Sandbox 将正在运行的 Sandbox 文件系统克隆到新的独立 Sandbox 中。这会执行全新启动,不会克隆正在运行的进程。返回的 `RailwaySandbox` 已经启动: ```typescript const child = await sandbox.fork({ idleTimeoutMinutes: 15 }) const result = await child.executeCommand('cat', ['/app/state.json']) console.log(result.stdout) ``` 除非通过 `fork()` 选项覆盖,否则 fork 后的 Sandbox 会继承父级的凭据和默认值。 ### Checkpoint 恢复 设置 `checkpointName`,可在 Railway Sandbox 被替换后保留其文件系统。调用 `start()` 时,`RailwaySandbox` 会首先尝试从 checkpoint 创建 Sandbox。如果 checkpoint 不存在,则会根据配置的 template 或默认镜像创建 Sandbox,然后捕获 checkpoint。 ```typescript const sandbox = new RailwaySandbox({ checkpointName: 'project-session-42', idleTimeoutMinutes: 30, }) ``` `RailwaySandbox` 会在空闲超时前不久刷新 checkpoint。恢复时会还原最近一次成功的 checkpoint,但不会还原正在运行的进程,也不会还原上次 checkpoint 后写入文件系统的内容。 请为每个独立文件系统使用一个稳定的 checkpoint 名称。不要在不相关的 Session 或项目之间共享 checkpoint 名称。 ### 克隆后的 Sandbox checkpoint 当已配置的 `RailwaySandbox` 作为 Sandbox 集群的 template 时,请使用 `clone({ checkpointName })`: ```typescript const template = new RailwaySandbox({ idleTimeoutMinutes: 30 }) const sessionSandbox = template.clone({ id: 'session-42', checkpointName: 'project-session-42', }) await sessionSandbox.start() ``` 克隆后的 Sandbox 使用传给 `clone()` 的 checkpoint。如果未传入覆盖值,则继承 template Sandbox 的 `checkpointName`。 ### Streaming 输出 通过 `onStdout` 和 `onStderr` 回调实时以 streaming 方式传输命令输出: ```typescript await sandbox.executeCommand('bash', ['-c', 'for i in 1 2 3; do echo "line $i"; sleep 1; done'], { onStdout: chunk => process.stdout.write(chunk), onStderr: chunk => process.stderr.write(chunk), }) ``` 两个回调均为可选,并且可以单独使用。 ### 重新连接到现有 Sandbox Railway Sandbox 的生命周期可以超过创建它的进程。通过 Railway ID 重新连接,而无需配置新的 Sandbox: ```typescript const sandbox = new RailwaySandbox({ sandboxId: 'existing-railway-sandbox-id' }) await sandbox._start() const result = await sandbox.executeCommand('cat', ['/tmp/state.txt']) ``` ## 构造函数参数 **id** (`string`): 此 Sandbox 实例的唯一标识符。 (Default: `自动生成`) **token** (`string`): 用于身份验证的 Railway API token。未提供时使用 RAILWAY\_API\_TOKEN 环境变量。 **environmentId** (`string`): Railway 环境 ID。未提供时使用 RAILWAY\_ENVIRONMENT\_ID 环境变量。 **sandboxId** (`string`): 按 Railway ID 重新连接到现有 Railway Sandbox,而不是创建新 Sandbox。设置后,start() 会调用 Sandbox.connect()。 **checkpointName** (`string`): 命名的 Railway checkpoint,用于初始化新 Sandbox,并在因空闲而拆除前保留文件系统。请为每个独立文件系统使用唯一且稳定的名称。 **idleTimeoutMinutes** (`number`): Railway 自动销毁 Sandbox 前,Sandbox 可保持空闲(无 exec 交互)的时长。有效范围和默认值取决于你的 Railway 套餐。 **networkIsolation** (`'ISOLATED' | 'PRIVATE'`): 网络访问模式。'ISOLATED' 仅允许访问外部互联网;'PRIVATE' 会加入环境的私有网络。 (Default: `'ISOLATED'`) **env** (`Record`): 写入 Sandbox 并可供每个命令使用的环境变量。 (Default: `{}`) **template** (`SandboxTemplate | (base: SandboxTemplate) => SandboxTemplate`): 使用 Railway template builder 构建的自定义基础镜像来配置 Sandbox。接受 builder 回调或预先构建的 template。设置 sandboxId 时会忽略。 **timeout** (`number`): 应用于未指定自身超时时间的命令的默认执行超时时间(以毫秒为单位)。省略时,命令会一直运行到退出。 **instructions** (`string | (opts) => string`): 覆盖默认 Agent instructions。字符串会将其完全替换;函数会接收默认 instructions 并返回最终文本。 ## 属性 **id** (`string`): Sandbox 实例标识符。 **name** (`string`): Provider 名称('RailwaySandbox')。 **provider** (`string`): Provider 标识符('railway')。 **status** (`ProviderStatus`): 'pending' | 'initializing' | 'ready' | 'stopped' | 'destroyed' | 'error' **railway** (`Sandbox`): 用于直接访问 SDK 的底层 Railway Sandbox 实例。如果 Sandbox 尚未启动,则抛出 SandboxNotReadyError。 **processes** (`RailwayProcessManager`): 后台进程管理器。请参阅 SandboxProcessManager 参考。 ## 方法 **fork** (`(options?) => Promise`): 将此正在运行的 Sandbox 克隆到新的独立 RailwaySandbox。返回的 Sandbox 已启动,并已重新连接到 fork 后的 Railway Sandbox。接受可选的 id、idleTimeoutMinutes、networkIsolation 和 env 覆盖值。如果此 Sandbox 尚未启动,则抛出 SandboxNotReadyError。 **clone** (`(options?) => RailwaySandbox`): 构造一个尚未启动、继承凭据和默认值的同级 Sandbox。接受可选的 id、sandboxId、env、idleTimeoutMinutes 和 checkpointName 覆盖值。设置 options.checkpointName 时,克隆后的 Sandbox 使用该值,否则继承 template 的 checkpointName。 ## 后台进程 `RailwaySandbox` 内置了用于生成和管理后台进程的进程管理器。每个生成的进程都作为一个 Railway `exec` Session 运行。 ```typescript const sandbox = new RailwaySandbox() await sandbox.start() // Spawn a background process const handle = await sandbox.processes.spawn('node server.js', { env: { PORT: '3000' }, onStdout: data => console.log(data), }) // Interact with the process console.log(handle.stdout) await handle.kill() ``` Railway 的 `exec` API 不支持 streaming stdin,因此不支持 `sendStdin()`。 有关完整 API,请参阅 [`SandboxProcessManager` 参考](https://mastra.zisheng.pro/reference/workspace/process-manager)。 ## Editor Provider 在 `MastraEditor` 中注册该 Provider,可将已存储的 Sandbox 配置还原为运行时实例: ```typescript import { railwaySandboxProvider } from '@mastra/railway' const editor = new MastraEditor({ sandboxes: { [railwaySandboxProvider.id]: railwaySandboxProvider }, }) ``` 有关注册自定义 Sandbox Provider 的详情,请参阅 [Sandbox Provider 参考](https://mastra.zisheng.pro/reference/editor/sandbox-provider)。