Skip to content

电脑操作 v1 ​

翻译说明: 本页与英文源规格一一对应。代码、协议字段和标识符保留原文;如翻译与英文源事实存在差异,以英文版本为准。

状态:阶段 1 已实现,但未经真机验证。本页是 ADR 0342 所述能力的权威契约,并由 ADR 0344 修订。当前唯一调用方是 Agent;语音入口在本页定义,但在阶段 3 才接通。拒绝逻辑、回路与工具自身路径已有单测覆盖;尚未驱动过任何真实应用,Windows 与 Linux 在阶段 2 之前一律返回 COMPUTER_PLATFORM_UNSUPPORTED。

范围 ​

电脑操作让 Agent 读取并操作用户机器上的原生应用。该能力默认关闭,与内置 Browser 工具相互独立。在设置中启用即是授权:此后 Agent 可以自行开启覆盖整个桌面的授权,每次只绑定一个窗口,并可在宿主不拒绝的窗口之间切换(ADR 0344)。不再询问用户选哪个窗口;能力的边界是各条拒绝、动作预算、空闲过期与"停止"。

语音入口在阶段 1 刻意不接通。接通后,实时语音也不获得任何自有权限——一句口述请求会变成绑定会话上的工作请求(见实时语音工作会话集成),由现有 Agent 轮次调用工具,会话的模型、权限模式和审批卡片完全不变。届时语音驱动的电脑操作是任务委派,不是逐帧遥控。

界面所有者可达范围
Browser 工具(pi.browser,ADR 0170)走白名单 CDP 的内置插件仅限内嵌 WebContentsView 宿体
Computer 工具(本页)Electron Main 执行,由 host-core 把关宿主不拒绝的所有原生窗口,每次绑定一个
实时语音Electron Main 与 Renderer音频、转录与工作委派;不做输入合成

所有权与进程模型 ​

text
Renderer(带"停止"的指示器、光标浮层)
  → Preload IPC → Electron Main
       Computer 工具处理器、自动申请授权、有界回路、绑定模型调用、
       作用域裁剪截取、浮层驱动
    → Rust host-core `computer.*`
       目标枚举、无障碍、合成、授权中介、窗口绑定、重校验、
       停止冷却、审计

host-core 拥有目标枚举、无障碍检查、事件合成、授权中介、授权当前绑定哪个窗口、动作预算、每动作重校验与审计记录。它是唯一能够拒绝的组件。回路与截取放在 Electron Main,因为回路需要模型 Provider、截取需要 Chromium,而 host-core 两者都不持有(见 05-host-core-rust 第 3 节)。

Renderer 永不拿到原生窗口句柄、原生元素引用或输入原语;它只拿到指示器的授权视图和浮层的绘制指令,并且完全不能签发授权或枚举窗口。Agent sidecar 只能通过现有 host.proxy 白名单中的 tools.execute 触达该工具——不新增代理方法;computer.* 不是插件宿主 API,也不出现在插件权限矩阵中。

Computer 沿用 GenerateImages 的形状:host-core 把它归为 high 并通过 tools.execute 做权限评估,Main 中的处理器只有在宿主放行后才运行。

授权与作用域 ​

作用域授权(scope grant) 是权限单位。自 ADR 0344 起,Computer 工具处理器在会话没有活动授权时,于首次调用自动签发一个不带目标的授权。

字段含义
grantId本次授权的身份;出现在每个工具结果和审计行中
scopedesktop(自动、可改绑)或 window(钉在一个窗口上)
target当前绑定的那一个窗口——不是整个作用域
revision绑定窗口的测量几何或身份变化时递增,包括每次改绑
inputPolicyautonomous-in-scope(默认)或 confirm-each(已定义、未实现)
capturea11y-only(默认)或 a11y-and-pixels
actionBudget授权关闭前剩余的输入动作数
idleExpiry墙钟上限;长时间无动作的授权自行关闭

