desktop-hosts.md 8.9 KB

服务器与电脑

一台服务器集中运行 Web(15300)与 Hermes(9119),其他 Mac 安装夭夭 App 后作为“电脑”出站连接服务器,向服务器上的 Bot 提供自己的真实桌面(截图、键鼠、独立浏览器)。产品中只用两种名称:运行服务的一端叫“服务器”,连接服务器的 Mac 叫“电脑”。服务器自己机器上的 App 继续走本机回环通道,内部编号为 local。

服务端执行与统一权限

所有 Bot 的聊天、模型、配置、记忆提炼都运行于服务端 Hermes。客户端 App 只负责界面和已授权的电脑操作,无需安装 Hermes。虚拟机 Runner 只在调用 computer_* 时建立工具会话;虚拟机离线不会转移聊天,也不会让普通聊天启动虚拟机。

电脑开放范围与审批策略在 Bot 设置统一管理,默认开放服务器、电脑、Grok Bot 云电脑和虚拟机。旧 Bot 的 computer、execution、envs、approvalPolicy 不再决定实际设备权限或模型运行位置。旧虚拟机共享关系保留,任务助手仍受所属任务的生命周期约束。

  • 消息来源:客户端每次发送时重新读取 deviceHost,服务端保存到消息和运行。省略 host 或使用「本机」/local 时,只解析为本轮来源电脑;切换客户端后新消息覆盖来源,已经运行的任务保留自己的来源快照。
  • 明确目标:desktop_* 的 host 可指定电脑名称或编号;server /「服务器」固定指服务器。重复名称需要用编号。来源未知、离线或全局关闭时明确报错,不用旧消息、Bot 绑定或其他在线机器兜底。普通浏览器未提供可控设备身份时须点名目标。
  • 协作与定时任务:Bot 转交、子任务和结果回传继承触发消息的来源。定时任务保存自己的「本机」目标,重启或换客户端查看不会改变它;旧任务未保存目标时须在内容中明确指定。
  • 并行环境:同一 Bot 可在一轮中操作多个环境。连接、系统授权和人工接管状态按设备校验,不按 Bot 区分权限。文件与命令授权不依赖屏幕录制或辅助功能。
  • 审批:所有 Bot 共用「询问我 / 自动允许 / 自动拒绝」,变更用于后续审批请求;已等待的请求单独答复。聊天中的允许只作用于本次,旧客户端的 auto 答复也只允许一次。
  • Hermes 原生工具:原生终端和文件工具始终操作服务器,与消息来源无关;访问来源客户端应使用 desktop_*。全局服务器电脑开关控制 desktop 适配器,旧 denyServerTools 字段停用,不再展示未接入的封禁开关。
  • 接管界面:/api/app/agents/:id/computer 系列接受 backend=desktop|cloud|vm,桌面可附带 host。界面显式选择目标。此处的 host=local 是历史 API 的服务器编号,不等于 Bot 工具中随消息变化的别名。

启用流程

  1. 在那台 Mac 上启动夭夭 App。首次启动会询问这台 Mac 的使用方式:「连接服务器(客户端)」或「作为服务器运行」,默认选择客户端。
    • 选「连接服务器」:弹出登录窗口,填写夭夭服务器地址(如 192.168.1.10:15300)、用户名和密码。登录成功后窗口直接使用远程服务器的夭夭界面(本机不运行 Web 服务);用管理员账号登录时,App 会自动把这台 Mac 注册为电脑(令牌经系统钥匙串加密保存在数据目录 desktop-host.enc,0600),无需任何配置文件。非管理员账号只登录界面,并提示需要管理员账号才能注册电脑控制。
    • 选「作为服务器运行」:在这台机器运行 Web,并连接这里配置的 Hermes。
    • 勾选「记住选择,之后启动不再询问」会把选择写入偏好(startupChoice);也可在菜单「运行模式 → 启动时询问运行模式」恢复每次询问。
  2. 后续启动直接进入远程模式;若登录会话已过期,App 会重新弹出登录窗口(服务器地址已预填)。会话 Cookie 保存在 App 的会话存储中,密码不落盘。使用中可随时通过「运行模式」切换服务器与客户端模式;「电脑 → 断开并忘记配置」会移除本机的电脑凭据。
  3. 服务器管理侧(可选):「设置 → Hermes 连接 → 电脑」列出各台已注册电脑(在线状态、机器名、最后在线)并可停用;停用立即断开那台 Mac。被停用的电脑不会因启动或普通重连自行恢复;用户再次显式登录管理员账号,或选择「电脑 → 重新授权…」后,服务复用原记录、轮换令牌并恢复连接。旧版没有安装编号的电脑通过原记录编号完成迁移,避免产生重复记录。
  4. 手动注册并下载 desktop-host.json 仍可用于不便登录的机器(菜单「电脑 → 导入电脑配置…」),但常规流程不再需要。
  5. 管理员在全局设置中开放电脑类型,在聊天右侧电脑面板查看各台电脑的连接与授权状态;无需为各 Bot 单独勾选环境或绑定默认执行机。
  6. 首次授权:管理员点「在桌面端授权」,那台 Mac 弹出原生授权对话框;确认后引导开启屏幕录制与辅助功能。授权按账号哈希(ownerKey)记录在各 Mac 的 computer-permissions.json,各机独立;菜单「撤销本机控制授权」同时作用于本机与远程通道。

