Conversation
…only delivery WeChat cannot edit or retract a sent message. Block-streamed commentary between tool calls and other interim text payloads were sent verbatim and then merged into the final reply again, so users received the same content twice. Skip interim (tool/block) text-only payloads at the deliver seam, keeping media, errors, approval prompts, and all final payloads. Fixes Tencent#292
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题摘要
Issue #292:agent 在工具调用之间产出的中间文本(旁白/commentary)被逐条直发到微信,且同一段文本随后又并入最终回复重发。微信不能编辑消息,用户收到重复消息(实测 A / B / A(重复) / 8 两起同构)。
根因
dispatchReplyFromConfig传disableBlockStreaming: true,但工具调用之间的块级旁白(block)仍从宿主直达插件的deliver回调并外发;directlySentBlockKeys/sentFinalPayloadDedupeKeys)只登记 terminal 内容、排除 commentary,因此最终回复再把相同文本重发一遍 —— 重复源自宿主,按 issue 约定本 PR 不改宿主。修复策略(插件侧,final-only 交付)
微信是不可编辑消息的通道,故对中间块文本采用 final-only 交付:在插件的
deliver路径识别并跳过「非最终、纯文本」的 block payload,只保留会被并入最终回复的前置内容,避免同文双发。src/messaging/interim-reply-policy.ts:纯函数isInterimTextOnlyWeixinReply(payload, info),仅在交付种类为block、且为纯文本时判定应跳过。src/messaging/process-message.ts的deliver回调读取宿主导入的第二个参数{ kind },对判定命中的 payload 提前返回(debug 日志记录)。final(含合法的多条 final)、携带媒体(mediaUrl/mediaUrls)、isError、审批(channelData.execApproval)、tool 摘要、以及 kind 未知(防御旧宿主)一律照常发送。测试说明
新增
src/messaging/interim-reply-policy.test.ts(9 例,vitest,co-located):本地验证
npm run ci全绿:oxfmt format:check + oxlint + tsc typecheck + vitest(28 文件 / 412 用例)+ build。oxlint 仅有既存告警(如process-message.ts:508,位于基线未改动行),与本次改动无关。Fixes #292