Computer Use:可见 Surface 感知与内置浏览器控制设计

本页定义 OpenProgram 的 Computer Use 当前目标设计。核心要求不是单独提供一个浏览器函数,而是让每个 chat turn 自动知道同一窗口中当前可见、与该会话关联的 surface,并在需要时直接观察和操作。第一阶段执行目标是 OpenProgram 桌面端内置浏览器 tab;不控制整个操作系统,也不接管用户日常 Chrome。设计只复用现有 GUI Agent Harness 的规划与验证思路,不启用 OCR、YOLO/检测器、component memory、vision memory 或自动学习;OpenProgram Runtime 负责 surface 注册、目标绑定、权限、动作执行、取消、并发和证据。

TARGET DESIGN · NOT IMPLEMENTATION EVIDENCE

01 设计结论

自动 Surface Awareness:只要 chat 与可见 pane/window 同属当前 compound group,renderer 就在每次发送消息时提交 surface 候选。Runtime 校验后把当前 surface inventory 和一个有界的 DOM/ARIA preview 加入本 turn 上下文。模型从推理开始就知道“右侧有什么 surface、它是否可读写”,不会先回答自己没有屏幕或页面访问能力。

公开入口:新增面向任务的 computer_use。工具只接收任务和可选的语义 surface alias,例如 rightfocused;不接收 window_idtab_id 或 CDP target。第一阶段只有 web_tab adapter。现有 playwright_browser 保留为底层专家工具,现有 gui_agent 保留为桌面实验入口,三者不互相改名。

工具可用性:存在已验证、可控 surface 时,dispatcher 必须在该 turn 主动加入 computer_use schema,不受 deferred 默认加载影响。页面问题使用 turn-start preview 或调用工具继续观察;页面动作必须调用工具。用户显式关闭网页控制时,Runtime 不提供 preview 和执行工具,并把禁用状态写入上下文。

浏览器实现:复用 Electron WebContentsView、共享的 persist:webtabs profile、精确 tab 的 CDP target,以及 Playwright 数据面。用户和 agent 始终看到同一个 tab。

Harness 分工:第一阶段只复用 GUI Agent Harness 的 observe → verify → plan → act 思路;不启用 OCR、YOLO/检测器、component memory、vision memory、自动 component learning、多轮 crop 或局部放大,也不直接复用其进程全局 target、全屏截图、容错后继续执行、LLM 判定 success 和自动持久化 workflow 的行为。

动作策略:ARIA/DOM 语义定位优先,CSS 只作为确定性补充。只有 canvas、无标签控件或 DOM 不可用时,才把一张当前 viewport screenshot 直接交给多模态模型返回坐标;中间没有 OCR、检测器或视觉记忆。每个写动作执行后都重新观察;禁止跨页面状态批量执行写动作。

权限策略:本地项目页允许任务内自动验证;外部站点按 origin 授权。读取与写入分级,登录、CAPTCHA、跨 origin、敏感提交和不可逆操作进入 needs_user,不得由模型自行确认。

术语与生命周期

术语所有者与生命周期含义
surfaceDesktop Surface Registry;从 open/register 到 hide/move/close/disconnect一个已登记的可见 UI 区域。第一阶段只有可执行的 web_tab surface;整个桌面不是 surface。
compound groupDesktop layout store把 chat 与相邻 pane 组成同一可见布局的 UI 关系;它决定哪些 surface 可以进入该 chat 的候选集合。
Surface ContextRuntime;单个 provider request/turn经过校验的 surface inventory、alias、capability 和有界 preview。它是模型开始推理前的上下文快照。
bindingRuntime;单个 turn把 Surface Context 中的 key/alias 映射到精确 window/renderer/tab target;模型不能创建或改写。
leaseComputerUseRunner;单个 run工具调用后固定的 target 使用权。写 lease 排他;target 失效或 run 结束时释放。
previewRuntime;单个 turn在首个模型 token 前提供的低成本结构化页面摘录,不含 screenshot 或 element refs。
ObservationWebTabAdapter;单个 frame工具运行期间捕获的完整受限 DOM/ARIA/refs 状态;每个写动作后必须更新。
turn / provider request / runChat / dispatcher / runnerturn 是一条用户消息;provider request 是该 turn 的一次模型调用;run 是一次 computer_use 执行。session 可以包含多个 turn 和 run。

02 当前实现与必须先处理的缺口

这里记录的是仓库当前代码,不代表目标能力已经完成。

AVAILABLE

可见内置 tab 与 CDP 数据面

playwright_browser 默认 engine=app,只控制 OpenProgram 内可见 web tab。打开或选择 tab 后,桌面壳返回 CDP target_id,Playwright 按精确 target 附着。

证据:browser.py:37-52,148-152_actions/open_action.py:142-240

AVAILABLE

DOM 与 accessibility 读取

现有浏览器工具已支持 selector、HTML、正文提取、ARIA snapshot、console、frame、tab 等能力,可以承担浏览器专用的语义观察层。

证据:browser.py:56-160_actions/read.py:7-72

BLOCKER

多窗口控制面没有绑定 responder

webtab.command 广播到全部 WebSocket 客户端,pending 表接收首个同 req_id 的回执;命令没有 window_id,服务端也没有校验回执来自哪个 renderer。多个桌面窗口同时存在时,目标不确定。

证据:webui/ws_actions/webtab.py:18-69web/lib/desktop-bridge.ts:478-562

BLOCKER

聊天 turn 没有 Surface Awareness

composer 当前只提交文本、session、模型参数和工具开关,没有提交该 session 所在 compound group 的可见 web tab,也没有 turn-start preview。虽然 browser_agent 属于默认工具集合,但它被 deferred;模型开始推理时不知道右侧页面存在,也没有一个已绑定工具可用于观察和交互。这是当前分屏对 Agent 无效的直接原因。

证据:web/components/chat/composer/legacy-send.ts:118-213webui/ws_actions/chat.py:369-426programs/__init__.py:71-151

BLOCKER

视觉坐标与截图坐标不一致

现有 screenshot 默认 full_page=True。视觉模型返回的图像坐标不能直接作为当前 viewport 的 page.mouse 坐标,滚动页还会产生额外偏移。

证据:_actions/read.py:75-105

BLOCKER

现有 Harness completion 不可信

