Command Queue (2026-01-16)
複数のエージェント実行が衝突するのを防ぎつつ、セッション間で安全な並列性を維持するために、受信自動返信実行(すべてのチャネル)を小さなインプロセスキューで直列化します。理由
- 自動返信実行は高コストになることがあり(LLM 呼び出し)、複数の受信メッセージが短時間に到着すると衝突する可能性があります。
- 直列化により共有リソース(セッションファイル、ログ、CLI stdin)の競合を避け、上流のレート制限に達する可能性を下げます。
仕組み
- レーン対応の FIFO キューが、設定可能な並行数上限で各レーンを処理します(未設定レーンのデフォルトは 1、main はデフォルトで 4、subagent は 8)。
runEmbeddedPiAgentは、セッションごとにアクティブな実行が 1 つだけになることを保証するため、セッションキー(レーンsession:<key>)単位でキューに入れます。- 各セッション実行はその後、全体の並列性が
agents.defaults.maxConcurrentで制限されるように、グローバルレーン(デフォルトではmain)にもキューイングされます。 - verbose ログが有効な場合、キューに入った実行は、開始までに約 2 秒以上待機したときに短い通知を出します。
- タイピングインジケーターは、待機中でもユーザー体験が変わらないよう、エンキュー時に即座に発火します(チャネルが対応している場合)。
キューモード(チャネルごと)
受信メッセージは、現在の実行に誘導することも、フォローアップターンを待つことも、その両方を行うこともできます:steer: 現在の実行に即座に注入します(次のツール境界の後で保留中のツール呼び出しをキャンセルします)。ストリーミング中でない場合は、followupにフォールバックします。followup: 現在の実行終了後の次のエージェントターン用にキューに入れます。collect: キューに入ったすべてのメッセージを 1 回の フォローアップターンにまとめます(デフォルト)。メッセージの対象チャネル/スレッドが異なる場合は、ルーティングを維持するため個別に処理されます。steer-backlog(別名steer+backlog): 今すぐ誘導し、さらに フォローアップターン用にメッセージを保持します。interrupt(レガシー): そのセッションのアクティブな実行を中止し、その後で最新メッセージを実行します。queue(レガシーエイリアス):steerと同じです。
collect または steer を推奨します。
/queue collect を単独コマンドとして送信する(セッションごと)か、messages.queue.byChannel.discord: "collect" を設定してください。
デフォルト(設定で未指定の場合):
- すべてのサーフェス →
collect
messages.queue でグローバルまたはチャネルごとに設定します:
キューオプション
オプションはfollowup、collect、steer-backlog に適用されます(また、steer が followup にフォールバックした場合にも適用されます):
debounceMs: フォローアップターン開始前に静穏状態を待ちます(「continue, continue」を防ぎます)。cap: セッションごとの最大キュー済みメッセージ数。drop: オーバーフロー時のポリシー(old、new、summarize)。
summary では、ドロップされたメッセージの短い箇条書きを保持し、それを合成フォローアッププロンプトとして注入します。
デフォルト: debounceMs: 1000、cap: 20、drop: summarize。
セッションごとのオーバーライド
- 現在のセッションのモードを保存するには、
/queue <mode>を単独コマンドとして送信します。 - オプションは組み合わせ可能です:
/queue collect debounce:2s cap:25 drop:summarize /queue defaultまたは/queue resetでセッションオーバーライドをクリアします。
スコープと保証
- Gateway 返信パイプラインを使うすべての受信チャネル(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat など)にわたる自動返信エージェント実行に適用されます。
- デフォルトレーン(
main)は受信 + メイン heartbeat 用のプロセス全体共有です。複数セッションの並列実行を許可するにはagents.defaults.maxConcurrentを設定します。 - 追加レーン(例:
cron、subagent)が存在することがあり、バックグラウンドジョブは受信返信をブロックせずに並列実行できます。これらの切り離された実行は background tasks として追跡されます。 - セッションごとのレーンにより、特定のセッションに同時に触れるエージェント実行は 1 つだけであることが保証されます。
- 外部依存やバックグラウンドワーカースレッドはありません。純粋な TypeScript + promises です。
トラブルシューティング
- コマンドが詰まっているように見える場合は、verbose ログを有効にし、「queued for …ms」という行を探してキューが処理されていることを確認してください。
- キューの深さが必要な場合は、verbose ログを有効にしてキューのタイミング行を確認してください。