Aller au contenu principal

RailwaySandbox

Exécute des commandes dans des Sandboxes Railway isolées et éphémères. Chaque Sandbox est une VM Debian Linux isolée, provisionnée à la demande au moyen du SDK TypeScript de Railway. Prend en charge l'exécution de commandes avec sortie en streaming, les délais d'expiration des commandes, un délai d'inactivité configurable, l'isolation réseau ISOLATED/PRIVATE, les images de base personnalisées au moyen du Template Builder de Railway, la récupération reposant sur des checkpoints, le fork d'une Sandbox en cours d'exécution et la reconnexion à une Sandbox existante à partir de son identifiant. Pour plus de détails sur l'interface, consultez l'interface WorkspaceSandbox.

Installation
Lien direct vers Installation

npm install @mastra/railway

Définissez vos identifiants Railway de l'une des trois manières suivantes.

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

Utilisation
Lien direct vers Utilisation

Ajoutez une RailwaySandbox à un Workspace et attribuez-la à un 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)

Réseau privé
Lien direct vers Réseau privé

Rejoignez le réseau privé de l'environnement pour accéder à d'autres services Railway (par exemple postgres.railway.internal) :

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

Le mode ISOLATED par défaut autorise uniquement l'accès sortant à Internet, sans connectivité au réseau privé.

Image de base personnalisée (templates)
Lien direct vers Image de base personnalisée (templates)

Préinstallez des packages et exécutez les étapes de configuration afin que chaque Sandbox soit prête au démarrage. Transmettez un callback de Builder au Template Builder de Railway : le template est construit une seule fois lors du premier appel à start() :

const workspace = new Workspace({
sandbox: new RailwaySandbox({
template: t => t.withPackages('git', 'curl').run('npm i -g pnpm').workdir('/app'),
}),
})

Vous pouvez également transmettre un SandboxTemplate préconstruit afin de le réutiliser dans plusieurs Sandboxes sans le reconstruire. Les templates sont ignorés lorsque sandboxId est défini, car la reconnexion utilise le système de fichiers de la Sandbox existante.

Fork d'une Sandbox en cours d'exécution
Lien direct vers Fork d'une Sandbox en cours d'exécution

Clonez le système de fichiers d'une Sandbox en cours d'exécution dans une nouvelle Sandbox indépendante : il s'agit d'un nouveau démarrage, sans les processus actifs. La RailwaySandbox renvoyée est déjà démarrée :

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

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

La Sandbox forkée hérite des identifiants et des valeurs par défaut de son parent, sauf remplacement au moyen des options de fork().

Récupération par checkpoint
Lien direct vers Récupération par checkpoint

Définissez checkpointName afin de préserver le système de fichiers d'une Sandbox lors de son remplacement par Railway. Pendant start(), RailwaySandbox tente d'abord de créer la Sandbox à partir du checkpoint. Si celui-ci est absent, elle crée une Sandbox depuis le template configuré ou l'image par défaut, puis capture le checkpoint.

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

RailwaySandbox actualise le checkpoint peu avant le délai d'inactivité. La récupération restaure le dernier checkpoint réussi. Elle ne restaure ni les processus en cours, ni les écritures du système de fichiers effectuées après le dernier checkpoint.

Utilisez un nom de checkpoint stable pour chaque système de fichiers indépendant. Ne partagez pas un nom de checkpoint entre des sessions ou des projets sans rapport.

Checkpoints des Sandboxes clonées
Lien direct vers Checkpoints des Sandboxes clonées

Utilisez clone({ checkpointName }) lorsqu'une RailwaySandbox configurée sert de template à une flotte de Sandboxes :

const template = new RailwaySandbox({ idleTimeoutMinutes: 30 })

const sessionSandbox = template.clone({
id: 'session-42',
checkpointName: 'project-session-42',
})

await sessionSandbox.start()

Une Sandbox clonée utilise le checkpoint transmis à clone(). Si aucun remplacement n'est transmis, elle hérite du checkpointName de la Sandbox template.

Sortie en streaming
Lien direct vers Sortie en streaming

Diffusez la sortie des commandes en temps réel au moyen des callbacks onStdout et onStderr :

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),
})

Les deux callbacks sont facultatifs et peuvent être utilisés indépendamment.

Reconnexion à une Sandbox existante
Lien direct vers Reconnexion à une Sandbox existante

Une Sandbox Railway survit au processus qui l'a créée. Reconnectez-vous au moyen de son identifiant Railway au lieu d'en provisionner une nouvelle :

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

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

Paramètres du constructeur
Lien direct vers Paramètres du constructeur

id?:

string
= Généré automatiquement
Identifiant unique de cette instance de Sandbox.

token?:

string
Token d'API Railway pour l'authentification. Utilise par défaut la variable d'environnement RAILWAY_API_TOKEN.

environmentId?:

string
Identifiant de l'environnement Railway. Utilise par défaut la variable d'environnement RAILWAY_ENVIRONMENT_ID.

sandboxId?:

string
Se reconnecte à une Sandbox Railway existante au moyen de son identifiant Railway au lieu d'en créer une nouvelle. Lorsque cette option est définie, start() appelle Sandbox.connect().

checkpointName?:

string
Checkpoint Railway nommé utilisé pour initialiser de nouvelles Sandboxes et préserver le système de fichiers avant sa destruction pour inactivité. Utilisez un nom unique et stable pour chaque système de fichiers indépendant.

idleTimeoutMinutes?:

number
Durée pendant laquelle la Sandbox peut rester inactive (sans interaction exec) avant que Railway ne la détruise automatiquement. La plage valide et la valeur par défaut dépendent de votre forfait Railway.

networkIsolation?:

'ISOLATED' | 'PRIVATE'
= 'ISOLATED'
Mode d'accès au réseau. 'ISOLATED' autorise uniquement l'accès sortant à Internet ; 'PRIVATE' rejoint le réseau privé de l'environnement.

env?:

Record<string, string>
= {}
Variables d'environnement intégrées à la Sandbox et disponibles pour chaque commande.

template?:

SandboxTemplate | (base: SandboxTemplate) => SandboxTemplate
Provisionne la Sandbox depuis une image de base personnalisée construite avec le Template Builder de Railway. Accepte un callback de Builder ou un template préconstruit. Ignoré lorsque sandboxId est défini.

timeout?:

number
Délai d'expiration par défaut de l'exécution, en millisecondes, appliqué aux commandes qui ne précisent pas leur propre délai. Lorsqu'il est omis, les commandes s'exécutent jusqu'à leur arrêt.

instructions?:

string | (opts) => string
Remplace les instructions par défaut de l'Agent. Une chaîne les remplace entièrement ; une fonction reçoit les instructions par défaut et renvoie le texte final.

Propriétés
Lien direct vers Propriétés

id:

string
Identifiant de l'instance de Sandbox.

name:

string
Nom du Provider ('RailwaySandbox').

provider:

string
Identifiant du Provider ('railway').

status:

ProviderStatus
'pending' | 'initializing' | 'ready' | 'stopped' | 'destroyed' | 'error'

railway:

Sandbox
Instance Railway Sandbox sous-jacente pour un accès direct au SDK. Lève SandboxNotReadyError si la Sandbox n'a pas été démarrée.

processes:

RailwayProcessManager
Gestionnaire de processus en arrière-plan. Consultez la référence de SandboxProcessManager.

Méthodes
Lien direct vers Méthodes

fork:

(options?) => Promise<RailwaySandbox>
Clone cette Sandbox en cours d'exécution dans une nouvelle RailwaySandbox indépendante. La Sandbox renvoyée est déjà démarrée et reconnectée à la Sandbox Railway forkée. Accepte des remplacements facultatifs pour id, idleTimeoutMinutes, networkIsolation et env. Lève SandboxNotReadyError si cette Sandbox n'a pas été démarrée.

clone:

(options?) => RailwaySandbox
Construit une Sandbox sœur non démarrée qui hérite des identifiants et des valeurs par défaut. Accepte des remplacements facultatifs pour id, sandboxId, env, idleTimeoutMinutes et checkpointName. La Sandbox clonée utilise options.checkpointName lorsqu'il est défini ; sinon, elle hérite du checkpointName du template.

Processus en arrière-plan
Lien direct vers Processus en arrière-plan

RailwaySandbox comprend un gestionnaire de processus intégré permettant de lancer et de gérer des processus en arrière-plan. Chaque processus lancé s'exécute sous la forme d'une session 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()

L'API exec de Railway ne diffuse pas stdin ; sendStdin() n'est donc pas pris en charge.

Consultez la référence de SandboxProcessManager pour découvrir l'API complète.

Provider Editor
Lien direct vers Provider Editor

Enregistrez le Provider auprès de MastraEditor afin de convertir les configurations de Sandbox stockées en instances d'exécution :

import { railwaySandboxProvider } from '@mastra/railway'

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

Consultez la référence des Providers Sandbox pour en savoir plus sur l'enregistrement de Providers Sandbox personnalisés.