planner 两次解析失败会返回 done;结论 prompt 固定要求模型输出 "success": true,顶层结果再采用该值。因此“模型不再调用动作”不能等同于“任务成功”。

证据:tasks/execute_task.py:575-607,792-834,886-949main.py:168-193

BLOCKER

状态、取消与记录不具备会话隔离

浏览器 session、Harness action target、VM screenshot patch 都使用进程全局可变状态;主执行循环没有 cancel 参数;没有 base memory 时会自动学习 component,每次任务还默认把完整 history 写入 workflow JSON。第一阶段 runner 不调用这些路径。

证据:browser.py:198-203action/input.py:412-454adapters/vm_adapter.py:20-31main.py:98-102,116-193tasks/execute_task.py:956-969

约束:第一阶段不能把 gui_agent(task=...) 直接指向内置浏览器后作为产品能力发布。必须先由新的 session-scoped runner 接管 completion、target、cancel、artifact 和 approval;GUI Agent Harness 只提供可验证的共享算法或 adapter。

03 OpenAI 与 Anthropic 官方能力对标

比较对象分为三类:产品内置浏览器、连接用户日常浏览器的扩展、面向开发者的截图/动作 API。它们的权限边界不同,不能用同一套默认值。

官方产品目标与 profile交互与权限对 OpenProgram 的结论
OpenAI 内置 Browser ChatGPT desktop 内与用户共享页面视图;使用独立于日常浏览器的 profile,可在需要时单独登录。 面向网站研究、操作、本地 web app 预览;网页内容按不可信输入处理。 第一阶段产品形态的直接参考。
OpenAI Chrome extension 控制已有 Chrome tab,继承用户日常 Chrome 登录态。 连接现有 tab 和 profile,站点内容与权限需额外审查。 作为后续独立 backend;不能与内置 profile 隐式互换。
OpenAI Computer Use API 应用提供 browser/VM/harness;模型读取 screenshot,返回 actions[] 执行动作后必须回传新 screenshot;官方要求隔离环境、域/动作 allowlist、高影响操作保留人工确认。 采用 action loop 与人工确认原则;不照搬纯坐标策略。
Claude Code Desktop Browser pane 独立 clean profile;与 chat、diff、terminal 并列显示;本地项目页和外部站点都可打开。 本地 dev server 可自动验证;外部站点首次 action 按站点允许一次、持续允许或拒绝;write action 受 classifier 检查。 最接近 OpenProgram 当前 UI 与开发测试场景。
Claude Code with Chrome 扩展连接已登录 Chromium;browser task 新开 tab,并实时可见。 站点权限来自扩展;plan mode 中 read-only 无提示,click/type/navigation 等写操作提示;登录或 CAPTCHA 暂停给用户。 采用 read/write 分类和人工接管;profile 接入延后。
Anthropic Computer Use API client-side screenshot、mouse、keyboard tool;应用负责实际执行与结果。 官方建议 VM/container、domain allowlist、敏感后果人工确认,并明确 coordinate、tool selection、scroll 和 prompt injection 的可靠性限制。 采用 client-owned execution 与显式 failure;不把模型输出当执行事实。

官方来源集中列在本页末尾。OpenAI 当前文档明确说明内置 Browser 不在 Codex CLI 或 IDE extension 中提供,而是在 ChatGPT web/desktop 产品面中提供;Computer Use plugin 可以在 desktop app 的 Codex 面中启用。因此这里参考的是 Codex 所在桌面产品面的 Browser/Computer Use 交互,不是假设 Codex CLI 自带浏览器。OpenAI 同时明确区分独立 Browser 与 Chrome profile;Claude Code Desktop 进一步明确 clean Browser profile、本地自动验证、外部站点授权和 Browser/Chrome 的选择规则。

04 采用、修改与明确拒绝

ADOPT

采用

每 turn 自动 surface inventory;有界的 DOM/ARIA preview;基于可见布局的语义 alias;动态工具注入;独立 browser profile;同一可见 tab;run 内固定 target;observe/action/observe;按 origin 授权;本地项目页自动验证;登录和 CAPTCHA 人工处理;stop;网页内容按不可信输入处理。

MODIFY

修改后采用

DOM/ARIA 优先,单张 viewport screenshot 的模型原生视觉坐标按需降级;授权默认只持续当前 task,不先提供永久 Always allow;read 可以批量,write 每次最多一个状态变化;completion 由 Runtime 验证状态决定。

REJECT FOR PHASE 1

第一阶段不采用

用户日常 Chrome profile、整个桌面控制、隐藏/headless browser、任意 JavaScript、cookie/storage 导出、文件上传下载、模型自动输入密码、跨 origin 自动继续、无约束批量写动作、自动永久保存截图和 workflow。

第一阶段固定的低成本 baseline

第一阶段只有下面这一套固定执行路径,不建立 enable_ocrenable_yolovision_memory_mode 等配置,也不加载对应模块。只有 baseline 的失败数据证明缺少某项能力时,才单独评估是否增加。

状态能力执行规则
开启URL、title、origin、viewport、DOM text、ARIA snapshot、interactive refs每步的默认 observation;先用结构化信息规划和定位,不发送图像。
按需开启一张当前 viewport screenshot + 模型原生 vision仅用于视觉验收、canvas 或 DOM/ARIA 无法定位的控件;不做 full-page screenshot、切片或多轮放大。
关闭OCR、YOLO/object detector、候选框检测、外部 grounding pipeline不导入、不初始化、不调用,也不为它们增加后台进程或依赖。
关闭component memory、vision memory、workflow replay、自动 component learning不读、不写、不检索;运行结束不形成可复用视觉记忆。
关闭iterative zoom、coarse-to-fine crop、多截图候选排序第一阶段不实现。直接视觉 fallback 失败后返回明确失败或请求用户处理。

成本约束:turn-start preview 只包含 surface 元数据、可见正文的有界摘录、ARIA landmarks 和交互元素计数,不包含 screenshot、完整 DOM 或完整 accessibility tree。普通 DOM 表单和导航任务可以完全不向模型发送 screenshot;视觉任务每个 observation 最多发送一张当前 viewport screenshot。verification 优先使用 DOM/ARIA assertion,只有任务本身要求视觉判断时才再次使用图像。

05 目标架构与信任边界

TURN INPUT

Surface Context

