Skip to content

refactor(reply): migrate public inbound SDK with legacy compatibility - #102

Merged
NewFuture merged 2 commits into
mainfrom
newfuture-public-channel-turns
Sep 6, 2026
Merged

NewFuture merged 2 commits into
mainfrom
newfuture-public-channel-turns

Conversation

@NewFuture

@NewFuture NewFuture commented Sep 6, 2026

Copy link
Copy Markdown
Owner

变更说明

Closes #98

Tencent/openclaw-weixin#251 拆出入站派发与消息 hook 迁移,采用 issue 中确认的兼容方案:保留 OpenClaw >=2026.6.1,按注入 runtime 的能力选择两种公开契约

  • 共用 inbound.buildContext、微信文本/媒体传输和进度逻辑;一个 inbound-turn.ts 适配现代 inbound.dispatch 与旧版 inbound.dispatchReply
  • 会话记录和 dispatcher 清理由公开宿主 helper 编排;返回实际客户端传输 message ID。
  • 现代入站与宿主管理的主动发送不再重复运行本地 hooks;旧版入站和独立 debug 消息保留必要本地 hooks。

已基于包含 #101main 重放提交,保留双方变更日志。后续简化去掉单次使用的文本发送包装、重复账号解析、重复请求类型和无效 context 赋值,净减少 28 行生产代码。完整 SDK/CLI 验证驱动保留在会话资料中,未放入本 PR。

验收标准

  • 新旧宿主使用相应公开派发入口;新入口存在但无效或派发失败时,不切换旧入口重发。
  • 每个实际逻辑发送只有一个修改/观察 hook 归属方,取消不发送、不伪造 ID;旧版无文字媒体也经过修改 hook。
  • 保留分块配置及别名优先级、账号级 context token、typing、人类延迟和结构化进度;排队接纳不被误当作最终完成。
  • 普通消息接纳、轮询连续性、独立审批通道、重放 claim 的提交/释放和停止轮询行为不变。

非目标与替代方案

不提高最低宿主、不升级依赖或插件版本,不改微信协议、账号/状态格式、授权策略、文件锁、配置写入或已有分块设置。CI、贡献指南和兼容检查驱动相对 main 无差异。

提高最低宿主可换取单一路径,但不符合保留 6.1 的要求。当前仅保留一个旧版公开契约适配,不保留第二套消息处理器,也不采用失败后回退重试。

关联任务与风险

关联 #98agent:readyrisk:privileged)。最高风险是宿主 hook 归属与延后回复生命周期。旧版 identity beforeDeliver 显式替换 SDK 的默认文本修改 hook,避免本地再次修改;reply_payload_sending 仍由宿主处理。

实际模型排队/接管、停止重载和微信客户端展示仍待人工整机验证,故保留 draft。合成 resolver 与回调测试不被当作真实排队运行的证明。

既有边界不在本 PR 修复:独立冷进程发送需要账号启动时恢复 context token;2026.6.34 回移了 channel 别名能力,现有按日期判断的别名检查会误报。

风险与不变量

openclaw-weixin 身份、最低宿主、Node.js 要求、凭据、context token、轮询游标和去重状态格式均不变。稳定别名用于路由,主账号继续拥有状态及传输凭据。旧版载荷准备留在 provider 投递内部,避免替换宿主持有的载荷元数据。错误继续脱敏;不增加全局账号兜底或跨契约重发。

自动化测试用例

