Aller au contenu principal

Sandbox

Ajouté dans : @mastra/core@1.1.0

Les Providers de Sandbox permettent aux Agents d’exécuter des commandes shell. Lorsque vous configurez un Sandbox dans un Workspace, les Agents peuvent exécuter des commandes dans le cadre de leurs tâches.

Un Provider de Sandbox exécute les commandes dans un environnement contrôlé :

  • Exécution de commandes : exécute des commandes shell avec des arguments
  • Processus en arrière-plan : lance des processus de longue durée, comme des serveurs de développement et des observateurs de fichiers
  • Répertoire de travail : exécute les commandes depuis un répertoire précis
  • Variables d’environnement : contrôle les variables disponibles
  • Délais d’expiration : empêche les commandes longues de rester bloquées
  • Isolation : propose une isolation facultative au niveau du système d’exploitation pour renforcer la sécurité
📹 À regarder

Regardez la présentation des Sandboxes distants de Mastra pour découvrir comment ils fournissent aux Agents un ordinateur isolé dans lequel travailler.

Providers pris en charge
Lien direct vers Providers pris en charge

  • LocalSandbox : exécute les commandes sur la machine locale
  • AgentCoreRuntimeSandbox : exécute les commandes dans des sessions AWS Bedrock AgentCore Runtime
  • AppleContainerSandbox : exécute les commandes dans des conteneurs Linux OCI locaux au moyen de la CLI container d’Apple
  • BlaxelSandbox : exécute les commandes dans des Sandboxes cloud Blaxel isolés
  • DaytonaSandbox : exécute les commandes dans des Sandboxes cloud Daytona isolés
  • DockerSandbox : exécute les commandes dans des conteneurs Docker de longue durée sur la machine locale
  • E2BSandbox : exécute les commandes dans des Sandboxes cloud E2B isolés
  • ModalSandbox : exécute les commandes dans des Sandboxes cloud Modal isolés
  • PlatformSandbox : exécute les commandes dans un Sandbox associé à un environnement de la plateforme Mastra
  • RailwaySandbox : exécute les commandes dans des Sandboxes cloud Railway isolés et éphémères
  • VercelSandbox : exécute les commandes dans une microVM Firecracker Vercel Sandbox éphémère
  • VercelServerlessSandbox : exécute les commandes sous forme de fonctions serverless Vercel sans état

Utilisation de base
Lien direct vers Utilisation de base

Créez un Workspace doté d’un Sandbox et attribuez-le à un Agent. Celui-ci peut alors exécuter des commandes shell :

src/mastra/agents/dev-agent.ts
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace'

const workspace = new Workspace({
filesystem: new LocalFilesystem({
basePath: './workspace',
}),
sandbox: new LocalSandbox({
workingDirectory: './workspace',
}),
})

const agent = new Agent({
id: 'dev-agent',
model: 'openai/gpt-5.6-sol',
instructions: 'You are a helpful development assistant.',
workspace,
})

// The agent now has the execute_command tool available
const response = await agent.generate('Run `ls -la` in the workspace directory')

Consultez la référence de LocalSandbox pour découvrir les options de configuration, notamment l’isolation de l’environnement et le Sandbox natif du système d’exploitation.

Sandbox dynamique
Lien direct vers Sandbox dynamique

L’option sandbox accepte une fonction de résolution à la place d’une instance statique. Cette fonction reçoit requestContext et renvoie un Sandbox pour chaque requête. Un même Workspace peut ainsi fournir différents Sandboxes selon l’identité, le rôle ou le locataire de l’appelant.

src/mastra/workspaces.ts
import { Agent } from '@mastra/core/agent'
import { Workspace, LocalSandbox } from '@mastra/core/workspace'

const workspace = new Workspace({
sandbox: ({ requestContext }) => {
const userId = requestContext.get('user-id') as string
return new LocalSandbox({
workingDirectory: `/workspaces/${userId}`,
})
},
})

const agent = new Agent({
id: 'multi-tenant-agent',
model: 'your-provider/your-model',
workspace,
})

Chaque requête résout son propre Sandbox au moment de l’exécution du Tool :

import { RequestContext } from '@mastra/core/request-context'

