Vos DM Telegram s'entassent dans un seul fil ? Donnez un topic à chaque nouveau message


Vous menez trois choses de front dans Telegram : traquer un bug de prod, rédiger un rapport hebdomadaire, et rafistoler un script pour un ami. Vous activez donc le mode /topic et donnez un fil à chacune. Configuration parfaite — jusqu’au moment où votre pouce dérape et où vous tapez une ligne directement dans la fenêtre principale du chat au lieu d’un topic.

Ce message ne démarre pas un nouveau fil. Il atterrit dans le topic que vous avez utilisé en dernier. Votre rapport hebdomadaire héberge maintenant une conclusion de debug, et le modèle commence joyeusement à mélanger les deux. Vous remontez le fil un bon moment avant de retrouver l’instant où ça a dérapé.

Le mode topic n’est pas cassé ; il fait un choix conservateur — un message dans le chat racine signifie « continue la dernière conversation ». Si vous préférez que chaque message racine reparte de zéro, Hermes a fusionné un interrupteur exactement pour ça le 19 octobre : dm_topic_auto_transfer.

Comment le mode topic se comporte aujourd’hui

Envoyez /topic dans un DM : Hermes vérifie que le bot peut créer des topics (Threaded Mode doit être activé dans BotFather), active le mode topic multi-session pour ce chat, crée un topic System épinglé pour les statuts et les commandes, et propose de restaurer des sessions antérieures jamais rattachées à un topic.

À partir de là, le chat racine est un lobby : les prompts normaux sont rejetés avec une indication qui pointe vers All Messages, tandis que les commandes système comme /status, /sessions, /usage et /help continuent d’y fonctionner.

Chaque topic est une session autonome — son propre historique, son propre état de modèle, sa propre exécution d’outils et son propre session id. La clé d’isolation est agent:main:telegram:dm:{chat_id}:{thread_id}, donc deux topics dans le même DM sont deux conversations différentes du point de vue de Hermes.

Le hic, c’est le choix conservateur ci-dessus : certains clients livrent un message tapé dans le chat racine sans message_thread_id. Hermes les traite comme une continuation et répond dans votre topic le plus récemment actif — ce que la doc appelle la lobby recovery. Le rappel qu’il envoie pour vous ramener vers un topic est limité à un message toutes les 30 secondes par (profile, chat), donc oublier et taper dix prompts d’affilée ne produit pas dix réponses.

L’interrupteur : une seule clé de config

Ajoutez une ligne au config.yaml de votre profile :

gateway:
  platforms:
    telegram:
      extra:
        dm_topic_auto_transfer: true   # défaut : false

La clé de premier niveau telegram.extra.dm_topic_auto_transfer fonctionne aussi (c’est celle affichée dans les réglages Desktop). Elle est strictement opt-in : omettez-la et rien ne change, y compris le repli vers votre topic le plus récent.

Avec elle activée, un message simple dans le DM racine déclenche ceci :

  1. Hermes crée immédiatement un topic neuf (nommé « Hermes Chat » jusqu’à ce que le pipeline de titrage automatique le renomme) ;
  2. une nouvelle session démarre dans ce topic ;
  3. votre réponse est postée dans ce topic.

Autrement dit, le chat racine cesse d’être un lobby et devient une porte : un message égaré, une pièce toute neuve.

Ce qui n’est jamais déplacé

Cet interrupteur gère exactement un cas — un humain qui tape un message simple dans le DM racine. Tout le reste est laissé tranquille par conception :

  • Les slash commands ne sont pas déplacées. Un /status tapé dans le chat racine reste une commande de lobby et ne crée jamais de topic.
  • Les réveils internes et les événements routés ne sont pas déplacés. Les déclenchements cron, les événements routés depuis d’autres platforms et les tâches de fond ne sont jamais poussés dans un topic neuf.
  • Le trafic hors DM n’est pas touché. Les groupes et les canaux n’ont rien à voir avec le mode topic.
  • Les expéditeurs non autorisés ne sont pas déplacés. Le contrôle d’autorisation a lieu au stade du lobby.
  • Une création de topic ratée retombe sur le comportement par défaut. Si Threaded Mode a été désactivé dans BotFather, la création échoue et Hermes revient au défaut : répondre dans votre topic le plus récemment actif plutôt que perdre le message.

Un détail d’implémentation vaut le détour : le transfert s’exécute à l’ingress de l’adaptateur, avant le calcul de la clé de session (il vit dans telegram_topic_transfer.py, au sein du plugin Telegram). Le tour, sa session et la réponse utilisent donc tous le nouveau topic — vous n’obtiendrez jamais une session dans un fil et une réponse dans un autre.

Deux petits pièges

D’abord, la réponse d’ouverture dans un nouveau topic n’a pas d’ancre de réponse. Votre message d’origine vit hors du topic et Telegram interdit qu’une réponse le traverse ; Hermes envoie donc uniquement par message_thread_id, sans ancre. On a l’impression que la réponse ne s’est pas rattachée à votre message ; le contenu est bien dans le nouveau topic, et c’est le comportement attendu.

Ensuite, dans les configurations multi-bot, la clé est lue par bot. Si une gateway sert plusieurs bots Telegram (un assistant personnel, un bot d’équipe), l’interrupteur est lu depuis le bot qui a reçu le message, pas depuis le bot de lancement. À garder en tête quand vous faites tourner plusieurs profiles derrière une gateway et supposez qu’un changement sur le profile par défaut couvre tout.

Une douceur liée : le renommage automatique des topics. Une fois qu’Hermes a généré un titre de session, il renomme le topic Telegram en best-effort pour qu’il corresponde — « New Topic » devient « Database migration plan ». Les échecs sont seulement journalisés ; la session n’est pas affectée. Si vous nommez vos topics à la main et voulez qu’on les laisse tranquilles, la doc explique comment désactiver ça.

Quand ça vaut le coup, et quand non

Ça vaut le coup si Telegram est votre établi multi-fils : un topic par sujet, et vous entrez souvent dans le chat depuis l’écran d’accueil de l’app. Chaque message devenant son propre topic, la règle « nouveau fil, nouveau contexte » s’applique, ce qui est généralement ce que vous vouliez.

Ça ne vaut pas le coup si vous avez surtout une seule conversation en cours et n’utilisez les topics qu’occasionnellement. Chaque message racine ajoute alors un fil de plus, et jusqu’à ce que le titrage automatique suive, vous verrez un mur de « Hermes Chat ».

Si ce qui vous intéresse vraiment est la frontière entre un topic, une session et un contexte, le guide des frontières de session du site en dresse la carte. L’article sur le picker inline Telegram couvre la sélection de modèles et de sessions depuis le chat, et les DM bot à bot constituent l’autre moitié de l’histoire Telegram. Vous partez de zéro ? Le guide d’installation donne la base de configuration des platforms.

En bref

dm_topic_auto_transfer est un petit interrupteur qui répond à une question très concrète : « à quelle conversation appartenait ce message égaré » ? L’ancienne réponse était « la dernière » ; la nouvelle est « une nouvelle ». Garder l’ancien comportement par défaut est juste — la plupart des gens ne veulent pas d’un topic par message — mais pour qui traite Telegram comme un établi, l’activer élimine toute une classe de contexte contaminé.