Command Queue (16.01.2026)
Wir serialisieren eingehende Auto-Reply-Läufe (alle Channels) über eine kleine In-Process-Queue. So verhindern wir, dass mehrere Agent-Läufe kollidieren, und ermöglichen trotzdem sichere Parallelität zwischen Sessions.
Warum
- Auto-Reply-Läufe können teuer sein (LLM-Aufrufe) und kollidieren, wenn mehrere Nachrichten kurz hintereinander eintreffen.
- Durch Serialisierung vermeiden wir Konflikte um gemeinsame Ressourcen (Session-Dateien, Logs, CLI stdin) und reduzieren das Risiko von Rate Limits.
So funktioniert es
- Eine Lane-aware FIFO-Queue verarbeitet jede Lane mit einem konfigurierbaren Concurrency-Limit (Standard: 1 für unkonfigurierte Lanes; main hat 4, subagent hat 8).
runEmbeddedPiAgentreiht nach Session Key ein (Lanesession:<key>), damit pro Session nur ein aktiver Lauf existiert.- Jeder Session-Lauf wird dann in eine globale Lane (
mainstandardmäßig) eingereiht, sodass die Gesamtparallelität durchagents.defaults.maxConcurrentbegrenzt wird. - Bei aktiviertem Verbose-Logging erscheint ein kurzer Hinweis, wenn ein Lauf mehr als ~2s gewartet hat.
- Typing-Indikatoren werden sofort beim Einreihen ausgelöst (wenn der Channel das unterstützt), damit die User Experience unverändert bleibt.
Queue-Modi (pro Channel)
Eingehende Nachrichten können den aktuellen Lauf steuern, auf eine Folgerunde warten oder beides:
steer: Sofort in den aktuellen Lauf injizieren (bricht ausstehende Tool-Aufrufe nach der nächsten Tool-Grenze ab). Ohne Streaming wird auf followup zurückgefallen.followup: Für die nächste Agent-Runde nach Ende des aktuellen Laufs einreihen.collect: Alle wartenden Nachrichten zu einer einzigen Folgerunde zusammenfassen (Standard). Bei Nachrichten für verschiedene Channels/Threads werden sie einzeln verarbeitet, um das Routing zu erhalten.steer-backlog(auchsteer+backlog): Jetzt steuern und die Nachricht für eine Folgerunde aufbewahren.interrupt(veraltet): Den aktiven Lauf für diese Session abbrechen, dann die neueste Nachricht ausführen.queue(veralteter Alias): Entsprichtsteer.
Bei steer-backlog bekommst du nach dem gesteuerten Lauf eine Folgeantwort, was bei Streaming wie Duplikate aussehen kann. Nutze lieber collect/steer, wenn du eine Antwort pro eingehender Nachricht willst.
Sende /queue collect als eigenständigen Befehl (pro Session) oder setze messages.queue.byChannel.discord: "collect".
Standardwerte (wenn nicht konfiguriert):
- Alle Oberflächen →
collect
Konfiguriere global oder pro Channel über messages.queue:
{
messages: {
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}
Queue-Optionen
Diese Optionen gelten für followup, collect und steer-backlog (und für steer, wenn es auf followup zurückfällt):
debounceMs: Wartet auf Ruhe, bevor eine Folgerunde startet (verhindert “weiter, weiter”).cap: Maximale Anzahl wartender Nachrichten pro Session.drop: Überlauf-Strategie (old,new,summarize).
Summarize behält eine kurze Aufzählung der verworfenen Nachrichten und fügt sie als synthetischen Followup-Prompt ein.
Standardwerte: debounceMs: 1000, cap: 20, drop: summarize.
Session-spezifische Überschreibungen
- Sende
/queue <mode>als eigenständigen Befehl, um den Modus für die aktuelle Session zu speichern. - Optionen lassen sich kombinieren:
/queue collect debounce:2s cap:25 drop:summarize /queue defaultoder/queue resetlöscht die Session-Überschreibung.
Geltungsbereich und Garantien
- Gilt für Auto-Reply-Agent-Läufe über alle eingehenden Channels, die die Gateway-Reply-Pipeline nutzen (WhatsApp Web, Telegram, Slack, Discord, Signal, iMessage, Webchat usw.).
- Die Standard-Lane (
main) gilt prozessweit für eingehende Nachrichten + Haupt-Heartbeats; setzeagents.defaults.maxConcurrent, um mehrere Sessions parallel zu erlauben. - Zusätzliche Lanes können existieren (z.B.
cron,subagent), damit Hintergrund-Jobs parallel laufen können, ohne eingehende Antworten zu blockieren. - Pro-Session-Lanes garantieren, dass nur ein Agent-Lauf gleichzeitig eine bestimmte Session bearbeitet.
- Keine externen Abhängigkeiten oder Hintergrund-Worker-Threads; reines TypeScript + Promises.
Troubleshooting
- Wenn Befehle hängen zu bleiben scheinen, aktiviere Verbose-Logs und suche nach “queued for …ms”-Zeilen, um zu bestätigen, dass die Queue abgearbeitet wird.
- Für die Queue-Tiefe aktiviere Verbose-Logs und beobachte die Queue-Timing-Zeilen.