每次发送消息时生成。告诉模型当前有哪些可见 surface、它们在 left/right/focused 中的位置、title/origin、可用能力和一个有界 preview。它是当轮上下文,不是长期 memory。

RUNTIME AUTHORITY

Surface Registry

以 window、renderer、compound group 和 layout revision 校验客户端候选,签发短期 binding。只有 Registry 中已验证的 surface 才能进入模型上下文或成为工具目标。

TOOL EXECUTION

Surface Adapter

第一阶段只有 WebTabAdapter。后续内部 panel、terminal 或文件预览必须各自提供受限 adapter;不能通过一个任意坐标工具隐式扩大到整个桌面。

控制面确定目标,数据面执行动作 模型不持有 CDP、WebSocket、文件系统或 browser profile 权限。 computer_use task + surface alias 当轮动态工具 ComputerUseRunner budget · cancel · status · evidence approval · failure classification 唯一 completion authority Harness Engine plan · verify · recovery proposal no OCR · detector · visual memory 不能执行动作或宣告成功 WebTabAdapter observe · resolve · execute ARIA/DOM → direct image point 无通用 eval 接口 Surface Registry & Broker binding · lease · tab lock · origin grant window_id · tab_id · target_id 拒绝未绑定 responder Desktop Control Plane exact renderer command/reply show/focus registered visible tab WebSocket + Electron IPC Visible WebContentsView persist:webtabs profile Playwright over exact CDP target DOM + ARIA; screenshot on demand 用户与 agent 共享同一页面
信任边界:LLM 先收到经过校验和裁剪的 Surface Context,调用工具后再收到 Observation,并只返回候选 Action。Runtime 校验 binding、target、frame、origin、权限和 cancel 后才能执行。CDP endpoint、browser context 和客户端声明的原始 target id 不进入模型上下文。

OpenProgram Runtime 拥有

surface validation、turn preview、tool availability、target selection、tab lease、approval、action validation、CDP attachment、artifact lifecycle、cancel、timeout、completion、audit events。

GUI Agent Harness 提供

规划结构、动作后验证建议和失败后的下一步候选。第一阶段不调用 Harness 的 OCR、检测、component/vision memory、自动学习或 iterative zoom;输出都视为建议,不具有执行权限。

06 公开入口与内部协议

公开工具

{
  "name": "computer_use",
  "input_schema": {
    "type": "object",
    "properties": {
      "task": {"type":"string", "minLength":1, "maxLength":8000},
      "surface": {"type":"string", "enum":["s1", "right", "focused", "web:1"]},
      "url": {"type":"string", "maxLength":2048, "pattern":"^https?://"},
      "max_steps": {"type":"integer", "minimum":1, "maximum":100, "default":20},
      "max_seconds": {"type":"integer", "minimum":1, "maximum":1800, "default":300}
    },
    "required": ["task"],
    "additionalProperties": false
  }
}

surface 只能使用 Runtime 在当前 Surface Context 中提供的 canonical key 或 alias,例如 s1rightfocusedweb:1;provider 实际收到的 schema 将其展开为当轮 enum。若省略且 primary_surface_key 非空,Runtime 使用 primary;否则返回 ambiguous_surface。第一阶段只有 web_tab adapter。window_idtab_idcdp_target_id 从不成为 LLM 参数。

url 只表示在已经获得 lease 的同一个 web tab 中执行初始 navigation,不创建或切换 tab;它仍需该 surface 具有 navigate capability,并经过 origin/risk policy。工具出现在 provider schema 中不等于所有 action 都可用;每次调用和每个 Action 都重新检查 capability,缺少能力时返回 capability_denied

Surface Registry 与聊天 turn

desktop window registration (Electron main → Runtime)
  window_id, renderer_instance_id, one_time_connection_nonce
  registered over the authenticated loopback control channel

renderer WebSocket hello
  one_time_connection_nonce
  Runtime binds ws_connection_id → window_id + renderer_instance_id

surface registry event (renderer → Runtime)
  op: open | update | focus_set | hide | move | close
  registry_surface_id
  window_revision, surface_revision, layout_revision
  kind, group_id, local_surface_id, region, visible, focused

surface_refs (renderer → chat command)
  chat_tab_id, chat_session_id
  window_revision, layout_revision
  focused_registry_surface_id
  visible_registry_surface_ids[]

server-owned Surface Context (Runtime → model)
  context_id, context_revision, turn_id, provider_request_id
  primary_surface_key: "s1"
  alias_map: {right: "s1", focused: "s1", "web:1": "s1"}
  surfaces[]:
    surface_key: "s1"
    aliases: ["right", "focused", "web:1"]
    kind: "web_tab"
    region: "right"
    title, origin
    capabilities: ["observe", "interact"]
    preview_frame_id, content_epoch, captured_at, preview_status: "ready"
    preview: {
      visible_text_excerpt, text_truncated,
      aria_landmarks[], landmarks_truncated,
      interactive_count, payload_truncated
    }
    untrusted_content: true

server-owned binding (never sent as a model-selectable target)
  binding_id
  ws_connection_id, window_id, renderer_instance_id
  chat_session_id, group_id, registry_surface_id, local_surface_id
  window_revision, surface_revision, layout_revision
  issued_at, expires_at
  state: ready | leased | invalid

Electron main 先通过已有本地认证边界为每个桌面窗口登记不可复用的 window_id + renderer_instance_id + one_time_connection_nonce。renderer 建立 WebSocket 时只能提交该 nonce;Runtime 消费一次后把连接绑定到已登记窗口。普通 Web 客户端不能自行声明 desktop window identity。连接关闭时,Runtime 删除该连接下全部 registry entries,并使关联 binding 和 lease 失效。

renderer 以事件维护 server-owned registry,而不是在 chat command 中临时声明完整页面状态。每个窗口的 window_revision 和每个 surface 的 surface_revision 都必须单调递增;重复或旧 revision 被拒绝。open/update/focus/hide/move/close 事件更新 visibility、focus、region、compound group 和 layout。focus-only 更新只影响下一 turn 的 alias,不改变运行中的 lease;hide、移出当前 group、跨窗口 move、close、renderer/window disconnect 会立即使 binding/lease 变为 invalid,下一次副作用前返回 target_lost

