Befehlswarteschlange (2026-01-16)

Eingehende Auto-Reply-Laeufe (aller Kanaele) werden ueber eine kleine In-Process-Warteschlange serialisiert. Das verhindert Kollisionen mehrerer Agent-Laeufe und erlaubt gleichzeitig sichere Parallelitaet ueber Sessions hinweg.

Warum

  • Auto-Reply-Laeufe koennen aufwaendig sein (LLM-Aufrufe) und kollidieren, wenn mehrere eingehende Nachrichten kurz hintereinander eintreffen.
  • Serialisierung verhindert Konflikte um gemeinsam genutzte Ressourcen (Session-Dateien, Logs, CLI-Stdin) und reduziert die Wahrscheinlichkeit von Upstream-Rate-Limits.

So funktioniert es

  • Eine lane-aware FIFO-Warteschlange arbeitet jede Lane mit einem konfigurierbaren Concurrency-Cap ab (Standard: 1 fuer nicht konfigurierte Lanes; main: 4, subagent: 8).
  • runEmbeddedPiAgent reiht per Session-Key ein (Lane session:<key>), um nur einen aktiven Lauf pro Session zu garantieren.
  • Jeder Session-Lauf wird anschliessend in eine globale Lane (main standardmaessig) eingereiht, sodass die Gesamtparallelitaet durch agents.defaults.maxConcurrent begrenzt wird.
  • Bei aktiviertem Verbose-Logging geben eingereihte Laeufe einen kurzen Hinweis aus, wenn sie laenger als ~2s warten mussten, bevor sie gestartet wurden.
  • Tipp-Indikatoren werden weiterhin sofort beim Einreihen ausgeloest (wenn vom Kanal unterstuetzt), damit sich die Benutzererfahrung nicht aendert, waehrend wir warten.

Queue-Modi (pro Kanal)

Eingehende Nachrichten koennen den aktuellen Lauf steuern, auf eine Folgerunde warten oder beides:

  • steer: sofort in den aktuellen Lauf einspeisen (bricht ausstehende Tool-Aufrufe nach der naechsten Tool-Grenze ab). Wenn kein Streaming aktiv ist, Fallback auf Followup.
  • followup: fuer die naechste Agent-Runde nach Ende des aktuellen Laufs einreihen.
  • collect: alle eingehenden Nachrichten zu einer einzigen Folgerunde zusammenfassen (Standard). Wenn Nachrichten verschiedene Kanaele/Threads ansprechen, werden sie einzeln abgearbeitet, um das Routing zu erhalten.
  • steer-backlog (auch steer+backlog): jetzt steuern und die Nachricht fuer eine Folgerunde aufheben.
  • interrupt (Legacy): den aktiven Lauf fuer diese Session abbrechen und die neueste Nachricht ausfuehren.
  • queue (Legacy-Alias): entspricht steer.

Steer-Backlog bedeutet, dass du nach dem gesteuerten Lauf eine Folgeantwort bekommst — bei Streaming-Oberflaechen kann das wie Duplikate aussehen. Bevorzuge collect/steer, wenn du eine Antwort pro eingehender Nachricht willst. Sende /queue collect als eigenstaendigen Befehl (pro Session) oder setze messages.queue.byChannel.discord: "collect".

Standards (wenn in der Config nicht gesetzt):

  • Alle Oberflaechen: collect

Konfiguriere global oder pro Kanal ueber messages.queue:

{
  messages: {
    queue: {
      mode: "collect",
      debounceMs: 1000,
      cap: 20,
      drop: "summarize",
      byChannel: { discord: "collect" },
    },
  },
}

Queue-Optionen

Die Optionen gelten fuer followup, collect und steer-backlog (sowie fuer steer, wenn es auf Followup zurueckfaellt):

  • debounceMs: Ruhepause abwarten, bevor eine Folgerunde gestartet wird (verhindert “weiter, weiter”).
  • cap: maximale eingereihte Nachrichten pro Session.
  • drop: Ueberlauf-Richtlinie (old, new, summarize).

Summarize erzeugt eine kurze Aufzaehlung der verworfenen Nachrichten und speist sie als synthetischen Followup-Prompt ein. Standards: debounceMs: 1000, cap: 20, drop: summarize.

Sitzungsspezifische Overrides

  • Sende /queue <mode> als eigenstaendigen Befehl, um den Modus fuer die aktuelle Session zu speichern.
  • Optionen lassen sich kombinieren: /queue collect debounce:2s cap:25 drop:summarize
  • /queue default oder /queue reset setzt den Session-Override zurueck.

Geltungsbereich und Garantien

  • Gilt fuer Auto-Reply-Agent-Laeufe ueber alle eingehenden Kanaele, die die Gateway-Reply-Pipeline nutzen (WhatsApp Web, Telegram, Slack, Discord, Signal, iMessage, WebChat usw.).
  • Die Standard-Lane (main) ist prozessweit fuer eingehende Nachrichten + Haupt-Heartbeats; setze agents.defaults.maxConcurrent, um mehrere Sessions parallel zuzulassen.
  • Zusaetzliche Lanes koennen existieren (z.B. cron, subagent), damit Hintergrund-Jobs parallel laufen koennen, ohne eingehende Antworten zu blockieren.
  • Pro-Session-Lanes garantieren, dass nur ein Agent-Lauf gleichzeitig auf eine bestimmte Session zugreift.
  • Keine externen Abhaengigkeiten oder Hintergrund-Worker-Threads; reines TypeScript + Promises.

Fehlerbehebung

  • Wenn Befehle haengen zu scheinen, aktiviere Verbose-Logging und suche nach “queued for …ms”-Zeilen, um zu bestaetigen, dass die Queue abgearbeitet wird.
  • Fuer die Queue-Tiefe aktiviere Verbose-Logging und beobachte die Queue-Timing-Zeilen.