Kein Neustart mehr: Hermes bedient neue Profile direkt im laufenden Gateway

Es ist zwei Uhr nachts, und du hast gerade einen dritten Bot fertig eingerichtet: hermes profile create, Bot-Token einfügen, schnell ein Hallo in Telegram – keine Antwort. Der Desktop zeigt das Gateway dieses Profils weiterhin als gestoppt. Du schlägst nach, und die Antwort lautet: Gateway neu starten. Aber die beiden anderen Profile stecken mitten in langen Jobs, und ein Neustart reißt beide mit heraus.
Diese Abwägung ist Geschichte. PR #109239, am 2026-09-12 nach main gemergt, bringt einem laufenden Multiplex-Gateway bei, Profile zu bemerken, die unter ihm auftauchen, und sie sofort zu bedienen – ohne Neustart und ohne Schaden für die Profile, die ohnehin schon arbeiten.
Was ein Multiplex-Gateway eigentlich ist
Standardmäßig bedeutet ein Profil eine eigenständige Konfiguration plus einen Bot, und damit dieser Bot online bleibt, läuft ein eigener Gateway-Prozess nur für ihn: hermes -p name gateway run. Mehr Profile, mehr Prozesse – mehr Speicher, mehr Logs, mehr Ports, um die man sich kümmern muss.
Ein Multiplex-Gateway macht es anders: ein einziger Gateway-Prozess beherbergt die Bot-Adapter mehrerer Profile gleichzeitig. Eingeschaltet wird das mit gateway.multiplex_profiles: true in der Konfiguration, und danach startest du nicht mehr pro Profil einen Prozess. Alles teilt sich ein Gateway, während jedes Profil seine eigene isolierte Laufzeit behält – eigenen Speicher, eigene SQLite-Datenbank, eigenen Agent-Cache.
Der Preis für dieses Design liegt beim Erkennen. Der Multiplexer hat das Verzeichnis profiles/ früher genau einmal durchsucht, nämlich beim Start: _start_secondary_profile_adapters baute Adapter aus der Liste, wie sie in diesem Moment aussah, _record_served_profiles notierte, wer bedient wird, und cron verwendete dieselbe profile_homes-Momentaufnahme. Ein danach angelegtes Profil stand nicht auf der Liste – kein Adapter, kein Polling, sein Bot konnte sich nie verbinden, und der Desktop meldete das Gateway dieses Profils als gestoppt. Wurde umgekehrt ein Profil gelöscht, blieb es für immer in served_profiles stehen.
In einer Welt von einem Bot pro Prozess ist das kein Problem: Ein neuer Bot bekommt einen neuen Prozess. Unter Multiplexing dagegen ist profiles/ ein Verzeichnis, das sich ändert, und das Gateway hatte genau einmal hineingesehen. Ein neu angelegtes Profil sollte einfach funktionieren – ohne dass du wegen eines nie gebauten Adapters das ganze Gateway neu startest und dabei die Langzeitjobs aller anderen zerreißt.
Drei Fälle, drei Wege
PR #109239 (gemergt am 2026-09-12, +641 / −43 über 27 Dateien) macht aus dem Multiplexer „einmal beim Start aufzählen“ ein „fortlaufend abgleichen“. Ein laufendes Gateway vergleicht das Verzeichnis profiles/ permanent mit der Menge, die es bereits bedient, und handelt nach der Differenz. Drei Situationen decken fast alles ab.
| Situation | Auslöser | Was das Gateway tut |
|---|---|---|
| Neues Profil | hermes profile create, POST /api/profiles des Dashboards, „New profile“ im Desktop |
Baut den Adapter und bedient das Profil sofort; zusätzlich pingt es den Control-Socket des Gateways über ein neues Verb, rescan-profiles |
| Zugangsdaten erst danach | config.yaml oder .env eines bedienten Profils ändert sich |
Die Signaturänderung löst einen Rescan aus; der Adapter entsteht im Laufzeitbereich genau dieses Profils. Bereits aktive Plattformen werden übersprungen, doppelte Tokens laufen in dieselbe Schutzprüfung |
| Profil gelöscht | Aus dem Verzeichnis profiles/ entfernt |
Baut den Adapter ab, beendet das Routing, gibt Handles für Pairing / Busy / Agent-Cache / SQLite / Speicher frei |
Angelegt: sofort bedient. Alle drei Wege funktionieren. Der Befehl hermes profile create, POST /api/profiles im Dashboard und der Ablauf „New profile“ im Desktop pingen nach dem Anlegen den Control-Socket und bitten das Gateway mit dem neuen Verb rescan-profiles, jetzt noch einmal nachzusehen statt erst im nächsten Durchlauf.
Zugangsdaten später. Erst das Profil anlegen und danach den Bot-Token einfügen ist die übliche Reihenfolge, und diese Zugangsdaten zählen als Konfiguration, die nach dem Start aufgetaucht ist. Dieser Fall wird über mtime-Änderungen an config.yaml oder .env des bedienten Profils erkannt: Die Änderung stößt einen Rescan an, und der Adapter wird im eigenen Laufzeitbereich des Profils gebaut. Plattformen, die schon aktiv sind, werden übersprungen, und ein doppelter Token trifft exakt auf dieselbe Schutzprüfung gegen doppelte Zugangsdaten, die es beim Start schon immer gab: Der zweite wird mit einer Warnung zurückgestellt und bekommt nie einen eigenen Poller, weil zwei Poller auf einem Bot-Token sich um dieselben Nachrichten streiten.
Gelöscht: abgebaut und aus dem Routing genommen. Reconnects werden abgebrochen, die Handles für Pairing / Busy / Agent-Cache / SQLite / Speicher freigegeben, die Pfade /p/name/ dieses Profils verschwinden, und served_profiles wird entsprechend aktualisiert. Zurück bleibt kein halbtoter Adapter, der Speicher hält oder auf einem Bot-Token sitzt.
Der Rescan alle 30 Sekunden als Rückfalllösung
Der Ping auf den Control-Socket ist der schnelle Weg, und schnelle Wege scheitern: Das Gateway fährt vielleicht gerade hoch, der Control-Socket hört noch nicht zu, oder es kommt schlicht keine Antwort. Deshalb bringt die Änderung zusätzlich einen überwachten Watcher mit, der profiles/ alle 30 Sekunden neu einliest (die Konstante im Quellcode lautet _PROFILE_RESCAN_INTERVAL_SECS = 30.0). Sofortiges Bedienen ist der Best-Effort-Pfad; für die Korrektheit sorgt der periodische Durchlauf darunter.
Der Client für den Control-Socket ist rescan_gateway_profiles(home, timeout=8.0), der rescan-profiles sendet und normalerweise ein Ergebnis mit served_profiles, added, removed und weiteren Feldern zurückgibt. Interessant ist der bewusst eingebaute Rückfall: Antwortet kein Gateway, oder ist das antwortende Gateway eine ältere Version, gibt der Aufruf None zurück. Der Aufrufer läuft nicht in einen Fehler, sondern fällt auf den periodischen Rescan zurück, was in der CLI bedeutet, dass der gewohnte Neustart-Hinweis stehen bleibt. In die andere Richtung ist es genauso nachsichtig: Eine ältere Hermes-Installation stürzt nicht ab, nur weil ein neuerer Client ihr eine Frage stellt, die sie nicht versteht.
Rescans sind billig, weil die Signaturerkennung nicht durch den Verzeichnisinhalt läuft: Sie sieht sich genau zwei Dateien an, config.yaml und .env, und vergleicht deren (mtime_ns, size). Das sind die Konstanten _PROFILE_SIGNATURE_FILES = ("config.yaml", ".env"). Genau deshalb löst das Einfügen von Zugangsdaten überhaupt einen Neuaufbau aus – du speicherst die Datei, die mtime bewegt sich, die Signatur ändert sich. Alles andere in der Nähe, etwa ein neues Logfile oder ein liegengebliebener Cache, löst keinen Fehlalarm aus.
Die Umsetzung steckt in einem neuen Modul, gateway/run_profile_reconcile.py, das als GatewayProfileReconcileMixin an der Gateway-Laufzeit hängt – eher ein Abgleicher, der ein Auge auf das Verzeichnis profiles/ hat, als eine weitere Schicht Prozessverwaltung.
cron, MCP-Erkennung und Log-Routing kommen mit
Ein neues Profil ist nicht nur ein weiterer Bot. Die cron-Timer wurden hier auf einen lebenden Enumerator umgestellt, sodass die geplanten Jobs eines neu angelegten Profils tatsächlich laufen, statt übergangen zu werden, weil das Profil in der Start-Momentaufnahme fehlte. Neue Profile bekommen außerdem MCP-Erkennung und Log-Routing. Genau diese Details machen den Satz „läuft, sobald es angelegt ist“ ehrlich – sonst würde dein neuer Bot Nachrichten beantworten, während seine eigenen geplanten Jobs einfach stillsitzen.
Wenn jedes Profil cron mit seinem eigenen Bot ausführen soll, findest du das vollständige Beispiel in der Anleitung zu cron pro Profil.
Alles andere läuft ungestört weiter
Die Frage, die man beim Hot-Serve wirklich stellen sollte, ist, ob es die anderen stillschweigend mit neu startet. Tut es nicht. Während des gesamten Abgleichs bleiben andere bediente Profile völlig unberührt: dieselbe pid, dieselben Poll-Zähler, und laufende Gespräche werden nicht unterbrochen. Der Abgleich fasst nur die Differenz an – Neues hinzufügen, Verschwundenes abbauen, alles bereits Korrekte exakt so lassen, wie es ist.
Darin liegt der eigentliche Unterschied zum Neustart des Gateways. Ein Neustart reißt den Prozess und mit ihm jeden Adapter nieder und baut alles neu auf. Der Abgleich ändert nur den Teil, der geändert werden muss. Für ein Multiplex-Gateway sollte genau das die Bedeutung des Wortes „heiß“ sein.
Was du in der Oberfläche siehst
Das sichtbarste Signal ist ein Banner, das aufhört zu erscheinen. Der Endpunkt für die Plattformkonfiguration (ein PUT auf /api/messaging/platforms/ mit der Plattform-ID) gibt jetzt ein Feld hot_served zurück. Ist es true, überspringen sowohl Desktop (in allen sechs Sprachen) als auch das Dashboard das Banner „Neustart erforderlich“.
Auch hermes profile create bestätigt das Hot-Serve direkt. Der Neustart-Hinweis bleibt nur dann stehen, wenn der Multiplexer das Profil tatsächlich nicht aufgenommen hat – etwa wenn gar kein Gateway läuft oder wenn der Control-Socket nicht geantwortet hat.
So verwendest du es
- Stelle sicher, dass Multiplexing aktiv ist:
gateway.multiplex_profiles: true. - Lege das Profil an:
hermes profile create nightshift. - Trage den Bot-Token in seine
.envoderconfig.yamlein. Beide Reihenfolgen sind in Ordnung; trägst du ihn später ein, baut die Signaturänderung den Adapter für dich. - Prüfe mit
hermes gateway status, ob das Profil unter den bedienten auftaucht. - Taucht es nicht auf: Gib dem Rückfall-Rescan bis zu 30 Sekunden. Bleibt es weiter aus, ist
hermes gateway restartnach wie vor der Notausgang. Ein älteres Gateway kennt das Verbrescan-profilesnicht, und dann ist der Neustart der einzige Weg – prüfe also zuerst, ob dein Hermes neu genug ist, um diese Änderung zu enthalten.
Kurz zusammengefasst
Diese Änderung fügt keinen neuen Befehl hinzu. Sie ändert, wie das Multiplex-Gateway auf Veränderungen reagiert: aus einmal beim Start aufzählen wird ein Abgleich im Betrieb. Neue Profile werden sofort bedient, nachgereichte Zugangsdaten bauen den Adapter neu auf, gelöschte Profile werden abgebaut und aus dem Routing genommen, ein Rescan alle 30 Sekunden fängt das Scheitern des schnellen Wegs auf, und bereits bediente Profile werden nie angefasst. Wenn du es selbst nachprüfen willst: tests/gateway/test_multiplex_hot_serve.py enthält drei Fälle, die genau diesen drei Wegen entsprechen – ein angelegtes Profil wird bedient, nachgereichte Zugangsdaten bauen einen Adapter, und bei einem gelöschten wird das Routing beendet.
Für das größere Bild mehrerer Profile auf einer Maschine siehe mehrere Profile parallel betreiben; wenn du steuern willst, welche Profile überhaupt Bots bedienen dürfen, gehst du in der Profil-Allowlist des Gateways tiefer.
Eine Versionsnotiz, weil sie wichtig ist: Das hier landete am 2026-09-12 auf main und gehört zur Arbeit nach v0.21.2, veröffentlicht am 2026-09-11. In einem getaggten Release ist es noch nicht enthalten – wenn du es heute willst, willst du main.