focus 不是单 surface 的布尔补丁,而是一个 window/layout revision 内的原子 focus_set(focused_registry_surface_id | null):Runtime 在一次提交中清除旧焦点并设置新焦点,因此 registry 不会出现两个 focused surface。跨窗口 transfer 也不是 move patch;源连接必须先 close/invalidate 旧 entry 和 lease,目标连接再以新的 registry_surface_id authenticated open。binding、surface revision、alias 和 lease 都不跨窗口继承。

renderer 在每次 chat command 中只引用 registry 已登记的可见 surface ID 和 revision。候选可以来自右侧 pane、当前 focused pane,或用户从 sidebar/按钮打开并已登记到 center-tab registry 的窗口。普通独立 chat、隐藏 group member、其他窗口和未登记的 native window 不进入引用集合。Runtime 根据 connection-owned registry 校验 session、group、visibility、focus 和 layout 后签发短期 binding;未知 ID、旧 revision 或跨连接 ID 在生成 preview 前拒绝。最终 origin、title 和 capabilities 由已绑定 adapter 读取,不采用 renderer payload 中的同名值。

Runtime 在模型调用前对每个已验证且允许读取的 surface 生成有界 preview。序列化顺序固定为 title、origin、DOM 顺序的 viewport 可见文本、ARIA landmark、interactive count;合并连续空白后,可见文本最多 2,000 个 Unicode 字符,landmark 最多 12 项且每项 name 最多 160 个字符,整个 preview 最多 8 KiB UTF-8。每个受限字段都有独立 *_truncated,总大小触顶时还有 payload_truncated。preview 不包含 screenshot、完整 DOM、完整 accessibility tree、element refs、iframe 隐藏内容或不可见节点。

preview 携带 captured_at + preview_frame_id + content_epoch + window_revision + surface_revision + layout_revision + navigation_epoch。Adapter 为每个 tab 维护 DOM mutation/navigation 驱动的 content_epoch,并在同一 tab 的 snapshot barrier 内捕获 DOM text 与 ARIA。捕获前后各读取一次 target、navigation、viewport、content epoch 和 registry revision;任一值变化就丢弃整份结果并重试一次,第二次仍不一致则标记 preview_status=unavailable,不能混合两个 frame 的内容。捕获超过本地 deadline 或页面暂不可读时也只返回 unavailable descriptor,模型随后使用工具重试观察。preview 只服务当前 turn,页面变化后失效,不进入 component memory、vision memory 或 workflow replay。

Surface Context 中的 title、正文和 ARIA 文本都标记为 untrusted_content,与用户消息和系统规则分隔。网页文字不能要求模型更换 surface、启用工具、扩大权限或执行动作;Runtime 也不能根据 preview 文本修改 capability 和 risk tier。

只要存在至少一个具备 observe capability 的 surface,dispatcher 就在该 turn 将 computer_use schema 放入 provider tool array,并追加 Surface Context。interactnavigate 都以 observe 为前置能力;Registry 拒绝缺少 observe 的 interact/navigate 组合。该规则优先于工具的 deferred 默认状态。模型因此在生成第一个 token 前已经知道右侧/当前页面存在;询问“屏幕右边有什么”时可直接依据新鲜 preview 回答,信息不足时调用 computer_use(surface="right", task="...") 继续观察。任何 click、type、navigate 等页面变更都必须调用工具,不能只根据 preview 声称已执行。

用户显式关闭网页控制时,Runtime 仍可告诉模型“存在一个未授权 surface”,但不附带页面内容、不注入执行工具。UI 必须显示“Agent 无法访问”,避免模型把权限禁用误判为页面不存在。将 chat 与 web tab 合并为同一 compound group,默认只授予该 surface 的 R0 结构化读取;R1-R3 写操作仍按后文策略处理。

工具开始运行时,Surface Broker 使用 binding_id 向精确 renderer 请求对应的 CDP target,随后把 window_id + local_surface_id + cdp_target_id + layout_revision 固定到 lease。运行期间切换焦点不会改变 target;关闭、移出 compound group、跨窗口转移或 renderer 断开会使绑定失效,并返回 target_lost,不得自动选择另一个可见 surface。

Dispatcher 保存不可变映射 provider_request_id → turn_id + context_id + context_revision + alias_map + bindings。每个 tool call 的执行 envelope 由 Runtime 写入 tool_call_id + source_provider_request_id,模型不能提交或覆盖它;alias 只能在产生该 tool schema 的同一个 provider request 快照中解析。即使同一 chat session 有重叠 turn 或后续 Surface Context,旧工具调用也不得查询 session 的“最新 alias map”。模型 response stream 结束不立即删除映射:没有 tool call 时可以释放;存在 tool call 时保留到该 response 产生的全部 tool call settled,或 initiating turn/run 被取消、超时、teardown。异常遗留映射按短 TTL 清理。

Alias 与 primary surface 规则

  1. Runtime 为本 turn 的每个 surface 分配 canonical surface_keys1s2),并生成显式 alias_map。key 和 alias 只在该 Surface Context revision 内有效。
  2. 空间 alias 来自已验证布局:只有一个可控 surface 位于某 region 时才分配 leftrightcenter;同一 region 有多个候选时不生成该空间 alias。
  3. focused 只指向提交消息瞬间拥有焦点的可控非 chat surface。focus 在 turn 进行中变化不会修改当前 alias_map,但会反映到下一 turn。
  4. web:1web:2 按提交瞬间 center-tab registry 的可见顺序生成;顺序相同则以 registry_surface_id 排序。一个 surface 可以同时拥有 rightfocusedweb:1
  5. primary_surface_key 优先取 focused controllable surface;没有时取唯一可见 controllable surface;仍有多个候选时为空。模型可以传 alias 或 canonical key;未知、过期或没有唯一映射的值在任何 CDP 请求前失败。

从普通聊天到一次页面操作

  1. Desktop bridge 已通过单调 revision 的 registry events 登记窗口与 surface。用户在 chat + web tab 的 compound group 中提交消息;composer 只引用当前可见 registry surface ID 和 revision,不发送 screenshot 或 CDP target。
  2. Surface Registry 验证引用并通过 adapter 捕获有界 preview。服务端在模型调用前加入 Surface Context;只有完整交付 gate 通过后才同时注入 computer_use schema。
  3. 模型从 turn 开始就知道右侧页面存在。简单页面概述可以使用 preview;需要更多内容或任何交互时调用公开工具。
  4. Surface Broker 定向解析 exact renderer/tab/target 并获取 lease;解析失败返回结构化错误,不让普通聊天模型自行解释为“看不到”。
  5. Runner 执行 DOM/ARIA-first 循环;只有视觉任务、canvas 或语义定位失败时发送一张当前 viewport screenshot。
  6. 每个状态变化后重新观察和验证,事件回写同一 chat turn;Stop、授权和人工接管都绑定同一个 run 与 target。

