Befehls-Warteschlange (2026-01-16)
Eingehende Auto-Reply-Läufe werden serialisiert (all channels) über eine kleine In-Process-Warteschlange um Kollisionen mehrerer Agent-Läufe zu vermeiden, bei weiterhin sicherer Parallelität über Sitzungen hinweg.
Warum
- Auto-Reply-Läufe können teuer sein (LLM-Aufrufe) und können kollidieren, wenn mehrere eingehende Nachrichten kurz nacheinander ankommen.
- Serialisierung vermeidet Konkurrenz um gemeinsame Ressourcen (Sitzungsdateien, Logs, CLI-stdin) und verringert die Gefahr von Upstream-Rate-Limits.
So funktioniert es
- Eine lane-bewusste FIFO-Warteschlange leert jede Lane mit konfigurierbarer Concurrency-Obergrenze (Standard 1 für nicht konfigurierte Lanes; main standardmäßig 4, Subagent 8).
runEmbeddedPiAgentreiht nach Sitzungsschlüssel ein (lanesession:<key>) um nur einen aktiven Lauf pro Sitzung zu garantieren.- Jeder Sitzungslauf wird dann in eine globale Lane eingereiht (
mainstandardmäßig) sodass die Gesamtparallelität begrenzt wird durchagents.defaults.maxConcurrent. - Bei aktiviertem ausführlichen Logging geben eingereihte Läufe eine kurze Meldung aus wenn sie mehr als ~2s vor dem Start gewartet haben.
- Tipp-Indikatoren feuern weiterhin sofort beim Einreihen (wenn vom Kanal unterstützt) sodass die Nutzererfahrung unverändert bleibt, während wir an der Reihe sind.
Warteschlangen-Modi (pro Kanal)
Eingehende Nachrichten können den aktuellen Lauf steuern, auf einen Follow-up-Turn warten, oder beides:
steer: sofort in den aktuellen Lauf injizieren (bricht ausstehende Tool-Aufrufe nach der nächsten Tool-Grenze ab). Ohne Streaming Fallback auf Follow-up.followup: für den nächsten Agent-Turn nach Ende des aktuellen Laufs einreihen.collect: alle eingereihten Nachrichten in einen Follow-up-Turn zusammenfassen (Standard). Wenn Nachrichten verschiedene Kanäle/Threads adressieren, werden sie einzeln abgearbeitet, um das Routing zu erhalten.steer-backlog(akasteer+backlog): jetzt steuern und die Nachricht für einen Follow-up-Turn behalten.interrupt(legacy): den aktiven Lauf für diese Sitzung abbrechen, dann die neueste Nachricht ausführen.queue(Legacy-Alias): wiesteer.
Bei Steer-backlog kann nach dem gesteuerten Lauf eine Follow-up-Antwort kommen, sodass
Streaming-Oberflächen wie Duplikate wirken können. Bevorzugen Sie collect/steer, wenn Sie
eine Antwort pro eingehende Nachricht wünschen.
Send /queue collect as a standalone command (per-session) or set messages.queue.byChannel.discord: "collect".Standard (wenn in Config nicht gesetzt):
- Alle Oberflächen →
collect
Global oder pro Kanal konfigurieren über messages.queue:
{
messages: {
queue: {
mode: "collect",
debounceMs: 1000,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" }
}
}
}Warteschlangen-Optionen
Optionen gelten für followup, collect, und steer-backlog (und für steer wenn auf Follow-up zurückgefallen wird):
debounceMs: auf Ruhe warten, bevor ein Follow-up-Turn gestartet wird (prevents “continue, continue”).cap: max. eingereihte Nachrichten pro Sitzung.drop: Überlauf-Richtlinie (old,new,summarize).
Summarize behält eine kurze Aufzählung verworfenen Nachrichten und injiziert sie als synthetischen Follow-up-Prompt.
Standard: debounceMs: 1000, cap: 20, drop: summarize.
Pro-Sitzungs-Überschreibungen
/queue <mode>als eigenständigen Befehl senden um den Modus für die aktuelle Sitzung zu speichern.- Optionen können kombiniert werden:
/queue collect debounce:2s cap:25 drop:summarize /queue defaultor/queue resetsetzt die Sitzungs-Überschreibung zurück.
Umfang und Garantien
- Gilt für Auto-Reply-Agent-Läufe über alle eingehenden Kanäle die die Gateway-Reply-Pipeline nutzen (WhatsApp web, Telegram, Slack, Discord, Signal, iMessage, webchat, etc.).
- Standard-Lane (
main) ist prozessweit für eingehende und Main-Heartbeats;agents.defaults.maxConcurrentsetzen, um mehrere Sitzungen parallel zu erlauben. - Zusätzliche Lanes können existieren (e.g.
cron,subagent) sodass Hintergrund-Jobs parallel laufen können ohne eingehende Replies zu blockieren. - Per-session lanes guarantee that only one agent run touches a given session at a time.
- No external dependencies or background worker threads; pure TypeScript + promises.
Troubleshooting
- If commands seem stuck, enable verbose logs und look for “queued for …ms” lines to confirm the queue is draining.
- If you need queue depth, enable verbose logs und watch for queue timing lines.