Skip to content

feat(channels): adopt Telegram Bot API 10.1 rich-text formatting and fix guest-mode escaping#6604

Merged
bug-ops merged 1 commit into
mainfrom
feat/issue-6541/telegram-rich-text-formatting
Jul 20, 2026
Merged

feat(channels): adopt Telegram Bot API 10.1 rich-text formatting and fix guest-mode escaping#6604
bug-ops merged 1 commit into
mainfrom
feat/issue-6541/telegram-rich-text-formatting

Conversation

@bug-ops

@bug-ops bug-ops commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • Guest-mode responses (TelegramChannel::flush_chunks) now format through the same markdown_to_telegram renderer used by regular messages, sending parse_mode = "MarkdownV2" instead of an unconverted "HTML" call that previously either broke Telegram's HTML parser or rendered literal Markdown to guest users.
  • TelegramRenderer now prefixes every line of a multi-line blockquote with > (previously only the first line was quoted). Nested blockquotes flatten to a single >-per-level instead of accumulating an unescaped >>, which Telegram's MarkdownV2 grammar rejects outright (400 can't parse entities, dropping the whole message). A MAX_BLOCKQUOTE_NESTING_DEPTH = 512 cap (same pattern as MAX_CHUNK_DEPTH from fix(index,core): add depth-cap guards against unbounded recursion DoS #6595) bounds tracked-mark memory for adversarially deep input.
  • Adds TelegramConfig.expandable_blockquote_min_lines (default 10): blockquotes at or above the threshold render as Bot API 10.1's expandable (collapsed-by-default) form; 0 disables it unconditionally. Wired into --init and --migrate-config.
  • Wires TelegramConfig.guest_mode/.bot_to_bot into create_channel — these fields were previously accepted but never threaded into the TelegramChannel builder, so Guest Mode and Bot-to-Bot were unreachable in a running agent even with both enabled (found during review; scope expanded with user approval since otherwise this PR's own guest-mode fix could never be live-verified).
  • Fixes a latent crash the wiring change exposed: the Guest Mode proxy's TcpListener was never set non-blocking before being handed to tokio, which panics on recent tokio versions the first time guest_mode = true is actually reached.
  • Updates sibling spec specs/007-channels/007-1-telegram-guest-mode.md and corrects specs/007-channels/007-3-telegram-rich-text.md §10's nested-blockquote edge case (the originally-specified "cumulative depth" approach was invalid MarkdownV2; flattening is correct).
  • Documents the new config field and blockquote behavior in book/src/guides/telegram.md.

Closes #6541

Test plan

  • cargo nextest run — zeph-channels, zeph-config, zeph, zeph-core all green (4543/4543 in the final developer run; reviewer independently re-ran and confirmed 4396 passed/0 failed/14 skipped)
  • cargo test --doc — passing
  • cargo +nightly fmt --check — clean
  • cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings — clean (independently re-run by reviewer)
  • gitleaks protect --staged — no leaks
  • New unit tests: guest/regular MarkdownV2 formatting parity, multi-line blockquote (2-9 lines), boundary at exactly min_lines, min_lines = 0 disables expandable, nested-blockquote flattening (depth 20 and depth 600-over-cap), special chars inside a blockquote line, create_channel wiring of guest_mode/bot_to_bot from config
  • Existing markdown.rs/telegram.rs suites pass unchanged (no weakened assertions — diffed to confirm)
  • Migration step 104 (migrate_telegram_expandable_blockquote_config) has dedicated behavioral tests (append/noop-no-section/noop-already-present/idempotent)
  • Live test against a real Telegram bot (guest-mode @mention response, 12-line expandable blockquote) — playbook scenarios written in .local/testing/playbooks/telegram.md but not yet run against a live bot; tracked as a follow-up live-verification step, not blocking merge given the extensive unit coverage and doc-confirmed MarkdownV2 grammar checks performed during review
  • Code-fence-inside-blockquote interaction (upstream Telegram parser behavior is genuinely undocumented/inconsistent here) is deliberately left as a characterization test pinning current output rather than a guessed fix, flagged in the playbook for live verification

…fix guest-mode escaping

Guest-mode responses (TelegramChannel::flush_chunks) now format through
the same markdown_to_telegram renderer used by regular messages and send
with parse_mode="MarkdownV2" instead of an unconverted "HTML" call, which
previously either broke Telegram's HTML parser or rendered literal
Markdown to guest users.

TelegramRenderer now prefixes every line of a multi-line blockquote with
">" (previously only the first line was quoted), and nested blockquotes
flatten to a single level instead of accumulating an unescaped ">>",
which Telegram's MarkdownV2 grammar rejects outright (400 can't parse
entities, dropping the whole message). A nesting-depth cap
(MAX_BLOCKQUOTE_NESTING_DEPTH = 512, same pattern as MAX_CHUNK_DEPTH from
#6595) bounds tracked-mark memory for adversarially deep input.

Adds TelegramConfig.expandable_blockquote_min_lines (default 10):
blockquotes at or above the threshold render as Bot API 10.1's
expandable (collapsed-by-default) form; 0 disables it unconditionally.
Wired into --init and --migrate-config.

Also wires TelegramConfig.guest_mode/.bot_to_bot into create_channel —
these fields were previously accepted but never threaded into the
TelegramChannel builder, so Guest Mode and Bot-to-Bot were unreachable
in a running agent even with both enabled. Fixes a latent crash this
exposed: the Guest Mode proxy's TcpListener was never set non-blocking
before handing it to tokio, which panics on recent tokio versions.

Closes #6541
@github-actions github-actions Bot added documentation Improvements or additions to documentation channels zeph-channels crate (Telegram) rust Rust code changes core zeph-core crate config Configuration file changes enhancement New feature or request size/XL Extra large PR (500+ lines) labels Jul 20, 2026
@bug-ops
bug-ops enabled auto-merge (squash) July 20, 2026 18:53
@bug-ops
bug-ops merged commit fdd887f into main Jul 20, 2026
47 checks passed
@bug-ops
bug-ops deleted the feat/issue-6541/telegram-rich-text-formatting branch July 20, 2026 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channels zeph-channels crate (Telegram) config Configuration file changes core zeph-core crate documentation Improvements or additions to documentation enhancement New feature or request rust Rust code changes size/XL Extra large PR (500+ lines)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(channels): adopt Telegram Bot API 10.1/10.2 rich-text formatting and fix guest-mode escaping

1 participant