规则:

  • desktop 授权初始绑定宿主不拒绝的最前窗口,之后可改绑到任何宿主不拒绝的窗口。window 授权是钉死的:改绑请求即作用域越界。目前 UI 不会签发 window 授权。
  • 绑定会对一次全新枚举重跑全部拒绝——自我目标、拒绝名单、提权——并且总是推进 revision,因此上一个窗口的每个 uid 与坐标 basis 都立即失效。computer.act 永不绑定窗口;它只在上一次检查所描述的窗口上动作,否则拒绝。
  • 绑定窗口消失时,desktop 授权回落到宿主不拒绝的最前窗口,而已在途的动作以 COMPUTER_STALE_REVISION 被拒绝——即使调用方没有指定 revision。window 授权则被撤销:它描述的东西已不存在。
  • 模型可以请求切换到宿主列出的窗口,但不能臆造窗口。它不能扩大作用域、提高预算或关闭某条拒绝;被拒绝的窗口会作为一步回报给它,而不是变成重试循环。
  • 每个桌面实例最多只有一个活动授权,与实时语音的单通话槽位一致。授权属于签发它的会话与轮次链;子 Agent 继承活动授权,但不能创建第二个。
  • 启用该功能是用户的决定,且没有自动截止期限(ADR 0310)。所有权限模式表现一致。语音路径(阶段 3)接通后也不带来任何自有权限:一句口述请求变成会话上的工作请求,该会话的轮次拿到与键入路径相同的自动授权和相同的拒绝。
  • 用户随时可以撤销:指示器的"停止"、关闭目标,或关闭该功能。"停止"同时撤销授权并中止持有它的轮次,而且 host-core 在之后 30 秒内以 COMPUTER_STOPPED_BY_USER 拒绝 Agent 自行签发——否则同一轮次的下一次工具调用会立刻再签一个。用户自己签发的授权会立即清除该冷却。
  • 授权从不持久化。重启、Renderer 重载或窗口导航都不会留下授权。

绝对拒绝 ​

以下两条拒绝不可通过任何权限模式、设置、授权选项或 auto 策略触达:

  1. 该能力永不以 PI-Desktop 自身窗口为目标——审批卡片、设置、密钥界面、实时语音悬浮件、插件视图。向本应用合成输入等于直接绕过权限中介。
  2. 当操作系统报告安全输入状态,或焦点落在密码字段时,截取与合成一律拒绝。 拒绝以错误码上报;该字段内容永不进入快照、截图或日志。

在这两条之上还有一份用户可编辑的应用拒绝名单。其中内置的凭据界面条目——平台钥匙串与凭据 UI、操作系统认证对话框——不可移除。

这些拒绝是桌面作用域的定义,而不是它上面的窟窿:"整个桌面"的含义就是宿主不拒绝的每个窗口,并在每次绑定时重新核验,因此被拒绝的窗口不会因为等待或切换而变得可达。

工具契约 ​

Computer 是内置高风险工具而非插件工具,因此它的影响面无法被表达成插件作者可以申请的权限。Plan 与 Goal 在权限评估之前就硬拒绝它,与 Write、Edit 相同:它改变的是工作区之外、宿主无法快照、比对或回滚的状态。

Agent 以一条自然语言 instruction 加可选 maxSteps 调用它;observeOnly 只描述作用域而不动作。它不接受 uid、坐标或窗口:寻址是内层回路的职责,绑定哪个窗口是宿主的职责。结果是一段有界摘要,说明改变了什么、跑了几步、为什么停下——不是内层回路的逐步记录。

其下由 Main 驱动以下宿主操作。它们不面向 Agent。

宿主操作风险行为
computer.capabilitieslow后端身份、保真度、各平台操作系统权限状态、会话类型
computer.requestPermissionlow由可信设置窗口向系统申请辅助功能权限;返回能力状态,不创建作用域授权;不支持的后端拒绝
computer.listTargetslow所有可枚举窗口;被拒绝的目标连同原因一起列出,绝不静默丢弃;Main 只把它交给回路,不交给 Renderer
computer.grantCreate / grantRevoke / grantDescribelow签发、撤销与读取唯一的活动授权;origin: agent 受"停止"冷却约束,不带 targetId 即签发桌面作用域
computer.inspectlow绑定窗口的结构化无障碍树:role、name、是否有值、是否可用、是否聚焦、bounds、按授权生成的不透明 uid、声明的保真度;可选 targetId 先改绑窗口
computer.acthigh重新测量绑定窗口后,执行一个已校验的动作,按 uid 寻址或按坐标配合 basis 寻址

