# NousResearch/hermes-agent · Telegram message formatting and MarkdownV2 chunk indicator handling

## Open now

- 0 issues, 1 PR open on GitHub.
- PR #11287: feat(gateway): send Telegram messages via MessageEntity instead of MarkdownV2

These issues and pull requests all concern how Telegram messages are formatted, especially when long messages are split into chunks. Some propose escaping chunk indicators for MarkdownV2, while others propose switching to HTML or MessageEntity, and one reports a fallback to plain text on chunked messages.

## TL;DR

- 5 member(s): 0 open issue(s), 1 closed issue(s), 1 open PR(s), 1 merged PR(s), 2 PR(s) closed without merging.
- A fix was merged to main in PR #1478. Verify it addresses your case.
- **Recommended:** read PR #1478 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-1478`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.40`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #1456: \[Bug\]: Telegram formatting falls back to plain text on chunked messages

## Prior & competing PRs

- **#1478: fix(telegram): escape chunk indicators in MarkdownV2**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`
  - files: `gateway/platforms/telegram.py`, `tests/gateway/test_telegram_format.py`
  - fix hunks:
  - `gateway/platforms/telegram.py`

    ```diff
    @@ -322,6 +322,14 @@ async def send(
                 # Format and split message if needed
                 formatted = self.format_message(content)
                 chunks = self.truncate_message(formatted, self.MAX_MESSAGE_LENGTH)
    +            if len(chunks) > 1:
    +                # truncate_message appends a raw " (1/2)" suffix. Escape the
    +                # MarkdownV2-special parentheses so Telegram doesn't reject the
    +                # chunk and fall back to plain text.
    +                chunks = [
    +                    re.sub(r" \((\d+)/(\d+)\)$", r" \\(\1/\2\\)", chunk)
    +                    for chunk in chunks
    +                ]
                 
                 message_ids = []
                 thread_id = metadata.get("thread_id") if metadata else None
    ```
  - `tests/gateway/test_telegram_format.py`

    ```diff
    @@ -7,7 +7,7 @@
     
     import re
     import sys
    -from unittest.mock import MagicMock
    +from unittest.mock import AsyncMock, MagicMock
     
     import pytest
     
    ```

    ```diff
    @@ -392,3 +392,27 @@ def test_plain_text_unchanged(self):
     
         def test_empty_string(self):
             assert _strip_mdv2("") == ""
    +
    +
    [redacted:email]
    +async def test_send_escapes_chunk_indicator_for_markdownv2(adapter):
    +    adapter.MAX_MESSAGE_LENGTH = 80
    +    adapter._bot = MagicMock()
    +
    +    sent_texts = []
    +
    +    async def _fake_send_message(**kwargs):
    +        sent_texts.append(kwargs["text"])
    +        msg = MagicMock()
    +        msg.message_id = len(sent_texts)
    +        return msg
    +
    +    adapter._bot.send_message = AsyncMock(side_effect=_fake_send_message)
    +
    +    content = ("**bold** chunk content " * 12).strip()
    +    result = await adapter.send("123", content)
    +
    +    assert result.success is True
    +    assert len(sent_texts) > 1
    +    assert re.search(r" \\\([0-9]+/[0-9]+\\\)$", sent_texts[0])
    +    assert re.search(r" \\\([0-9]+/[0-9]+\\\)$", sent_texts[-1])
    ```
- **#1457: fix(telegram): switch formatting from MarkdownV2 to HTML**. closed without merge
  - maintainer direction: category `duplicate_of`; implication `duplicate`; refs `#1478`, `#1456`
- **#1477: fix(gateway): escape Telegram chunk indicators for MarkdownV2**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `#1478`
- **#11287: feat(gateway): send Telegram messages via MessageEntity instead of MarkdownV2**. open
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`
  - files: `gateway/platforms/telegram.py`, `tests/gateway/test_telegram_entities.py`, `tests/gateway/test_telegram_format.py`, `tests/gateway/test_telegram_reply_mode.py`

## Fix status

- Merged to main in PR #1478 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-03-16`. This confirmation is old and may be out of date (a revert/reopen would not have invalidated it here); re-verify.
- Subsystem: `gateway`
