Files
Evrard-Nil 0a8428fda1 fix(telegram): handle 'message is too long' with retry splitting (#1943)
* fix(telegram): handle "message is too long" with retry splitting

Reduce TELEGRAM_MAX_MESSAGE_LEN from 4096 to 4000 for safety margin
against Markdown entity/emoji counting edge cases. Add SendError::TooLong
variant and send_chunk() helper that recursively halves chunks on
"message is too long" rejections (up to 3 levels deep), splitting at
natural boundaries.

[skip-regression-check]

* fix: address review feedback — return last chunk id, handle TooLong on plain-text retry

- Extract split_and_send() helper returning last message_id for correct
  reply threading when chunks are split
- Handle TooLong on ParseEntities plain-text fallback path
- Update doc comments on send_message and split_message

[skip-regression-check]

* fix: address review feedback — UTF-16 split, depth cap, markdown flag, tests

- Use UTF-16 code units (via prefix_within_utf16_limit) for midpoint
  calculation in split_and_send, matching Telegram's actual limit
- Extract find_split_midpoint() as a pure testable function
- Reduce MAX_SPLIT_DEPTH from 3 to 2 (max 4 sub-messages per chunk)
- Pass use_markdown flag through recursion so ParseEntities fallback
  disables Markdown for all subsequent splits of that chunk
- Add debug logging on successful sends
- Improve error message when depth limit exhausted
- Add empty-text guard in split_and_send
- Add 5 unit tests for find_split_midpoint (paragraph, newline, space,
  no-boundary, emoji-heavy)
- Fix stale doc comments

* fix: guard against empty first half after trim in split_and_send

Whitespace-heavy text could produce an empty first half after
trim_end(). Skip directly to the second half in that case.

* refactor(telegram): unify message splitting into single parameterized splitter

Collapse the duplicate boundary-search logic in find_split_midpoint /
split_and_send into split_message by parameterizing its UTF-16 limit.
The TooLong retry path now calls split_message(text, limit/2) and sends
each sub-chunk, so the retry benefits from the same paragraph → newline
→ sentence → word hierarchy the initial split already used.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Illia Polosukhin <ilblackdragon@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 14:28:36 +09:00
..
2026-04-01 08:27:07 -07:00