computer.act 支持 click、double_click、right_click、set_value、press_keys、scroll 与 select。每一项都优先通过平台无障碍动作派发,只有在不存在对应动作时才回退到面向窗口的事件。截取在 Main 中通过 Chromium 的 desktopCapturer 完成,按 host-core 测得的几何裁剪,并在 a11y-only 授权下被拒绝。

元素身份以无障碍为先。uid 不透明、按授权生成,并在 revision 变化时失效。inspect 不返回元素取值,只返回是否有值,因此读取字段内容是一个用户能在转录中看到的显式 inspect 结果字段,而不是枚举的副作用。

坐标与新鲜度 ​

坐标输入只以 computer.act 配合 basis 的形式存在:basis 是授权 revision 加上同一作用域的那次截取所依据的窗口几何。宿主在合成前立即重新测量并校验 basis,并拒绝过期值。因此:

  • 模型永远无法派发盲点击。没有截取就没有 basis,没有 basis 就没有坐标。
  • 目标在截取与动作之间移动、改变尺寸、revision 变化或失去焦点时失败关闭,而不是点击此刻占据那片像素的东西。
  • 坐标相对作用域,并被夹到测得的窗口边界内。越界坐标是错误,不是被夹紧后照样点击。

绑定模型与回路 ​

电脑操作有自己的模型绑定——用户在设置里从已配置的 Provider 行中挑选的一组 { providerId, modelId },沿用 imageGeneration 的先例。对话模型不用来驱动机器,也没有静默回退:没有配置绑定时,工具报配置错误。哪个模型可以操作自己的电脑、为此花多少钱,由用户决定。

回路是 packages/computer-use 中与 Electron 无关的纯模块:

  1. 观察:绑定窗口的无障碍树、宿主给出的窗口列表(含各自的拒绝原因)、授权允许像素时再加一张作用域裁剪截图,以及授权视图。
  2. 决策:向绑定模型发一次请求,它必须按严格 schema 回答恰好一个动作,或 switch,或 done,或 ask。
  3. 校验:先校验 schema,再校验 uid 是否在当前树中、坐标是否在测得几何内、授权 revision、以及剩余预算。任何超出 schema 的内容都是拒绝,而不是尝试。
  4. 动作:执行一次 computer.act,然后重新观察。switch 则改为带 targetId 经宿主重新观察:它消耗一个回路步数,但不消耗动作预算;宿主的拒绝被记为该步,而不是结束整次运行。

回路在 done、步数上限(本次调用的 maxSteps 被授权动作预算夹紧)、被撤销、过期,或同一步反复失败时停止。模型散文绝不会未经解析进入工具结果:摘要由回路实际做过的事组装而成,切换窗口永不算作在机器上完成的工作。模型回答中的任何内容都不能扩大作用域、触达被拒绝的窗口、提高预算或关闭某条拒绝。

Agent 的光标是画出来的,不是抢来的 ​

动作通过无障碍动作或面向窗口的事件派发,因此真实系统光标永不被挪动。Agent 工作期间用户的鼠标和键盘仍归自己;只能靠挪动真实指针来动作的平台路径会被拒绝而不是被采用。

一个独立的无边框、透明、穿透点击、置顶浮层窗口画出 Agent 自己的光标:它移动到即将被操作的元素上,并在动作派发时显示一次按下。该浮层只是可视化。它不拥有动作的任何部分,永不接收输入(创建时即忽略鼠标事件),画不出来既不会阻塞动作也不会替代动作。它也不是动作落点的事实来源——宿主的重新测量才是,浮层跟随它。浮层随授权一起关闭。

权限流程 ​

设置开关治理这项能力;权限模式不再收窄它(ADR 0344)。

阶段askaccept-editsauto
创建授权Agent 首次调用时自动自动自动
检查、截取、切换窗口与作用域描述允许允许允许
autonomous-in-scope(默认)下的一次输入动作允许允许允许
confirm-each 下的一次输入动作未实现未实现未实现
"停止"后 30 秒内新建授权COMPUTER_STOPPED_BY_USER同左同左
Plan / Goal硬拒绝硬拒绝硬拒绝

