跳至主要內容

RailwaySandbox

在暫存且隔離的 Railway Sandbox 中執行指令。每個 Sandbox 都是透過 Railway TypeScript SDK 依需求佈建的隔離 Debian Linux VM。支援串流輸出的指令執行、指令逾時、可設定的閒置逾時、ISOLATED/PRIVATE 網路隔離、透過 Railway template builder 使用自訂基礎映像、由 checkpoint 支援的復原、分叉執行中的 Sandbox,以及透過 ID 重新連接現有 Sandbox。介面詳情請參閱 WorkspaceSandbox 介面

安裝
「安裝」的直接連結

npm install @mastra/railway

使用下列三種方式之一設定 Railway 認證。

export RAILWAY_API_TOKEN=your-api-token
export RAILWAY_ENVIRONMENT_ID=your-environment-id

使用方式
「使用方式」的直接連結

RailwaySandbox 加入 Workspace,並指派給 Agent:

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):

const workspace = new Workspace({
sandbox: new RailwaySandbox({
networkIsolation: 'PRIVATE',
env: { NODE_ENV: 'production' },
}),
})

預設的 ISOLATED 模式僅允許對外網際網路存取,無法連線至私有網路。

自訂基礎映像(template)
「自訂基礎映像(template)」的直接連結

預先安裝 package 並執行設定步驟,讓每個 Sandbox 啟動後即可使用。將 builder 回呼函式傳給 Railway template builder;template 會在首次 start() 時建立一次:

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 的檔案系統。

分叉執行中的 Sandbox
「分叉執行中的 Sandbox」的直接連結

將執行中 Sandbox 的檔案系統複製到新的獨立 Sandbox。這會全新啟動,不會複製執行中的處理程序。回傳的 RailwaySandbox 已啟動:

const child = await sandbox.fork({ idleTimeoutMinutes: 15 })

const result = await child.executeCommand('cat', ['/app/state.json'])
console.log(result.stdout)

除非透過 fork() 選項覆寫,否則分叉的 Sandbox 會繼承父層的憑證與預設值。

Checkpoint 復原
「Checkpoint 復原」的直接連結

設定 checkpointName 可在 Railway Sandbox 更換時保留 Sandbox 檔案系統。呼叫 start() 時,RailwaySandbox 會先嘗試從 checkpoint 建立 Sandbox。如果 checkpoint 不存在,則從已設定的 template 或預設映像建立 Sandbox,然後擷取 checkpoint。

const sandbox = new RailwaySandbox({
checkpointName: 'project-session-42',
idleTimeoutMinutes: 30,
})

RailwaySandbox 會在閒置逾時前不久更新 checkpoint。復原會還原最近成功的 checkpoint,但不會還原執行中的處理程序,也不會還原最後一個 checkpoint 之後進行的檔案系統寫入。

每個獨立檔案系統都應使用各自穩定的 checkpoint 名稱。請勿在不相關的工作階段或專案之間共用 checkpoint 名稱。

複製 Sandbox 的 checkpoint
「複製 Sandbox 的 checkpoint」的直接連結

當已設定的 RailwaySandbox 做為 Sandbox 叢集的 template 時,請使用 clone({ checkpointName })

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

串流輸出
「串流輸出」的直接連結

透過 onStdoutonStderr 回呼函式即時串流傳輸指令輸出:

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
「重新連接現有 Sandbox」的直接連結

Railway Sandbox 的存續時間比建立它的處理程序更長。可使用其 Railway ID 重新連接,而不是佈建新 Sandbox:

const sandbox = new RailwaySandbox({ sandboxId: 'existing-railway-sandbox-id' })
await sandbox._start()

const result = await sandbox.executeCommand('cat', ['/tmp/state.txt'])

建構函式參數
「建構函式參數」的直接連結

id?:

string
= 自動產生
此 Sandbox 執行個體的唯一識別碼。

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
Sandbox 可保持閒置(沒有 exec 互動)的時間,超過後 Railway 會自動銷毀。有效範圍與預設值取決於你的 Railway 方案。

networkIsolation?:

'ISOLATED' | 'PRIVATE'
= 'ISOLATED'
網路存取模式。'ISOLATED' 僅允許對外網際網路存取;'PRIVATE' 會加入該環境的私有網路。

env?:

Record<string, string>
= {}
寫入 Sandbox 且所有指令均可使用的環境變數。

template?:

SandboxTemplate | (base: SandboxTemplate) => SandboxTemplate
從使用 Railway template builder 建立的自訂基礎映像佈建 Sandbox。可接受 builder 回呼函式或預先建立的 template。設定 sandboxId 時會忽略此選項。

timeout?:

number
以毫秒為單位的預設執行逾時,套用於未指定自身逾時的指令。省略時,指令會一直執行到結束為止。

instructions?:

string | (opts) => string
覆寫預設 Agent 指示。字串會完全取代預設指示;函式會接收預設指示並回傳最終文字。

屬性
「屬性」的直接連結

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<RailwaySandbox>
將此執行中 Sandbox 複製成新的獨立 RailwaySandbox。回傳的 Sandbox 已啟動,並重新連接到分叉的 Railway Sandbox。接受選用的 id、idleTimeoutMinutes、networkIsolation 與 env 覆寫值。如果此 Sandbox 尚未啟動,則拋出 SandboxNotReadyError。

clone:

(options?) => RailwaySandbox
建立尚未啟動且繼承憑證與預設值的同層 Sandbox。接受選用的 id、sandboxId、env、idleTimeoutMinutes 與 checkpointName 覆寫值。設定時,複製的 Sandbox 會使用 options.checkpointName;否則會繼承 template checkpointName。

背景處理程序
「背景處理程序」的直接連結

RailwaySandbox 內建處理程序管理器,可產生及管理背景處理程序。每個產生的處理程序都以 Railway exec 工作階段執行。

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 不會串流傳輸 stdin,因此不支援 sendStdin()

完整 API 請參閱 SandboxProcessManager 參考

Editor Provider
「Editor Provider」的直接連結

MastraEditor 中註冊 Provider,將儲存的 Sandbox 設定實體化為執行階段的執行個體:

import { railwaySandboxProvider } from '@mastra/railway'

const editor = new MastraEditor({
sandboxes: { [railwaySandboxProvider.id]: railwaySandboxProvider },
})

如需註冊自訂 Sandbox Provider 的詳細資訊,請參閱 Sandbox Provider 參考