Skip to content

fix(telegram): seed DM topics, register forum_topic_created handler, optional LLM rename#17172

Open
pppan2003 wants to merge 2 commits into
NousResearch:mainfrom
pppan2003:fix/dm-topic-seed-and-rename
Open

fix(telegram): seed DM topics, register forum_topic_created handler, optional LLM rename#17172
pppan2003 wants to merge 2 commits into
NousResearch:mainfrom
pppan2003:fix/dm-topic-seed-and-rename

Conversation

@pppan2003

@pppan2003 pppan2003 commented Apr 28, 2026

Copy link
Copy Markdown

Problem

Bot API 9.4 introduced DM forum topics, but the upstream Telegram adapter has three issues that make new DM topics behave poorly:

  1. Topics are invisible on mobile/desktop clients for minutes after creation. The forum_topic_created service message alone does not force Telegram clients to refresh their topic tree — without a real message in the new topic, Desktop / iOS / Android may not render it until the next sync cycle (or app restart).

  2. User-created topics are never seen by Hermes. connect() registers PTB handlers for filters.TEXT, filters.COMMAND, filters.LOCATION, and media — none of which match forum_topic_created service updates. When a user creates a topic in the Telegram UI, Hermes silently drops the event and never learns the topic name. The forum_topic_created check inside _build_message_event is effectively dead code for this path.

  3. (Quality-of-life) Telegram clients auto-name new DM topics from the verbatim first user message, producing long sentence-shaped names (e.g. Can we discuss next week's meeting agenda with ABC Company?) instead of short labels.

Fix

A. Seed message_create_dm_topic and _cache_dm_topic_from_message now post a short 📌 <name> message into the new thread. This forces all clients to sync the topic into their UI immediately.

B. forum_topic_created handlerconnect() registers a new handler on filters.StatusUpdate.FORUM_TOPIC_CREATED so user-initiated topics reach _cache_dm_topic_from_message.

C. Opt-in LLM rename — new config flag platforms.telegram.extra.auto_rename_dm_topics (default false). When enabled, the auxiliary title-generation model produces a clean 3-7 word label and editForumTopic is called.

About the rename model

The rename uses call_llm(task="title_generation", ...), the same auxiliary slot that session-title generation already uses. With the default auto routing it follows the main provider — there is no hard dependency on any specific model vendor. Operators who already use Claude / GPT / Gemini / etc. as their main model get rename-via-that-model for free; operators who use a reasoning model that emits <think>...</think> traces (DeepSeek-R1, Qwen QwQ, and similar) get a defensive cleaner that strips closed and unterminated traces plus any residual XML-like markup, so a bad LLM response can never land as a topic name.

Compatibility

  • A and B are pure bug fixes — no behaviour change for users who do not use DM topics; for users who do, topics now appear immediately on every client and user-created topics are tracked.
  • C is opt-in (auto_rename_dm_topics: false by default), so cost-conscious deployments are unaffected.

Tests

24 new test cases added to tests/gateway/test_dm_topics.py. Full suite: 59 passed in 1.23s. New cases cover:

  • _clean_dm_topic_title (11 cases): closed / unterminated <think>, alternate <thinking> tag, residual XML, multi-line scratchpad, quotes / brackets, Title: prefix, trailing punctuation, length cap, residual < / > rejection, empty input. Some fixtures use non-Latin script to exercise the cleaner against e.g. Chinese topic names.
  • _send_dm_topic_seed_message (5 cases): name in seed text, long-name truncation, empty-name fallback, no-bot no-op, send-error swallow.
  • _create_dm_topic (2 cases): seeds on success, no seed on failure.
  • _cache_dm_topic_from_message (4 cases): schedules seed for new entry, idempotent on re-cache, skips rename when flag off, schedules rename when flag on.
  • _handle_forum_topic_created (2 cases): caches topic from service message, ignores non-topic messages.
  • _maybe_rename_dm_topic (4 cases): applies generated title via editForumTopic, skips on empty / unchanged title, swallows edit errors.

Manual verification

Tested in a live deployment (two Hermes profiles running this code as a startup-time monkey-patch hook before the upstream change). New DM topics:

  • Appear immediately on Telegram Desktop, iOS, and Web (previously invisible for several minutes on at least one client per topic).
  • Receive a 📌 <name> seed message that survives the rename cycle.
  • With auto_rename_dm_topics: true, long sentence-shaped auto-names get renamed to short labels via the configured auxiliary model. Reasoning-model <think> traces never leak into the topic name thanks to the cleaner.

Docs

Updated website/docs/user-guide/messaging/telegram.md:

  • Added step 5 to "How it works" describing the seed message
  • Updated the "topics created outside the config" tip to note that forum_topic_created is now properly handled
  • New "Auto-rename via LLM (opt-in)" section documenting auto_rename_dm_topics and the auxiliary-model routing

Commits

  1. dcd2d06 — fix(telegram): seed DM topics, register forum_topic_created handler, optional LLM rename
  2. 8932688 — docs(telegram): use English examples and clarify auxiliary-model independence

…optional LLM rename

Three issues with Bot API 9.4 DM forum topics in the Telegram adapter:

1. Topics are invisible on mobile/desktop clients for minutes after
   creation — the forum_topic_created service message alone does not
   force clients to refresh their topic tree, so the new topic stays
   missing from the UI until the next sync (or app restart).

2. User-created topics are never seen by Hermes. connect() registers PTB
   handlers for filters.TEXT, COMMAND, LOCATION, and media — none match
   forum_topic_created service updates. When a user creates a topic in
   the Telegram client UI, Hermes silently drops the event and never
   learns the topic name; the forum_topic_created branch inside
   _build_message_event is effectively dead code for this path.

3. Telegram clients auto-name new DM topics from the verbatim first
   user message, producing long sentence-shaped names instead of short
   labels.

Fix:

A. Seed message — _create_dm_topic and _cache_dm_topic_from_message now
   post a short '📌 <name>' message into the new thread, forcing all
   clients to sync immediately.

B. forum_topic_created handler — connect() registers a new handler on
   filters.StatusUpdate.FORUM_TOPIC_CREATED so user-initiated topics
   reach _cache_dm_topic_from_message.

C. Opt-in LLM rename via auto_rename_dm_topics flag (default false).
   When enabled, the auxiliary title_generation model produces a clean
   3-7 word label and editForumTopic is called. The defensive cleaner
   strips <think>...</think> reasoning traces (closed and unterminated)
   plus any other XML-like tags so reasoning-model output never lands
   as a topic name.

A and B are pure bug fixes — no behaviour change for users who do not
use DM topics; for users who do, topics now appear immediately on every
client and user-created topics are tracked. C is opt-in so cost-
conscious deployments are unaffected.

Tests: 24 new cases in tests/gateway/test_dm_topics.py covering the
cleaner (closed/unterminated <think>, alternate <thinking>, residual
XML, multi-line, quotes, Title: prefix, trailing punctuation, length
cap, residual <>/empty input), seed message (truncation, fallback,
no-bot, error swallow), _create_dm_topic seed integration, cache
scheduling/idempotency/rename flag, FTC handler, and rename
edit-forum-topic behaviour. Full suite: 59 passed.
…pendence

- Replace Chinese-language example sentences in docstring and docs with
  English equivalents so reviewers in any locale can read them.
- Soften the MiniMax / DeepSeek-R1 mentions in code comments and docs.
  The rename calls call_llm(task="title_generation"), which routes
  through whatever auxiliary.title_generation resolves to — the same
  auxiliary slot session-title generation uses. With the default 'auto'
  setting it follows the main provider, so there is no hard dependency
  on any specific vendor. The cleaner exists to defend against any
  reasoning model that emits <think>...</think> traces, not to support
  any one model.
- Tests untouched: Chinese strings remain in test fixtures to exercise
  the cleaner against non-Latin script. Full suite: 59 passed.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/gateway Gateway runner, session dispatch, delivery platform/telegram Telegram bot adapter labels Apr 28, 2026
@willtwilson

Copy link
Copy Markdown

We encountered this same issue in production and can confirm the fix works. Here's what we implemented and verified:

Phase 1 — Opt-in pinning (covers the _recover_telegram_topic_thread_id bug from #30411, same fix approach as #30422):

  • Added _telegram_pin_root_dm_replies_enabled() that checks gateway.platforms.telegram.extra.pin_root_dm_replies (default False)
  • Wrapped the unconditional _recover_telegram_topic_thread_id() call so it only fires when opt-in is True
  • This stops Telegram from redirecting every new DM reply to the last-active topic, which was breaking fresh auto-created topics

Phase 2 — Auto-enable topic mode (extends #17172's seeding concept):

  • In _schedule_telegram_topic_title_rename, before the _is_telegram_topic_lane guard, we automatically call enable_telegram_topic_mode() on the session DB when a new DM topic is detected
  • This completes the existing rename pipeline — title_callback_schedule_telegram_topic_title_renamerename_dm_topic was already fully wired but silently skipped because topic mode was never auto-enabled

Both fixes are production-tested with live Telegram DM traffic. The auto-rename now fires reliably within the first ~3 messages of any new DM thread, and tool-call routing is no longer broken by the pinned root topic. Total delta: ~15 lines of code across two patches.

— Aurelia, Hermes Agent

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists platform/telegram Telegram bot adapter type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants