Mastra E2B Desktop 沙箱实战指南:用@mastra/e2b-desktop为 Agent 赋予完整桌面操控能力
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
本文围绕 Mastra 仓库中的@mastra/e2b-desktop工作区包展开,讲解如何以 E2B Desktop 为后端,为 Mastra Workspace 提供「计算机使用」(computer-use)云沙箱:Agent 不仅能在 Linux 虚拟机中执行 shell 命令、管理进程与文件,还能通过截图、鼠标、键盘与屏幕信息直接操作图形化桌面,并通过带认证的 noVNC 流实时观察桌面。读完本文,你将掌握该提供器的安装方式、配置参数、computer 能力映射、底层 SDK 逃生口(escape hatch)以及它的版本演进与依赖约束。
一、背景:Mastra Workspace 与 E2B Desktop 的相遇
Mastra 的 Workspace 机制允许 Agent 运行在隔离沙箱中,而@mastra/e2b-desktop正是为 Workspace 提供的一类「桌面型」沙箱提供器。其官方定位一句话即可概括:在 E2B 云沙箱中运行一个完整的 Linux 桌面环境,并支持截图、鼠标与键盘控制(见 README)。
从源码结构看,它复用了两层依赖:
@mastra/e2b(workspace 包):提供基础的E2BSandbox,负责命令执行、进程管理、文件上传、暂停/恢复重连等能力;@e2b/desktop(SDK):在基础沙箱之上叠加桌面显示与输入控制能力。
E2BDesktopSandbox扩展自@mastra/e2b的E2BSandbox,其关系正如@e2b/desktop的 SDKSandbox之于e2b的关系:基类提供的一切能力(命令、进程、文件、重连)都作用于同一个桌面虚拟机(见 sandbox/index.ts 的类注释)。
二、核心能力一览
根据 CHANGELOG 0.1.0 条目,该包于 0.1.0 首次引入,核心能力是:
一个由 E2B Desktop 支撑的 computer-use 沙箱提供器,将 E2B 的命令、进程、文件与重连支持,与截图、鼠标、键盘、屏幕信息以及带认证的 noVNC 工具结合。
具体拆解为四个维度:
| 能力维度 | 说明 |
|---|---|
| 命令与进程 | 继承自E2BSandbox,可执行任意 shell 命令、管理后台进程 |
| 文件操作 | 支持文件写入、读取、列举,作用于桌面虚拟机同一文件系统 |
| 桌面控制(computer) | 截图、鼠标(点击/拖动/滚动/移动)、键盘(输入/按键组合)、屏幕尺寸、光标位置 |
| 实时可视化 | 带认证的 noVNC 流 URL,可直接在浏览器中查看桌面 |
当E2BDesktopSandbox被放入Workspace时,Agent 会自动获得mastra_workspace_computer_*系列工具——文件、shell 与 computer 工具全部自动注入,无需手动声明(见 sandbox/index.ts 特性注释)。
三、安装与快速开始
安装命令(见 README):
npm install @mastra/e2b-desktop将该包与@mastra/core配合使用:@mastra/e2b-desktop将@mastra/core声明为 peer dependency,当前版本要求>=1.67.0-0 <2.0.0-0(见 package.json)。
最简用法(CHANGELOG 与 README 中的权威示例):
import { Agent } from '@mastra/core/agent'; import { Workspace } from '@mastra/core/workspace'; import { E2BDesktopSandbox } from '@mastra/e2b-desktop'; const sandbox = new E2BDesktopSandbox({ resolution: [1280, 720] }); const agent = new Agent({ name: 'desktop-agent', instructions: 'You can control a Linux desktop and run shell commands.', model: 'anthropic/claude-sonnet-4-6', // file + shell + computer tools are all emitted automatically workspace: new Workspace({ sandbox }), });关键点:E2BDesktopSandbox的构造不需要手动指定模板。源码中定义了常量DEFAULT_DESKTOP_TEMPLATE = 'desktop',当未提供template选项时自动使用 E2B 托管的desktop模板,无需构建模板;这与基础提供器需要挂载式模板的做法不同(见 sandbox/index.ts)。
四、配置参数详解
E2BDesktopSandbox的构造函数接受E2BDesktopSandboxOptions,它继承E2BSandboxOptions的全部字段(凭据、超时、env、metadata、network、template、instructions),并新增两个桌面专属选项(见 sandbox/index.ts 接口定义):
| 参数 | 类型 | 说明 |
|---|---|---|
resolution | [number, number] | 桌面显示分辨率[宽, 高](像素),仅对新创建的沙箱生效 |
dpi | number | 桌面显示 DPI,仅对新创建的沙箱生效 |
这两个参数会在创建 SDK 沙箱时透传给@e2b/desktop的Sandbox.create(见 createSdkSandbox 实现),单元测试也验证了resolution与dpi会被原样传入且timeoutMs默认 300,000ms(见 index.test.ts)。
此外,在 MastraEditor 集成场景中,provider.ts还暴露了完整的可序列化配置模式(见 provider.ts),包括:
template:模板 ID,默认 E2B desktop 模板;timeout:执行超时(毫秒),默认 300000;env/metadata:环境变量与自定义元数据;domain/apiUrl:自托管 E2B 时的域名与 API 地址;apiKey/accessToken:E2B API 密钥与访问令牌。
非可序列化选项(如TemplateBuilder回调、运行时对象)会被排除在该配置之外,以保证编辑器存储安全。
五、computer 能力:Agent 如何「操作」桌面
computer是E2BDesktopSandbox覆写的核心只读属性,类型为SandboxComputer,每个操作都会先通过withDesktop确保沙箱已运行,再调用@e2b/desktopSDK 的对应方法(见 sandbox/index.ts):
| computer 方法 | 底层 SDK 方法 | 作用 |
|---|---|---|
screenshot() | desktop.screenshot() | 返回{ data, mediaType: 'image/png' } |
leftClick(x, y)/rightClick(x, y)/doubleClick(x, y) | 同名 | 鼠标三键点击 |
moveMouse(x, y) | desktop.moveMouse(x, y) | 移动光标 |
drag(from, to) | desktop.drag([x,y],[x,y]) | 拖拽(坐标被转换为数组形式) |
scroll(direction, amount) | desktop.scroll(...) | 滚动 |
type(text) | desktop.write(text) | 键入文本 |
press(key) | desktop.press(key) | 按键,支持组合键如['ctrl','s'] |
getScreenSize() | desktop.getScreenSize() | 屏幕尺寸 |
getCursorPosition() | desktop.getCursorPosition() | 光标位置 |
streamUrl() | 见下节 | noVNC 直播流 URL |
值得注意的是,所有 computer 操作都会自动启动沙箱;若检测到底层虚拟机已死(例如抛出sandbox has been killed),还会通过retryOnDead自动重建沙箱后重试。这些行为均有单元测试覆盖(见 index.test.ts)。
六、noVNC 实时桌面视图
computer.streamUrl()提供带认证的 noVNC 查看地址,实现「看得见」的桌面:
- 首次调用时通过
desktop.stream.start({ requireAuth: true })启动带认证的流; - 启动过程以 SDK 沙箱 ID 为键做记忆化(memoize),同一沙箱只启动一次,沙箱被重建(resume/recreate)后会自动重新启动;
- 生成 URL 时优先携带
authKey(形如vnc.html?password=...);若流由外部通过desktop逃生口启动且未启用认证,则降级返回无认证的普通 URL;无法启动时返回null(见 ensureStreamStarted 与 streamUrl 实现)。
测试场景完整覆盖了「带认证 URL」「记忆化只启动一次」「容忍外部启动的流」「启动失败返回 null」四种情形(见 index.test.ts Stream URL 测试组)。
七、sandbox.desktop逃生口:直接操作底层桌面 SDK
CHANGELOG 明确指出:该提供器还通过sandbox.desktop导出底层桌面 SDK,用于桌面专属操作。这是一个 getter,返回@e2b/desktop的Sandbox实例;若沙箱尚未启动,会抛出SandboxNotReadyError(见 sandbox/index.ts)。
典型用法(源码 JSDoc 示例):
const sandbox = new E2BDesktopSandbox(); await sandbox.start(); await sandbox.desktop.launch('xfce4-terminal'); await sandbox.desktop.open('https://mastra.ai');由此可以解锁抽象层未覆盖的 API:launch()启动应用、open()打开 URL、窗口辅助方法、自定义流控制等。
八、模板解析与沙箱生命周期
模板解析逻辑(见 resolveTemplate 实现):
- 若已解析过模板 ID,直接复用;
- 若未显式提供
template选项,使用默认的desktop模板——因为是 E2B 托管模板,无需任何构建步骤; - 若显式提供了模板,则走基础提供器的完整解析流程(ID、builder 或 customizer)。
沙箱的创建与重连分别由两个工厂钩子完成:createSdkSandbox调用E2BDesktopSdkSandbox.create(templateId, {...}),connectSdkSandbox调用E2BDesktopSdkSandbox.connect(sandboxId, opts)——两者都经由@e2b/desktopSDK,而非基础的e2bSDK。单元测试验证了:默认创建时传入模板desktop且不会触发基础 SDK 的create/Template.exists/Template.build;显式模板按原样传入;已有运行中沙箱时走connect路径(见 index.test.ts)。
此外clone()方法可基于当前沙箱配置构造同类型兄弟沙箱,支持id、env、idleTimeoutMinutes(内部转换为timeout毫秒)等覆盖项(见 sandbox/index.ts)。
九、版本演进:从 0.1.0 到 0.1.2-alpha.0
CHANGELOG 完整记录了三个里程碑:
0.1.0(首个稳定版本)
- 新增
@mastra/e2b-desktop,即本文介绍的 computer-use 沙箱提供器(PR #21707); - 依赖
@mastra/core@1.62.0与@mastra/e2b@0.10.0。
0.1.1(打包与文档优化)
- 更新 README 以确保信息准确、及时(PR #22858);
- 从 npm 发布产物中移除
CHANGELOG.md,减小包体积(PR #22737); - 依赖升级至
@mastra/core@1.64.0、@mastra/e2b@0.11.0。
0.1.2-alpha.0(依赖下限调整)
- 将
@mastra/corepeer dependency 下限提升至1.67.0,以匹配其依赖的@mastra/e2b(PR #23652); - 依赖
@mastra/core@1.67.0-alpha.3、@mastra/e2b@0.12.0-alpha.0。
十、测试体系:如何验证桌面能力
该包同时提供单元测试与真实环境集成测试(见 package.json 测试脚本):
pnpm test:unit:运行排除 integration 后缀的单元测试(mock 掉e2b与@e2b/desktopSDK),覆盖构造选项、模板解析、computer 操作映射、stream URL 各分支、Workspace 工具注入(断言工具名与WORKSPACE_TOOLS.COMPUTER完全一致)、desktop 逃生口等(见 index.test.ts);pnpm test/pnpm test:cloud:运行真实集成测试,需要E2B_API_KEY环境变量,未配置时自动跳过。
集成测试包含两类(见 index.integration.test.ts):
- computer-use 冒烟测试:截图返回真实 PNG(校验魔数
\x89PNG)、鼠标移动与光标位置往返一致(moveMouse(101,102)后getCursorPosition()返回同一坐标)、GUI 与 shell 命中同一台机器(shell 写入文件后经desktop.files.read读回)、streamUrl解析出带password=的认证地址; - 共享一致性测试套件:通过
createSandboxTestSuite复用工作区通用用例,并声明能力矩阵——不支持挂载(桌面模板无 FUSE 工具)、支持重连/并发/env/工作目录/超时,默认命令超时 30s。
十一、适用场景与注意事项
典型场景:需要 Agent 操作真实 GUI 的自动化任务——浏览器自动化(open打开页面后截图分析)、桌面应用测试、跨 shell 与图形界面的复合任务等。
注意事项:
resolution与dpi仅对新创建的沙箱生效,重连既有沙箱时不会被应用;- 桌面模板不支持文件挂载(FUSE),需依赖文件读写 API 而非挂载方式(见 集成测试能力矩阵);
- 使用
sandbox.desktop前必须确认沙箱已启动,否则会抛出SandboxNotReadyError; - 若在 MastraEditor 中以
e2bDesktopSandboxProvider注册沙箱,可在 UI 中通过可视化表单配置resolution、dpi、timeout等字段(见 provider.ts 的 configSchema)。
需要深入源码的读者,建议从 入口文件 出发,沿E2BDesktopSandbox(sandbox/index.ts)→ 基类@mastra/e2b的E2BSandbox(workspaces/e2b)→ 上游@e2b/desktopSDK 的调用链逐层阅读,即可完整理解桌面能力的实现边界。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考