autonomous-in-scope 在所有权限模式下都是默认值。confirm-each 仍保留在设置契约中,但背后没有审批卡片,因此设置页不提供该选项:一个什么都没收窄的控件只会误导用户。运行始终受动作预算、空闲过期、每动作重校验与"停止"约束。Computer 不存在 allow-session 授权:作用域授权本身就是会话级决定。

平台支持 ​

三个桌面平台都在范围内。截取各平台一致——Chromium 的 desktopCapturer,在 Main 中按 host-core 测得的几何裁剪——因此只有检查与输入是平台相关的工作。

平台检查与输入阶段说明
macOSAXUIElement 动作,需 Accessibility TCC 授权;按键用 CGEventPostToPid 投向被授权应用1手写 framework FFI,不引入新 crate;安全输入会同时拒绝截取与输入。无障碍窗口与 CGWindowList 条目通过 _AXUIElementGetWindow 返回的窗口 id 对应(用 dlsym 取,取不到则退回几何匹配,D683)——台前调度显示缩略图时,窗口服务器与无障碍对同一窗口的几何说法不同,只靠几何会拒绝所有不在台前的窗口。授权的几何取无障碍的窗口框,因为元素 bounds、坐标夹取、绘制光标与截取裁剪都在这个坐标系里
WindowsUI Automation 模式,回退到面向窗口的消息2由更高完整性级别进程拥有的窗口被拒绝,绝不静默丢弃
Linux / X11AT-SPI 动作,尽力而为2需要无障碍总线;工具包不支持时如实上报,不做猜测
Linux / Wayland拒绝输入—不存在可移植的合成输入;截取仍通过门户可用

后端尚未落地的平台,在任何需要它的操作上都返回 COMPUTER_PLATFORM_UNSUPPORTED,并且 computer.capabilities 会在用户尝试之前就说明这一点。保真度只是部分的后端必须在自己的 inspect 结果里声明,而不是返回一棵读起来像空窗口的空树。缺失的能力永不表现为挂起,也永不以成功回报空操作。

设置与 UX 界面 ​

  • 电脑操作默认关闭。打开开关本身不会申请操作系统权限、截取画面或枚举窗口——但它确实授权 Agent 在下一次 Computer 调用时开启覆盖整个桌面的授权,因此这一行如实说明这一点,而不是描述一个已经不存在的"交接"。
  • 设置页陈述作用域而不提供选择:每次一个窗口、Agent 可自行切换、PI-Desktop 自身窗口与凭据界面永不可达、"停止"结束整次运行。在 confirm-each 还没有卡片之前,不提供输入审批行。
  • 模型绑定是显式的。设置里提供用户已配置的 Provider 行;功能已开启但没有绑定是一个可见的未配置状态,而不是静默回退到对话模型。
  • 体检视图按平台报告操作系统权限状态(无障碍、截取、无障碍总线、会话类型),并区分"未申请"、"已拒绝"与"本平台不支持"。被拒绝的 TCC 授权不得呈现为功能损坏。
  • macOS 上,缺少辅助功能权限时,设置中的状态是可用键盘访问的申请按钮,功能关闭时也可点击。点击 pi-desktop/computer/permission/request 后,由 Main 的 systemPreferences.isTrustedAccessibilityClient 查询并申请主应用自己的 TCC 权限,不再让身份可能不同的 Rust 子进程代为申请。宿主的 computer.requestPermission 保留为后端 API。仍未授权时,Main 打开固定的系统设置辅助功能页面,由用户手动开启开关;不会自动获得权限或交接目标。macOS 的可信查询无法区分未申请与已拒绝,两者均在获准前显示 not-requested。
  • 请求期间显示忙碌并禁用按钮,重复点击不会重复申请。申请失败或系统设置打开失败会显示错误码并允许重试。返回应用或页面再次可见时仅重新查询能力,不再次弹授权提示。过期查询不得覆盖申请结果;卸载页面清理监听并丢弃未完成结果。已授权与不支持状态仅显示标签。申请 IPC 拒绝非主窗口来源,不新增 host.proxy 白名单入口。
  • 桌面能力信息新增可选 applicationAccessibility,由 Main 实时查询;原 accessibility 继续表示操作后端的系统权限。设置优先显示主应用权限,旧宿主无新增字段时仍回退到原字段。如果主应用已授权而后端未授权,显示已授权标签并单独提示后端权限异常。主应用查询结果仅用于显示,不传给 host-core 作为放行依据,检查、窗口交接和输入仍由后端核验。adhoc 构建的应用与可执行路径可能有不同 TCC 身份,系统设置中的应用勾选不代表后端已能操作。
  • 申请后仍未授权时,在页面可见期间每秒查询一次能力,最多持续 60 次计时。轮询不弹权限提示,主应用获准或页面卸载时停止;轮询结束后,焦点与可见性恢复仍会重新查询。等待中的请求不重复执行。
  • 没有目标挑选器,也没有授权卡片。Renderer 既不能枚举窗口也不能签发授权,因此这两个界面根本不存在,也就无从绕过。
  • 授权指示器在授权存续期间始终可见,标明当前绑定的窗口并随每次改绑更新,显示剩余预算与截取模式,并带有"停止"。应用退到后台时它仍然可见;没有活动授权时它完全不出现。
  • "停止"撤销授权,并在持有它的轮次属于当前会话时中止该轮次。它永不中止其他会话的工作。
  • 光标浮层在一次授权的首次观察时出现,切换窗口时重新框住新窗口,并随授权一起关闭。