文件与命令(全面操作)

屏幕授权之外是独立的第二档授权「文件与命令」:电脑面板直接提供「授权文件与命令」按钮,无需先完成屏幕授权,Mac 端弹窗单独确认。授权后该账号下所有机器人获得四个工具:

  • desktop_file_list / desktop_file_read / desktop_file_write:在这台 Mac 的用户主目录范围内列目录、读文件(≤12MB)和写文件(≤10MB);..、绝对路径越界和符号链接逃逸都会被拒绝,TCC 保护目录仍按系统权限处理。
  • desktop_shell:在主目录执行一条 zsh 命令(最长 120 秒,stdout/stderr 各截断 512KB,超时终止并如实报告)。

两档授权分别记录(approved 与 approvedFull),「撤销本机控制授权」同时清除;工具目录按账号下可用设备的授权汇总,且每次调用在服务端二次校验。

传输与边界

  • 机器端点 POST /api/desktop-host/v1/<hostId>/exchange:Bearer 令牌(sha256 后 timingSafeEqual)+ x-desktop-host-protocol: 1;拒绝任何携带 Origin 的请求,不进入用户会话、CSRF 或 CORS 体系;Host 白名单照常生效。
  • 交换协议沿用桌面端 {host, results} → {commands} 格式:每轮最多 8 条命令、20 条结果,请求体上限 24MB。App 成功后 400ms 轮询,网络错误指数退避至 5s;令牌失效(401/403)即停止并提示重新导入。
  • 每台电脑独立持有命令队列、截图缓存、接管凭据与授权状态;连接 epoch(App 每次启动/撤销时轮换的 host.id)变化即围栏在途命令。人工接管的 generation/epoch/30 秒续期语义与单台电脑时一致,接管记录以 desktop:<hostKey>:<resource> 区分。
  • 远程明文 HTTP(服务器地址以 http:// 登录)时,App 保存的电脑配置自动带 allowInsecureLan: true,与 Runner 规则一致;公网部署应使用 HTTPS 并把域名加入外网访问地址。登录凭据只走该服务器地址,密码不落盘。
  • 停用电脑立即断开那台 Mac 并围栏其在途命令;旧令牌不能恢复,必须通过显式管理员登录重新授权。

范围

  • 物理机控制仅支持 macOS(屏幕录制、辅助功能与 computer-helper 签名校验均为 macOS 专属)。
  • 本功能只提供真实桌面与独立浏览器环境;远程机器上的 Linux 虚拟桌面(无 Hermes 电脑节点)不在本范围。
  • 服务器侧 Bot 会话、模型与记忆全部留在服务器的 Hermes;卫星机不安装 Hermes。

验证

  • 服务端:tests/server/desktopHosts.test.ts(注册令牌一次性、准入与协议头、撤销围栏)、tests/server/desktopEnvironments.test.ts(消息来源解析、离线不回退、全局权限、文件与屏幕授权独立、并发来源隔离、按机围栏)。
  • App:desktop/remote-login.test.mjs(地址归一化、账号密码登录的 CSRF/Origin 往返、管理员注册电脑、错误路径)、desktop/host-files.test.mjs(目录内列/读/写、路径与符号链接逃逸拒绝、命令退出码/超时/工作目录)、desktop/host-manager.test.mjs(配置校验、加密导入、交换往返、403 停止、退避重试)、desktop/preferences.test.mjs(启动选择与远程地址偏好持久化)。启动选择/登录窗口需按上述流程手工验收(自动化桌面测试通过 fixture 环境固定走本地路径)。
  • 浏览器:tests/e2e/desktop-hosts.spec.ts(注册/下载/停用;模拟远程电脑连接与电脑面板状态)。真实多机链路需按上述流程手工验收。