diff --git a/.openclaw-sync/source.json b/.openclaw-sync/source.json index 3a2261e60..7e94901a0 100644 --- a/.openclaw-sync/source.json +++ b/.openclaw-sync/source.json @@ -1,5 +1,5 @@ { "repository": "openclaw/openclaw", - "sha": "601596bfe292739993c7c883fa173f2f6a97f79c", - "syncedAt": "2026-04-30T00:06:01.930Z" + "sha": "30a2b3049ae04c695e6e65308196c55189c78d25", + "syncedAt": "2026-04-30T00:26:46.012Z" } diff --git a/docs/.generated/config-baseline.sha256 b/docs/.generated/config-baseline.sha256 index 21e0608e9..32b2e7519 100644 --- a/docs/.generated/config-baseline.sha256 +++ b/docs/.generated/config-baseline.sha256 @@ -1,4 +1,4 @@ -2af6bef21f530dc64e0379f7631bed410aee1d5c86604ef9fb149f546cfcb0e8 config-baseline.json -8d75df355b7f6e44b9c2f195d9df86130beb697e26061469df7d60b7e8a2f204 config-baseline.core.json +dbb3d39ddeb8a9ce03459d69774db7e457d33f47c585e0f8c7130b14b92cfcff config-baseline.json +2197788a6a1e677fb34a4971ac4f254116c243753452397824e08431f8740aab config-baseline.core.json fab66aa304db5697e87259165ad261006719eb6e6cdbd25f957fcba2b7b324e9 config-baseline.channel.json c4231c2194206547af8ad94342dc00aadb734f43cb49cc79d4c46bdbb80c3f95 config-baseline.plugin.json diff --git a/docs/.i18n/glossary.zh-CN.json b/docs/.i18n/glossary.zh-CN.json index 466000477..ff1616612 100644 --- a/docs/.i18n/glossary.zh-CN.json +++ b/docs/.i18n/glossary.zh-CN.json @@ -51,6 +51,10 @@ "source": "Agent loop", "target": "Agent loop" }, + { + "source": "Steering queue", + "target": "Steering queue" + }, { "source": "Models", "target": "Models" diff --git a/docs/concepts/agent.md b/docs/concepts/agent.md index 3277b7d4f..d7280dd0e 100644 --- a/docs/concepts/agent.md +++ b/docs/concepts/agent.md @@ -86,13 +86,15 @@ Legacy session folders from other tools are not read. When queue mode is `steer`, inbound messages are injected into the current run. Queued steering is delivered **after the current assistant turn finishes -executing its tool calls**, before the next LLM call. Steering no longer skips -remaining tool calls from the current assistant message; it injects the queued -message at the next model boundary instead. +executing its tool calls**, before the next LLM call. Pi drains all pending +steering messages together for `steer`; legacy `queue` drains one message per +model boundary. Steering no longer skips remaining tool calls from the current +assistant message. When queue mode is `followup` or `collect`, inbound messages are held until the current turn ends, then a new agent turn starts with the queued payloads. See -[Queue](/concepts/queue) for mode + debounce/cap behavior. +[Queue](/concepts/queue) and [Steering queue](/concepts/queue-steering) for mode +and boundary behavior. Block streaming sends completed assistant blocks as soon as they finish; it is **off by default** (`agents.defaults.blockStreamingDefault: "off"`). diff --git a/docs/concepts/messages.md b/docs/concepts/messages.md index c25a6a7ba..adbf5d243 100644 --- a/docs/concepts/messages.md +++ b/docs/concepts/messages.md @@ -127,9 +127,9 @@ current run, or collected for a followup turn. - Default mode is `steer`, with a 500ms followup debounce when steering falls back to queued followup delivery. - Modes: `steer`, `followup`, `collect`, `steer-backlog`, `interrupt`, and the - legacy `queue` alias. + legacy one-at-a-time `queue` mode. -Details: [Command queue](/concepts/queue). +Details: [Command queue](/concepts/queue) and [Steering queue](/concepts/queue-steering). ## Channel run ownership diff --git a/docs/concepts/queue-steering.md b/docs/concepts/queue-steering.md new file mode 100644 index 000000000..74419e0e4 --- /dev/null +++ b/docs/concepts/queue-steering.md @@ -0,0 +1,90 @@ +--- +summary: "How active-run steering queues messages at runtime boundaries" +read_when: + - Explaining how steer behaves while an agent is using tools + - Changing active-run queue behavior or runtime steering integration + - Comparing steer, queue, collect, and followup modes +title: "Steering queue" +--- + +When a message arrives while a session run is already streaming, OpenClaw can +send that message into the active runtime instead of starting another run for +the same session. The public modes are runtime-neutral; Pi and the native Codex +app-server harness implement the delivery details differently. + +## Runtime boundary + +Steering does not interrupt a tool call that is already running. Pi checks for +queued steering messages at model boundaries: + +1. The assistant asks for tool calls. +2. Pi executes the current assistant message's tool-call batch. +3. Pi emits the turn end event. +4. Pi drains queued steering messages. +5. Pi appends those messages as user messages before the next LLM call. + +This keeps tool results paired with the assistant message that requested them, +then lets the next model call see the latest user input. + +The native Codex app-server harness exposes `turn/steer` instead of Pi's +internal steering queue. OpenClaw adapts the same modes there: + +- `steer` batches queued messages for the configured quiet window, then sends a + single `turn/steer` request with all collected user input in arrival order. +- `queue` keeps the legacy serialized shape by sending separate `turn/steer` + requests. +- `followup`, `collect`, `steer-backlog`, and `interrupt` stay OpenClaw-owned + queue behavior around the active Codex turn. + +Codex review and manual compaction turns reject same-turn steering. When a +runtime cannot accept steering, OpenClaw falls back to the followup queue where +that mode allows it. + +## Modes + +| Mode | Active-run behavior | Later followup behavior | +| --------------- | ---------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | +| `steer` | Injects all queued steering messages together at the next runtime boundary. This is the default. | Falls back to followup only when steering is unavailable. | +| `queue` | Legacy one-at-a-time steering. Pi injects one queued message per model boundary; Codex sends separate `turn/steer` requests. | Falls back to followup only when steering is unavailable. | +| `steer-backlog` | Same active-run steering behavior as `steer`. | Also keeps the same message for a later followup turn. | +| `followup` | Does not steer the current run. | Runs queued messages later. | +| `collect` | Does not steer the current run. | Coalesces compatible queued messages into one later turn after the debounce window. | +| `interrupt` | Aborts the active run, then starts the newest message. | None. | + +## Burst example + +If four users send messages while the agent is executing a tool call: + +- `steer`: the active runtime receives all four messages in arrival order before + its next model decision. Pi drains them at the next model boundary; Codex + receives them as one batched `turn/steer`. +- `queue`: legacy serialized steering. Pi injects one queued message at a time; + Codex receives separate `turn/steer` requests. +- `collect`: OpenClaw waits until the active run ends, then creates a followup + turn with compatible queued messages after the debounce window. + +## Scope + +Steering always targets the current active session run. It does not create a new +session, change the active run's tool policy, or split messages by sender. In +multi-user channels, inbound prompts already include sender and route context, so +the next model call can see who sent each message. + +Use `collect` when you want OpenClaw to build a later followup turn that can +coalesce compatible messages and preserve followup queue drop policy. Use +`queue` only when you need the older one-at-a-time steering behavior. + +## Debounce + +`messages.queue.debounceMs` applies to followup delivery, including `collect`, +`followup`, `steer-backlog`, and `steer` fallback when active-run steering is not +available. For Pi, active `steer` itself does not use the debounce timer because +Pi naturally batches messages until the next model boundary. For the native +Codex harness, OpenClaw uses the same debounce value as the quiet window before +sending the batched `turn/steer`. + +## Related + +- [Command queue](/concepts/queue) +- [Messages](/concepts/messages) +- [Agent loop](/concepts/agent-loop) diff --git a/docs/concepts/queue.md b/docs/concepts/queue.md index a3ff4ec6e..50e7d7ae5 100644 --- a/docs/concepts/queue.md +++ b/docs/concepts/queue.md @@ -31,24 +31,28 @@ When unset, all inbound channel surfaces use: - `drop: "summarize"` `steer` is the default because it keeps the active model turn responsive without -starting a second session run. If the current run cannot accept steering, +starting a second session run. It drains all steering messages that arrived +before the next model boundary. If the current run cannot accept steering, OpenClaw falls back to a followup queue entry. ## Queue modes Inbound messages can steer the current run, wait for a followup turn, or do both: -- `steer`: queue a steering message into the active Pi run. Pi delivers it **after the current assistant turn finishes executing its tool calls**, before the next LLM call. If the run is not actively streaming or steering is unavailable, OpenClaw falls back to a followup queue entry. +- `steer`: queue steering messages into the active runtime. Pi delivers all pending steering messages **after the current assistant turn finishes executing its tool calls**, before the next LLM call; Codex app-server receives one batched `turn/steer`. If the run is not actively streaming or steering is unavailable, OpenClaw falls back to a followup queue entry. +- `queue` (legacy): old one-at-a-time steering. Pi delivers one queued steering message at each model boundary; Codex app-server receives separate `turn/steer` requests. Prefer `steer` unless you need the previous serialized behavior. - `followup`: enqueue each message for a later agent turn after the current run ends. - `collect`: coalesce queued messages into a **single** followup turn after the quiet window. If messages target different channels/threads, they drain individually to preserve routing. - `steer-backlog` (aka `steer+backlog`): steer now **and** preserve the same message for a followup turn. - `interrupt` (legacy): abort the active run for that session, then run the newest message. -- `queue` (legacy alias): same as `steer`. Steer-backlog means you can get a followup response after the steered run, so streaming surfaces can look like duplicates. Prefer `collect`/`steer` if you want one response per inbound message. +For runtime-specific timing and dependency behavior, see +[Steering queue](/concepts/queue-steering). + Configure globally or per channel via `messages.queue`: ```json5 @@ -67,7 +71,7 @@ Configure globally or per channel via `messages.queue`: ## Queue options -Options apply to `followup`, `collect`, and `steer-backlog` (and to `steer` when it falls back to followup): +Options apply to `followup`, `collect`, and `steer-backlog` (and to `steer` or legacy `queue` when steering falls back to followup): - `debounceMs`: quiet window before draining queued followups. Bare numbers are milliseconds; units `ms`, `s`, `m`, `h`, and `d` are accepted by `/queue` options. - `cap`: max queued messages per session. Values below `1` are ignored. @@ -115,4 +119,5 @@ keys. ## Related - [Session management](/concepts/session) +- [Steering queue](/concepts/queue-steering) - [Retry policy](/concepts/retry) diff --git a/docs/docs.json b/docs/docs.json index 3edd4ad3a..954694659 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1177,7 +1177,8 @@ "concepts/messages", "concepts/streaming", "concepts/retry", - "concepts/queue" + "concepts/queue", + "concepts/queue-steering" ] } ] @@ -2650,7 +2651,8 @@ "zh-TW/concepts/messages", "zh-TW/concepts/streaming", "zh-TW/concepts/retry", - "zh-TW/concepts/queue" + "zh-TW/concepts/queue", + "zh-TW/concepts/queue-steering" ] } ] @@ -3508,7 +3510,8 @@ "ja-JP/concepts/messages", "ja-JP/concepts/streaming", "ja-JP/concepts/retry", - "ja-JP/concepts/queue" + "ja-JP/concepts/queue", + "ja-JP/concepts/queue-steering" ] } ] @@ -4366,7 +4369,8 @@ "es/concepts/messages", "es/concepts/streaming", "es/concepts/retry", - "es/concepts/queue" + "es/concepts/queue", + "es/concepts/queue-steering" ] } ] @@ -5224,7 +5228,8 @@ "pt-BR/concepts/messages", "pt-BR/concepts/streaming", "pt-BR/concepts/retry", - "pt-BR/concepts/queue" + "pt-BR/concepts/queue", + "pt-BR/concepts/queue-steering" ] } ] @@ -6082,7 +6087,8 @@ "ko/concepts/messages", "ko/concepts/streaming", "ko/concepts/retry", - "ko/concepts/queue" + "ko/concepts/queue", + "ko/concepts/queue-steering" ] } ] @@ -6940,7 +6946,8 @@ "de/concepts/messages", "de/concepts/streaming", "de/concepts/retry", - "de/concepts/queue" + "de/concepts/queue", + "de/concepts/queue-steering" ] } ] @@ -7798,7 +7805,8 @@ "fr/concepts/messages", "fr/concepts/streaming", "fr/concepts/retry", - "fr/concepts/queue" + "fr/concepts/queue", + "fr/concepts/queue-steering" ] } ] @@ -8656,7 +8664,8 @@ "ar/concepts/messages", "ar/concepts/streaming", "ar/concepts/retry", - "ar/concepts/queue" + "ar/concepts/queue", + "ar/concepts/queue-steering" ] } ] @@ -9514,7 +9523,8 @@ "it/concepts/messages", "it/concepts/streaming", "it/concepts/retry", - "it/concepts/queue" + "it/concepts/queue", + "it/concepts/queue-steering" ] } ] @@ -10372,7 +10382,8 @@ "vi/concepts/messages", "vi/concepts/streaming", "vi/concepts/retry", - "vi/concepts/queue" + "vi/concepts/queue", + "vi/concepts/queue-steering" ] } ] @@ -11230,7 +11241,8 @@ "nl/concepts/messages", "nl/concepts/streaming", "nl/concepts/retry", - "nl/concepts/queue" + "nl/concepts/queue", + "nl/concepts/queue-steering" ] } ] @@ -12088,7 +12100,8 @@ "tr/concepts/messages", "tr/concepts/streaming", "tr/concepts/retry", - "tr/concepts/queue" + "tr/concepts/queue", + "tr/concepts/queue-steering" ] } ] @@ -12946,7 +12959,8 @@ "uk/concepts/messages", "uk/concepts/streaming", "uk/concepts/retry", - "uk/concepts/queue" + "uk/concepts/queue", + "uk/concepts/queue-steering" ] } ] @@ -13804,7 +13818,8 @@ "id/concepts/messages", "id/concepts/streaming", "id/concepts/retry", - "id/concepts/queue" + "id/concepts/queue", + "id/concepts/queue-steering" ] } ] @@ -14662,7 +14677,8 @@ "pl/concepts/messages", "pl/concepts/streaming", "pl/concepts/retry", - "pl/concepts/queue" + "pl/concepts/queue", + "pl/concepts/queue-steering" ] } ] diff --git a/docs/gateway/config-agents.md b/docs/gateway/config-agents.md index a7baf7a80..b1861d7c2 100644 --- a/docs/gateway/config-agents.md +++ b/docs/gateway/config-agents.md @@ -1226,7 +1226,7 @@ See [Multi-Agent Sandbox & Tools](/tools/multi-agent-sandbox-tools) for preceden ackReactionScope: "group-mentions", // group-mentions | group-all | direct | all removeAckAfterReply: false, queue: { - mode: "steer", // steer | followup | collect | steer-backlog | steer+backlog | queue | interrupt + mode: "steer", // steer | queue (legacy one-at-a-time) | followup | collect | steer-backlog | steer+backlog | interrupt debounceMs: 500, cap: 20, drop: "summarize", // old | new | summarize diff --git a/docs/help/faq.md b/docs/help/faq.md index a9c228787..c9db380d7 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -1943,13 +1943,14 @@ lives on the [Models FAQ](/help/faq-models). Queue mode controls how new messages interact with an in-flight run. Use `/queue` to change modes: - - `steer` - queue steering for the next model boundary in the current run + - `steer` - queue all pending steering for the next model boundary in the current run + - `queue` - legacy one-at-a-time steering - `followup` - run messages one at a time - `collect` - batch messages and reply once - `steer-backlog` - steer now, then process backlog - `interrupt` - abort current run and start fresh - Default mode is `steer`. You can add options like `debounce:0.5s cap:25 drop:summarize` for followup modes. See [Command queue](/concepts/queue). + Default mode is `steer`. You can add options like `debounce:0.5s cap:25 drop:summarize` for followup modes. See [Command queue](/concepts/queue) and [Steering queue](/concepts/queue-steering). diff --git a/docs/plugins/codex-harness.md b/docs/plugins/codex-harness.md index dd9a835bf..d6223cf81 100644 --- a/docs/plugins/codex-harness.md +++ b/docs/plugins/codex-harness.md @@ -946,6 +946,14 @@ originating chat, and the next queued follow-up message answers that native server request instead of being steered as extra context. Other MCP elicitation requests still fail closed. +Active-run queue steering maps onto Codex app-server `turn/steer`. With the +default `messages.queue.mode: "steer"`, OpenClaw batches queued chat messages +for the configured quiet window and sends them as one `turn/steer` request in +arrival order. Legacy `queue` mode sends separate `turn/steer` requests. Codex +review and manual compaction turns can reject same-turn steering, in which case +OpenClaw uses the followup queue when the selected mode allows fallback. See +[Steering queue](/concepts/queue-steering). + When the selected model uses the Codex harness, native thread compaction is delegated to Codex app-server. OpenClaw keeps a transcript mirror for channel history, search, `/new`, `/reset`, and future model or harness switching. The diff --git a/docs/tools/slash-commands.md b/docs/tools/slash-commands.md index 05543cd6a..3d5c88063 100644 --- a/docs/tools/slash-commands.md +++ b/docs/tools/slash-commands.md @@ -142,7 +142,7 @@ Current source-of-truth: - `/exec host= security= ask= node=` shows or sets exec defaults. - `/model [name|#|status]` shows or sets the model. - `/models [provider] [page] [limit=|size=|all]` lists configured/auth-available providers or models for a provider; add `all` to browse that provider's full catalog. - - `/queue ` manages queue behavior (`steer`, `followup`, `collect`, `steer-backlog`, `interrupt`) plus options like `debounce:0.5s cap:25 drop:summarize`; `/queue default` or `/queue reset` clears the session override. See [Command queue](/concepts/queue). + - `/queue ` manages queue behavior (`steer`, legacy `queue`, `followup`, `collect`, `steer-backlog`, `interrupt`) plus options like `debounce:0.5s cap:25 drop:summarize`; `/queue default` or `/queue reset` clears the session override. See [Command queue](/concepts/queue) and [Steering queue](/concepts/queue-steering).