Skip to content

fix(bot): coalesce Telegram-split messages into a single prompt#180

Open
8x22b wants to merge 1 commit into
grinev:mainfrom
8x22b:fix/merge-telegram-split-messages
Open

fix(bot): coalesce Telegram-split messages into a single prompt#180
8x22b wants to merge 1 commit into
grinev:mainfrom
8x22b:fix/merge-telegram-split-messages

Conversation

@8x22b

@8x22b 8x22b commented Jul 7, 2026

Copy link
Copy Markdown

Problem

Telegram delivers long text — and a single paste — as several consecutive message updates (the ~4096-char client split, plus some clients splitting one input into multiple messages). The bot dispatches each update as its own prompt, so one long message becomes several independent agent runs and the conversation breaks.

Fix

Buffer plain-text prompts per chat for a short window (MESSAGE_MERGE_WINDOW_MS, default 1500; 0 disables). Each new chunk restarts the window; once it elapses with no new chunk, the buffered texts are joined (\n\n) and dispatched as a single session.prompt.

Only the final plain-text fallback path is buffered. Commands and active interaction flows (question answers, task/model-search/rename input, command/skill arguments) keep being handled immediately and are never buffered.

Because the window restarts on every chunk, messages sent a few seconds apart are still processed independently.

Config

Var Default Notes
MESSAGE_MERGE_WINDOW_MS 1500 0 disables merging and processes every message immediately

Tradeoffs

  • Chunks are joined with \n\n. For a 4096-char split this adds one blank line per boundary (negligible in a long prompt); for genuinely separate quick messages it reads as separate paragraphs. Easy to change the separator if a maintainer prefers.
  • Merging is on by default so the split-message bug is fixed without extra config. If default-off is preferred, it's a one-line flip.

Tests

New tests/bot/handlers/message-merger.test.ts covers: disabled window (immediate), single buffered message, multi-chunk merge with window restart, gap-beyond-window flushes separately, per-chat independence, manual flushPendingPrompt, and latest ctx used on merge. The merger state is also reset in tests/helpers/reset-singleton-state.ts so timers can't leak between tests.

npm run lint, npm run build, npm test (1095 tests) pass. No OS-specific code.

Telegram delivers long text (and a single paste) as several consecutive message updates, which the bot dispatched as separate prompts - one agent run per chunk.

Buffer plain-text prompts per chat for MESSAGE_MERGE_WINDOW_MS (default 1500; 0 disables). Each new chunk restarts the window; when it elapses, buffered texts are joined and dispatched as one prompt. Commands and active interaction flows (question/task/rename/catalog) are unaffected.
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.

1 participant