指示器、浮层与体检视图的组件级措辞随实现变更落地,不在本页。

审计与隐私 ​

每一次授权、每一次改绑与每一个动作都通过现有 audit.* 落盘:授权身份、作用域、签发方(agent 或 user)、目标身份、动作类型、元素 role 与 uid、以及结果。改绑追加 computer.grant.rebound 并记录移动到的应用身份,因此审计能看出一次桌面授权实际碰过哪些应用。键入的文本只记录长度,绝不记录取值。像素永不写入审计日志。

进入模型的截图走现有的无损工具图片存储路径,裁剪到授权作用域并缩小;因此在 a11y-and-pixels 下它们会留存在会话转录里——这正是 a11y-only 存在的原因,也是授权卡片要点明该选择的原因。被截取的像素、无障碍取值与从窗口读到的文本都是不可信输入:它们是数据,绝不是能改变 Agent 作用域、工具、授权或权限的指令。

错误码 ​

错误码登记在 08-error-codes §3.10,统一使用 COMPUTER_ 前缀。契约是每一种拒绝都可单独归因:功能关闭、未配置绑定、无授权、用户已停止(冷却期内)、作用域越界、basis 过期、revision 过期、预算耗尽、授权过期、拒绝自我目标、拒绝安全输入、目标在拒绝名单上、缺少操作系统权限、目标提权、平台不支持、元素未找到或不可操作、模型回答超出动作 schema,以及超时。

验证与限制 ​

  • 在任何部分交付之前,自动化覆盖必须包含:自我目标拒绝、安全输入拒绝、basis 与 revision 过期拒绝、坐标夹取、预算与过期关闭、单授权互斥、Plan/Goal 拒绝、不支持平台的路径、缺少绑定的路径,以及模型回答超出动作 schema 的情形。
  • 桌面作用域另外要求:绑定最前可用窗口、整桌面无可用窗口、改绑重跑全部拒绝、window 授权拒绝改绑、绑定窗口关闭后回落并拒绝在途动作,以及"停止"冷却拒绝 Agent 自签而放行用户签发。
  • 回路的覆盖不需要 Provider:模型调用是注入的,因此 schema、校验、步数上限与停止条件都用脚本化回答做单测,包含畸形与对抗性回答。
  • 无障碍树、合成路径与截取路径都与平台相关,无法用 fixture 证明。各平台的真机验收是单独且需显式授权的矩阵;fixture 全绿不等于真机通过。
  • E2E 场景列在 04-e2e-test-plan 的 E2E-COMPUTER-USE- 前缀下。

本地优先 · 模型可替换 · 插件可扩展。 AIUO.NET