fix(gateway): config-driven text-debounce batching for WhatsApp + Weixin - #35391
Merged
Conversation
WhatsApp and WeChat (Weixin/iLink) both deliver messages individually without any client-side batching, so rapid multi-message bursts (forwarded batches, paste-splits, etc.) each trigger a separate agent invocation. This wastes tokens (redundant system prompts / context for each fragment) and degrades UX (the user receives reply fragments instead of a single coherent response). Both adapters now mirror the Telegram adapter's proven text-debounce pattern: - _text_batch_delay_seconds / _text_batch_split_delay_seconds (configurable via env vars) - _pending_text_batches dict for per-session aggregation - _enqueue_text_event() concatenates successive TEXT messages and resets the flush timer - _flush_text_batch() dispatches after the quiet period expires Configurable via env vars: HERMES_WHATSAPP_TEXT_BATCH_DELAY_SECONDS (default 5.0) HERMES_WHATSAPP_TEXT_BATCH_SPLIT_DELAY_SECONDS (default 10.0) HERMES_WEIXIN_TEXT_BATCH_DELAY_SECONDS (default 3.0) HERMES_WEIXIN_TEXT_BATCH_SPLIT_DELAY_SECONDS (default 5.0)
Convert the salvaged text-debounce delays from HERMES_* env vars to config.yaml (gateway.platforms.<name>.extra.text_batch_delay_seconds / text_batch_split_delay_seconds), per the '.env is for secrets only' policy. Adds a finite/non-negative guard so bad YAML values fall back to the defaults instead of crashing asyncio.sleep(). - whatsapp.py / weixin.py: read delays via _coerce_float_extra(config.extra) - update Weixin content-dedup regression test for the deferred dispatch path - add text-debounce coverage (whatsapp + weixin): defaults, config override, bad-value fallback, env-var-ignored, burst-collapse, lone-message - docs: WhatsApp + Weixin config keys
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
invalid-assignment |
1 |
First entries
gateway/platforms/whatsapp.py:1224: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
gateway/platforms/weixin.py:1488: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_last_chunk_len` on type `MessageEvent`
tests/gateway/test_weixin.py:950: [invalid-assignment] invalid-assignment: Object of type `def _capture(event) -> CoroutineType[Any, Any, Unknown]` is not assignable to attribute `handle_message` of type `def handle_message(self, event: MessageEvent) -> CoroutineType[Any, Any, None]`
✅ Fixed issues: none
Unchanged: 4931 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
This was referenced May 30, 2026
1 task
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.
Summary
WhatsApp and Weixin now batch rapid-fire text bursts into one agent invocation, with the debounce delays configured in
config.yaml(not env vars).Salvages @redpiggy-cyber's PR #35302 (closes #35301) and converts its
HERMES_*env-var config to theconfig.yamlpath per our ".envis for secrets only" policy.Changes
gateway/platforms/whatsapp.py,weixin.py: text-debounce batching (contributor commit), delays read via_coerce_float_extra(config.extra)instead ofos.getenv(); finite/non-negative guard so bad YAML falls back to defaults instead of crashingasyncio.sleep()gateway.platforms.{whatsapp,weixin}.extra.text_batch_delay_seconds/text_batch_split_delay_seconds(defaults 5/10s WhatsApp, 3/5s Weixin)Validation
handle_messageDedup still runs before enqueue in Weixin
_process_message, so the #16182 duplicate-drop fix is preserved.Closes #35301. Supersedes #35302 (@redpiggy-cyber, authorship preserved via cherry-pick) and #17165 (@keiravoss94, WhatsApp-only).
Infographic