fix(reply): suppress trailing acks after message-tool sends#97513
fix(reply): suppress trailing acks after message-tool sends#97513mushuiyu886 wants to merge 2 commits into
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 10, 2026, 9:57 PM ET / July 11, 2026, 01:57 UTC. Summary PR surface: Source +19, Tests +48. Total +67 across 4 files. Reproducibility: yes. at source level. Current main's 10-character duplicate floor explains why short acknowledgements survive, and the PR supplies the pre-fix resolver failure plus after-fix production-resolver output. Review metrics: none identified. Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Refresh this focused candidate onto current main, retain its sent-text, route, thread/account, and media guards, and land it after exact-head checks; Telegram Desktop proof can add visible confirmation but is not required to repair the implementation. Do we have a high-confidence way to reproduce the issue? Yes at source level. Current main's 10-character duplicate floor explains why short acknowledgements survive, and the PR supplies the pre-fix resolver failure plus after-fix production-resolver output. Is this the best way to solve the issue? Yes. The PR extends the canonical route-scoped text-dedupe boundary established by the merged predecessor and is narrower and better targeted than the closed competing implementations. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 67e1d4391153. Label changesLabel justifications:
Evidence reviewedPR surface: Source +19, Tests +48. Total +67 across 4 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
Review history (1 earlier review cycle)
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
e0f6690 to
6483c49
Compare
Fixes #96681
Summary
已发 #22141,Sent above,核心回答如下,OK,已发, 不再追加总结,Sent. Replied in thread., andOK, that's the fix.from final reply payloads after a same-route message-tool send.OK, here is the actual answer..What Problem This Solves
When an agent sends the main response via the
messagetool, some models still append a short final acknowledgement. OpenClaw's delivery path treated that acknowledgement as a second source-channel reply, so users could see the main message followed by a duplicate-looking acknowledgement message.User Impact
Users receive the intended message-tool response without a second acknowledgement-only bubble. Distinct short replies, replies for another route, and media payloads remain deliverable.
Origin / follow-up
N/A — independent root-cause fix linked directly to #96681.
Root Cause
resolveFollowupDeliveryPayloads->filterMessagingToolDuplicates->isMessagingToolDuplicate. That duplicate helper intentionally ignores normalized text shorter thanMIN_DUPLICATE_TEXT_LENGTH = 10and only checks overlap withsentTexts. Simple and compound post-tool-send acknowledgement text is usually below that floor or semantically unrelated to the long sent body, so the resolver returned it as a second payload.Competition / linked PR analysis
Related open PR scan: The same-root candidates fix(reply): suppress post-tool-send meta commentary as duplicate reply #96680 and fix(reply): filter short trailing acks after message-tool sends #96763 are now closed; no open same-root candidate remains.
Current main status: Current
mainstill has no post-message-tool acknowledgement filter, so this PR remains the only open candidate linked to Duplicate reply: message-tool sends followed by short trailing acks ("已发 #xxx", "Sent above", "核心回答如下", "OK") #96681.fix(reply): filter short trailing acks after message-tool sends #96763 used a smaller ack matcher inside
filterMessagingToolDuplicates, but had broader false-positive exposure for phrases such asThanksand lacked an in-repo resolver regression test. This patch keeps the same narrow integration point while adding RED/GREEN resolver coverage, compound-ack coverage, and a more conservative pattern set.fix(reply): suppress post-tool-send meta commentary as duplicate reply #96680 used a separate meta-commentary filter across multiple delivery paths, resulting in a broader change surface. This patch instead folds the conservative meta-ack check into the existing source-of-truth text dedupe helper, so existing callers of
filterMessagingToolDuplicatesbenefit without adding a second payload-filtering API.Real behavior proof
messagetool send, acknowledgement-only final payloads no longer become a second source-channel reply.messagetool send →MessagingToolSendroute/text metadata →resolveMessagingToolPayloadDedupe→resolveFollowupDeliveryPayloadsor normal reply-payload construction →filterMessagingToolDuplicates→ outbound source-channel delivery effect.normalizeTextForComparisonhelper; no provider-owned contract or numeric constraint is involved./media/vdb/code/ai/aispace/openclaw-worktrees/pr-97513, exercising the production source-channel reply payload resolver and existing dedupe helper through the project's auto-reply reply Vitest config plus a standalone Node runtime proof outside the test runner. The runtime artifacts are embedded below with route details redacted where relevant.node scripts/run-vitest.mjs run --config test/vitest/vitest.auto-reply-reply.config.ts src/auto-reply/reply/followup-delivery.test.ts node scripts/run-vitest.mjs run --config test/vitest/vitest.auto-reply-reply.config.ts src/auto-reply/reply/followup-delivery.test.ts src/auto-reply/reply/reply-payloads.test.ts node scripts/run-vitest.mjs run --config test/vitest/vitest.auto-reply-reply.config.ts src/auto-reply/reply/followup-delivery.test.ts --reporter verbose node --import tsx "$EVIDENCE_DIR/runtime-resolver-proof-20260629.mjs" git diff --check git diff --check origin/main...HEAD node scripts/run-tsgo.mjs -p test/tsconfig/tsconfig.test.src.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/test-src.tsbuildinfo[]; the compound-ack regression drops已发, 不再追加总结,Sent. Replied in thread., andOK, that's the fix.while preservingOK, here is the actual answer.as a substantive short reply. The standalone runtime proof outside the test runner also shows ack-shaped text remains deliverable when there is no prior same-route message-tool sent text or when the message-tool send is for a different route. Existing route/media/text dedupe tests still pass.workflow_dispatchattempt for the Mantis Telegram Desktop proof on PR fix(reply): suppress trailing acks after message-tool sends #97513 failed withHTTP 403: Must have admin rights to Repository, so an authorized maintainer can still add stronger visible-channel proof by dispatching the workflow or posting@openclaw-mantis telegram desktop proof: verify a message-tool main reply followed by a short final ack shows one Telegram message and no trailing ack bubble.Regression Test Plan
src/auto-reply/reply/followup-delivery.test.tscovers the production resolver path;src/auto-reply/reply/reply-payloads.test.tswas rerun to guard existing text/media/route dedupe helpers.messagetool send records route text, then final payloads contain simple and compound acknowledgement text. The expected resolved payload list is empty for ack-only payloads, whileOK, here is the actual answer.remains deliverable.resolveFollowupDeliveryPayloads, the same boundary that applies threading, route matching, media dedupe, and text dedupe before source-channel delivery. It catches the user-visible duplicate without requiring a brittle end-to-end fixture for every provider.Review findings addressed
workflow_dispatchattempt returnedHTTP 403: Must have admin rights to Repository; this PR does not claim that transport-level recording was completed.OK, here is the actual answer.as substantive content, and preserve ack-shaped text when there is no prior same-route send or the send targets another route.mainstill lacks this acknowledgement filter, leaving this PR as the only open candidate linked to Duplicate reply: message-tool sends followed by short trailing acks ("已发 #xxx", "Sent above", "核心回答如下", "OK") #96681.main, and the focused implementation remains unchanged.git diff --checkandgit diff --check origin/main...HEADpassed with no output.Merge risk
merge-risk:message-deliveryand session-state-adjacent signals were considered because this patch suppresses final text payloads after message-tool sends and touches embedded-agent helper exports.return falseis the normal non-match result for an anchored predicate. The public-surface-looking export is a helper barrel export used internally by reply payload dedupe, not a config/schema/protocol/default contract change.sentTexts.length > 0, inside the existing message-tool text dedupe filter, and media payloads return before the predicate. Legitimate long content, unrelated routes, payloads without prior sent text, and the explicit substantive short-reply guard keep the existing behavior.Risk / Compatibility
MIN_DUPLICATE_TEXT_LENGTHbehavior, substring duplicate semantics, route matching, account/thread matching, media duplicate handling, provider configuration, and channel plugin behavior are unchanged.filterMessagingToolDuplicatesafterresolveMessagingToolPayloadDedupehas chosen same-route sent text evidence. The fix does not add a second downstream delivery filter or alter provider routing contracts.What was not changed