2026-05-20 21:39:12 +08:00

92 lines
4.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Desktop Op 桌面操作模块
created: 2026-05-14
updated: 2026-05-14
type: entity
tags: [module, runtime, agent, backend]
sources: [packages/backend/src/modules/desktop_op/, packages/backend/src/modules/netaclaw/tools/builtin/weixin_send_text.ts, docs/superpowers/specs/2026-05-14-neta-desktop-op-design.md]
---
# Desktop Op 桌面操作模块
Desktop Op 是 2026-05-14 新增的通用桌面 GUI Agent 模块。它把本机窗口定位、截图、键鼠输入、VLM 验证、队列互斥和审计日志封装成后端模块,当前 MVP 只注册 `WeixinAdapter`,服务于 [[agent-channel]] 的 weixin-db 群聊自动回复。
## 目录结构
```text
desktop_op/
├── config.ts
├── controller/admin/ # action_log 与 config 管理 API
├── entity/ # desktop_op_config / desktop_op_action_log
├── runtime/ # 核心运行时、输入、截图、VLM、安全护栏、适配器
└── service/ # DesktopOpService 与配置 bootstrap
```
## 运行时拓扑
`DesktopOpRuntime.runTask()` 是核心执行入口:
```text
DesktopTask
-> SafetyGuard 校验 task/app/action
-> AdapterRegistry 选择 AppAdapter
-> WindowLocator 定位并激活窗口
-> adapter.preFlightCheck()
-> adapter.buildSteps()
-> ActionExecutor 逐步执行 clipboard / hotkey / wait 等动作
-> adapter.verifyResult()
-> TaskResult
```
所有任务都接收 `AbortSignal`。运行时在开始、激活窗口后、preflight 后、每个动作前和 verify 前检查中止状态,因此 [[agent-channel]] 删除频道、关闭 weixinReply 或任务超时时可以级联取消。
## 服务层队列与互斥
`DesktopOpService` 提供两个入口:
- `runAndWait(task, timeoutMs)`:同步等待结果,当前由 [[tool-system]] 的 `weixin_send_text` 调用。
- `enqueue(task)`fire-and-forget 留口,后续可用于异步桌面任务。
队列按 `appId + adapter.queueKey(target)` 分组,同一个微信会话串行执行;真正执行前还会获取全局 `DesktopMutex`,避免多个任务同时争用键鼠。每个 queue key 最多保留 20 个任务,溢出时写 `queue-overflow` 审计日志。
## WeixinAdapter
`runtime/adapters/weixin_adapter.ts` 是当前唯一适配器:
- `appId = "weixin"`,支持 `send-text`
- 通过 `WindowLocator.findByAppName("Weixin")` 找到未最小化的最大微信窗口。
- preflight 截图并用 VLM 宽松判断当前顶部对话名是否匹配目标群。
- `buildSteps()` 固定生成 `clipboard-write -> ctrl+v -> wait -> enter -> wait`
- verify 再次截图并用 VLM 检查最新己方消息,但 MVP 中为避免 VLM 误判导致重复发送build steps 成功后默认按成功处理。
这意味着 Desktop Op 当前不是完整自主 GUI 探索 Agent而是“适配器主导的确定性动作序列 + VLM 状态验证”。
## 数据模型
| 表名 | Entity | 用途 |
| --- | --- | --- |
| `desktop_op_config` | `entity/desktop_op_config.ts` | 全局白名单、危险按键、频率上限和默认水印 |
| `desktop_op_action_log` | `entity/desktop_op_action_log.ts` | 每个桌面任务的终态审计,包括 channelId、roomName、modelChannel、状态、耗时和错误 |
`desktop_op_config` 不再保存默认模型渠道v4 约定模型来自桌面操作 Agent 自己的 `modelChannelId`
## 与微信双 Agent 的关系
weixin-db 群聊自动回复采用双 Agent
1. reply agent 读取群消息、决定是否回复,并通过 `delegate_task` 委托。
2. desktop agent 持有 `weixin_desktop` toolset 和 `weixin_send_text` 工具。
3. `weixin_send_text``_netaRuntime.bizContext.channelId``currentAgent.modelChannelId` 读取运行时上下文。
4. 工具创建 `DesktopTask(appId="weixin", actionType="send-text")`,交给 `DesktopOpService.runAndWait()`
5. Desktop Op 激活微信窗口、粘贴、发送并记录 `desktop_op_action_log`
保存 weixin-db 渠道配置时,后端会自动为 desktop agent 补齐 `weixin_desktop` toolset并把 `weixin_send_text` 配置为可在子 Agent 中使用且强制走主进程代理。
## 相关页面
- [[agent-channel]] — weixin-db 渠道和双 Agent 回复配置
- [[tool-system]] — `weixin_send_text` 工具和工具路由
- [[netaclaw-module]] — NetaClaw 主模块与外部渠道入口
- [[frontend-architecture]] — 频道管理页的 weixinReply 配置 UI
- [[database-entity-overview]] — desktop_op 表速查