问题描述
@tencent-weixin/openclaw-weixin@2.4.3 在发送较长微信回复时,当前缺少可靠的 Markdown-safe 分块流程。
OpenClaw core 已经提供了 channel outbound chunking contract:channel adapter 可以通过 outbound.chunker、outbound.chunkerMode、textChunkLimit 等字段声明如何在发送前拆分文本。
但 openclaw-weixin 当前的 outbound adapter 只声明了 textChunkLimit,没有声明 chunker / chunkerMode。在 OpenClaw core 的通用 outbound delivery 路径中,实际分块依赖 adapter 提供 chunker;如果没有 chunker,文本会作为单条消息进入 sendText。
因此,openclaw-weixin 没有实际接入 OpenClaw core 的 outbound chunking contract。
相关代码路径
当前 openclaw-weixin 的 outbound adapter 大致是:
outbound: {
deliveryMode: "direct",
textChunkLimit: 4000,
sendText: async (ctx) => {
// ...
},
}
这里缺少:
chunker: ...,
chunkerMode: "markdown",
此外,普通入站回复路径使用了插件自定义的 reply dispatcher delivery:
createReplyDispatcherWithTyping({
deliver: async (payload) => {
const rawText = payload.text ?? "";
const f = new StreamingMarkdownFilter();
const text = f.feed(rawText) + f.flush();
await sendMessageWeixin({
to: ctx.To,
text,
opts: { ... },
});
},
});
这个路径中:
deliver 内部没有执行文本分块。
sendMessageWeixin 只负责发送单条文本消息,没有分块逻辑。
StreamingMarkdownFilter 是 Markdown 过滤/转换器,不是 chunker。
- 每次
deliver 都会新建一个 StreamingMarkdownFilter,无法保留跨 chunk 的 Markdown 状态。
dispatchReplyFromConfig 调用中设置了:
replyOptions: { ...replyOptions, disableBlockStreaming: true }
这会关闭 core 的 block streaming chunker。
实际影响
当 AI 回复较长,尤其包含 Markdown 内容时,可能出现:
- 微信消息发送失败
- 微信侧截断
- 用户只收到部分回复
- fenced code block 被切坏
- inline code / link / bold / italic 标记被破坏
- Markdown 表格、列表结构显示异常
- 过滤器在分片边界处无法正确处理 Markdown 状态
容易受影响的内容包括:
- fenced code block
- inline code
- Markdown link
- bold / italic
- table
- list
- 长中文段落
- emoji 或其他多字节字符
期望行为
希望 openclaw-weixin 在发送微信文本消息前提供统一、可靠的分块能力:
- 长文本回复自动拆分为多条微信消息。
- 分块逻辑适配微信侧单条消息长度限制。
- 优先按自然边界拆分:
- 分块过程尽量保持 Markdown 结构完整。
- fenced code block 不应被直接截断;必要时应 close/reopen code fence。
- 尽量避免破坏 inline code、链接、粗体、斜体等 Markdown 结构。
- 不产生空白 chunk。
- 普通回复路径和 outbound
sendText 路径使用一致的分块逻辑。
- 发送层检查微信/iLink API 返回体中的业务错误码,而不只是 HTTP 状态。
可能的修复方向
方案 A:接入 OpenClaw outbound chunking contract
在 openclaw-weixin 的 outbound adapter 中声明 chunker 和 chunkerMode:
outbound: {
deliveryMode: "direct",
textChunkLimit: ...,
chunker: ...,
chunkerMode: "markdown",
sendText: async (ctx) => {
// ...
},
}
这样 OpenClaw core 的通用 outbound delivery 路径可以在调用 sendText 前完成分块。
方案 B:普通回复路径复用同一套 chunker
在 process-message.ts 的自定义 deliver 路径中,在调用 StreamingMarkdownFilter 和 sendMessageWeixin 前显式执行 chunking。
推荐顺序是:
raw markdown
-> Markdown-safe chunking
-> per-chunk StreamingMarkdownFilter
-> sendMessageWeixin per chunk
避免先简单截断文本,再对每段独立运行 filter。
方案 C:实现 WeChat 专用 chunker
如果 core 现有 chunker 无法完全覆盖微信需求,可以在插件侧实现专用 chunker:
- 支持微信安全长度阈值
- 支持 UTF-8 byte-aware 计算,或至少允许配置安全阈值
- 优先按段落、换行、空格拆分
- 保护 fenced code block
- 尽量保护 inline Markdown
- 过滤空 chunk
- 每个 chunk 单独发送
- 必要时加入发送间隔,避免微信侧限流或丢消息
总结
openclaw-weixin 当前缺少可靠的长文本分块发送流程:
- outbound adapter 没有声明
chunker / chunkerMode,未实际接入 OpenClaw outbound chunking contract。
- 普通回复路径使用自定义
deliver,内部没有分块。
StreamingMarkdownFilter 只负责 Markdown 过滤/转换,不负责分块。
- block streaming chunker 在普通回复路径中被禁用。
- 插件侧没有实现微信专用 Markdown-safe chunker。
希望插件能在发送层统一处理微信长文本分块,避免长回复、Markdown 回复和代码块回复在微信侧失败或显示异常。
问题描述
@tencent-weixin/openclaw-weixin@2.4.3在发送较长微信回复时,当前缺少可靠的 Markdown-safe 分块流程。OpenClaw core 已经提供了 channel outbound chunking contract:channel adapter 可以通过
outbound.chunker、outbound.chunkerMode、textChunkLimit等字段声明如何在发送前拆分文本。但
openclaw-weixin当前的 outbound adapter 只声明了textChunkLimit,没有声明chunker/chunkerMode。在 OpenClaw core 的通用 outbound delivery 路径中,实际分块依赖 adapter 提供chunker;如果没有chunker,文本会作为单条消息进入sendText。因此,
openclaw-weixin没有实际接入 OpenClaw core 的 outbound chunking contract。相关代码路径
当前
openclaw-weixin的 outbound adapter 大致是:这里缺少:
此外,普通入站回复路径使用了插件自定义的 reply dispatcher delivery:
这个路径中:
deliver内部没有执行文本分块。sendMessageWeixin只负责发送单条文本消息,没有分块逻辑。StreamingMarkdownFilter是 Markdown 过滤/转换器,不是 chunker。deliver都会新建一个StreamingMarkdownFilter,无法保留跨 chunk 的 Markdown 状态。dispatchReplyFromConfig调用中设置了:这会关闭 core 的 block streaming chunker。
实际影响
当 AI 回复较长,尤其包含 Markdown 内容时,可能出现:
容易受影响的内容包括:
期望行为
希望
openclaw-weixin在发送微信文本消息前提供统一、可靠的分块能力:sendText路径使用一致的分块逻辑。可能的修复方向
方案 A:接入 OpenClaw outbound chunking contract
在
openclaw-weixin的outboundadapter 中声明chunker和chunkerMode:这样 OpenClaw core 的通用 outbound delivery 路径可以在调用
sendText前完成分块。方案 B:普通回复路径复用同一套 chunker
在
process-message.ts的自定义deliver路径中,在调用StreamingMarkdownFilter和sendMessageWeixin前显式执行 chunking。推荐顺序是:
避免先简单截断文本,再对每段独立运行 filter。
方案 C:实现 WeChat 专用 chunker
如果 core 现有 chunker 无法完全覆盖微信需求,可以在插件侧实现专用 chunker:
总结
openclaw-weixin当前缺少可靠的长文本分块发送流程:chunker/chunkerMode,未实际接入 OpenClaw outbound chunking contract。deliver,内部没有分块。StreamingMarkdownFilter只负责 Markdown 过滤/转换,不负责分块。希望插件能在发送层统一处理微信长文本分块,避免长回复、Markdown 回复和代码块回复在微信侧失败或显示异常。