> Discover all available pages from the documentation index: https://mastra.zisheng.pro/zh-HK/llms.txt # SandboxProcessManager **新增於:** `@mastra/core@1.7.0` 用於管理 Sandbox 背景程序的抽象基礎類別。提供產生程序、列出程序、按 PID 取得 handle,以及終止程序的方法。 [`BlaxelSandbox`](https://mastra.zisheng.pro/zh-HK/reference/workspace/blaxel-sandbox)、[`DaytonaSandbox`](https://mastra.zisheng.pro/zh-HK/reference/workspace/daytona-sandbox)、[`E2BSandbox`](https://mastra.zisheng.pro/zh-HK/reference/workspace/e2b-sandbox)、[`ModalSandbox`](https://mastra.zisheng.pro/zh-HK/reference/workspace/modal-sandbox) 及 [`LocalSandbox`](https://mastra.zisheng.pro/zh-HK/reference/workspace/local-sandbox) 均內置程序管理器。除非你正在建立自訂 Sandbox Provider,否則無需直接建立此類別的執行個體。 ## 使用範例 透過 Sandbox 的 `processes` 屬性存取程序管理器: ```typescript import { LocalSandbox } from '@mastra/core/workspace' const sandbox = new LocalSandbox({ workingDirectory: './workspace' }) await sandbox.start() // Spawn a background process const handle = await sandbox.processes.spawn('node server.js', { env: { PORT: '3000' }, onStdout: data => console.log(data), }) // List all tracked processes const procs = await sandbox.processes.list() // Get a handle by PID const proc = await sandbox.processes.get(handle.pid) // Kill a process await sandbox.processes.kill(handle.pid) ``` ## 方法 ### `spawn(command, options?)` 產生背景程序。立即傳回 `ProcessHandle`,而不會等待程序完成。 ```typescript const handle = await sandbox.processes.spawn('npm run dev', { cwd: '/app', env: { NODE_ENV: 'development' }, onStdout: data => console.log(data), }) ``` **參數:** **command** (`string`): 要執行的指令。由 shell 解譯。 **options** (`SpawnProcessOptions`): 所產生程序的選用設定。 **options.timeout** (`number`): 逾時時間,以毫秒為單位。如超出此時間,便會終止程序。 **options.env** (`NodeJS.ProcessEnv`): 程序的環境變數。 **options.cwd** (`string`): 程序的工作目錄。 **options.onStdout** (`(data: string) => void`): stdout 資料區塊的 callback。會在資料抵達時呼叫。 **options.onStderr** (`(data: string) => void`): stderr 資料區塊的 callback。會在資料抵達時呼叫。 **options.abortSignal** (`AbortSignal`): 中止程序的訊號。中止時,程序會被終止。 **傳回:** `Promise` ### `list()` 列出所有追蹤中的程序。傳回每個程序的資料,包括 PID、運行狀態及結束代碼。 ```typescript const procs = await sandbox.processes.list() for (const proc of procs) { console.log(proc.pid, proc.running, proc.exitCode) } ``` **傳回:** `Promise` ### `get(pid)` 按 PID 取得程序的 handle。如果找不到程序或已將其忽略,便傳回 `undefined`。 ```typescript const handle = await sandbox.processes.get(1234) if (handle) { console.log(handle.stdout) await handle.kill() } ``` **傳回:** `Promise` ### `kill(pid)` 按 PID 終止程序。傳回前會等待程序終止。如程序已終止,傳回 `true`;如找不到程序,則傳回 `false`。 ```typescript const killed = await sandbox.processes.kill(handle.pid) ``` **傳回:** `Promise` ## `ProcessInfo` 由 `list()` 傳回的追蹤中程序資料。 **pid** (`number`): 程序 ID。 **command** (`string`): 已執行的指令。 **running** (`boolean`): 程序是否仍在運行。 **exitCode** (`number`): 程序已完成時的結束代碼。 *** ## `ProcessHandle` 已產生背景程序的 handle。提供讀取輸出、傳送 stdin、等待完成及終止程序的方法。 你不會直接建立 `ProcessHandle` 執行個體。這些執行個體由 `spawn()` 及 `get()` 傳回。 ### 使用範例 ```typescript const handle = await sandbox.processes.spawn('npm run dev', { onStdout: data => console.log(data), }) // Read accumulated output console.log(handle.pid) console.log(handle.stdout) console.log(handle.stderr) console.log(handle.exitCode) // undefined while running // Wait for completion const result = await handle.wait() // Send stdin await handle.sendStdin('input data\n') // Kill the process await handle.kill() ``` ### 屬性 **pid** (`number`): 程序 ID。 **stdout** (`string`): 截至目前累積的 stdout 輸出。 **stderr** (`string`): 截至目前累積的 stderr 輸出。 **exitCode** (`number | undefined`): 結束代碼。程序仍在運行時為 undefined。 **command** (`string | undefined`): 已產生程序的指令。由程序管理器自動設定。 **reader** (`Readable`): stdout 的可讀取 stream。適用於透過 stdio 通訊的 LSP 或 JSON-RPC 等協定。 **writer** (`Writable`): 連至 stdin 的可寫入 stream。適用於透過 stdio 通訊的 LSP 或 JSON-RPC 等協定。 ### 方法 #### `wait(options?)` 等待程序結束並傳回結果。你亦可傳入 `onStdout`/`onStderr` callback,在等待期間串流輸出。`wait()` 完成時會自動移除 callback。 ```typescript // Simple wait const result = await handle.wait() console.log(result.success, result.exitCode, result.stdout) // Wait with streaming const result = await handle.wait({ onStdout: data => process.stdout.write(data), onStderr: data => process.stderr.write(data), }) ``` **參數:** **options** (`WaitOptions`): 等待時的選用設定。 **options.onStdout** (`(data: string) => void`): 等待期間 stdout 資料區塊的 callback。 **options.onStderr** (`(data: string) => void`): 等待期間 stderr 資料區塊的 callback。 **傳回:** `Promise` `CommandResult` 物件包含: **success** (`boolean`): 如結束代碼為 0,則為 true。 **exitCode** (`number`): 數字結束代碼。 **stdout** (`string`): 完整 stdout 輸出。 **stderr** (`string`): 完整 stderr 輸出。 **executionTimeMs** (`number`): 執行時間,以毫秒為單位。 **timedOut** (`boolean`): 如程序因逾時而被終止,則為 true。 **killed** (`boolean`): 如程序因訊號而被終止,則為 true。 #### `kill()` 終止程序。如程序已終止,傳回 `true`;如程序早已結束,則傳回 `false`。 ```typescript const killed = await handle.kill() ``` **傳回:** `Promise` #### `sendStdin(data)` 向程序的 stdin 傳送資料。如程序已結束或 stdin 無法使用,便會拋出錯誤。 ```typescript await handle.sendStdin('console.log("hello")\n') ``` **傳回:** `Promise` ## Stream 互通 `ProcessHandle` 提供 `reader` 及 `writer` 屬性,可整合使用 Node.js stream 的協定,例如 LSP 或 JSON-RPC: ```typescript import { createMessageConnection, StreamMessageReader, StreamMessageWriter, } from 'vscode-jsonrpc/node' const handle = await sandbox.processes.spawn('typescript-language-server --stdio') const connection = createMessageConnection( new StreamMessageReader(handle.reader), new StreamMessageWriter(handle.writer), ) connection.listen() ``` ## 建立自訂程序管理器 要為自訂 Sandbox Provider 建立程序管理器,請擴充 `SandboxProcessManager` 並實作 `spawn()` 及 `list()`。基礎類別會自動使用 `ensureRunning()` 包裝你的方法,讓 Sandbox 在任何程序操作前啟動。 ```typescript import { SandboxProcessManager, ProcessHandle } from '@mastra/core/workspace' import type { ProcessInfo, SpawnProcessOptions } from '@mastra/core/workspace' class MyProcessManager extends SandboxProcessManager { async spawn(command: string, options: SpawnProcessOptions = {}): Promise { // Your spawn implementation const handle = new MyProcessHandle(/* ... */) this._tracked.set(handle.pid, handle) return handle } async list(): Promise { return Array.from(this._tracked.values()).map(handle => ({ pid: handle.pid, running: handle.exitCode === undefined, exitCode: handle.exitCode, })) } } ``` 透過 `MastraSandbox` 的 `processes` 選項,將程序管理器傳遞至你的 Sandbox: ```typescript class MySandbox extends MastraSandbox { constructor() { super({ name: 'MySandbox', processes: new MyProcessManager(), }) } } ``` 提供程序管理器後,`MastraSandbox` 會自動建立預設的 `executeCommand` 實作,並使用 `spawn()` + `wait()`,因此無需同時實作兩者。 ## 相關內容 - [Sandbox](https://mastra.zisheng.pro/zh-HK/docs/workspace/sandbox) - [WorkspaceSandbox 介面](https://mastra.zisheng.pro/zh-HK/reference/workspace/sandbox) - [LocalSandbox 參考](https://mastra.zisheng.pro/zh-HK/reference/workspace/local-sandbox) - [E2BSandbox 參考](https://mastra.zisheng.pro/zh-HK/reference/workspace/e2b-sandbox) - [DaytonaSandbox 參考](https://mastra.zisheng.pro/zh-HK/reference/workspace/daytona-sandbox)