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

6.8 KiB
Raw Blame History

title created updated type tags sources
Agent 渠道系统 2026-04-14 2026-05-14 entity
agent
api
module
packages/backend/src/modules/netaclaw/service/agent_channel.ts
packages/backend/src/modules/netaclaw/service/weixin.ts
packages/backend/src/modules/netaclaw/service/weixin_db.ts
packages/backend/src/modules/netaclaw/service/weixin_archive_sync.ts
packages/backend/src/modules/netaclaw/entity/agent_channel_group.ts
packages/frontend/src/modules/agent/views/channel-management.vue

Agent 渠道系统

将 Agent 接入外部消息平台当前支持微信实现消息接收、Agent 处理、澄清/风险确认降级和回复闭环。2026-05-14 后这里已经分成两条微信路径:旧 weixin ClawBot 私聊助手,以及新的 weixin-db 本地代理群聊路径。

数据模型

netaclaw_agent_channel 表:

name(唯一) | type(weixin/weixin-db) | agentId | agentName | config(JSON) | credential(JSON,加密) | runtime(JSON: syncBuf/contextTokens/seenMessageIds) | loginStatus(pending/disconnected/connected/error/unsupported_platform) | lastError | lastConnectedAt

netaclaw_agent_channel_group 表:

channelId | roomId(channel 内唯一) | roomName | status(0禁用/1启用/-1忽略) | triggerMode(at_mention/all) | boundAgentId | replyIdentityOverride | firstSeenAt | lastSeenAt | lastActiveAt

关键文件

文件 职责
entity/agent_channel.ts 渠道 Entity
service/agent_channel.ts 渠道 CRUD + QR 登录 + 后台运行器
service/weixin.ts 微信协议层QR 登录、消息收发)
service/weixin_db.ts 本机 PC 微信数据库增量读取、WAL watcher、群白名单缓存
service/weixin_archive_sync.ts 按 channel 工作目录同步历史归档
runtime/weixin_db/* key 抽取、WCDB 解密、增量读取、room 解析、消息伪协议构建
entity/agent_channel_group.ts 群白名单、触发策略和每群 Agent 覆盖
service/agent_executor.ts Agent 执行器(渠道消息触发 Agent 推理)
controller/admin/agent_channel.ts REST API
controller/admin/agent_channel_group.ts 群管理 API

微信接入模式

类型 场景 消息来源 回复路径
weixin ClawBot 个人助手,当前主打私聊 iLink/ClawBot API 轮询 weixinService.sendText() 直接发送
weixin-db 本机 PC 微信群聊代理 本地数据库解密 + WAL watcher v4 双 Agentreply agent 委托 desktop agent 调 desktop-op-module 发送

ClawBot 私聊流程

创建渠道 → 绑定 Agent
  → createWeixinQr() 生成二维码
  → 用户扫码 → pollWeixinQr() 轮询状态
  → 状态流转wait → scaned_but_redirect → confirmed
  → 获取 credentialaccountId, token, baseUrl, userId
  → syncRunner() 启动后台消息轮询800ms 间隔)

routeInboundMessage() 会丢弃 ClawBot 收到的群消息,避免旧 iLink 路径和新的群聊本地代理互相串线。

weixin-db 群聊流程

创建 weixin-db 渠道,填写 wxid
  → syncRunner() 对启用渠道调用 WeixinDbService.bindChannel()
  → 自动定位 xwechat_files seedDir
  → extractWeixinKeys() 抽取 message/session/contact DB key
  → IncrementalReader 初始化 per-channel workDir
  → WalWatcher 监听 message DB WAL
  → readIncrement() 增量解密消息
  → room_resolver + 群白名单过滤
  → buildPseudoMessageFromDb() 构造伪消息
  → routeInboundMessage()

非 Windows 平台会把状态标记为 unsupported_platform,服务保持 idle不让启动流程崩溃。

群白名单与触发

netaclaw_agent_channel_group 管理每个 channel 下的群:

  • status=1 的群才进入 weixin-db 增量读取白名单。
  • triggerMode 当前支持 at_mentionallprefix 仅兼容存量数据。
  • boundAgentId 是 weixin-db 群聊的必填 reply agent不再回退 channel 默认 Agent。
  • replyIdentityOverride 是 weixin-db 群聊的必填回复身份;不再回退 channel 级回复身份。
  • 群增删启停后会调用 WeixinDbService.refreshWhitelist(),让下一次 WAL tick 使用最新白名单。

消息处理循环

runLoop() 或 WalWatcher 收到消息
  → decideChatScope() 区分 DM / group
  → seenMessageIds 5 分钟去重
  → context_token 按 chatId 保存
  → pendingClarify / 风险确认短路
  → senderQueues 按 DM sender 或群 chatId 串行
  → handleInboundMessage()

群聊路径会先检查群记录、触发策略和每群 Agent 覆盖,再调用 agentExecutor.execute()。weixin-db v4 不再由 agent_channel 自动发送最终内容reply agent 必须通过 delegate_task 委托 desktop agent否则服务会记录“未调用 delegate_task”的告警避免消息静默丢失。

生命周期管理

  • restoreConnectedRunners():启动时恢复已连接渠道的运行器
  • disconnect():断开 ClawBot 连接,停止轮询
  • restart():重启运行器
  • clearSessions():清空渠道的所有会话
  • delete():删除群记录、解绑 weixin-db、删除 channel archive并通过 desktop-op-module 取消该 channel 的 pending/running 桌面任务
  • weixin-db 健康探针每 60 秒检查 PC 微信进程和数据库可读性,失败后尝试 unbind/rebind

v4 双 Agent 自动回复

weixin-db 的 config.weixinReply 启用后,渠道保存会做额外校验:

  • 必须配置 desktopAgentId,且不能与 reply agent 相同。
  • 后端会自动给 desktop agent 加入 weixin_desktop toolset。
  • 后端会把 weixin_send_text 设置为 allowInSubagent=trueforce-main-process-proxy
  • weixinReply.enabled 从 true 改为 false 时,会级联取消该 channel 下的桌面操作任务。

最终链路是:群消息进入 reply agentreply agent 用 delegate_task 把发送动作委托给 desktop agentdesktop agent 调用 tool-systemweixin_send_text,再由 desktop-op-module 操作 PC 微信窗口。

Clarify 纯文本降级

微信渠道不支持 WebSocket 交互,clarify-tool 采用纯文本 + 数字映射方案:

  1. 构造文本消息:❓ 问题\n1. 选项1\n2. 选项2\n请回复数字或直接输入
  2. 通过微信 API 发送,存入 pendingClarify Mapkey: ${channelId}:${senderId}
  3. 用户回复数字 → 映射到 choices[num-1];回复文本 → 直接使用
  4. 解决 PromiseAgent 继续执行

相关页面