用例 覆盖边界 预期结果 命令与结果
原始 public dispatch 缺失 processor 与新旧入口 共用公开 builder,仅调用选定入口,不手动二次记录/创建 dispatcher focused Vitest、npm run check:通过
原始 hook 重复 非幂等修改、宿主主动发送 一个 backend send 对应一次修改和一次观察;原实现已复现双重修改/观察 隔离真实 SDK/CLI 验证:通过;本地回归:通过
两个完成块及最终回复 分块与账号/别名覆盖 顺序及配置优先级不变;关闭分块时仅最终回复 processor 回归及真实 SDK:通过
取消、无文字媒体、不可见结果 修改 hook 与 transport 不发送、不伪造 ID、不产生成功观察 adapter/shared-hook 回归及真实 SDK:通过
文本、本地/远程媒体、未知协议回退 每个传输分支 使用正确账号 token 并返回实际 ID;媒体失败不回退重发文本 processor/channel 回归:通过
文本账号解析与拒绝边界 单账号、别名、未配置、暂停 账号只解析一次,使用同一主账号凭据和 token;无效账号不进入 transport channel 回归:通过,原先两次解析已由失败断言复现
无效 API、已投递后的派发失败、下载/传输失败 错误出口 显式失败、单次结算、不切换 dispatcher;错误脱敏 adapter/channel/shared-hook 回归:通过
延后返回、接管、完成及放弃 admission 与进度生命周期 释放接纳通道,进度保留到宿主完成边界;同步转发 run-start 返回值 deferred-promise 回归:通过
活跃普通 turn、审批、重放、预处理失败、abort monitor 与 claim 无关消息/审批可推进,claim 正确提交或释放,停止取消长轮询 monitor 回归:通过
别名/主账号、媒体作用域、debug 状态隔离与隐私 路由和传输账号不混用,debug 不泄露正文或标识 processor/channel 回归:通过

兼容性验证

最低宿主仍为 2026.6.1,lockfile/current 为 2026.8.2。以下为实施期间的隔离验证记录(Windows),不是仅凭 CI 配置或 mock 推断:

精确 OpenClaw Node.js 契约 结果
2026.6.1 24.19.0 legacy 安装后 typecheck/build、全新进程导入/注册、公开 SDK 与主动发送场景通过;本次简化后再次通过
2026.7.1 22.22.3 legacy 实施阶段同上通过
2026.8.1 22.22.3、24.19.0 routed 实施阶段同上通过
2026.8.2 24.19.0 routed 同上通过;本次简化后再次通过
2026.9.1(运行时解析的 beta) 24.19.0 routed 同上通过;本次简化后再次通过
2026.9.2 24.19.0 routed 补充检查通过
2026.6.34(extended-stable) 24.19.0 legacy SDK/发送通过;仅隔离验证器修正了已实际观察到的别名能力预期,未修改仓库脚本

每个版本均在可丢弃目录安装精确 SDK,断言安装版本,再执行 npm run typechecknpm run build 和无 Vitest mock 的编译产物验证。真实 SDK 使用合成 replyResolver,真实宿主主动发送使用 HTTP/CDN 拦截;均无微信网络访问。验证驱动按范围收敛要求保存在会话资料中,不纳入本 PR。根目录依赖保持 lockfile 版本。

基于 #101 的后续简化已重新覆盖 minimum/current/beta;inbound-turn.ts 的类型合并未改变其编译后 JavaScript(字节级比较一致)。没有新增宿主接口或放宽回退规则。

整机实测结果

  • 状态:等待人工实测(Pending human validation)
  • 测试人员:待指定人工测试人员
  • 操作系统与架构:待人工填写
  • Node.js:待人工填写
  • OpenClaw:待人工填写
  • 插件版本或 commit:eafa36c28d41ef42b4104703c7587a418a17e5d5
  • 安装方式:待人工填写
场景 预期结果 实际结果
正常回复、多个完成块、关闭分块 内容有序,最终回复不重复,关闭时仅最终回复 等待人工实测
hook 修改/取消、媒体回复 修改一次,取消不发送,媒体正常 等待人工实测
真实排队/接管及进度 接纳不阻塞,进度不过早结束 等待人工实测
停止/重载及活跃普通 turn 期间审批 长轮询及时中止,审批独立推进 等待人工实测

脱敏关键日志

无人工整机日志。自动化原始日志、配置、状态及私有数据均未附加。

