Skip to content

fix: improve WhatsApp UX — chunking, formatting, streaming - #8723

Merged
teknium1 merged 1 commit into
mainfrom
hermes/hermes-798ab9b3
Apr 13, 2026
Merged

fix: improve WhatsApp UX — chunking, formatting, streaming#8723
teknium1 merged 1 commit into
mainfrom
hermes/hermes-798ab9b3

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

Addresses user complaints about poor WhatsApp experience (tweet from @joaopanizzutti): "sends the whole code all the time" and "terminal gets interrupted and gets cooked."

Competitive analysis of OpenClaw's WhatsApp implementation revealed three root causes in our adapter, all fixed here.

Changes

1. Reclassify WhatsApp from TIER_LOW → TIER_MEDIUM (display_config.py)

The Baileys bridge already implements a /edit endpoint, so WhatsApp supports message editing — it was incorrectly grouped with platforms that don't (Signal, WeChat). This single-line change enables:

  • Streaming: progressive response delivery instead of buffering the entire response
  • Tool progress: "new" mode shows users what tools are running (vs silence)

2. Fix send() — add chunking + formatting (whatsapp.py)

  • MAX_MESSAGE_LENGTH: 65536 → 4096 (practical UX limit — 64K messages are unreadable on mobile)
  • send() now calls format_message() and truncate_message() before sending, then loops through chunks with 300ms delay between them
  • reply_to only set on the first chunk
  • Empty/whitespace-only messages return early (matches Telegram pattern)
  • The base class truncate_message() already handles code block boundary detection (closes/reopens ``` fences at chunk boundaries)

3. Override format_message() — markdown → WhatsApp conversion (whatsapp.py)

WhatsApp uses different formatting syntax than standard markdown:

  • **bold***bold*
  • __underline__*bold* (WhatsApp has no underline)
  • ~~strike~~~strike~
  • # headers*headers* (bold text)
  • [text](url)text (url)
  • Code blocks and inline code are protected from conversion via placeholder substitution (same approach as OpenClaw's markdownToWhatsApp())

What this fixes

  • "sends the whole code all the time" → messages chunked at 4K with proper WhatsApp formatting and code block preservation
  • "terminal gets interrupted and gets cooked" → streaming + tool progress give visual feedback so users don't send follow-up messages that interrupt the running agent

Future improvements (not in this PR)

  • Per-platform busy_input_mode default (currently global config only)
  • WhatsApp-specific code block handling (send as document attachment for very long blocks)

Test plan

  • 22 new tests in test_whatsapp_formatting.py covering format_message, chunking, send behavior
  • Updated test_display_config.py to reflect WhatsApp's new tier
  • All 86 WhatsApp + display_config tests pass
  • 2665/2688 gateway tests pass (23 pre-existing failures in signal/sms/telegram/matrix)

Three changes that address the poor WhatsApp experience reported by users:

1. Reclassify WhatsApp from TIER_LOW to TIER_MEDIUM in display_config.py
   — enables streaming and tool progress via the existing Baileys /edit
   bridge endpoint. Users now see progressive responses instead of
   minutes of silence followed by a wall of text.

2. Lower MAX_MESSAGE_LENGTH from 65536 to 4096 and add proper chunking
   — send() now calls format_message() and truncate_message() before
   sending, then loops through chunks with a small delay between them.
   The base class truncate_message() already handles code block boundary
   detection (closes/reopens fences at chunk boundaries). reply_to is
   only set on the first chunk.

3. Override format_message() with WhatsApp-specific markdown conversion
   — converts **bold** to *bold*, ~~strike~~ to ~strike~, headers to
   bold text, and [links](url) to text (url). Code blocks and inline
   code are protected from conversion via placeholder substitution.

Together these fix the two user complaints:
- 'sends the whole code all the time' → now chunked at 4K with proper
  formatting
- 'terminal gets interrupted and gets cooked' → streaming + tool progress
  give visual feedback so users don't accidentally interrupt with
  follow-up messages
@teknium1
teknium1 merged commit 15b1a3a into main Apr 13, 2026
2 of 4 checks passed
@teknium1
teknium1 deleted the hermes/hermes-798ab9b3 branch April 13, 2026 02:20
aj-nt pushed a commit to aj-nt/hermes-agent that referenced this pull request May 1, 2026
…rch#8723)

Three changes that address the poor WhatsApp experience reported by users:

1. Reclassify WhatsApp from TIER_LOW to TIER_MEDIUM in display_config.py
   — enables streaming and tool progress via the existing Baileys /edit
   bridge endpoint. Users now see progressive responses instead of
   minutes of silence followed by a wall of text.

2. Lower MAX_MESSAGE_LENGTH from 65536 to 4096 and add proper chunking
   — send() now calls format_message() and truncate_message() before
   sending, then loops through chunks with a small delay between them.
   The base class truncate_message() already handles code block boundary
   detection (closes/reopens fences at chunk boundaries). reply_to is
   only set on the first chunk.

3. Override format_message() with WhatsApp-specific markdown conversion
   — converts **bold** to *bold*, ~~strike~~ to ~strike~, headers to
   bold text, and [links](url) to text (url). Code blocks and inline
   code are protected from conversion via placeholder substitution.

Together these fix the two user complaints:
- 'sends the whole code all the time' → now chunked at 4K with proper
  formatting
- 'terminal gets interrupted and gets cooked' → streaming + tool progress
  give visual feedback so users don't accidentally interrupt with
  follow-up messages
@bgmbgm94

bgmbgm94 commented May 4, 2026

Copy link
Copy Markdown

Sharing a related data point from a Windows Discord gateway deployment.

We saw intermittent Discord send 429 pressure around long/chunked replies. A local mitigation that helped was pacing outbound Discord channel.send(...) calls with a small await asyncio.sleep(0.5) before chunk sends and before the plain-text fallback resend path.

This did not look related to a separate silent Process exited with code 0 investigation, but it did reduce burst pressure during Discord replies. The WhatsApp chunk delay here feels like a useful precedent for platform-level send pacing; if Discord send behavior is revisited, a configurable Discord send throttle / adapter pacing helper might be worth considering too.

02356abc pushed a commit to 02356abc/hermes-agent that referenced this pull request May 14, 2026
…rch#8723)

Three changes that address the poor WhatsApp experience reported by users:

1. Reclassify WhatsApp from TIER_LOW to TIER_MEDIUM in display_config.py
   — enables streaming and tool progress via the existing Baileys /edit
   bridge endpoint. Users now see progressive responses instead of
   minutes of silence followed by a wall of text.

2. Lower MAX_MESSAGE_LENGTH from 65536 to 4096 and add proper chunking
   — send() now calls format_message() and truncate_message() before
   sending, then loops through chunks with a small delay between them.
   The base class truncate_message() already handles code block boundary
   detection (closes/reopens fences at chunk boundaries). reply_to is
   only set on the first chunk.

3. Override format_message() with WhatsApp-specific markdown conversion
   — converts **bold** to *bold*, ~~strike~~ to ~strike~, headers to
   bold text, and [links](url) to text (url). Code blocks and inline
   code are protected from conversion via placeholder substitution.

Together these fix the two user complaints:
- 'sends the whole code all the time' → now chunked at 4K with proper
  formatting
- 'terminal gets interrupted and gets cooked' → streaming + tool progress
  give visual feedback so users don't accidentally interrupt with
  follow-up messages
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…rch#8723)

Three changes that address the poor WhatsApp experience reported by users:

1. Reclassify WhatsApp from TIER_LOW to TIER_MEDIUM in display_config.py
   — enables streaming and tool progress via the existing Baileys /edit
   bridge endpoint. Users now see progressive responses instead of
   minutes of silence followed by a wall of text.

2. Lower MAX_MESSAGE_LENGTH from 65536 to 4096 and add proper chunking
   — send() now calls format_message() and truncate_message() before
   sending, then loops through chunks with a small delay between them.
   The base class truncate_message() already handles code block boundary
   detection (closes/reopens fences at chunk boundaries). reply_to is
   only set on the first chunk.

3. Override format_message() with WhatsApp-specific markdown conversion
   — converts **bold** to *bold*, ~~strike~~ to ~strike~, headers to
   bold text, and [links](url) to text (url). Code blocks and inline
   code are protected from conversion via placeholder substitution.

Together these fix the two user complaints:
- 'sends the whole code all the time' → now chunked at 4K with proper
  formatting
- 'terminal gets interrupted and gets cooked' → streaming + tool progress
  give visual feedback so users don't accidentally interrupt with
  follow-up messages
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.

2 participants