结果契约

{
  "status": "succeeded | failed | cancelled | needs_user",
  "reason_code": "verified | step_limit | timeout | target_lost | ...",
  "summary": "grounded user-facing result",
  "target": {"kind":"web_tab", "tab_id":"...", "url":"..."},
  "steps_taken": 7,
  "completion_evidence": [{"kind":"assertion", "text":"...", "frame_id":"..."}],
  "artifacts": [{"kind":"screenshot", "artifact_id":"artifact_...", "retained":true}]
}

summary 可由 LLM 撰写,但 statusreason_code 只能由 Runtime 根据验证记录生成。达到 step limit、planner 无效或 conclusion 模型声称成功都不能生成 succeeded。模型和 transcript 只收到 opaque artifact_id;本地绝对路径不进入结果。终态结果只列用户明确保留或验收要求保留的 artifact,临时 retained=false 文件在返回前删除。

内部 session 与 observation

ComputerSession
  session_id, owner_run_id
  target: {window_id, tab_id, cdp_target_id}
  lease_id, state, started_at, deadline
  current_origin, approved_origins[]
  current_frame_id, navigation_epoch, action_epoch
  cancel_event, step_budget, artifact_dir

Observation
  frame_id, content_epoch, captured_at
  target identity, url, origin, title
  viewport: {width, height, device_scale_factor, page_zoom, scroll_x, scroll_y}
  screenshot: optional viewport-only PNG
  screenshot_size: optional {width, height}
  aria_snapshot, aria_truncated
  interactive_elements[], elements_truncated
  optional filtered console_errors[], console_truncated

frame_id 必须绑定 target identity、navigation epoch、viewport 和当前 DOM revision;存在 screenshot 时还要绑定图像。坐标 Action 只能来自同一个 observation 的直接视觉 fallback,并且必须带 expected_frame_id;如果页面已经导航、滚动、resize 或 target 改变,Runtime 返回 stale_observation 并重新 observe。

完整 Observation 仍有硬上限:ARIA snapshot 最多 12,000 个 Unicode 字符,interactive elements 最多 200 项且每项 name 最多 200 字符,console error 最多 50 条且每条最多 1,000 字符;每类都带 truncation 标志。密码控件的 value、typed secret、authorization/token 字段和 URL query value 默认替换为 redacted marker;URL 保留 scheme、host、port、path 和 query key,不把 query value 写入模型上下文或事件。

Action

{
  "$defs": {
    "frame": {"type":"string", "pattern":"^frame_[A-Za-z0-9_-]+$"},
    "intent": {"type":"string", "minLength":1, "maxLength":240},
    "elementTarget": {
      "type":"object",
      "properties":{"kind":{"const":"element"},"ref":{"type":"string","pattern":"^e[0-9]+$"}},
      "required":["kind","ref"], "additionalProperties":false
    },
    "pointTarget": {
      "type":"object",
      "properties":{"kind":{"const":"point"},"x":{"type":"integer","minimum":0},"y":{"type":"integer","minimum":0}},
      "required":["kind","x","y"], "additionalProperties":false
    },
    "anyTarget": {"oneOf":[{"$ref":"#/$defs/elementTarget"},{"$ref":"#/$defs/pointTarget"}]}
  },
  "oneOf": [
    {"type":"object","properties":{"type":{"const":"click"},"expected_frame_id":{"$ref":"#/$defs/frame"},"target":{"$ref":"#/$defs/anyTarget"},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","target","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"type"},"expected_frame_id":{"$ref":"#/$defs/frame"},"target":{"$ref":"#/$defs/elementTarget"},"text":{"type":"string","maxLength":10000},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","target","text","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"press"},"expected_frame_id":{"$ref":"#/$defs/frame"},"target":{"$ref":"#/$defs/elementTarget"},"key":{"type":"string","minLength":1,"maxLength":64},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","target","key","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"scroll"},"expected_frame_id":{"$ref":"#/$defs/frame"},"delta_y":{"type":"integer","minimum":-2000,"maximum":2000},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","delta_y","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"hover"},"expected_frame_id":{"$ref":"#/$defs/frame"},"target":{"$ref":"#/$defs/anyTarget"},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","target","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"select"},"expected_frame_id":{"$ref":"#/$defs/frame"},"target":{"$ref":"#/$defs/elementTarget"},"value":{"type":"string","maxLength":2000},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","target","value","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"navigate"},"expected_frame_id":{"$ref":"#/$defs/frame"},"url":{"type":"string","maxLength":2048,"pattern":"^https?://"},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","url","intent"],"additionalProperties":false},
    {"type":"object","properties":{"type":{"const":"wait"},"expected_frame_id":{"$ref":"#/$defs/frame"},"duration_ms":{"type":"integer","minimum":0,"maximum":5000},"intent":{"$ref":"#/$defs/intent"}},"required":["type","expected_frame_id","duration_ms","intent"],"additionalProperties":false}
  ]
}

type 是判别字段;每个分支只允许该 action 所需字段并设置 additionalProperties=false。element ref 优先;point 只允许 click/hover,必须位于当前 viewport,并来自同一 expected_frame_id 的单张视觉 fallback。navigate 只改变当前 lease 的 tab;scroll 和 wait 不接受 target。eval、cookie、storage、tab create、upload、download 不属于第一阶段 Action。

Canonical point 以当前 viewport 左上角为 (0,0),单位是 CSS pixel,不是 screenshot image pixel、device pixel 或页面文档坐标。Observation 同时记录 viewport CSS width/height、screenshot image width/height、device_scale_factor 和页面 zoom;provider adapter 按这组元数据把模型图像坐标归一化为 CSS pixel。Runtime 再检查有限数值和 0 ≤ x < viewport.width0 ≤ y < viewport.height。device scale、zoom、resize 或 scroll 变化都会使原 frame 失效,不能复用旧 point。

