DeepChat Computer Use 快照 PiP:从任务分解到验收标准的全链路实施解析
【免费下载链接】deepchat🐬DeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchat
本文基于 DeepChat 仓库中的功能任务清单 tasks.md,完整梳理「Computer Use 快照画中画(PiP)」这一功能的 17 项实施任务、实施顺序与完成定义。读完本文,你将掌握该功能如何在 MCP 工具执行链中注入运行标识、如何在进程级共享的 NativeKit 原生叠加层上实现 Browser 与 Computer Use 双来源仲裁、如何用有界图像管线消费get_window_state快照结果,以及该功能在打包 QA 与性能预算上的验收口径,并可对照仓库中已落地的源码实现逐项验证。
一、功能定位与文档状态
Computer Use 快照 PiP 的目标是:当 Agent 通过 Computer Use(CUA)工具操控桌面应用时,用户在 DeepChat 会话中无需切走窗口就能看到目标应用的最新状态。该表面是一个只读的「最新快照」PiP——它不引入轮询、不修改 CUA 运行时,帧的唯一来源是成功的get_window_state内联图片结果,外加一次合格的click成功后调度的一次私有快照刷新。
任务清单开头给出的 Status 明确了当前进度:
- 实现、聚焦自动化验证和完整渲染器测试套件已完成;
- 完整主进程套件中仍保留一个与本功能无关的 provider 元数据预期失败;
- 性能度量和打包平台 QA仍处于 open 状态(对应 T14、T15)。
设计层面的完整契约(可行性评估、目标架构、类型化契约、图像管线参数、平台矩阵、失败行为表)记录在同目录的 spec.md,实施计划见 plan.md,本文聚焦任务清单本身的执行视角。
二、任务清单全解(T01–T17)
任务清单按「身份与所有权 → 观察器与管线 → 渲染器契约 → 生命周期与回归 → 事件驱动刷新 → 度量与收口」推进。以下逐组继承原文档任务内容,并给出源码佐证。
阶段一:运行标识与进程级共享所有权(T01–T03)
这一阶段解决两个前置问题:Agent 运行身份如何在 MCP 路径上到达工具执行层,以及 NativeKit 唯一的进程级叠加层如何被两个来源安全共享。
T01 — 通过 MCP 执行链路传播 Agent 运行身份(已完成)
- 在内部接口
McpServicePort、McpService和ToolManager的调用选项中新增runId; - 由
ToolService的 MCP 分支转发ToolCallOptions.runId; - 确保该值不进入
MCPToolCall序列化与 CUA 工具参数(它只是执行元数据); - 增加聚焦的传播测试与「参数未变化」测试。
T02 — 抽取共享的进程级 PiP 协调器(已完成)
- 将 NativeKit 生命周期、能力探测、宿主/显示器同步、展示所有权从 Browser 专用适配器中移出;
- 在应用组合根中只实例化一个协调器;
- 保持 Browser 原有 Native 与 Canvas 行为;
- 维持「同一时刻只有一个可见 PiP」的不变量。
对应实现是 AgentPreviewCoordinator:从源码看,该类持有唯一的overlay、唯一的host、唯一的target,并提供claim/dismiss/hide/present等所有权原语;其toolbarOptions()在overlay.start()时按来源配置工具栏——Browser 为「Open in panel + Close」,Computer Use 只有「Close」,这正是 T03 来源档案(source profile)的落地。
T03 — 来源档案与仲裁(已完成)
- Browser 保留Open in panel与Close控件;
- Computer Use 档案只有Close,且忽略原生激活(activation);
- Browser 工具活动与 CUA 快照调用开始各自「认领」(claim)其来源;
- 帧刷新不得抢占所有权;
- 后台宿主/会话的认领不得抢占前台会话;
- 增加共享的按 run 作用域的「关闭(dismissal)」语义。
协调器内部的claims(按会话的单调递增nextClaimSequence)与dismissedRuns(按会话的 run 级抑制表)支撑了上述规则;handleActivate仅在目标来源为browser时派发激活动作,Computer Use 的激活被显式忽略。
阶段二:MCP 观察器与有界快照管线(T04–T06)
T04 — 窄范围 Computer Use MCP 观察器(已完成)
- 向
ToolManager注入started、completed、failed回调; - 使用解析后的
ownerPluginId/sourceId、原始工具名和准备好的参数; - 只观察权限解析之后的真实调用;
- 保持工具响应、中止、进度与错误语义不变。
实现见 ToolManager 的 ComputerUsePreviewObserver 注入。从源码结构看,createComputerUsePreviewCall会在缺少conversationId或runId、或 MCP 客户端不属于官方 CUA 插件时返回null,即「无身份则调用照常执行但不具备预览资格」,与任务约束一致。
T05 — Computer Use 目标与运行状态(已完成)
- 新增
ComputerUsePreviewPresenter; - 跟踪宿主、会话、run、工具调用、
pid、windowId、epoch、claim 与 dismissal; - 新 run 或新目标时移除此前的展示;
- 拒绝过期与乱序的终止结果。
对应 ComputerUsePreviewPresenter 中的ComputerUsePreviewState:epoch在started()检测到 run 或(pid, windowId)变化时自增并清空frame/pendingSnapshot;completed()在result.isError、dismissedRunId命中、runId/toolCallId/toolCallEpoch不匹配时直接丢弃结果。测试位于 ComputerUsePreviewPresenter.test.ts。
T06 — 有界快照管线(已完成)
- 只接受成功的
get_window_state的 PNG/JPEG 内联图片; - 校验 base64、输入大小、解码后尺寸与输出大小;
- 在 480 x 300 内等比缩放、不放大、编码 JPEG 质量 72;
- 同一时刻保持一个变换在途、一个最新待定结果(latest-wins);
- 帧仅驻留内存,日志不含像素。
实现中的常量与任务约束逐一对应:FRAME_MAX_WIDTH = 480、FRAME_MAX_HEIGHT = 300、FRAME_MAX_BYTES = 512 * 1024、INPUT_MAX_BYTES = 16 * 1024 * 1024(16 MiB 输入上限)、INPUT_MAX_DIMENSION = 8192、JPEG_QUALITY = 72、SUPPORTED_MIME_TYPES = {image/jpeg, image/png}(ComputerUsePreviewPresenter.ts#L57-L66)。decodeBase64额外校验 base64 长度、% 4 === 1非法长度与字符集;enqueueSnapshot用transformActive标记实现「一个变换在途」,变换期间新到的快照仅覆盖pendingSnapshot,天然构成 latest-wins 且无无界队列。
阶段三:类型化契约与渲染端(T07–T09a)
T07 — 类型化 Computer Use 预览契约(已完成)
- 新增
computerUse.setPreviewMode、computerUse.dismissPreview路由与仅 Canvas 使用的computerUse.preview.frame事件; - 通过类型化 preload 客户端暴露;
- 主进程校验路由发送者与活跃会话。
路由定义见 computerUse.routes.ts。
T08 — 渲染器生命周期协同(已完成)
- 在 Browser PiP 控制器旁挂载
AgentComputerUsePiP.vue(由ChatTabView.vue挂载,见 ChatTabView.vue); - 从既有 store/client 派生活跃会话、working 状态、路由与焦点;
- 发送
eligible、suspended、stopped三态迁移; - Native 模式下该组件是无头(headless)的,不接收任何图像事件。
T09 — Canvas 回退 UI(已完成)
- 渲染最新有效快照,仅提供一个Close按钮;
- 非控件区域可拖拽,但不向目标应用转发输入;
- 新帧完全解码前保留旧像素;
- 拒绝过期帧序列,卸载时释放渲染器资源;
- 复用既有
common.close文案,不新增用户可见文案。
T09a — NativeKit 不可用时禁用回退 UI(已完成)
- 只在存在具体 Computer Use 目标时才加载 NativeKit;
- 进程级稳定失败(加载失败)后返回
none; - 不再订阅任何渲染器帧、不渲染任何 Computer Use PiP;
- CUA 工具执行与结果完全不受影响。
从源码看,requestCurrentPresentation在协调器不可用且初始化失败后调用stopState并把 surface 置为none,同时向渲染器广播computerUse.preview.surface.changed事件(只携带身份与 surface 元数据,从不携带图像字节),渲染端据此彻底静默。
阶段四:生命周期、隐私与回归覆盖(T10–T12)
T10 — 生命周期与隐私清理(已完成)
- 宿主失焦/隐藏/最小化以及非活跃路由/会话时隐藏;
- run/会话终止、目标变化、宿主关闭、应用退出时移除;
- 保证其他宿主/会话永远不会看到被保留的像素;
- 磁盘、设置、遥测、崩溃元数据与通用 MCP 事件存储中不出现任何帧字节。
T11 — 主进程回归覆盖(已完成)
覆盖范围包括:共享协调器启停、工具栏切换、仲裁与关闭;Browser 提取后的激活、关闭、捕获刷新与面板交接;CUA 识别、权限路径、run 身份、目标变化与过期结果;合法、畸形、不支持、超大、失败、中止的图像结果;native/fallback 路由与 latest-wins 调度。任务清单确认:协调器、Browser 提取、信任/权限/run 传播、native/fallback、PNG/JPEG、畸形/不支持/超大/尺寸校验、失败/中止调用、目标 epoch、关闭与 latest-wins 均已被覆盖。
T12 — 渲染器回归覆盖(已完成)
覆盖范围包括:native 无头模式与「无帧订阅」断言;Canvas 首帧、帧保留、序列拒绝、拖拽与关闭;焦点、最小化、会话切换、终止态与卸载清理;并验证 Computer Use不暴露任何展开/打开面板行为。任务清单确认:native 无头、首帧、帧保留、epoch/序列拒绝、仅关闭控件、焦点暂停/恢复、终态清理、拖拽、会话切换、卸载与 Browser 抢占(supersession)均已被覆盖。
阶段五:仅 PiP 的点击后刷新(T13)
T13 — PiP-only 点击后刷新(已完成)
- 在一次合格的、精确的 CUA
click成功后,异步调用一次私有的get_window_state({ pid, window_id }); - 调用以「可信插件所有权、有效 session/run/target 身份、活跃 PiP、presenter 未被 dismissal」为门禁;
- 私有结果只经由预览观察器路由:从不发布、不缓存、不返回给 Agent;
- 保持 click 的响应、时延、权限、中止与失败行为;
- 覆盖成功隔离以及失败、不可信、无效目标、非活跃预览各路径。
实现位于 ToolManager.scheduleComputerUsePreviewAfterClick:仅当工具名精确为click、响应非错误、get_window_state的工具策略判定为allow、且观察器shouldCaptureAfterClick同步返回真时才调度;私有调用复用 clickCall 的身份但将toolCallId追加:pip-snapshot后缀,随后以void异步执行captureComputerUsePreviewSnapshot,不阻塞、不修改原始 click 响应。shouldCaptureAfterClick的完整门禁(mode === 'eligible'、run/pid/windowId 全部匹配、dismissedRunId未命中)在 ComputerUsePreviewPresenter.ts#L85-L108 中实现。
阶段六:度量、QA 与收口(T14–T17,open)
T14 — 验证性能预算(未完成)
- 确认每次合格
click至多一次私有捕获,且空闲时零轮询; - 确认一个变换在途、无无界队列;
- 以参考桌面为基准,度量「有效结果到达 → 可见帧」的 p95 是否满足 150 ms 预算;
- NativeKit 慢推警告阈值保持 25 ms(与 Browser 基线一致,源码常量
SLOW_PUSH_WARNING_MS = 25); - 确认 native 模式向渲染器发送零图像字节。
T15 — 打包平台 QA(未完成)
- 验证一个 NativeKit 原生叠加运行时;
- 验证一个 native 不可用运行时;
- 验证 Browser 打开其既有侧面板、Computer Use 不显示 PiP;
- 演练宿主焦点/最小化/恢复与目标应用前台行为;
- 演练 Browser/Computer 来源切换与工具栏档案变化;
- 演练关闭、后续 run、路由/会话切换与应用退出。
T16 — 仓库验证(未完成,部分完成)
- 运行
pnpm run format、pnpm run i18n、pnpm run lint、pnpm run typecheck; - 先跑聚焦的主进程与渲染器测试,再跑完整受影响套件。
- 清单记录的部分完成状态:format、i18n、lint、typecheck、聚焦套件以及全部1,625 个渲染器测试通过;主进程套件通过5,383 个测试,唯一失败是
ModelConfigHelper > Configuration Priority > uses provider metadata until a user config overrides it——该未改动的 provider 测试在单独运行时同样失败,与本功能无关。
T17 — 收口实现文档(未完成,部分完成)
- 更新提案状态并记录偏差;
- 用已实现的共享所有权契约更新 Browser NativeKit 架构文档;
- 只把已验证的任务标记为完成;
- PR 中附 BEFORE/AFTER ASCII 布局与平台 QA 状态。
- 部分完成状态:实现状态、偏差、关联的 Browser 架构文档、已验证任务、ASCII 布局与未决 QA 均已记录,PR 交接仍 open。
三、实施顺序与依赖关系
任务清单显式给出六步实施顺序,它本身就是该功能的架构分层:
- T01–T03建立运行身份与安全的进程级所有权(没有
runId传播,快照结果无法归属到正确的 Agent run;没有共享协调器,两个来源会互相覆盖 NativeKit 全局配置); - T04–T06把可信的 CUA 结果接入有界的主进程快照管线;
- T07–T09添加类型化的渲染端协同与回退 UI;
- T10–T12加固生命周期、隐私与回归测试;
- T13增加事件驱动的点击后刷新;
- T14–T17度量、验证并收口文档。
这一顺序保证了:任何一层失效(身份缺失、仲裁失败、帧过期)都不会污染下一层的行为,预览故障永远不改变 MCP 工具结果或 Agent 执行结果。
四、完成定义(Done Definition)
原文档的完成定义是验收该功能的完整口径,逐条继承如下:
- 当前 run 一次成功的 CUA
get_window_state图像能呈现一个最新快照 PiP;一次合格的click成功可调度一次私有、仅 PiP 的刷新,且无空闲轮询; - Browser 与 Computer Use 安全共享一个NativeKit 所有者,并保留各自的来源专属控件;
- Computer Use PiP 只有一个Close按钮,只读,且绝不影响 Agent 或目标应用;
- run、target、session、host 与 epoch 校验防止过期像素泄露;
- native 路径避免向渲染器传输图像流量;不支持的运行时不暴露 Computer Use PiP;
- 图像工作内存态、有界、latest-wins,且有聚焦测试覆盖;
- Browser PiP 行为保持回归测试保护;
- 必需的检查通过,且至少一次 native 加一次 native-unavailable 的打包 QA 运行通过。
五、任务与源码实现的对照索引
| 任务 | 关键落地位置 |
|---|---|
| T01 runId 传播 | ToolManager 的调用选项与createComputerUsePreviewCall |
| T02/T03 共享协调与仲裁 | AgentPreviewCoordinator |
| T04 MCP 观察器 | ComputerUsePreviewObserver |
| T05 目标与运行状态 | ComputerUsePreviewPresenter |
| T06 有界管线 | 同文件 L57-L66 常量区与transformSnapshot |
| T07 类型化契约 | computerUse.routes.ts |
| T08 渲染端协同 | AgentComputerUsePiP.vue 挂载点 |
| T11/T12 回归覆盖 | ComputerUsePreviewPresenter.test.ts |
| 组合根装配 | composition.ts |
六、小结与当前边界
这份任务清单的价值在于把「让 Agent 自动化过程对用户可见」这一模糊需求,拆解为可逐项验证的 17 个任务:身份传播、进程级所有权仲裁、有界图像管线、类型化 IPC 契约、隐私清理、事件驱动刷新与验收度量,每个任务都附带明确的验证方式。截至清单记录,T01–T13 及 T16/T17 的主体工作已完成并通过了 1,625 个渲染器测试与 5,383 个主进程测试(一个与功能无关的既有失败),剩余工作是 150 ms p95 结果-可见延迟的实测(T14)、native 与 native-unavailable 两种运行时的打包 QA(T15),以及 PR 交接收口(T17)。对读者而言,若需要复用这套「MCP 结果 → 主进程有界管线 → 进程级单一叠加层」的模式,可以直接沿本文第五节的对照索引进入源码,逐层确认每一道门禁的实现细节。
【免费下载链接】deepchat🐬DeepChat - A smart assistant that connects powerful AI to your personal world项目地址: https://gitcode.com/GitHub_Trending/dee/deepchat
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考