Mastra × E2B Desktop:在云端 Linux 桌面沙箱中构建可操控桌面的 Agent Workspace
2026/9/15 11:09:26 网站建设 项目流程

Mastra × E2B Desktop:在云端 Linux 桌面沙箱中构建可操控桌面的 Agent Workspace

【免费下载链接】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 的 computer-use(桌面操作)沙箱 Provider,它在@mastra/e2b的 E2B 云沙箱之上叠加了一整套 Linux 桌面环境,并提供截图、鼠标、键盘控制能力。本文将带你掌握如何把它接入WorkspaceAgent,如何用computer能力驱动桌面 Agent,以及如何深入底层理解其实现机制。

背景:为什么需要桌面沙箱

常规的代码执行沙箱只能跑命令、读写文件,无法“看见”和“操作”一个图形界面。而许多真实任务——操作浏览器、填写 GUI 表单、使用桌面应用——都需要 Agent 具备 computer-use 能力:截图观察屏幕、移动鼠标点击、键盘输入。

E2B Desktop 正是在 E2B 云沙箱中运行一个完整的 Linux 桌面环境,@mastra/e2b-desktop把这个桌面环境接入 Mastra Workspace 体系。它的定位非常清晰:继承@mastra/e2bE2BSandbox的全部能力(命令执行、进程管理、文件上传、暂停/恢复重连),同时叠加桌面控制能力,@e2b/desktopSDK 之于e2bSDK 的扩展方式,与@mastra/e2b-desktop之于@mastra/e2b的扩展方式完全一致——基础 Provider 支持的一切能力,都作用在同一个桌面 VM 上。

安装

在 Mastra 项目中安装:

npm install @mastra/e2b-desktop

从源码看,package.json 声明了以下依赖关系:

  • 运行时依赖@e2b/desktop^2.3.1)与e2b^2.36.0),以及 workspace 内的@mastra/e2b
  • @mastra/core作为 peer dependency,版本要求>=1.67.0-0 <2.0.0-0
  • 要求 Node.js>=22.13.0

快速开始:把桌面沙箱挂进 Agent

以下是完整的接入示例(直接取自包的用法文档,并补充了可运行细节):

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 三类工具都会自动注入 workspace: new Workspace({ sandbox }), });

关键点:

  • resolution: [1280, 720]指定桌面显示分辨率(像素宽高),也可用dpi指定显示 DPI;两者都只对新建的沙箱生效;
  • 由于沙箱实现了computer能力,supportsComputer(sandbox)true,Workspace 会自动向 Agent 注入mastra_workspace_computer_*系列工具(见下文"Computer 能力"一节),无需手动声明;
  • 与基础E2BSandbox不同,桌面沙箱默认无需构建模板——未显式提供template时,使用 E2B 托管的desktop模板(源码中的DEFAULT_DESKTOP_TEMPLATE = 'desktop',见 sandbox/index.ts)。

环境变量与鉴权

@mastra/e2b一致,凭据可通过构造参数或环境变量提供:

配置项作用回退环境变量
apiKeyE2B API 密钥E2B_API_KEY
accessTokenE2B 访问令牌E2B_ACCESS_TOKEN
domain自托管 E2B 域名E2B_DOMAIN
apiUrl自托管 E2B API 地址E2B_API_URL

构造选项(Options)全解

E2BDesktopSandboxOptions继承E2BSandboxOptions的全部字段,并新增两个桌面专属字段。下表综合了 sandbox/index.ts 与上游 workspaces/e2b/src/sandbox/index.ts 的完整定义:

