Skip to content

fix: suppress trailing post-message-tool meta-acknowledgements#99320

Closed
krissding wants to merge 1 commit into
openclaw:mainfrom
krissding:fix/post-meta-ack-filter
Closed

fix: suppress trailing post-message-tool meta-acknowledgements#99320
krissding wants to merge 1 commit into
openclaw:mainfrom
krissding:fix/post-meta-ack-filter

Conversation

@krissding

@krissding krissding commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Closes #96681

What Problem This Solves

After an agent calls the message tool (action=send) to deliver its main reply, models often append a short trailing meta-acknowledgement -- patterns like 已发 #22141, Sent above, 核心回答如下, OK, Roger, Got it, and compound forms like Sent. Replied in thread., 已发, 不再追加总结.

These acks carry no information beyond the message-tool send that already went out, but OpenClaw currently delivers them as a second visible message in the channel.

The existing filterMessagingToolDuplicates only catches full-content duplicates via substring match with a 10-char minimum, so short meta-acks (e.g. 已发 #22141, 9 chars) escape the floor and reach the channel as a duplicate message.

Why This Change Was Made

This patch adds a complementary filter -- filterMessagingToolMetaCommentary -- that recognizes post-tool-send meta commentary by pattern (Chinese + English) and suppresses it from the final reply payload.

Key design decisions:

  1. Compound ack coverage -- Two-pass detection: first try full-text anchored patterns, then split on sentence boundaries and verify every segment independently matches an ack pattern. Catches Sent. Replied in thread., 已发, 不再追加总结, OK. Done. while preserving mixed forms like OK, that's the fix.

  2. Only fires after message-tool sends (sentTexts.length > 0). Agents with no message-tool sends are unaffected.

  3. Length-capped at 200 chars and anchored patterns only -- prefix matches like Oklahoma weather, 已发现问题 are not suppressed.

  4. Media payloads always preserved, even if caption is a meta-ack.

  5. Wired into both paths: agent-runner-payloads.ts (final reply) and followup-delivery.ts (queued follow-up).

Evidence

Real behavior proof (tsx runtime)

============================================================
Real Behavior Proof: Post-Message-Tool Meta-Ack Filter
============================================================

[1] Meta-ack pattern detection:
  ✓ "已发 #22141" → true
  ✓ "Sent above" → true
  ✓ "OK" → true
  ✓ "核心回答如下" → true
  ✓ "Sent. Replied in thread." → true
  ✓ "已发, 不再追加总结" → true
  ✓ "OK. Done." → true
  ✓ "Got it. Will do." → true
  ✓ "了解, 收到" → true
  ✓ "OK, that's the fix." → false
  ✓ "Done, the migration is complete." → false
  ✓ "Got it, let me take a look at the code." → false
  ✓ "Oklahoma weather" → false
  ✓ "已发现问题" → false
  Accuracy: 14/14

[2] Pipeline: 3 meta-acks + 1 real reply → filters to 1 payload
  Output: 1 payloads, kept: "Here is the real follow-up analysis..."

[3] Media payloads always preserved:
  1 media payload(s) preserved after filter

✓ All behavior checks passed.

Test coverage (reply-payloads.test.ts)

All 134 tests pass (includes 109 new test cases for meta-ack detection):

 Test Files  1 passed (1)
      Tests  134 passed (134)
   Duration  5.10s

Standalone meta-acks covered (46 positive cases): 已发, 已发 #22141, 已发送, 已发完毕, 主回复已发, 消息已发出, 回复已发, 好了, 收到, 完毕, 完成, 了解, 知道了, 明白, 核心回答如下, 总结如下, 以下为核心回答, 以下为总结, 不再追加总结, 不再追加, 以下为回复, 答案如下, 如上, 回复如上, Sent, Sent above, Done., Replied above, Replied in thread, See above, As above, Posted., Acknowledged., OK, Okay, Roger, Got it, Gotcha, Copy that, Copied, Ack, Will do, On it, Noted, Understood, Thanks

Compound meta-acks covered (13 cases): Sent. Replied in thread., 已发, 不再追加总结, 已发. 不再追加., OK. Done., Roger, copy., Done. Sent., 收到. 已发., Sent above. Replying in thread., Got it. Will do., 已发, 完成, OK, noted, 了解, 收到, Copied, thanks

False positives excluded (18+ cases): Oklahoma weather, sentence fixed, 已发现问题, 已发现, 已收到消息, sentry deployed, okay let's go, OK, that's the fix., Got it, let me take a look at the code., Done, the migration is complete., Sent, but I noticed the logs have an error., 收到, 但是这个方案有一个问题, real reply content, and more.

Build verification

The full project builds successfully with these changes:

[build-all] phase timings: total 506.3s

No type errors, no build failures.

Merge Risk

Low. The new filter is additive and only activates when message-tool sends happened this run (sentTexts.length > 0). It does not modify the existing dedupe logic. Media payloads are explicitly preserved. The worst-case failure mode is a false positive suppressing a real reply, which the anchored patterns + 200-char limit + compound segment validation guard against.

🤖 Generated with Claude Code

…al reply

After an agent calls the message tool (action=send), models often append
short trailing meta-acks ("已发 openclaw#22141", "Sent above", "OK", "Roger")
that escape the existing 10-char dedupe floor and appear as a second
visible message in the channel.

Add isPostToolSendMetaCommentary with full-text anchored patterns plus
compound ack detection (sentence-boundary split, every segment must
independently match ack patterns). Wire filterMessagingToolMetaCommentary
into both agent-runner-payloads and followup-delivery paths after the
existing content dedupe. Preserves mixed-content forms like
"OK, that's the fix." and media payloads.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M labels Jul 3, 2026
@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Close as superseded: the same root cause is already owned by #97513, which is open, mergeable, proof-sufficient, and narrower than this branch, so keeping this duplicate landing candidate open would add review churn without a unique necessary fix.

Canonical path: Land one canonical route-scoped meta-ack suppression, preferably the already proof-sufficient #97513 unless maintainers choose otherwise, then close the canonical issue and retire duplicate candidates.

So I’m closing this here and keeping the remaining discussion on #97513.

Review details

Best possible solution:

Land one canonical route-scoped meta-ack suppression, preferably the already proof-sufficient #97513 unless maintainers choose otherwise, then close the canonical issue and retire duplicate candidates.

Do we have a high-confidence way to reproduce the issue?

Yes at source level: current main keeps the 10-character duplicate floor and routes final/follow-up payloads through text dedupe without a meta-ack classifier. I did not run a live channel reproduction in this read-only review.

Is this the best way to solve the issue?

No for this PR as the landing path: the existing dedupe seam is right, but #97513 already implements the same root fix in a smaller, proof-sufficient, mergeable branch.

Security review:

Security review cleared: No concrete security or supply-chain concern found; the diff only changes internal TypeScript reply filtering exports and tests.

AGENTS.md: found and applied where relevant.

What I checked:

Likely related people:

  • steipete: Peter Steinberger extracted the follow-up delivery seam that shares the message-tool dedupe invariant and is the dominant contributor in the sampled reply-delivery files. (role: adjacent owner; confidence: high; commits: 43e6c923ded1, ea018a68ccb9; files: src/auto-reply/reply/followup-delivery.ts, src/auto-reply/reply/agent-runner-payloads.ts)
  • vincentkoc: Vincent Koc split the reply-payload dedupe helpers and recently touched the messaging-dedupe surface that this PR changes. (role: recent area contributor; confidence: high; commits: 125e778fe618, e085fa1a3ffd; files: src/auto-reply/reply/reply-payloads-dedupe.ts, src/agents/embedded-agent-helpers/messaging-dedupe.ts)

Codex review notes: model internal, reasoning high; reviewed against 18360ac668f8.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. mantis: telegram-visible-proof Mantis should capture Telegram visible proof. labels Jul 3, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 3, 2026
@clawsweeper clawsweeper Bot closed this Jul 3, 2026
@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

🦞✅
ClawSweeper autoclose is complete.

Reason: structured ClawSweeper close marker: close-required (sha=42f8c62bae98a3dd88087cbcfd8c2f236c1d696f)

Closed:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling mantis: telegram-visible-proof Mantis should capture Telegram visible proof. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Duplicate reply: message-tool sends followed by short trailing acks ("已发 #xxx", "Sent above", "核心回答如下", "OK")

1 participant