ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Mastra Modal 云沙箱详解:用 @mastra/modal 在 Modal 云端运行 Agent Workspace 命令

Mastra Modal 云沙箱详解:用 @mastra/modal 在 Modal 云端运行 Agent Workspace 命令 Mastra Modal 云沙箱详解用 mastra/modal 在 Modal 云端运行 Agent Workspace 命令【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra本篇文章围绕 Mastra 仓库中mastra/modal包workspaces/modal/CHANGELOG.md讲解其完整能力如何在 Mastra Workspace 中接入 Modal 云端沙箱执行隔离命令如何配置工作目录、环境变量、生命周期与进程管理以及clone()模板化批量派生沙箱等高级用法。读完本文你将能够使用ModalSandbox为 AI Agent 搭建一个具备认证、暂停/恢复、后台进程与重连能力的云端执行环境并理解其底层实现与行为边界。一、包概览Modal 云沙箱在 Mastra 中的定位mastra/modal是 Mastra 的 Modal 云端沙箱 provider位于 workspaces/modal 目录。它把 Modal 的隔离 Sandbox 能力封装进 Mastra 的 Workspace 抽象Agent 通过Workspace调用executeCommand()执行 shell 命令时实际命令运行在 Modal 云端而不是本地机器上。从包入口 workspaces/modal/src/index.ts 可以看到它只导出三个符号export { ModalSandbox, type ModalSandboxOptions } from ./sandbox; export { ModalProcessManager } from ./sandbox/process-manager;其中ModalSandbox继承自mastra/core的抽象基类MastraSandbox定义于 packages/core/src/workspace/sandbox/mastra-sandbox.tsModalProcessManager则负责把 Modal 的ContainerProcess适配为 Mastra 统一的ProcessHandle。包声明workspaces/modal/package.json显示其唯一运行时依赖是 Modal 官方 SDKmodal并以mastra/core1.12.0 且 2.0.0为 peer 依赖Node 版本要求 22.13.0。该包自 0.2.0 版本起由 PR #14486 引入核心价值是用一段极简代码把隔离执行环境放到云端且天然支持 pause/resume暂停/恢复、后台进程、流式输出与按 id 重连。二、快速开始安装、认证与首个 Workspace安装npm install mastra/modal认证ModalSandbox使用 Modal 的 token 对tokenIdtokenSecret完成云端认证。有两种提供方式环境变量设置MODAL_TOKEN_ID和MODAL_TOKEN_SECRET构造时不传任何 token 参数即可自动读取构造参数显式传入tokenId/tokenSecret选项。从源码实现看workspaces/modal/src/sandbox/index.ts_getClient()在首次调用时创建ModalClient仅在选项存在时才把 token 传给 SDK因此完全依赖环境变量也是可行的。最小接入示例import { Agent } from mastra/core/agent; import { Workspace } from mastra/core/workspace; import { ModalSandbox } from mastra/modal; const workspace new Workspace({ sandbox: new ModalSandbox({ id: dev-sandbox, baseImage: ubuntu:22.04, timeoutMs: 60_000, }), }); const agent new Agent({ id: developer-agent, name: Developer agent, instructions: Use the workspace to inspect and modify the project., model: openai/gpt-5.6-sol, workspace, });创建 Workspace 后Agent 即可通过内置的workspace_execute_command工具由 packages/core/src/workspace/sandbox/sandbox.ts 中的WorkspaceSandbox.executeCommand支撑在 Modal 云端执行命令。集成测试workspaces/modal/src/sandbox/sandbox.integration.test.ts验证了最核心的行为命令执行返回 stdout/stderr、非零退出码、沙箱级环境变量注入、spawn()流式输出与cwd切换等。ModalSandboxOptions 完整参数表ModalSandboxOptions继承MastraSandboxOptions并扩展了如下字段见 workspaces/modal/src/sandbox/index.ts参数类型默认值说明idstring自动生成modal-sandbox-时间戳-随机沙箱稳定名称。复用同一 id 会重连到已运行的沙箱appNamestringmastra关联的 Modal App 名称baseImagestringubuntu:22.04沙箱使用的 Docker 镜像如python:3.12-slimtimeoutMsnumber300_0005 分钟沙箱墙钟最大存活时间到期即终止Modal 上限为 24 小时86_400_000msenvRecordstring, string{}创建时烘焙进沙箱的环境变量workdirstring无沙箱内默认工作目录。已废弃请用workingDirectory两者同时设置时后者优先tokenId/tokenSecretstring环境变量MODAL_TOKEN_ID/MODAL_TOKEN_SECRETModal 认证凭据instructionsstring \| ((opts) string)默认指令自定义工具描述指令函数形式可基于默认指令加工onStart/onStop/onDestroy生命周期钩子无继承自MastraSandboxOptions见下文“生命周期钩子”workingDirectorystring无命令执行的默认工作目录0.6.0 新增见第三节其中onStart/onStop/onDestroy是MastraSandboxOptions提供的生命周期钩子packages/core/src/workspace/sandbox/mastra-sandbox.tsonStart在沙箱进入running后、挂载处理前触发适合做“每台 VM 只做一次”的初始化且其抛错是致命的start()会 reject 并将沙箱标记为erroronStop/onDestroy则是尽力而为的清理钩子。三、默认工作目录workingDirectory 与别名迁移0.6.0 版本PR #22697为所有沙箱 provider 引入了统一的workingDirectory选项mastra/modal也完整支持。它的语义是实例级的默认命令执行目录。优先级规则单条命令显式传入的cwd总是优先于实例级workingDirectory两者都未提供时回退到 provider 的历史默认值Modal 无显式默认时workdir参数不传递由 Modal 侧决定生效值可通过新增的sandbox.workingDirectorygetter 读取。CHANGELOG 中给出的示例const sandbox new E2BSandbox({ workingDirectory: /home/user/my-repo }); await sandbox.executeCommand(pwd); // /home/user/my-repo await sandbox.executeCommand(pwd, [], { cwd: /tmp }); // /tmp对mastra/modal而言历史遗留的workdir选项被保留为废弃别名两者同源workspaces/modal/src/sandbox/index.tsif (options.workingDirectory undefined options.workdir ! undefined) { this.setWorkingDirectory(options.workdir); }即未传workingDirectory时才用workdir填充两者同时给出时workingDirectory胜出。这一规则在单元测试 workspaces/modal/src/sandbox/sandbox.test.ts 中有明确断言。使用绝对路径workingDirectory的值会原样传给 provider不做~或$HOME之类的展开因此强烈建议使用绝对路径。例外情况是LocalSandbox等明确文档化了路径展开行为的 provider。该约束来自MastraSandboxOptions.workingDirectory的文档说明packages/core/src/workspace/sandbox/mastra-sandbox.ts。workingDirectory不仅作用于命令执行还会作为 Modal 创建沙箱时的workdir参数传入workspaces/modal/src/sandbox/index.ts并作为spawn()未指定cwd时的默认值workspaces/modal/src/sandbox/process-manager.ts。四、环境变量体系构造期、运行期与单命令优先级0.5.1 版本PR #22250统一了沙箱运行期环境变量setEnv()/getEnv()在所有 provider 中的行为。mastra/modal属于“自有 exec 传输”的 provider 一类其行为规则如下构造期env在创建沙箱时把环境变量烘焙进 Modal 容器sandboxes.create的env参数。源码中仅当 env 非空时才传递workspaces/modal/src/sandbox/index.ts空对象不会产生env参数测试见 sandbox.test.ts运行期setEnv()构造之后再设置的环境变量会合并进之后每次spawn()的环境由核心 spawn 包装层负责合并。测试setEnv after construction reaches subsequent spawns验证了这一点sandbox.test.ts单命令envexecuteCommand/spawn的options.env只对当前命令生效且优先级最高——它叠加在沙箱级环境之上。在ModalProcessManager.spawn()中环境合并逻辑会过滤掉值为undefined的条目process-manager.ts对应测试spawn() filters undefined values from envsandbox.test.ts。集成测试也验证了“沙箱级 env 可被printenv读取”以及“per-spawn env 覆盖 base env”sandbox.integration.test.ts。兼容性提示0.5.1 同时移除了两个仅用于手工构造进程管理器时透传env的导出类型BlaxelProcessManagerOptions、RailwayProcessManagerOptions因为核心 spawn 包装层已经接管了环境合并mastra/modal不受影响。五、沙箱克隆clone() 模板化派生0.4.0 版本PR #19616为沙箱 provider 增加了clone()支持。ModalSandbox.clone()会构造一个未启动的同源兄弟沙箱继承模板的全部配置凭据、app、基础镜像、workdir、instructions并允许按实例覆盖id与env——非常适合“一个配置好的沙箱当作模板批量派生多台沙箱例如每个项目一台”的场景const template new E2BSandbox({ apiKey, template: base }); const projectSandbox template.clone({ id: mc-project-42, env: { GITHUB_TOKEN: token }, idleTimeoutMinutes: 30, }); await projectSandbox.start();ModalSandbox的clone()实现workspaces/modal/src/sandbox/index.ts要点零 I/O克隆构造不发起任何网络请求真正的创建/重连发生在各自start()时options.id覆盖逻辑 idoptions.env覆盖环境变量options.idleTimeoutMinutes映射为 Modal 的timeoutMs毫秒idleTimeoutMinutes * 60_000options.sandboxId被忽略——因为 Modal 按逻辑id重连而非 provider 自己的 sandboxId克隆出的实例会继承模板的 token、appName、baseImage 等配置测试见 sandbox.test.ts。需要说明的是idleTimeoutMinutes在跨 provider 层面是“尽力而为”的提示Railway 对应idleTimeoutMinutes、E2B/Modal/Vercel 对应毫秒级超时、Daytona 对应autoStopInterval、Blaxel 对应 TTL 时长而 Docker 与 Apple Container 因没有 provider 侧的空闲回收机制会忽略它。clone()是WorkspaceSandbox接口的可选能力其设计意图记录在 packages/core/src/workspace/sandbox/sandbox.tsSandboxCloneOptions的完整字段id、sandboxId、env、workingDirectory、idleTimeoutMinutes、checkpointName、seedCheckpointName、actingUserId定义于 packages/core/src/workspace/sandbox/sandbox.ts。六、生命周期启动、暂停/恢复与销毁ModalSandbox的生命周期控制是它相对本地沙箱的核心差异点全部围绕 Modal SDK 实现workspaces/modal/src/sandbox/index.tsstart()按 id 重连或新建start()首先尝试client.sandboxes.fromName(appName, id)重连到同名运行中的沙箱若抛出NotFoundError则走创建路径获取必要时创建Modal App、从注册表镜像构建Image再sandboxes.create(...)新建沙箱。start()是幂等的——已启动时直接返回测试见 sandbox.test.ts。这正是“复用同一id即重连”这一特性的来源。stop()快照 终止暂停/恢复stop()先尽力终止所有运行中的进程然后调用snapshotFilesystem()把沙箱文件系统固化为镜像快照失败则跳过最后terminate({ wait: true })终止沙箱。下次start()时如果存在快照会直接从快照重建沙箱——实现上相当于 Modal 侧的“暂停/恢复”文件系统状态得以保留。若换成新的ModalSandbox实例没有快照则会从基础镜像全新创建测试见 sandbox.test.ts。destroy()彻底销毁与stop()不同destroy()不保留任何快照直接终止沙箱并清空_imageSnapshot完全结束沙箱生命周期。死沙箱自动重试ModalSandbox还实现了retryOnDead()workspaces/modal/src/sandbox/index.ts当底层调用抛出“沙箱已死”类错误ClientClosedError、NotFoundError、包含sandbox not found/has been terminated/NOT_FOUND或 gRPC NOT_FOUND code 5 的错误信息判定逻辑见isSandboxDeadError时自动重启沙箱并重试一次重试再次失败则不再重试。ModalProcessManager.spawn()的每次调用都包裹在该重试逻辑中process-manager.ts测试覆盖了“首次失败重试成功”“连续失败不二次重试”“非死沙箱错误不重试”三种场景sandbox.test.ts。状态与元数据status字段取值为pending/running/stopped/destroyed/error等ProviderStatusgetInfo()返回沙箱 id、provider、状态、创建时间及元数据appName、image、timeoutMsgetInstructions()提供 Agent 工具描述可用instructions选项以字符串整体替换或以函数基于默认指令加工测试见 sandbox.test.ts通过sandbox.modalgetter 可拿到底层 ModalSandbox实例做直接 SDK 操作未启动时访问会抛出SandboxNotReadyError。七、进程管理ProcessHandle、超时与 stdin 边界ModalProcessManagerworkspaces/modal/src/sandbox/process-manager.ts把 Modal 的ContainerProcess适配成 Mastra 的ProcessHandle每次spawn()对应一次 Modalexec()命令包装Modal 的exec()接收string[]argv因此 Mastra 先包装为[sh, -c, command]从而原生支持管道、重定向等 shell 语法测试断言了这一点sandbox.test.ts流式输出通过proc.stdout.getReader()/stderr.getReader()逐块读取并触发onStdout/onStderr回调同时累积进handle.stdout/handle.stderrwait() 幂等首次调用后缓存CommandResult重复调用返回相同结果sandbox.test.ts。超时与终止语义单命令超时spawn(command, { timeout })会把超时以timeoutMs传给 Modalexec()同时wait()在 Mastra 层也做了一次超时兜底——超时后 kill 并以约定退出码124、killed: true、timedOut: true返回process-manager.tskill 语义Modal JS SDK 没有按次 exec 的 kill 接口kill()只能取消本地 stdout/stderr 读取器远端进程会运行到沙箱超时为止本地句柄立即以exitCode: 137SIGKILL 约定值、killed: true返回process-manager.ts0.2.1 版本PR #17281修复了被 kill 与超时命令的执行结果上报即上面这套killed/timedOut字段。stdin 的边界0.5.0 版本PR #21606为ProcessHandle增加了closeStdin()以向后台进程发送 EOF。但对mastra/modal而言由于Modal JS SDK 的exec()不暴露 stdinsendStdin()直接抛出不支持错误closeStdin()抛出UnsupportedStdinCloseError该错误类型及基类默认行为来自mastra/core让现有ProcessHandle子类无需改动即可编译handle.writer.end()调用同样会触发 closeStdin 路径在 provider 无法关闭 stdin 时以无错误方式结束。这与 Local / Docker 沙箱形成对比后两者原生支持关闭 stdin。集成测试 sandbox.integration.test.ts 验证了命令执行、stderr 分离、环境变量、流式输出与 cwd 等真实云端行为而sendStdin不支持在单元测试中也有断言sandbox.test.ts。八、质量保障与工程细节单元测试sandbox.test.tsmock Modal SDK覆盖生命周期、stop-and-resume、元数据、进程管理、死沙箱重试与 clone 共 40 个断言场景无需真实云端凭据即可运行集成测试sandbox.integration.test.ts需要真实MODAL_TOKEN_ID/MODAL_TOKEN_SECRET通过pnpm test在 workspaces/modal 下运行用describe.skipIf(!hasCredentials)在没有凭据时自动跳过测试沙箱 id 使用时间戳保证唯一性并在afterAll中销毁包体优化0.6.0 起CHANGELOG.md不再随 npm 分发减小了安装包体积供应链安全0.2.4 是 2026-06-17 easy-day-js 供应链事件的修复版本通过补丁版本发布干净版本并前移latestdist-tag取代声明了恶意easy-day-js依赖的被污染版本依赖关系0.6.0 依赖mastra/core1.64.0peer 依赖范围1.12.0-0 2.0.0-0workspaces/modal/package.json。九、版本演进速查版本核心变更0.2.0包首次发布ModalSandbox基础能力、Modal 认证、pause/resume0.2.1修复被 kill 与超时命令的执行结果上报PR #172810.2.4easy-day-js 供应链事件安全修复0.4.0新增clone()模板化沙箱派生idleTimeoutMinutes映射 ModaltimeoutMsPR #196160.5.0新增ProcessHandle.closeStdin()Modal 因 SDK 无 stdin 接口抛出UnsupportedStdinCloseErrorPR #216060.5.1统一运行期环境变量setEnv()/getEnv()在 Modal 的 per-call env 下合并PR #222500.6.0新增统一workingDirectory选项与sandbox.workingDirectorygetterworkdir降级为废弃别名PR #22697十、总结什么时候选择 ModalSandbox综合来看mastra/modal适合这类场景希望 Agent 在云端隔离环境中执行命令、又需要暂停恢复快照与按 id 重连能力的团队。与本地沙箱相比它的隔离性更强、无需占用本地资源与 Docker 沙箱相比它免去了本地容器运行时的维护且天然支持云上生命周期管理。使用时请牢记几个关键边界工作目录必须使用绝对路径~/$HOME不会展开sendStdin/closeStdin不受支持kill()只能本地取消流读取远端进程会运行至沙箱超时timeoutMs是墙钟最大存活时间Modal 上限 24 小时。这些行为均有源码与测试佐证可在 workspaces/modal/src/sandbox/index.ts 与 workspaces/modal/src/sandbox/process-manager.ts 中进一步核实。【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表