// User Alice — commands run in /workspaces/alice
const aliceCtx = new RequestContext([['user-id', 'alice']])
await agent.generate('List files in cwd', { requestContext: aliceCtx })

// User Bob — commands run in /workspaces/bob
const bobCtx = new RequestContext([['user-id', 'bob']])
await agent.generate('List files in cwd', { requestContext: bobCtx })

Par défaut, les instructions du Workspace décrivent le Sandbox d’exécution à l’aide d’un texte indicatif stable. Consultez la section Instructions du Workspace pour inclure des informations concrètes propres à chaque requête.

La fonction de résolution peut également être asynchrone, par exemple pour rechercher la configuration d’un locataire dans une base de données :

const workspace = new Workspace({
sandbox: async ({ requestContext }) => {
const tenant = await db.getTenant(requestContext.get('tenant-id'))
return new LocalSandbox({ workingDirectory: tenant.workspacePath })
},
})

Responsabilité du cycle de vie
Lien direct vers Responsabilité du cycle de vie

Lorsque le Sandbox est une instance statique, workspace.init() appelle sa méthode start() et workspace.destroy() appelle sa méthode destroy(). Avec une fonction de résolution, le Workspace ne possède aucune instance à gérer lors de sa construction : l’appelant est responsable du cycle de vie du Sandbox renvoyé.

La fonction de résolution doit renvoyer un Sandbox prêt à l’emploi, soit déjà démarré, soit capable de traiter des appels sans démarrage explicite. L’appelant est également responsable du moment où les Sandboxes renvoyés sont nettoyés.

Le nettoyage peut être effectué par requête, locataire ou utilisateur. Il peut également s’inscrire dans un pool de Sandboxes de longue durée. workspace.destroy() ne détruit pas les Sandboxes renvoyés par la fonction de résolution.

remarque

Les fonctions de résolution de sandbox sont incompatibles avec mounts et lsp: true. Ces deux options nécessitent une instance concrète de Sandbox lors de la construction. Les combiner avec une fonction de résolution lève donc une erreur INVALID_CONFIG pour mounts, ou désactive LSP en affichant un avertissement pour lsp: true.

Enregistrement des Tools
Lien direct vers Enregistrement des Tools

Avec un Sandbox statique, le Workspace examine l’instance pour déterminer les Tools à enregistrer. Avec une fonction de résolution, le Workspace suppose que toutes les fonctionnalités sont disponibles et enregistre execute_command (avec la prise en charge de background), get_process_output et kill_process. Si le Sandbox résolu n’implémente pas une fonctionnalité, l’environnement d’exécution lève une erreur SandboxFeatureNotSupportedError explicite.

Continuité des processus en arrière-plan
Lien direct vers Continuité des processus en arrière-plan

Les processus en arrière-plan peuvent survivre à un seul appel de Tool. get_process_output et kill_process doivent donc atteindre le même Sandbox que celui qui a démarré le processus. Par défaut, un Sandbox résolu est mis en cache pour chaque requête. Pour assurer la continuité entre les requêtes de suivi, par exemple lors d’un tour ultérieur de la conversation, définissez sandboxCacheKey sur un identifiant stable. Le Sandbox résolu est alors mis en cache selon cette clé plutôt que selon la requête :

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
sandboxCacheKey: ({ requestContext }) => requestContext.get('thread-id') as string,
})

Sans sandboxCacheKey, la fonction de résolution doit elle-même renvoyer le même Sandbox pour les appels de suivi qui partagent un locataire, un utilisateur ou une session.

Lorsqu’un Sandbox mis en cache n’est plus nécessaire, détruisez-le dans votre propre code de gestion du cycle de vie, puis appelez workspace.clearSandboxCache(cacheKey) pour supprimer l’entrée du cache du Workspace. Appelez workspace.clearSandboxCache() pour supprimer toutes les entrées de Sandbox indexées par une clé.

Instructions du Workspace
Lien direct vers Instructions du Workspace

Les instructions du Workspace décrivent l’environnement dans le message système de l’Agent. Avec une fonction de résolution de Sandbox, le Workspace n’appelle pas cette fonction pour construire les instructions. Il émet un texte indicatif stable : la construction du prompt ne provisionne donc jamais un Sandbox appartenant à l’appelant, et le message système reste cohérent entre les requêtes, ce qui préserve l’efficacité du cache des prompts.

