Skip to content

fix(gateway): add inbound text batching to Discord, Matrix, WeCom + adaptive delay for all#6979

Merged
teknium1 merged 7 commits into
mainfrom
hermes/hermes-62b6865d
Apr 10, 2026
Merged

fix(gateway): add inbound text batching to Discord, Matrix, WeCom + adaptive delay for all#6979
teknium1 merged 7 commits into
mainfrom
hermes/hermes-62b6865d

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Ports the adaptive text batching pattern from the Telegram adapter to Discord, Matrix, and WeCom. Also adds adaptive delay to Feishu's existing batching.

Problem: When users paste long messages, the messaging client splits them at the platform's character limit. Without batching, only the first chunk is processed — the rest is silently lost or processed as a separate message after the agent has already responded. Discord (2000-char limit) is worst affected.

Solution: Buffer rapid successive text messages from the same user/session, concatenate them, and dispatch as one event after a quiet period.

Changes per platform

Platform What changed Limit Threshold
Telegram Added adaptive delay to existing batching 4096 4000
Discord Full batching + adaptive delay (new) 2000 1900
Matrix Full batching + adaptive delay (new) 4000 3900
WeCom Full batching + adaptive delay (new) 4000 3900
Feishu Added adaptive delay to existing batching ~4096 4000

Adaptive delay logic

  • Normal text: 0.6s quiet period (configurable per platform)
  • Chunk near the split threshold: 2.0s quiet period (continuation almost certain)
  • Each new chunk resets the timer — chains correctly for any number of splits

Key design decisions

  • TEXT only: Only text messages are batched. Commands (/stop, /approve) and media dispatch immediately — they won't be client-side split.
  • Bypass at delay=0: When batch delay is 0, messages dispatch synchronously (no async task). Useful for tests and for users who don't want batching.
  • Session-scoped keys: Uses build_session_key() (not simple chat_id:user_id) for proper session routing.

Attribution

Cherry-picked from:

Fixes #6892

Test plan

22 new tests across all 5 platforms:

  • Single message dispatch, split aggregation (2/3-way), cross-chat isolation
  • Adaptive delay verification (near-limit chunks wait longer)
  • State cleanup after flush

Existing tests: adapter._text_batch_delay_seconds = 0 bypasses batching for synchronous assertion patterns. 0 regressions in the gateway test suite.

teknium1 added 7 commits April 9, 2026 22:35
Cherry-picked from PR #6891 by SHL0MS.
When a chunk is near the 4096-char split point, wait 2.0s instead of 0.6s
since a continuation is almost certain.
Cherry-picked from PR #6894 by SHL0MS with fixes:
- Only batch TEXT messages; commands/media dispatch immediately
- Use build_session_key() for proper session-scoped batch keys
- Consistent naming (_text_batch_delay_seconds)
- Proper Dict[str, MessageEvent] typing

Discord splits at 2000 chars (lowest of all platforms). Adaptive delay
waits 2.0s when a chunk is near the limit, 0.6s otherwise.
Ports the adaptive batching pattern from the Telegram adapter.
Matrix clients split messages around 4000 chars. Adaptive delay waits
2.0s when a chunk is near the limit, 0.6s otherwise. Only text messages
are batched; commands dispatch immediately.

Ref #6892
Ports the adaptive batching pattern from the Telegram adapter.
WeCom clients split messages around 4000 chars. Adaptive delay waits
2.0s when a chunk is near the limit, 0.6s otherwise. Only text messages
are batched; commands/media dispatch immediately.

Ref #6892
Feishu already had text batching with a static 0.6s delay. This adds
adaptive delay: waits 2.0s when a chunk is near the ~4096-char split
point since a continuation is almost certain.

Tracks _last_chunk_len on each queued event to determine the delay.
Configurable via HERMES_FEISHU_TEXT_BATCH_SPLIT_DELAY_SECONDS (default 2.0).

Ref #6892
…eishu

22 tests covering:
- Single message dispatch after delay
- Split message aggregation (2-way and 3-way)
- Different chats/rooms not merged
- Adaptive delay for near-limit chunks
- State cleanup after flush
- Split continuation merging

All 5 platform adapters tested.
Set _text_batch_delay_seconds = 0 on test adapter fixtures so messages
dispatch immediately (bypassing async batching). This preserves the
existing synchronous assertion patterns while the batching logic is
tested separately in test_text_batching.py.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Gateway] Split inbound messages lost on Discord, Feishu, Matrix, WeCom — no text batching

1 participant