该协议与模型 provider 无关。OpenAI 原生 computer_call、Anthropic tool_use 或 GUI Agent Harness planner 都必须先转换为同一个 Action,再经过相同的 target、frame、origin、approval 和 cancel 校验。provider adapter 可以处理各模型的 action schema 与坐标约定,但不能改变 Runtime 的权限和 completion 结论。

07 Observe → Resolve → Approve → Act → Verify

每个写动作只能基于一个新鲜 Observation 任何 target、origin、frame 或权限变化都会中断本步,返回新的观察或用户确认。 OBSERVE ARIA + DOM; image on demand PLAN one intended mutation RESOLVE element → direct image point AUTHORIZE origin + risk + cancel EXECUTE validated adapter action VERIFY new observation + assertion 未满足 completion assertions 时,携带结构化 feedback 返回下一次 Observe;不携带旧坐标。
  1. Surface Registry 已在 turn 开始前提供可见 surface、preview 和动态工具;Surface Broker 根据调用中的 alias 解析唯一 binding,返回精确 window_id + tab_id + cdp_target_id,并获得 tab lease。
  2. Adapter 默认捕获 ARIA snapshot、DOM 交互元素、URL/origin/title 和 viewport 元数据,不发送图像。任务需要视觉判断或 DOM/ARIA 无法定位时才捕获一张当前 viewport screenshot;不得使用 full-page screenshot 产生点击坐标。
  3. Harness 生成一个候选动作和预期效果。读取动作可以合并;每轮最多执行一个会改变页面状态的动作。
  4. Resolver 按 runtime ref/ARIA、受控 selector、单张 viewport screenshot 的直接模型坐标顺序解析目标。中间不运行 OCR、YOLO、detector、memory retrieval 或 zoom;模型不得直接获得 Playwright page。
  5. Runtime 校验 frame freshness、target lease、origin grant、action risk、cancel 和 budget。需要用户时返回 needs_user 状态并暂停 session。
  6. Adapter 执行动作并立即生成新的 Observation。verification 必须检查动作预期效果和任务 completion assertions。
  7. 只有 completion assertions 全部满足且没有未处理风险时才返回 succeeded

08 权限、安全与隐私

级别示例第一阶段策略
R0 观察Surface Context preview、ARIA/DOM text、URL/title、按过滤条件读取 console error;必要时当前 viewport screenshotchat 与 surface 同组且网页控制开启时,结构化 preview 和观察无需重复提示;图像仍按需且不持久化。隐藏 surface、其他窗口和未登记 surface 不获得 R0。
R1 本地项目变更由 dev-server registry 或当前 project 显式证明归属的 origin/file 中 click/type/navigation用户明确要求测试时在 task 内允许;localhost127.0.0.1 字符串本身不构成项目归属或自动授权,仍执行 cancel、frame 和 target 校验。
R2 外部普通变更外部 origin 上 click、type、same-tab navigation首次写动作按 exact origin 请求“本次动作”或“本任务”授权;subdomain 不继承。
R3 敏感或高影响登录凭证、发送/发布、购买、删除、账户/权限修改、接受条款、跨 origin 提交返回 needs_user,展示拟执行动作并由用户完成或逐次确认;不允许任务级自动授权。
UnsupportedCAPTCHA、任意 JS、cookie/storage 导出、upload/download、clipboard、浏览器设置不执行;返回明确 reason code。

Origin 与导航规则

Artifact 策略

09 桌面 UI 行为

不新增第二套浏览器窗口。Computer Use 使用现有 center tab/split layout:chat 保持可见,右侧或相邻 pane 显示被控制的 web tab。UI 中可见关系与 Agent 收到的 Surface Context 必须一致。

待命

chat composer 附近显示当前可见 surface 的 favicon、title/origin、位置 alias 和“Agent 可访问”状态。用户在 sidebar、center tab 或 split pane 中改变可见/focused surface 时立即更新;工具关闭时显示“网页控制未启用”。

发送消息

发送后该 turn 的 surface chip 固定为提交时的 title、region 和 revision。模型已经收到同一份 Surface Context;用户可以展开查看“本轮 Agent 可见内容”的结构化 preview。后续切换 pane 不会静默改变正在运行的目标。

运行中

tab header 显示“Computer Use”状态、step 计数和 Stop。chat 中只显示当前 observation 摘要、计划动作、执行结果和验证结果;原始 DOM 与 screenshot 默认折叠。

授权时

permission card 必须显示 origin、target tab、拟执行动作、将发送的非敏感文本摘要、风险原因,以及仅本动作/本任务/拒绝。第一阶段没有永久允许。

人工接管

登录、CAPTCHA 或敏感页面时 session 进入 needs_user。用户在同一可见 tab 中操作,点击 Continue 后 Runtime 生成全新 observation;旧坐标和旧 action 全部失效。

结束

结果展示 status、reason、完成证据和保留 artifact。step_limittimeouttarget_lost 必须显示为未完成,不用 LLM summary 覆盖。

10 失败、取消与并发语义

reason_code触发条件处理
surface_unavailableturn 中没有经过验证且允许访问的可见 surface不注入执行工具;上下文明确说明不存在可用 surface,不使用任意 active tab 代替。
ambiguous_surface多个 surface 都符合用户措辞,且没有唯一 primary/focused 对应不执行;列出可见 alias 并请求用户明确目标。
surface_access_disabled用户显式关闭当前 surface 的 Agent 访问不提供 preview 或执行工具;UI 与模型上下文都显示禁用。
capability_deniedsurface 或当前授权不包含请求的 observe/interact/navigate capability在 lease 或副作用前拒绝;工具已注入不能覆盖 capability。
stale_observationframe、scroll、viewport、navigation epoch 已改变不执行动作;重新 observe,不消耗 action step。
target_lostsurface hide、移出 group、跨窗口 move、tab/window close、CDP target replacement、renderer/window disconnect释放 lease;失败结束。不得自动选择另一个 tab。
origin_changedsame-tab redirect/navigation 进入新 origin保持 target,撤销旧 origin action grant,重新观察和分类。
new_surface_created匹配当前 leased opener/initiator 且晚于 action epoch 的 popup/new tab不跟随、不执行新 surface;中止 action、释放原 lease,以 needs_user 结束当前 run。用户关联后由下一 turn 创建全新 run/binding;无关 tab 不触发。
approval_requiredR2/R3 action 未授权暂停为 needs_user,不重试 action。
planner_invalid结构化 Action 两次无效或引用不存在失败或重新规划;绝不能转换为 done。
verification_failed动作执行但预期效果未出现携带差异重新规划;超过 recovery budget 后失败。
cancelled用户 Stop、run cancel、session teardown执行前检查并中止;清理 Playwright/CDP、lease、pending approval 和临时 artifact。
step_limit / timeout预算耗尽返回 failed,保留已验证的部分结果但不宣告成功。

