hermes - ✅(Solved) Fix [Bug] Telegram DM topic binding not refreshed after compression-induced session split — causes preflight compression loop [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#20470Fetched 2026-05-06 06:36:41
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
0
Author
Participants
Timeline (top)
labeled ×4cross-referenced ×2commented ×1

Error Message

entry = self.session_store._entries.get(session_key) if entry: entry.session_id = agent.session_id self.session_store._save() try: self._record_telegram_topic_binding(source, entry) except Exception: logger.exception("Failed to refresh telegram topic binding after session split")

Root Cause

gateway/run.py lines ~13785–13800 (in _run_agent):

if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        entry.session_id = agent.session_id
        self.session_store._save()
    # ← `telegram_dm_topic_bindings` row never updated here

session_store._entries (in-memory + sessions.json) is updated, but the SQLite topic-binding row is not. On the next message, the gateway reads the stale row via _session_db.get_telegram_topic_binding() and forces switch_session(session_key, bound_session_id) back to the pre-compression session.

Fix Action

Fixed

PR fix notes

PR #20485: fix: refresh Telegram DM topic binding after session split (#20470)

Description (problem / solution / changelog)

Fixes #20470

Problem

When a session bound to a Telegram DM topic splits during mid-turn context compression, the gateway updates session_store._entries with the new session ID but does not update the corresponding row in telegram_dm_topic_bindings. On the next inbound message in that topic, the gateway reads the stale binding, calls switch_session() back to the pre-compression root session, reloads its full transcript, fires preflight compression, splits again — repeat forever.

Symptom: every message in a Telegram DM topic prints 📦 Preflight compression: ~N tokens >= threshold even after the conversation has been compressed multiple times. Each turn pays the full compression latency before any real work begins.

Fix

After session_store._save() updates the in-memory entry and persists it, call _record_telegram_topic_binding(source, entry) to also refresh the SQLite topic-binding row. The call is wrapped in try/except to guard against edge cases where bind_telegram_topic might raise (e.g. if the new session ID is already linked to a different topic).

_record_telegram_topic_binding already early-returns when source.thread_id is falsy, so this is safe across all platform surfaces — only Telegram DM topic bindings are affected.

Before vs After

BeforeAfter
Topic binding after splitPoints to pre-compression root sessionPoints to post-split child session
Preflight compression on next messageTriggers every time (infinite loop)Skipped (child session is small)
Compression latency per turnFull compression costZero (no re-compression needed)

Changed files

  • gateway/run.py (modified, +11/-0)

PR #20486: fix(telegram): refresh topic binding after session split

Description (problem / solution / changelog)

Summary

  • refresh Telegram DM topic bindings when context compression rotates a gateway session id
  • keep the existing SessionStore rollover behavior for all platforms
  • add a regression test for topic bindings after compression-created session splits

Closes #20470

Verification

  • scripts/run_tests.sh tests/gateway/test_telegram_topic_mode.py

Non-goals

  • does not change Telegram topic creation, /new handling, or existing session switching semantics
  • does not attempt to repair historical stale bindings automatically

Changed files

  • gateway/run.py (modified, +24/-4)
  • tests/gateway/test_telegram_topic_mode.py (modified, +52/-0)

Code Example

if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        entry.session_id = agent.session_id
        self.session_store._save()
    # ← `telegram_dm_topic_bindings` row never updated here

---

entry = self.session_store._entries.get(session_key)
if entry:
    entry.session_id = agent.session_id
    self.session_store._save()
    try:
        self._record_telegram_topic_binding(source, entry)
    except Exception:
        logger.exception("Failed to refresh telegram topic binding after session split")

---

UPDATE telegram_dm_topic_bindings
SET session_id = '<latest-descendant-of-current>', updated_at = strftime('%s','now')
WHERE chat_id = ? AND thread_id = ?;
RAW_BUFFERClick to expand / collapse

Describe the bug

When a session bound to a Telegram DM topic splits during mid-turn context compression, the gateway updates session_store._entries with the new session ID but does not update the corresponding row in telegram_dm_topic_bindings. On the next inbound message in that topic, the gateway reads the stale binding, calls switch_session() back to the pre-compression root session, reloads its full transcript, fires preflight compression, splits again — repeat forever.

Symptom: every message in a Telegram DM topic prints 📦 Preflight compression: ~N tokens >= threshold even after the conversation has been compressed multiple times. Each turn pays the full compression latency before any real work begins.

Reproduction Steps

  1. Enable Telegram DM topic mode.
  2. Hold a conversation in a topic long enough for mid-turn context compression to fire and split the session.
  3. Send another message in the same topic.
  4. Preflight compression triggers again, even though the post-split child is small.
  5. Every subsequent message repeats the loop. The transcript loaded for each turn is always the original pre-compression root, never the latest child.

Root Cause

gateway/run.py lines ~13785–13800 (in _run_agent):

if agent and session_key and hasattr(agent, 'session_id') and agent.session_id != session_id:
    _session_was_split = True
    logger.info("Session split detected: %s → %s (compression)", session_id, agent.session_id)
    entry = self.session_store._entries.get(session_key)
    if entry:
        entry.session_id = agent.session_id
        self.session_store._save()
    # ← `telegram_dm_topic_bindings` row never updated here

session_store._entries (in-memory + sessions.json) is updated, but the SQLite topic-binding row is not. On the next message, the gateway reads the stale row via _session_db.get_telegram_topic_binding() and forces switch_session(session_key, bound_session_id) back to the pre-compression session.

Proposed Fix

bind_telegram_topic() is already an upsert and _record_telegram_topic_binding() early-returns when source.thread_id is falsy, so a single call after _save() is safe across all surfaces:

entry = self.session_store._entries.get(session_key)
if entry:
    entry.session_id = agent.session_id
    self.session_store._save()
    try:
        self._record_telegram_topic_binding(source, entry)
    except Exception:
        logger.exception("Failed to refresh telegram topic binding after session split")

The try/except guards the edge case where bind_telegram_topic raises ValueError if the new session ID is somehow already linked to a different topic — shouldn't happen since the child was just minted by the compressor, but a freak race shouldn't crash a turn.

Existing stale bindings can be repaired manually:

UPDATE telegram_dm_topic_bindings
SET session_id = '<latest-descendant-of-current>', updated_at = strftime('%s','now')
WHERE chat_id = ? AND thread_id = ?;

extent analysis

TL;DR

Update the telegram_dm_topic_bindings table with the new session ID after a session split to prevent infinite compression loops.

Guidance

  • The issue arises from the telegram_dm_topic_bindings table not being updated with the new session ID after a session split, causing the gateway to read a stale binding and trigger preflight compression repeatedly.
  • To fix this, update the gateway/run.py file to call _record_telegram_topic_binding() after updating the session_store._entries with the new session ID.
  • Use a try-except block to handle potential exceptions when updating the binding, such as a ValueError if the new session ID is already linked to a different topic.
  • Existing stale bindings can be repaired manually using an SQL UPDATE statement to update the session_id and updated_at fields in the telegram_dm_topic_bindings table.

Example

entry = self.session_store._entries.get(session_key)
if entry:
    entry.session_id = agent.session_id
    self.session_store._save()
    try:
        self._record_telegram_topic_binding(source, entry)
    except Exception:
        logger.exception("Failed to refresh telegram topic binding after session split")

Notes

  • The proposed fix assumes that the _record_telegram_topic_binding() method is an upsert and will update the existing binding if it already exists.
  • The try-except block is used to handle potential exceptions, but it is expected that the new session ID will not be already linked to a different topic since it was just created by the compressor.

Recommendation

Apply the proposed workaround by updating the gateway/run.py file to call _record_telegram_topic_binding() after updating the session_store._entries with the new session ID, as this will prevent the infinite compression loops and ensure that the correct session ID is used.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

hermes - ✅(Solved) Fix [Bug] Telegram DM topic binding not refreshed after compression-induced session split — causes preflight compression loop [2 pull requests, 1 comments, 2 participants]