Pour inclure des informations concrètes sur le Sandbox propres à chaque requête, définissez instructions.dynamicSandbox sur 'resolve' :

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: { dynamicSandbox: 'resolve' },
})

'resolve' appelle la fonction de résolution à chaque requête, ce qui peut provisionner le Sandbox et rend le message système propre à la requête. Vous pouvez plutôt transmettre une fonction afin de renvoyer un texte personnalisé à partir de requestContext sans résoudre le Sandbox :

const workspace = new Workspace({
sandbox: ({ requestContext }) => resolveSandbox(requestContext),
instructions: {
dynamicSandbox: ({ requestContext }) =>
`Sandbox scoped to tenant ${requestContext.get('tenant-id')}.`,
},
})

Tools des Agents
Lien direct vers Tools des Agents

Lorsque vous configurez un Sandbox dans un Workspace, les Agents reçoivent le Tool execute_command pour exécuter des commandes shell.

Si votre Provider de Sandbox prend en charge l’exécution de processus en arrière-plan, le Tool execute_command accepte également background: true pour démarrer des processus de longue durée, et deux Tools supplémentaires sont enregistrés :

ToolDescription
execute_commandExécute une commande shell. Renvoie stdout, stderr et le code de sortie. Prend en charge background: true pour lancer un processus de longue durée et renvoyer un PID.
get_process_outputRécupère stdout, stderr et l’état d’un processus en arrière-plan à partir de son PID. Prend en charge tail pour limiter le nombre de lignes renvoyées et wait: true pour bloquer jusqu’à la fin du processus.
kill_processArrête un processus en arrière-plan à partir de son PID. Renvoie la sortie récente.

Ces Tools sont enregistrés automatiquement. Consultez la référence de la classe Workspace pour obtenir la liste complète de leurs noms.

Callbacks des processus en arrière-plan
Lien direct vers Callbacks des processus en arrière-plan

Lorsque des Agents démarrent des processus en arrière-plan au moyen du Tool execute_command, vous pouvez recevoir des callbacks de cycle de vie pour stdout, stderr et la fin du processus. Configurez-les au moyen de l’option backgroundProcesses du Tool execute_command :

src/mastra/workspaces.ts
import { Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'

const workspace = new Workspace({
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
backgroundProcesses: {
onStdout: (data, { pid }) => console.log(`[${pid}] ${data}`),
onStderr: (data, { pid }) => console.error(`[${pid}] ${data}`),
onExit: ({ pid, exitCode }) => console.log(`Process ${pid} exited: ${exitCode}`),
},
},
},
})

Ces callbacks sont déclenchés pour tous les processus en arrière-plan démarrés par l’Agent au moyen du Tool execute_command.

Signal d’abandon
Lien direct vers Signal d’abandon

Par défaut, les processus en arrière-plan héritent du signal d’abandon de l’Agent et sont arrêtés lorsque celui-ci se déconnecte. Contrôlez ce comportement avec l’option abortSignal :

  • undefined (par défaut) : utilise le signal d’abandon de l’Agent
  • AbortSignal : utilise un signal personnalisé
  • null ou false : désactive l’abandon ; les processus persistent après l’arrêt de l’Agent
src/mastra/workspaces.ts
import { Workspace, LocalSandbox, WORKSPACE_TOOLS } from '@mastra/core/workspace'

const workspace = new Workspace({
sandbox: new LocalSandbox({ workingDirectory: './workspace' }),
tools: {
[WORKSPACE_TOOLS.SANDBOX.EXECUTE_COMMAND]: {
backgroundProcesses: {
abortSignal: null, // Processes survive agent disconnection
},
},
},
})

Utilisez null ou false pour les Sandboxes cloud, par exemple E2B, Daytona ou Modal, dans lesquels les processus doivent survivre à l’Agent.

remarque

Pour découvrir l’API complète de SandboxProcessManager, notamment le lancement programmatique de processus, la lecture de leur sortie et l’envoi de données à stdin, consultez la référence de SandboxProcessManager.