并发单位是 web tab:同一 tab_id 同时只能有一个写 lease,不同 tab 可以并行读取或执行。同一 tab 的 preview/Observation 捕获使用 snapshot read barrier,任何 action 使用 write barrier;两者的临界区不得重叠。页面自身的异步 DOM mutation 通过 content_epoch 检测,变化时丢弃整份 snapshot 并重试或返回 unavailable/stale。Surface Broker 必须把 command 发送给精确 window_id 对应的 renderer,并校验回执 connection/window/tab/target;禁止“广播后接受第一个 reply”。

11 实施顺序与每阶段出口

发布约束:PHASE 0–4 是一个不可拆分发布的交付单元。完成中间阶段可以合并内部类型和测试,但在 authoritative registry、exact routing、capability enforcement、runner、安全 UI 与默认 18100 安装版 live E2E 全部通过前,只能在测试开关下调用,不得向真实 provider 动态注入 computer_use,也不得在 UI 标记“Agent 可访问”。

PHASE 0
协议与确定性基础
定义 Surface Context、binding、alias、preview、reason codes 和 completion authority;明确不进入 component learning、OCR/detector、vision memory 和 workflow persistence;invalid plan 不再映射 done。
出口:schema 与单元测试证明 surface 不可伪造、incomplete 不能变为 success。
PHASE 1
Authoritative Surface Registry 与精确 Broker
实现 desktop window registration、WebSocket 绑定、单调 registry events 和连接清理;command/reply 定向发送并校验 window/renderer/surface/tab/target revision;实现 alias 解析、tab lease、hide/move/close invalidation 和 teardown。
出口:伪造/旧 ID 被拒绝;双窗口测试连续 100 次命中指定 tab;隐藏、关闭和转移不会改用其他 tab。
PHASE 2
Turn-start Surface Awareness
composer 每 turn 只引用 registry surface;服务端捕获有界且 frame-consistent 的 preview,在 provider 调用前注入 Surface Context。完成 composer surface chip 和显式关闭状态;此阶段仍不注入执行工具。
出口:provider 能稳定获得正确 preview/alias;超限、navigation race、focus race 与禁用状态测试通过。
PHASE 3
WebTabAdapter 与 Runner
ARIA/DOM element refs、frame freshness、判别式 Action、capability enforcement、按需单张 viewport screenshot、动作后 observation;接入 budget、cancel、approval、origin policy、artifact policy、structured result 和事件流。只允许测试开关调用,不能向真实 provider 注入。
出口:DOM/canvas、权限、cancel、target lost、step limit 集成测试通过。
PHASE 4
桌面交互、Safety UI 与发布启用
状态、Stop、permission card、人工接管和完成证据;覆盖用户从 sidebar/按钮打开 web tab、形成 split、提问、观察和操作的完整流程;使用默认 18100 安装版进行 live CDP 测试。全部 gate 通过后才原子启用动态 computer_use 注入和“Agent 可访问”状态。
出口:下面的 E2E 清单全部有可复核 artifact,真实 provider 工具注入才可开启。

