Messages and delivery
コマンドキュー
インバウンドの自動返信実行(全チャネル)を小さなインプロセスキュー経由でシリアライズし、複数のエージェント実行が衝突するのを防ぎつつ、セッション間では安全な並列処理を引き続き可能にします。
理由
- 自動返信実行は高コスト(LLM 呼び出し)になることがあり、複数のインバウンドメッセージが近いタイミングで到着すると衝突する可能性があります。
- シリアライズにより、共有リソース(セッションファイル、ログ、CLI stdin)の奪い合いを避け、上流のレート制限にかかる可能性を下げます。
仕組み
- レーン対応の FIFO キューは、各レーンを設定可能な同時実行上限(未設定レーンのデフォルトは 1、main のデフォルトは 4、subagent は 8)でドレインします。
runEmbeddedPiAgentは セッションキー(レーンsession:<key>)ごとにエンキューし、セッションごとにアクティブな実行が 1 つだけになることを保証します。- 各セッション実行はその後 グローバルレーン(デフォルトは
main)にキューされるため、全体の並列度はagents.defaults.maxConcurrentによって制限されます。 - 詳細ログが有効な場合、キュー済みの実行は開始までに約 2 秒以上待機すると短い通知を出力します。
- タイピングインジケーターは、(チャネルが対応している場合)エンキュー時にすぐ発火するため、順番待ちの間もユーザー体験は変わりません。
デフォルト
未設定の場合、すべてのインバウンドチャネルサーフェスは次を使用します。
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
steer がデフォルトなのは、2 つ目のセッション実行を開始せずに、アクティブなモデルターンの応答性を保てるためです。次のモデル境界より前に到着したすべてのステアリングメッセージをドレインします。現在の実行がステアリングを受け付けられない場合、OpenClaw はフォローアップキューエントリにフォールバックします。
キューモード
インバウンドメッセージは、現在の実行をステアリングする、フォローアップターンを待つ、またはその両方を行えます。
steer: アクティブなランタイムにステアリングメッセージをキューします。Pi は保留中のすべてのステアリングメッセージを、現在のアシスタントターンがツール呼び出しの実行を終えた後、次の LLM 呼び出しの前に配信します。Codex app-server はバッチ化された 1 つのturn/steerを受け取ります。実行がアクティブにストリーミングしていない場合やステアリングを利用できない場合、OpenClaw はフォローアップキューエントリにフォールバックします。queue(レガシー): 旧来の 1 件ずつのステアリングです。Pi は各モデル境界でキュー済みのステアリングメッセージを 1 件配信します。Codex app-server は個別のturn/steerリクエストを受け取ります。以前のシリアライズされた動作が必要な場合を除き、steerを推奨します。followup: 現在の実行が終わった後のエージェントターン用に、各メッセージをエンキューします。collect: 静穏ウィンドウの後、キュー済みメッセージを 単一の フォローアップターンにまとめます。メッセージが異なるチャネルやスレッドを対象にしている場合は、ルーティングを保持するため個別にドレインされます。steer-backlog(別名steer+backlog): 今すぐステアリングし、かつ 同じメッセージをフォローアップターン用に保持します。interrupt(レガシー): そのセッションのアクティブな実行を中止し、最新のメッセージを実行します。
steer-backlog では、ステアリングされた実行の後にフォローアップ応答を受け取る可能性があるため、ストリーミングサーフェスでは重複のように見えることがあります。インバウンドメッセージごとに応答を 1 つにしたい場合は、collect/steer を推奨します。
ランタイム固有のタイミングと依存関係の動作については、ステアリングキューを参照してください。明示的な /steer <message> コマンドについては、ステアを参照してください。
messages.queue により、グローバルまたはチャネルごとに設定します。
{
messages: {
queue: {
mode: "steer",
debounceMs: 500,
cap: 20,
drop: "summarize",
byChannel: { discord: "collect" },
},
},
}
キューオプション
オプションは followup、collect、steer-backlog(およびステアリングがフォローアップにフォールバックする場合の steer またはレガシー queue)に適用されます。
debounceMs: キュー済みフォローアップをドレインする前の静穏ウィンドウ。単位なしの数値はミリ秒です。/queueオプションではms、s、m、h、dの単位を受け付けます。cap: セッションごとのキュー済みメッセージの最大数。1未満の値は無視されます。drop: "summarize": デフォルトです。必要に応じて最も古いキューエントリを削除し、コンパクトな要約を保持して、合成フォローアッププロンプトとして注入します。drop: "old": 必要に応じて最も古いキューエントリを削除しますが、要約は保持しません。drop: "new": キューがすでに満杯の場合、最新のメッセージを拒否します。
デフォルト: debounceMs: 500、cap: 20、drop: summarize。
優先順位
モード選択では、OpenClaw は次の順に解決します。
- インラインまたは保存済みのセッションごとの
/queueオーバーライド。 messages.queue.byChannel.<channel>。messages.queue.mode。- デフォルトの
steer。
オプションでは、インラインまたは保存済みの /queue オプションが設定より優先されます。その後、チャネル固有のデバウンス(messages.queue.debounceMsByChannel)、Plugin のデバウンスデフォルト、グローバルな messages.queue オプション、組み込みデフォルトが適用されます。cap と drop はグローバルまたはセッションのオプションであり、チャネルごとの設定キーではありません。
セッションごとのオーバーライド
- 現在のセッションにモードを保存するには、
/queue <mode>を単独のコマンドとして送信します。 - オプションは組み合わせられます:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultまたは/queue resetはセッションのオーバーライドをクリアします。
スコープと保証
- Gateway 返信パイプラインを使用するすべてのインバウンドチャネル(WhatsApp web、Telegram、Slack、Discord、Signal、iMessage、webchat など)にまたがる自動返信エージェント実行に適用されます。
- デフォルトレーン(
main)は、インバウンドとメイン Heartbeat に対してプロセス全体で共有されます。複数セッションの並列実行を許可するにはagents.defaults.maxConcurrentを設定します。 - 追加レーン(例:
cron、cron-nested、nested、subagent)が存在する場合があり、バックグラウンドジョブはインバウンド返信をブロックせずに並列実行できます。分離された Cron エージェントターンはcronスロットを保持し、その内側のエージェント実行はcron-nestedを使用します。どちらもcron.maxConcurrentRunsを使用します。共有の非 Cronnestedフローは、それぞれ独自のレーン動作を保持します。これらの切り離された実行はバックグラウンドタスクとして追跡されます。 - セッションごとのレーンにより、特定のセッションに触れるエージェント実行は同時に 1 つだけであることが保証されます。
- 外部依存関係やバックグラウンドワーカースレッドはありません。純粋な TypeScript + promises です。
トラブルシューティング
- コマンドが止まっているように見える場合は、詳細ログを有効にし、キューがドレインされていることを確認するために "queued for ...ms" の行を探してください。
- キューの深さが必要な場合は、詳細ログを有効にし、キューのタイミング行を監視してください。
- Codex app-server の実行がターンを受け付けた後に進捗の出力を止めた場合、Codex adapter によって中断されるため、外側の実行タイムアウトを待つ代わりにアクティブなセッションレーンを解放できます。
- 診断が有効な場合、
diagnostics.stuckSessionWarnMsを超えてprocessingのままで、返信、ツール、ステータス、ブロック、ACP 進捗が観測されないセッションは、現在のアクティビティによって分類されます。アクティブな作業はsession.long_runningとしてログに記録されます。最近の進捗がないアクティブな作業はsession.stalledとしてログに記録されます。session.stuckはアクティブな作業がない古いセッション管理情報のために予約されており、その経路だけが影響を受けたセッションレーンを解放して、キュー済み作業をドレインできます。繰り返されるsession.stuck診断は、セッションが変化しない間はバックオフします。