- Added a new script `bundle-openclaw.mjs` to bundle OpenClaw runtime dependencies. - Updated `after-pack.cjs` to copy bundled OpenClaw runtime and its node_modules. - Improved cleanup of unnecessary development files in node_modules. - Adjusted paths for resources in the packaging process. style: update loading indicator styles in ChatHistoryPanel - Changed the border radius and padding for the loading indicator in ChatHistoryPanel. fix: improve ProvidersSection to handle provider account syncing - Added logic to sync model configuration to provider accounts. - Introduced error handling and loading states during the sync process. - Enhanced vendor resolution and account management logic. fix: fallback session handling in chat store - Implemented fallback session logic in loadSessions to ensure a valid session is always available on error.
18 KiB
ClawX 浏览器自动化能力迁移规划
1. 背景与结论
- 现象:在
ClawX中发送“打开:http://www.baidu.com”,模型可以真实驱动浏览器打开页面;在zn-ai中发送同样内容,当前不会真实操作浏览器。 - 结论:问题不在“模型名”或“prompt”本身,而在聊天请求最终是否进入了真正的
OpenClaw runtime / gateway / tool execution loop。 ClawX目前走的是完整的OpenClaw Gateway链路,且会在启动前把~/.openclaw/openclaw.json的browser.enabled等配置补齐。zn-ai当前聊天主链路仍是in-process provider.chat(...),没有真实OpenClaw子进程、没有 browser config sync、没有 tool execution protocol,所以模型只能生成文本,不能真实调用浏览器工具。zn-ai已经有playwright、browser-use-sdk依赖,但它们并没有接入当前聊天主链路,因此现在并不构成功能闭环。
这份文档是对 OpenClaw-Chat-Alignment-Plan.md 的浏览器自动化专题补充,重点回答:
- 为什么
ClawX能打开浏览器而zn-ai不能。 zn-ai还缺哪些关键文件/能力。- 下一步迁移应该按什么顺序做。
2. 两个项目的真实执行链路对比
2.1 ClawX
ClawX 的对话会进入真实 Gateway/Runtime:
- Renderer 发消息:
ClawX/src/stores/chat/runtime-send-actions.ts:192-218通过invokeIpc('gateway:rpc', 'chat.send', ...)或chat:sendWithMedia发起调用。 - Main IPC 转发:
ClawX/electron/main/ipc-handlers.ts:1209-1216ClawX/electron/main/ipc-handlers.ts:1298-1368 - Gateway Manager 托管 OpenClaw 子进程、WebSocket、重连、ready 状态:
ClawX/electron/gateway/manager.ts:1-205ClawX/electron/gateway/process-launcher.ts:91-144 - 启动前同步
openclaw.json:ClawX/electron/gateway/config-sync.ts:251-323ClawX/electron/utils/openclaw-auth.ts:1169-1321 OpenClawruntime 真正执行tool_use / tool_result,包括浏览器工具。- Renderer 可以展示 thinking、tool card、tool result:
ClawX/src/pages/Chat/message-utils.ts:153-201ClawX/src/stores/chat.ts:1886-2015ClawX/src/pages/Chat/ChatMessage.tsx:1-220
2.2 zn-ai
zn-ai 当前对话仍停留在“直接调用模型”:
- Renderer 发消息:
zn-ai/src/stores/chat.ts:271-294通过gatewayRpc('chat.send', ...)进入本地 gateway。 - Main IPC 只做本地转发:
zn-ai/electron/main.ts:94-97 - Gateway Manager 仍是 in-process 模式:
zn-ai/electron/gateway/manager.ts:53-62 - Chat handler 直接取 provider account 后调用:
zn-ai/electron/gateway/handlers/chat.ts:48-49zn-ai/electron/gateway/handlers/chat.ts:134-161 - 当前事件协议只有
chat:delta/final/error/aborted:zn-ai/electron/gateway/types.ts:10-47 - 当前消息 UI 只展示普通文本/附件,不展示 tool/thinking 执行过程:
zn-ai/src/components/chat/ChatMessageList.tsx:23-90zn-ai/src/components/chat/types.ts:15-24
因此,zn-ai 现在收到“打开百度”时,并没有一个真正的浏览器工具执行器可以被模型调用。
3. 为什么 ClawX 能打开浏览器
ClawX 能成功,不是因为“它装了 Playwright”这么简单,而是它把下面这几层都打通了:
3.1 有真实 OpenClaw Runtime
ClawX/electron/gateway/process-launcher.ts会通过utilityProcess.fork(...)启动 Gateway 子进程。ClawX/package.json:39-42,123已经引入openclaw与配套 bundling 脚本。ClawX/electron-builder.yml:16-31会把build/openclaw/打进安装包。
3.2 启动前会把浏览器能力写进 openclaw.json
ClawX/electron/utils/openclaw-auth.ts:1181-1194会确保:browser.enabled = truebrowser.defaultProfile = 'openclaw'browser.ssrfPolicy.dangerouslyAllowPrivateNetwork = true
ClawX/electron/gateway/config-sync.ts:317-320会在 Gateway 启动前统一执行这类配置同步。
3.3 聊天调用的是 Gateway,不是裸模型
ClawX的聊天发送不是直接provider.chat(...),而是先进入gateway:rpc -> chat.send。- 这样模型在运行时可以发出
tool_use,再由 runtime 真正执行浏览器操作。
3.4 前端能消费工具执行过程
ClawX的消息解析和 UI 会识别tool_use/tool_result,所以不仅能执行,也能在界面上看到执行轨迹。
4. 为什么 zn-ai 现在不能打开浏览器
4.1 当前没有真实 OpenClaw 子进程接入聊天链路
zn-ai/electron/gateway/manager.ts明确返回mode: 'in-process'。zn-ai/electron/gateway/openclaw-process-owner.ts目前只是占位实现:prepare()只创建目录start()只把状态切到running- 没有真正
fork进程 - 也没有 WebSocket / JSON-RPC / ready 检测
4.2 当前聊天处理器直接打模型
zn-ai/electron/gateway/handlers/chat.ts里核心执行是:- 取
provider account - 拼消息历史
createProvider(accountId)provider.chat(messages, model, { signal })
- 取
这条链路天然不会触发 OpenClaw 的浏览器工具。
4.3 当前没有 browser config sync
zn-ai虽然已经有electron/utils/paths.ts和openclaw-process-owner.ts这些雏形, 但没有对应ClawX/electron/utils/openclaw-auth.ts与ClawX/electron/gateway/config-sync.ts那一整套启动前配置同步逻辑。- 即使未来把
openclaw包带进来,如果不写入browser.enabled,浏览器能力仍可能不会生效。
4.4 当前协议和 UI 也没有完整 tool 语义
zn-ai/electron/gateway/types.ts目前没有面向 tool execution 的 richer event protocol。zn-ai/src/components/chat/ChatMessageList.tsx目前也没有对应tool card / thinking / tool result的展示结构。
5. 缺少哪些文件
这里分成两类:P0 必需缺失文件 和 已有但需要重构的文件。
5.1 P0 必需缺失文件
这些文件是让“聊天真正能调用浏览器工具”最关键的一批,建议优先迁:
| 能力 | ClawX 参考文件 | zn-ai 当前状态 | 结论 |
|---|---|---|---|
| OpenClaw 子进程启动 | ClawX/electron/gateway/process-launcher.ts |
缺失 | 必需补 |
| Gateway 启动前配置同步 | ClawX/electron/gateway/config-sync.ts |
缺失 | 必需补 |
| browser/config 写入 | ClawX/electron/utils/openclaw-auth.ts |
缺失 | 必需补 |
| Gateway WebSocket/ready | ClawX/electron/gateway/ws-client.ts |
缺失 | 必需补 |
| Gateway 协议定义 | ClawX/electron/gateway/protocol.ts |
缺失 | 必需补 |
| Gateway request 跟踪 | ClawX/electron/gateway/request-store.ts |
缺失 | 建议补 |
| 启动/重连/生命周期控制 | ClawX/electron/gateway/lifecycle-controller.ts restart-controller.ts connection-monitor.ts |
缺失 | 建议补 |
| 进程守护与诊断 | ClawX/electron/gateway/supervisor.ts startup-orchestrator.ts startup-stderr.ts |
缺失 | 建议补 |
| openclaw 打包脚本 | ClawX/scripts/bundle-openclaw.mjs |
缺失 | 必需补 |
| openclaw 插件打包 | ClawX/scripts/bundle-openclaw-plugins.mjs |
缺失 | 浏览器最小闭环非必需,但后续强相关 |
| openclaw 安装包资源声明 | ClawX/electron-builder.yml 中 build/openclaw -> openclaw |
zn-ai/electron-builder.yml 未配置 |
必需补 |
5.2 已有但需要重构的文件
这些文件在 zn-ai 里已经存在,但当前实现还是过渡态:
| zn-ai 文件 | 当前问题 | 改造方向 |
|---|---|---|
electron/gateway/manager.ts |
仍是 in-process manager | 改成真实 OpenClaw gateway manager,负责 start/stop/restart/status/rpc |
electron/gateway/openclaw-process-owner.ts |
只是状态占位,没有真实进程 | 接入 utilityProcess.fork、ready 检测、退出处理 |
electron/gateway/handlers/chat.ts |
直接 provider.chat(...) |
改成调用真实 Gateway RPC,不再直接驱动 provider |
electron/main.ts |
只初始化本地 gateway bridge | 增加 OpenClaw runtime 启动、配置同步、事件注册 |
electron/utils/paths.ts |
已有路径层,但没接 runtime bundling | 继续沿用,作为 runtime/package path 基础设施 |
package.json |
没有 openclaw 依赖和 bundling 脚本 |
对齐 ClawX 的 runtime 打包入口 |
electron-builder.yml |
没有 openclaw extraResources |
把 runtime 资源打进安装包 |
scripts/after-pack.cjs |
只处理 playwright/chromium-bidi/bytenode |
增加 openclaw/node_modules/plugins 复制逻辑 |
src/stores/chat.ts |
只消费简化事件 | 增加 tool/thinking/tool_result 流式状态处理 |
src/components/chat/ChatMessageList.tsx |
只渲染简单消息卡片 | 对齐 ClawX 的工具执行展示能力 |
src/components/chat/types.ts |
message shape 过于简单 | 增加 tool execution 相关 UI 数据结构 |
5.3 可后置但建议保留参考的文件
这批不是“打开网址”的最小闭环必需,但如果目标是后续继续向 ClawX 对齐,建议一起纳入规划:
ClawX/electron/utils/openclaw-proxy.tsClawX/electron/utils/openclaw-control-ui.tsClawX/electron/utils/openclaw-cli.tsClawX/electron/utils/openclaw-doctor.tsClawX/electron/gateway/reload-policy.tsClawX/electron/gateway/process-policy.tsClawX/electron/gateway/restart-governor.tsClawX/src/pages/Chat/message-utils.tsClawX/src/pages/Chat/ChatMessage.tsx
6. 推荐迁移顺序
Phase 1:先打通最小运行闭环
目标:让 zn-ai 的聊天可以真正进入 OpenClaw runtime。
建议优先完成:
package.json引入openclaw,补bundle-openclaw.mjs。electron-builder.yml和scripts/after-pack.cjs补 runtime 打包。- 基于
electron/utils/paths.ts实现真实process-launcher + process-owner。 - 增加
config-sync.ts + openclaw-auth.ts,确保 browser 配置被写入openclaw.json。
完成标准:
- 开发态和打包态都能找到
openclaw入口。 GatewayManager能拉起真实 Gateway 子进程。~/.openclaw/openclaw.json中出现有效的browser.enabled配置。
Phase 2:替换聊天执行面
目标:让对话不再直接 provider.chat(...),而是走真实 Gateway。
建议改造:
electron/gateway/manager.tselectron/gateway/handlers/chat.tselectron/main.ts
完成标准:
- “打开:http://www.baidu.com” 时,请求进入真实 Gateway,而不是本地 provider adapter。
- 聊天不再依赖
provider.chat(...)直接生成最终文本。
Phase 3:补齐 tool 事件与前端可视化
目标:不仅能执行,还能在 UI 看见执行过程。
建议改造:
src/stores/chat.tssrc/components/chat/types.tssrc/components/chat/ChatMessageList.tsx- 参考
ClawX/src/pages/Chat/message-utils.ts和ChatMessage.tsx
完成标准:
- UI 能显示
thinking / tool_use / tool_result。 - 浏览器执行失败时,前端能展示明确错误,而不是只有空白或文本兜底。
Phase 4:补诊断与运维能力
目标:减少“本地能跑、打包后失效”。
建议纳入:
openclaw doctor- Control UI URL
- restart / health / ready / diagnostics
- proxy 同步与 reload policy
7. sub-agent 数量估算
7.1 推荐编制
- 分析 sub-agent:
1 - 迁移开发 sub-agent:
4 - 集成验收 sub-agent:
1 - 推荐总数:
6
7.2 峰值编制
- 如果希望把
Phase 4的 diagnostics / doctor / control UI 也并行推进,可以临时再拆出1个运维诊断 sub-agent。 - 峰值总数:
7
7.3 最小可行编制
- 主控 Codex 兼任分析与最终验收
- 保留
3个开发 sub-agent +1个集成角色 - 最小总数:
4
7.4 为什么推荐 6 个
- 这次迁移至少横跨
Runtime Packaging、Gateway Process & Config Sync、Chat Execution、Renderer Tool UI四条主要开发线。 - 这四条线的写集可以基本拆开,适合并行推进。
- 如果开发角色少于
4,很容易出现“runtime 已经能拉起,但 chat path 还没切完”或者“后端已经有 tool 事件,但前端完全看不见”的串行阻塞。
8. sub-agent 分工与推进安排
8.1 推荐分工
| 角色 | 数量 | 负责范围 | 文件所有权 |
|---|---|---|---|
| A1:浏览器自动化契约分析 | 1 | 持续对照 ClawX,冻结最小闭环契约、补验收 checklist、识别遗漏能力 |
只读分析、文档 |
| M1:Runtime Packaging / Paths | 1 | 引入 openclaw、补 bundling、after-pack、resources 布局、运行时路径管理 |
package.json electron-builder.yml scripts/bundle-openclaw.mjs scripts/after-pack.cjs electron/utils/paths.ts |
| M2:Gateway Process / Config Sync | 1 | 实现真实进程拉起、ready 检测、WebSocket 通信、启动前同步 openclaw.json 浏览器配置 |
electron/gateway/process-launcher.ts electron/gateway/ws-client.ts electron/gateway/config-sync.ts electron/gateway/openclaw-process-owner.ts electron/utils/openclaw-auth.ts |
| M3:Chat Execution / IPC 集成 | 1 | 把 chat.send 从本地 provider.chat(...) 切到真实 Gateway,补主进程生命周期与状态接口 |
electron/gateway/manager.ts electron/gateway/handlers/chat.ts electron/gateway/types.ts electron/main.ts electron/api/routes/gateway.ts |
| M4:Renderer Tool Events / UI | 1 | 接 tool/thinking/tool_result 事件,补消息结构、流式状态与工具执行可视化 | src/stores/chat.ts src/components/chat/types.ts src/components/chat/ChatMessageList.tsx src/pages/Home/index.tsx |
| I1:联调验收 / 回归收口 | 1 | 维护 smoke checklist、验证开发态/打包态、补文档与测试基线 | 测试、文档、回归记录 |
8.2 可选扩编角色
如果要把运维诊断一起提前做,可以额外拆出:
| 角色 | 数量 | 负责范围 | 文件所有权 |
|---|---|---|---|
| D1:Diagnostics / Control UI / Doctor | 1 | 补 OpenClaw 诊断入口、Control UI URL、health diagnostics 展示 | electron/utils/openclaw-control-ui.ts electron/utils/openclaw-cli.ts electron/utils/openclaw-doctor.ts electron/api/routes/* 设置/诊断相关前端 |
这个角色建议只在 M3 把基础 gateway status 契约稳定后再启动,避免和 gateway/manager.ts 产生写冲突。
8.3 建议并行波次
| 波次 | 并行角色 | 目标 |
|---|---|---|
| Wave 1 | A1 + M1 | 冻结最小闭环契约,先把 openclaw 资源打包和路径层打通 |
| Wave 2 | M2 + M3 | 一边实现真实 Gateway 进程与 config sync,一边切换聊天执行面到 Gateway |
| Wave 3 | M4 + I1 | 对接 tool 事件与 UI 展示,同时开始做 smoke 与回归清单 |
| Wave 4 | D1 + 主控 Codex | 可选补 diagnostics / doctor / control UI,并做最终跨层收口 |
8.4 开工顺序建议
- 先开
M1- 这是最靠前的阻塞项,因为没有 runtime bundling 和路径层,后面的真实 Gateway 无法稳定拉起。
- 紧接着开
M2- 它负责把
openclaw真正跑起来,并把browser.enabled等关键配置写入openclaw.json。
- 它负责把
M3与M2并行M3可以先把manager/chat/main的调用面改成“面向真实 Gateway”的接口,再等待M2落地真实进程。
M4在M3暴露稳定事件后接入- 避免前端先写死一套后端并不会发出的事件结构。
I1从Wave 2就开始- 不要等所有人写完再验,因为开发态和打包态的差异很可能会在中途暴露。
8.5 文件冲突规避
M1不要改electron/gateway/manager.tsM2不要改src/*M3尽量只拥有manager/chat/main/routes,不要接管process-launcher/config-syncM4不要改electron/*I1不直接改生产实现,除非主控明确分配
这样拆分后,主要写冲突只会集中在接口边界,而不会集中在同一个文件。
9. 最小验收清单
当下面这些都满足时,才算“浏览器自动化已迁成功”:
- 在
zn-ai中发送“打开:http://www.baidu.com”时,真实浏览器会打开对应页面。 - 聊天链路里能看到
tool_use或等价工具执行痕迹,而不是只有纯文本回复。 GatewayManager状态不再只是mode: 'in-process'。- 打包后的应用也能执行同样操作,不仅是开发环境可用。
- provider/account 切换后,浏览器能力不需要手动改
openclaw.json才能生效。
10. 风险与注意点
- 不建议只尝试“把 Playwright 接到某个单独 service”来修这件事。这样也许能做出一个临时浏览器工具,但会绕开
OpenClaw的 tool protocol、会话、history、tool_result、diagnostics,后续维护成本更高。 zn-ai已有的openclaw-process-owner.ts和paths.ts可以继续复用,不需要完全推翻。- 如果短期目标只是先实现“打开网址”,可以先不迁全部插件/Control UI,但
process-launcher + config-sync + browser.enabled + real gateway rpc这四块不能省。
11. 结论
zn-ai 现在不能像 ClawX 一样准确打开浏览器,核心原因不是缺某一个浏览器脚本,而是聊天主链路还没有接到真正的 OpenClaw runtime。
最关键的迁移入口是四块:
- 引入并打包
openclaw runtime - 用真实 Gateway 子进程替换当前 in-process chat execution
- 启动前同步
openclaw.json的 browser 配置 - 前端补齐 tool execution 的事件消费和展示
按这个顺序推进,推荐以 6 个 sub-agent 为常态编制;如果把 diagnostics / doctor 也一起并行推进,峰值可以短时扩到 7 个。这样后续浏览器、文件、搜索等工具能力都会比“单点硬接 Playwright”更稳。