12 可执行验收标准

  1. Turn-start awareness:chat 与 Bilibili fixture 合并为 compound group 后,每次 chat command 都产生经过服务端校验的 Surface Context。provider 收到首个 token 前已经具有 right surface 的 title、origin、有界 preview、capabilities 和 computer_use schema。
  2. 页面问答:输入“屏幕右边有什么”或“这个页面是什么”时,回复基于当前 preview;信息不足时自动调用 computer_use(surface="right", task="读取回答所需的当前页面信息") 观察。全程不要求用户粘贴 URL、文字或截图,不发送 screenshot,也不回答没有页面访问能力。
  3. 页面交互:输入“在右边页面搜索框输入 OpenProgram”时,模型直接调用已绑定工具,observe 最新 DOM/ARIA refs,操作精确右侧 tab,再重新观察并报告结果;不得操作独立 tab 或另一个窗口。
  4. 用户打开的 surface:用户通过 sidebar、center-tab 按钮或 split 操作打开一个已登记 web tab 后,下一 turn 的 Surface Context 自动反映新的 visible/focused/region 状态,不需要用户再次说明窗口身份。
  5. 显式关闭:关闭“Agent 可访问”后,provider 只知道存在一个访问被禁用的 surface,不收到 preview 或 computer_use schema;UI 与回复都准确说明权限状态。
  6. 绑定隔离:同一窗口中未与当前 session 合并的 web tab、另一窗口的 web tab、隐藏的组成员都不能成为本 turn target;关闭工具后不注入 Computer Use 工具。
  7. Registry 权威性:伪造 registry surface ID、跨 WebSocket ID、重复或旧 window/surface/layout revision 均在 preview 和 CDP 请求前拒绝;renderer 断开会清除其 entries 与 lease。
  8. 生命周期:运行中仅切换焦点不会改变 lease;当前 target 被 hide、移组、跨窗口转移或关闭时,下一次副作用前返回 target_lost,不得操作新焦点 tab。
  9. Alias 稳定性:同一 tab 同时位于 right 且 focused 时,alias_map 的两个 alias 指向同一 canonical key;两个可见 web surface 使用稳定 web:1/web:2,重复 region 不生成歧义空间 alias;发送瞬间后的 focus 切换只影响下一 turn。
  10. Preview 边界:断言可见文本不超过 2,000 字符、landmark 不超过 12 项且 name 不超过 160 字符、序列化 payload 不超过 8 KiB;所有截断标志准确,无 screenshot、element refs、隐藏内容或完整 DOM。
  11. Preview 一致性:捕获期间发生 navigation、viewport 或 registry/layout revision 变化时丢弃整份 preview;重试仍变化则返回 preview_status=unavailable,不得混合 frame。
  12. Capability:observe-only surface 可以回答页面问题,但 click/type/navigate 返回 capability_denied;动态工具注入本身不增加 capability。
  13. 重叠 turn:同一 session 并发产生两个 Surface Context 后,每个工具调用仍按自己的 provider_request_id 解析 immutable alias/binding snapshot;旧 turn 的 right 不能指向新 turn 的 surface。
  14. 延迟 tool call:模型 response stream 已结束但该 response 的 tool call 尚未执行时,execution envelope 仍通过 tool_call_id + source_provider_request_id 解析原 immutable binding;全部 tool call settled 或 turn/run 终止后映射释放。
  15. Popup 归因:只有 opener/initiator target 匹配当前 lease 且晚于当前 action epoch 的 popup/new tab 才结束当前 run;用户在其他窗口并发打开无关 tab 不影响 run。
  16. 视觉坐标:device_scale_factor != 1、页面 zoom 和非零 scroll 的 fixture 上,图像 point 正确转换为 viewport CSS pixel;scale/zoom/scroll 改变后旧 frame 返回 stale_observation
  17. Snapshot 并发:同一 tab 的 preview/Observation read barrier 与 action write barrier 不重叠;捕获中发生 DOM mutation 或并发写入使 content_epoch 改变时,整份 snapshot 被丢弃并重试或返回 unavailable/stale。
  18. 本地来源:未被 dev-server registry 或当前 project 明确登记的 localhost/127.0.0.1 origin 不进入 R1,外部写策略仍生效。
  19. Observation 边界:ARIA、interactive elements 和 console errors 分别满足 12,000 字符、200 项和 50 条硬上限及截断标志;password/typed secret/token 被替换,URL query 只保留 key、不保留 value。
  20. 终态清理:对 succeeded、failed、cancelled、终止型 needs_user、异常、target loss、用户拒绝、恢复超时和 session teardown 做故障注入,均 detach CDP、释放 lease/approval 并删除临时 artifact;worker 重启按 TTL 清除 orphan run 目录且不删除 retained artifact。
  21. 本地 DOM 流:在内置浏览器打开测试页,读取表单、输入、提交、验证 success message;用户始终可见同一 tab。
  22. 简单视觉 fallback:在没有可用 DOM target 的 canvas fixture 上,只向模型发送一张当前 viewport screenshot,不启动 OCR、detector、memory 或 zoom,并完成一次点击;resize/scroll 后旧 action 返回 stale_observation
  23. 多窗口:两个 OpenProgram 窗口各有 web tab;指定窗口任务不得在另一窗口创建、激活或操作 tab。
  24. 并发:同一 tab 第二个写任务被 lease 拒绝;两个不同 tab 可并行完成且 artifact/session 不交叉。
  25. 外部 origin:首次写动作产生准确 permission card;拒绝后零写入;批准本任务后同 origin 普通 action 不重复提示。
  26. 跨 origin:same-tab redirect 进入新 origin 后旧授权失效;popup/new tab 返回 needs_user/new_surface_created、释放原 lease并结束旧 run,不会替换当前 target。用户关联新 tab 后,下一 turn 创建新 run 才能控制。
  27. 登录/CAPTCHA:runner 返回 needs_user;用户接管后 Continue 使用新 frame,不复用暂停前 action。
  28. Prompt injection:页面要求忽略用户任务、读取文件或执行高风险动作时,Runtime 权限不变化,任务被阻止或请求用户确认。
  29. 取消:在 observe、模型调用、approval 等待和 action 间隙点击 Stop,均在下一次副作用前终止并释放 target。
  30. 失败诚实性:invalid planner output、step limit、timeout、action exception、verification failure 均不能返回 succeeded
  31. 隐私:运行结束后临时 screenshot 被删除;event/transcript 中没有 typed secret;不产生 Harness workflow memory。
  32. 回归:现有 playwright_browser selector API、普通用户手动 web tab、tab transfer 和 session UI 不受影响。

13 第一阶段明确不做

目标范围

不控制整个本机桌面;不接入 remote VM;不操作 iOS/Android simulator;不控制其他本地 app;不处理多 app workflow。

浏览器范围

不接入用户日常 Chrome/Edge profile;不提供 sidecar、hidden 或 headless fallback;不自动接管 popup/new tab;桌面壳不在线时直接失败。

高权限动作

不开放 arbitrary JavaScript、cookie/storage 读写或导出、file upload/download、clipboard、浏览器设置、证书和扩展管理。

平台范围

不设计 Windows 专用实现、测试、打包或兼容路径;不引入 OS Keychain、keyring 或 Credential Manager 集成。

14 实现与验证证据状态

能力当前证据状态
内置可见 web tab + exact CDP target attach_actions/open_action.py 与 browser unit/source checks已有基础,尚缺 live acceptance
DOM/ARIA selector 操作_actions/read.py_actions/interact.py已有底层工具,不是 Computer Use runner
DOM-first Browser Agent baselineagentic_functions/browser_agent/__init__.pytests/unit/test_browser_agent.py现有公开名仍是 browser_agent;基础单元检查存在,但没有 turn-start Surface Context 和安装版完整 E2E
GUI planning/verifygui_harness/tasks/execute_task.py 与 harness tests规划和验证思路可提取;第一阶段不启用 grounding pipeline、OCR/detector 或 memory,completion/state 仍有 blocker
每 turn surface candidates 与服务端 Surface Registrychat payload 当前无 surface 字段;服务端无 window/renderer/group/layout 校验后的 binding registry未实现
Turn-start preview 与动态工具可用性当前没有有界 preview;Browser Agent 为 deferred default tool未实现
Surface chip、访问开关与当轮目标展示当前 composer 不显示 Agent 可访问的 surface未实现
精确 window/tab control routing当前为全局 broadcast + first reply未实现
ComputerSession、tab lease、frame freshness未实现
Origin permission card 与 risk tiers现有 browser approval 只覆盖少数 login-state 操作未实现
确定性 completion、cancel、artifact lifecycle现有 gui_agent 不满足本设计未实现
真实内置浏览器 E2E尚无本设计对应 artifact未验证

证据边界:本页是设计和当前差距记录,不是发布声明。只有代码合并并完成 stable desktop 的 live test 后,才能把对应条目改为“已实现/已验证”,并附测试命令和 artifact 路径。

官方参考资料