Skip to content

fix(weixin): preserve intentional repeated slash commands - #129536

Closed
Wenfengcheng wants to merge 2 commits into
NousResearch:mainfrom
Wenfengcheng:fix/29779-weixin-repeat-commands
Closed

Wenfengcheng wants to merge 2 commits into
NousResearch:mainfrom
Wenfengcheng:fix/29779-weixin-repeat-commands

Conversation

@Wenfengcheng

@Wenfengcheng Wenfengcheng commented Sep 30, 2026 •

Copy link
Copy Markdown

Problem

Distinct Weixin messages repeating /approve, /deny, /retry, or a custom slash command are dropped for five minutes by content-fingerprint deduplication before reaching gateway command handling.

Fixes #29779.

Root cause

WeixinAdapter._process_message applies the ordinary-text fingerprint cache to control messages too. The separate message-ID cache already rejects transport retransmissions. Leading-whitespace commands also need command classification to avoid entering the text debounce queue.

Change

  • Exempt slash-command-shaped text from content-fingerprint dedup, retaining message-ID dedup.
  • Use the same whitespace-tolerant command classification at the batching boundary.
  • Preserve ordinary-text dedup, original text, and empty-message handling.

Salvages @briandevans's closed #29787 with original commit authorship preserved, ported to current main and strengthened with deterministic ingress tests. #36707 and #81124 are also author-closed, unmerged. Actual diffs of #36758 (ordinary text-batch fingerprint release), #97581 (missing message-ID media), and #129176 (quoted-text attribution) cover different contracts; none exempts repeated commands.

Verification

Base: 5c08ad68f7ec488057880752f8071cee154a6e60.

Native Windows, isolated HOME/USERPROFILE/HERMES_HOME/APPDATA/LOCALAPPDATA, existing Python 3.11.15; no production credentials or network transport used.

bash scripts/run_tests.sh tests/gateway/test_weixin_command_dedup.py -j 2 --file-retries 0

  • Base RED: 5 failed, 1 passed (distinct command IDs are dropped; whitespace command queues).
  • Initial focused GREEN: 6 passed; same-PR continuation expands the regression to real active-session bypass and media-caption commands: base 10 failed / 1 passed → head 11 passed.
  • Final head b06ff5480511290bcf10487432d426c063a6fef5: 76 passed across test_weixin.py, test_weixin_command_dedup.py, test_weixin_typing.py, test_weixin_secret_scope.py, test_message_deduplicator.py, and test_approve_deny_commands.py using the repository runner. An initial sparse-checkout run failed because hermes_platform and locale assets were absent; after materializing those existing repository paths, the complete selection passes.
  • Real local ingress → base-adapter busy guard → installed handler is covered for /approve and /deny, with and without media, including whitespace and message-ID replay. Custom commands use a captured ingress handoff; no claim of live WeChat service coverage.
  • Independent Codex exact-head static review completed. Claude Code 2.1.280 / Opus 5.5 returned repeated HTTP 503s and timed out; its review remains pending, not PASS. No full-repository-suite claim.

Non-goals / continuation

No approval authorization/session-key changes, no ordinary-text TTL redesign, no no-ID synthetic identity, no quoted-message parsing changes. The reported repeated-command contract is delivered. Continuation completed on this PR with commit b06ff5480511 (real busy-guard and media-command coverage). Remaining work is the unavailable Claude review; adjacent ordinary-text lifecycle changes stay with #36758, rather than expanding this PR into that owned contract.

briandevans and others added 2 commits October 1, 2026 02:58
…edup

The weixin adapter's secondary content-fingerprint dedup (added in NousResearch#16182
to catch iLink redeliveries that share text but use fresh message_ids)
treats every repeated text from the same sender within the 5-minute TTL
as a duplicate. That silently drops intentional re-issues of slash
commands such as `/approve` (one per pending approval), `/restart-sglang`,
and `/help` — the user sees the message arrive in gateway logs but never
in the message-handler pipeline.

Skip the content dedup when the text is a slash command. `message_id`
dedup still catches genuine network-layer retries, and the original
NousResearch#16182 protection still applies to free-form text (the existing
regression test in this class continues to pass).

Detection tolerates leading whitespace so clients that don't trim
identically all hit the same path.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/wecom WeCom / WeChat Work adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages labels Sep 30, 2026
@webtecnica

Copy link
Copy Markdown

Verified: all 11 tests in test_weixin_command_dedup.py pass on Windows with Python 3.14.7. Repeated slash commands (/approve, /deny, /retry, etc.) with or without media bypass the content-fingerprint deduplication cache as expected, while message_id dedup continues to prevent genuine transport retries and plain text deduplication remains unaffected. LGTM — ready for merge.

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

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/wecom WeCom / WeChat Work adapter sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

WeChat adapter content dedup silently drops repeated commands, breaking /approve workflow

4 participants