选项类型默认值说明
resolution[number, number]无(SDK 默认)桌面分辨率[宽, 高],仅对新建沙箱生效
dpinumber桌面显示 DPI,仅对新建沙箱生效
idstring自动生成沙箱逻辑 ID,用于元数据发现与重连
sandboxIdstring优先按 E2B Provider 沙箱 ID 确定性重连(见下文)
templateTemplateSpec'desktop'模板:字符串 ID / TemplateBuilder / 定制函数;不传则用 E2B 托管 desktop 模板,无需构建
timeoutnumber300_000(5 分钟)执行超时(毫秒)
envRecord<string, string>{}注入沙箱的环境变量
metadataRecord<string, unknown>{}自定义元数据(会自动合并mastra-sandbox-id
networkSandboxNetworkOpts创建时的网络配置
lifecycleSandboxLifecycle{ onTimeout: 'pause' }超时行为:pause快照暂停(下次start()恢复重连);kill则销毁重建,适合状态外置(如 S3 挂载)的沙箱
domain/apiUrl/apiKey/accessTokenstring环境变量鉴权与自托管配置
instructionsstring \| (opts) => string默认说明覆盖默认沙箱指令

关于 lifecycle 与 timeout 的行为

上游E2BSandbox源码注释说明(workspaces/e2b/src/sandbox/index.ts):默认onTimeout: 'pause'会把整个 VM(文件系统、内存、运行中的进程)冻结快照并停止计费,下次start()重连并恢复,后台进程依然存活;显式stop()无论该设置如何都会暂停。timeout会被写入创建参数timeoutMs,单位毫秒。

用 Workspace 执行代码

接入 Workspace 后,可直接执行代码与命令:

const sandbox = new E2BDesktopSandbox({ timeout: 60_000 }); const workspace = new Workspace({ sandbox }); // 在桌面 VM 中执行代码 const result = await workspace.executeCode('console.log("Hello from desktop VM!")');

与基础 Provider 相同,桌面沙箱还支持executeCommand、文件上传(writeFiles)、后台进程管理等能力。集成测试中有一个非常直观的例子:通过 shell 写入文件,再用桌面 SDK 读回,验证 GUI 与 shell 两条通道作用在同一台机器上(见 index.integration.test.ts)。

Computer 能力:截屏、鼠标与键盘

E2BDesktopSandbox覆写了computer: SandboxComputer能力,其全部操作由withDesktop()统一编排:先ensureRunning()确保沙箱已启动,再通过retryOnDead()在检测到 VM 已死时自动重建并重试。因此所有 computer 操作都会在沙箱未运行时自动启动它

屏幕观察

await sandbox.start(); const { data, mediaType } = await sandbox.computer.screenshot(); // mediaType === 'image/png',data 为 PNG 字节 const { width, height } = await sandbox.computer.getScreenSize(); const cursor = await sandbox.computer.getCursorPosition();

getScreenSize()返回{ width, height }getCursorPosition()返回{ x, y }。单元测试验证了截图返回 PNG 魔数\x89PNG(见 index.test.ts)。

鼠标控制

await sandbox.computer.leftClick(100, 200); await sandbox.computer.rightClick(100, 200); await sandbox.computer.doubleClick(100, 200); await sandbox.computer.moveMouse(100, 200); await sandbox.computer.drag({ x: 1, y: 2 }, { x: 3, y: 4 }); await sandbox.computer.scroll('down', 3);

所有坐标以像素计;drag接受起点/终点坐标对象,底层映射为desktop.drag([from.x, from.y], [to.x, to.y])scroll接受方向(如'down')与步数。

键盘输入

await sandbox.computer.type('hello world'); // 映射为 desktop.write(text) await sandbox.computer.press('Enter'); // 单个按键 await sandbox.computer.press(['ctrl', 's']); // 组合键

type底层调用desktop.writepress支持单个键名或键名数组(组合键)。测试用例覆盖了这三种调用形态(index.test.ts)。

实时桌面查看(noVNC 流)

const viewerUrl = await sandbox.computer.streamUrl();

streamUrl()会做三件事:

  1. 通过ensureStreamStarted()启动一个要求鉴权的 VNC 流(desktop.stream.start({ requireAuth: true })),并按沙箱 ID 记忆化——同一 VM 只启动一次,重启/重建的 VM 会重新启动;
  2. desktop.stream.getAuthKey()拼出带password=参数的 noVNC 查看器 URL;
  3. 兼容外部已启动的流(拿不到 auth key 时返回普通 URL);任何失败都返回null而非抛错。

单元测试验证了"重复调用只启动一次流""外部已启动的流被容忍""失败返回 null"等行为(index.test.ts)。集成测试确认返回 URL 形如https://...且包含password=(index.integration.test.ts)。

桌面专属逃生通道:sandbox.desktop

不是所有桌面 API 都值得抽象进统一接口,E2BDesktopSandbox提供了desktopgetter 直接暴露底层@e2b/desktopSDK 的Sandbox实例:

await sandbox.start(); await sandbox.desktop.launch('xfce4-terminal'); // 启动应用 await sandbox.desktop.open('https://mastra.ai'); // 打开 URL await sandbox.desktop.files.read('/tmp/x.txt'); // 文件操作

注意:desktop在沙箱未启动时访问会抛出SandboxNotReadyError(源码 sandbox/index.ts,测试见 index.test.ts)。这是定制流、窗口管理、启动任意应用等高级操作的入口。

生命周期:启动、暂停、重连与销毁

E2BDesktopSandbox继承了E2BSandbox的生命周期管理,并针对桌面场景做了关键改造:

  • 创建:重写createSdkSandbox(),调用@e2b/desktopSandbox.create(templateId, opts),并把resolutiondpi透传给 SDK;创建参数包含timeoutMs、lifecycle 以及合并了mastra-sandbox-id的 metadata(测试验证了这些透传,index.test.ts);
  • 重连:重写connectSdkSandbox()@e2b/desktopSandbox.connect(sandboxId, opts)start()时优先按sandboxId选项确定性重连,否则按mastra-sandbox-id元数据发现已有沙箱;只有"沙箱已消失"类错误才回退到新建,鉴权、配额、限流、超时、网络错误会直接抛出,避免创建重复 VM(workspaces/e2b/src/sandbox/index.ts);
  • 暂停/恢复stop()对 VM 做快照暂停(冻结文件系统、内存与进程并停止计费),下次start()重连恢复;FUSE 挂载会先卸载、启动时再对账恢复;
  • 销毁destroy()杀掉全部后台进程、卸载挂载并kill沙箱;对未在本进程附着的沙箱,按身份直接 pause/kill,无需唤醒它(workspaces/e2b/src/sandbox/index.ts);
  • 模板解析:重写resolveTemplate(),未显式提供template时直接返回 E2B 托管的desktop模板 ID,并重写buildDefaultTemplate()为无操作——桌面模板由 E2B 托管,无需构建(sandbox/index.ts)。

集成测试对沙箱一致性(conformance)的声明也印证了能力边界(index.integration.test.ts):支持重连、并发、环境变量、工作目录与超时;不支持挂载(FUSE)——桌面模板没有 FUSE 工具链,这一点与基础 E2BSandbox 的云存储挂载能力不同。

在 MastraEditor 中作为可序列化 Provider 使用

@mastra/e2b-desktop还导出一个e2bDesktopSandboxProvider描述符(见 provider.ts),用于 MastraEditor:

import { e2bDesktopSandboxProvider } from '@mastra/e2b-desktop'; const editor = new MastraEditor({ sandboxes: [e2bDesktopSandboxProvider], });

该描述符提供 JSON Schema 配置(configSchema),覆盖templatetimeout(默认 300000ms)、envmetadataresolutiondpidomainapiUrlapiKeyaccessToken等字段;不可序列化的回调(如 TemplateBuilder、运行时对象)被排除在外。编辑器据此渲染配置表单,并通过createSandbox(config)实例化真正的E2BDesktopSandbox

自动注入的 computer 工具

当 Workspace 挂载支持 computer 能力的沙箱时,会向 Agent 注入一组mastra_workspace_computer_*工具(截图、点击、输入、滚动等),核心包的 tools/types.ts 提供了两个常用调优项:

  • screenshotAfterAction:动作类工具(click/type/scroll 等)完成后是否自动附一张新截图,让 computer-use 循环无需额外截图即可看到操作后的桌面状态,默认true
  • screenshotDelayMs:动作与操作后截图之间的延迟(默认 500ms),给 UI 菜单、动画留出反应时间。

示例配置:

const agent = new Agent({ // ... workspace: new Workspace({ sandbox }), tools: { // 点击后不附加截图,减少 token 消耗 mastra_workspace_computer_click: { screenshotAfterAction: false }, // 桌面输入需要人工审批 mastra_workspace_computer_type: { requireApproval: true }, }, });

测试与验证方式

包内测试分两层:

  • 单元测试(index.test.ts):mock 掉e2b@e2b/desktopSDK,验证模板解析、SDK 工厂钩子、computer 能力映射、流记忆化、workspace 工具注入、桌面逃生通道等,不消耗真实资源;
  • 集成测试(index.integration.test.ts):需要真实E2B_API_KEY(未设置时自动跳过),针对真实桌面沙箱验证截图 PNG 魔数、鼠标移动→光标位置回读、shell 与 GUI 共享文件系统的跨通道回环、鉴权 noVNC URL 解析。

想在自己的项目里快速验证,可以运行:

const sandbox = new E2BDesktopSandbox({ id: `demo-${Date.now()}`, timeout: 120_000, }); await sandbox.start(); const shot = await sandbox.computer.screenshot(); // PNG 字节 const url = await sandbox.computer.streamUrl(); // noVNC 查看器 await sandbox.computer.type('echo desktop-ok > /tmp/x'); await sandbox.executeCommand('cat /tmp/x'); await sandbox.destroy();

小结

@mastra/e2b-desktop让 Mastra Agent 第一次能够"看见并操作"一个云端 Linux 桌面:它完整继承@mastra/e2b的命令、进程、文件与暂停/恢复重连能力,叠加截图、鼠标、键盘与鉴权 noVNC 实时流,默认使用无需构建的 E2B 托管桌面模板,并通过mastra_workspace_computer_*工具把这一切自动暴露给 Agent。无论是构建 computer-use 自动化,还是需要一个同时支持 GUI 与 shell 的隔离执行环境,它都是一个开箱即用的选择。

相关代码入口:

  • 包 README:安装、用法与能力概述
  • 核心实现 sandbox/index.ts:E2BDesktopSandboxcomputer能力
  • Provider 描述符 provider.ts:MastraEditor 可序列化配置
  • 单元测试 index.test.ts 与 集成测试 index.integration.test.ts
  • 上游基类 @mastra/e2b:选项、生命周期、挂载与重连语义
  • computer 工具配置:mastra_workspace_computer_*工具行为调优

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询