其他验证命令

  • npm run test:unit -- src/channel.test.ts src/auth/account-store.test.ts src/messaging/inbound-turn.test.ts src/messaging/process-message.test.ts:通过,136 个用例。
  • npm run check:通过,49 个文件、826 个用例,未降低覆盖率阈值。
  • npm run pack:check:通过,98 个发布文件。
  • rebase 后 npm test --prefix docs/site:通过,46 个用例;npm run build --prefix docs/site:通过。后续简化未修改文档。
  • git diff --check:通过。初始差异的只读审查未发现显著问题。
  • 首次全量执行曾有未改动的 context-token-store 用例 15 秒加载超时;单独重跑和完整门禁随后通过。隔离 SDK 的冷启动也遇到导入/CLI 注册超时,保持原超时和断言重跑后通过;未弱化验证。

检查清单

  • 已在本地或 CI 中通过 npm run check
  • 已运行并列出完整的受影响测试矩阵。
  • 行为变更包含原始故障回归测试和能够区分真实修复的反例。
  • 兼容性修复保留了旧版本和当前版本测试,或已说明不适用。
  • 运行时行为改动包含人工整机实测结果;不影响运行时行为的改动已说明不适用。
  • 必要时已更新文档及中英文变更日志。
  • Issue、PR、测试和脱敏日志均未包含凭据、账号标识、二维码或私聊内容等敏感信息。
  • 已关联包含可验证验收标准的 issue,或说明为何不需要。
  • 我已审阅并对全部提交内容负责,包括 AI 辅助生成的内容。

Share the inbound context and transport pipeline across routed and legacy public dispatch. Keep the 2026.6.1 floor, preserve admission and progress callbacks, and settle message hooks once.

Refs #98

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@NewFuture NewFuture added the risk:privileged Touches authentication, state, workflows, release, security, or package metadata label Sep 6, 2026
Resolve each text-send account once, share the public inbound request shape, and remove unused pre-builder context assignments while preserving dispatch and hook ownership.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@NewFuture
NewFuture marked this pull request as ready for review September 6, 2026 15:32
Copilot AI balanced review requested due to automatic review settings September 6, 2026 15:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The high-risk host hook and deferred-turn lifecycle migration still awaits the required human whole-system validation.

Pull request overview

Migrates inbound reply handling to public OpenClaw APIs while retaining legacy host compatibility and preserving lifecycle, account, and hook behavior.

Changes:

  • Adds routed/legacy inbound dispatch adaptation.
  • Centralizes legacy reply hooks and transport message IDs.
  • Expands lifecycle, transport, compatibility, and documentation coverage.
File summaries
File Description
test/helpers/channel-runtime.ts Supports both runtime contracts.
src/monitor/monitor.ts Updates dispatch documentation.
src/monitor/monitor.test.ts Tests replay scheduling after failure.
src/messaging/process-message.ts Uses public context and turn dispatch.
src/messaging/process-message.test.ts Covers dispatch, hooks, media, and lifecycle.
src/messaging/outbound-hooks.ts Centralizes local hook settlement.
src/messaging/outbound-hooks.test.ts Tests cancellation and settlement.
src/messaging/inbound.ts Updates session-key documentation.
src/messaging/inbound-turn.ts Adds modern/legacy compatibility adapter.
src/messaging/inbound-turn.test.ts Tests both public contracts.
src/channel.ts Removes duplicate outbound hooks.
src/channel.test.ts Verifies host-owned outbound hooks.
docs/zh-CN/architecture.md Documents the new architecture in Chinese.
docs/en/architecture.md Documents the new architecture in English.
CHANGELOG.md Adds Chinese release notes.
CHANGELOG_EN.md Adds English release notes.
Review details
  • Files reviewed: 16/16 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@NewFuture
NewFuture merged commit 0eece27 into main Sep 6, 2026
18 checks passed
@NewFuture
NewFuture deleted the newfuture-public-channel-turns branch September 6, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:privileged Touches authentication, state, workflows, release, security, or package metadata

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Task]: Migrate inbound turns and hooks to the public channel-turn SDK

2 participants