Skip to content

Commit 6dc1c0d

Browse files
authored
Merge branch 'main' into fix/session-store-load-recovery-clean
2 parents a5b2326 + 17bbd18 commit 6dc1c0d

326 files changed

Lines changed: 5333 additions & 2057 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.oxlintrc.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"eslint/no-useless-computed-key": "error",
3131
"eslint/no-useless-concat": "error",
3232
"eslint/no-useless-constructor": "error",
33+
"eslint/no-unused-vars": "off",
3334
"eslint/no-warning-comments": "error",
3435
"eslint/no-unmodified-loop-condition": "error",
3536
"eslint/no-new-wrappers": "error",

CHANGELOG.md

Lines changed: 25 additions & 1 deletion
Large diffs are not rendered by default.

apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3406,21 +3406,25 @@ public struct TalkSessionSubmitToolResultParams: Codable, Sendable {
34063406
public let sessionid: String
34073407
public let callid: String
34083408
public let result: AnyCodable
3409+
public let options: [String: AnyCodable]?
34093410

34103411
public init(
34113412
sessionid: String,
34123413
callid: String,
3413-
result: AnyCodable)
3414+
result: AnyCodable,
3415+
options: [String: AnyCodable]?)
34143416
{
34153417
self.sessionid = sessionid
34163418
self.callid = callid
34173419
self.result = result
3420+
self.options = options
34183421
}
34193422

34203423
private enum CodingKeys: String, CodingKey {
34213424
case sessionid = "sessionId"
34223425
case callid = "callId"
34233426
case result
3427+
case options
34243428
}
34253429
}
34263430

@@ -5819,6 +5823,7 @@ public struct ChatSendParams: Codable, Sendable {
58195823
public let sessionid: String?
58205824
public let message: String
58215825
public let thinking: String?
5826+
public let fastmode: Bool?
58225827
public let deliver: Bool?
58235828
public let originatingchannel: String?
58245829
public let originatingto: String?
@@ -5835,6 +5840,7 @@ public struct ChatSendParams: Codable, Sendable {
58355840
sessionid: String?,
58365841
message: String,
58375842
thinking: String?,
5843+
fastmode: Bool?,
58385844
deliver: Bool?,
58395845
originatingchannel: String?,
58405846
originatingto: String?,
@@ -5850,6 +5856,7 @@ public struct ChatSendParams: Codable, Sendable {
58505856
self.sessionid = sessionid
58515857
self.message = message
58525858
self.thinking = thinking
5859+
self.fastmode = fastmode
58535860
self.deliver = deliver
58545861
self.originatingchannel = originatingchannel
58555862
self.originatingto = originatingto
@@ -5867,6 +5874,7 @@ public struct ChatSendParams: Codable, Sendable {
58675874
case sessionid = "sessionId"
58685875
case message
58695876
case thinking
5877+
case fastmode = "fastMode"
58705878
case deliver
58715879
case originatingchannel = "originatingChannel"
58725880
case originatingto = "originatingTo"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
632c00a35e0ed2413604ff28f5b4df0718131492208863c5d39576d76a9b7c88 config-baseline.json
1+
0c9cdf45265ecb198f11fdc0fee838019f21020272d910596a5202c8074f573d config-baseline.json
22
7ac9eadabe0119deba4418dbaadc478092fa32617fab3f9618e0a14210720e4b config-baseline.core.json
3-
42264b147fb29e0ba7017b4ec018a0793bb9cd23e58bf5fb796d6b33bf9ca829 config-baseline.channel.json
3+
7d3b4153a6eda2e83c32a0063d2ae179d16c3ce1e3b81a74a9b752fe418831ba config-baseline.channel.json
44
df93bfde8e3de8d6f80dbf1b0ae43ad250f216f2fc0244c5d9a19afca50806f6 config-baseline.plugin.json

docs/channels/discord.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,8 +1172,7 @@ Auto-join example:
11721172
discord: {
11731173
voice: {
11741174
enabled: true,
1175-
mode: "stt-tts",
1176-
model: "openai/gpt-5.4-mini",
1175+
model: "openai-codex/gpt-5.5",
11771176
autoJoin: [
11781177
{
11791178
guildId: "123456789012345678",
@@ -1184,12 +1183,10 @@ Auto-join example:
11841183
decryptionFailureTolerance: 24,
11851184
connectTimeoutMs: 30000,
11861185
reconnectGraceMs: 15000,
1187-
tts: {
1186+
realtime: {
11881187
provider: "openai",
1189-
openai: {
1190-
model: "gpt-4o-mini-tts",
1191-
voice: "cedar",
1192-
},
1188+
model: "gpt-realtime-2",
1189+
voice: "cedar",
11931190
},
11941191
},
11951192
},
@@ -1199,10 +1196,11 @@ Auto-join example:
11991196

12001197
Notes:
12011198

1202-
- `voice.tts` overrides `messages.tts` for voice playback only.
1203-
- `voice.mode` controls the conversation path: `stt-tts` keeps the existing batch STT plus TTS flow, `talk-buffer` uses a realtime voice shell for turn timing/transcription/playback while the OpenClaw agent produces the answer, and `bidi` lets the realtime model converse directly while exposing `openclaw_agent_consult` for the OpenClaw brain.
1199+
- `voice.tts` overrides `messages.tts` for `stt-tts` voice playback only. Realtime modes use `voice.realtime.voice`.
1200+
- `voice.mode` controls the conversation path. The default is `agent-proxy`: a realtime voice shell handles turn timing, transcription, interruption, and playback, while the routed OpenClaw agent produces the answer with the same session/tool permissions as a typed Discord prompt from that speaker. `stt-tts` keeps the older batch STT plus TTS flow. `bidi` lets the realtime model converse directly while exposing `openclaw_agent_consult` for the OpenClaw brain.
12041201
- `voice.agentSession` controls which OpenClaw conversation receives voice turns. Leave it unset for the voice channel's own session, or set `{ mode: "target", target: "channel:<text-channel-id>" }` to make the voice channel act as the microphone/speaker extension of an existing Discord text channel session such as `#maintainers`.
12051202
- `voice.model` overrides the OpenClaw agent brain for Discord voice responses and realtime consults. Leave it unset to inherit the routed agent model. It is separate from `voice.realtime.model`.
1203+
- `agent-proxy` routes speech through `discord-voice`, which preserves normal owner/tool authorization for the speaker and target session but hides the agent `tts` tool because Discord voice owns playback.
12061204
- In `stt-tts` mode, STT uses `tools.media.audio`; `voice.model` does not affect transcription.
12071205
- In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.voice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai-codex/gpt-5.5"`.
12081206
- `voice.realtime.bargeIn` controls whether Discord speaker-start events interrupt active realtime playback. If unset, it follows the realtime provider's input-audio interruption setting.
@@ -1234,16 +1232,20 @@ STT plus TTS pipeline:
12341232
- `voice.model`, when set, overrides only the response LLM for this voice-channel turn.
12351233
- `voice.tts` is merged over `messages.tts`; streaming-capable providers feed the player directly, otherwise the resulting audio file is played in the joined channel.
12361234

1237-
Default voice-channel session example:
1235+
Default agent-proxy voice-channel session example:
12381236

12391237
```json5
12401238
{
12411239
channels: {
12421240
discord: {
12431241
voice: {
12441242
enabled: true,
1245-
mode: "stt-tts",
1246-
model: "openai/gpt-5.4-mini",
1243+
model: "openai-codex/gpt-5.5",
1244+
realtime: {
1245+
provider: "openai",
1246+
model: "gpt-realtime-2",
1247+
voice: "cedar",
1248+
},
12471249
},
12481250
},
12491251
},
@@ -1252,20 +1254,22 @@ Default voice-channel session example:
12521254

12531255
With no `voice.agentSession` block, each voice channel gets its own routed OpenClaw session. For example, `/vc join channel:234567890123456789` talks to the session for that Discord voice channel.
12541256

1255-
Realtime talk-buffer example:
1257+
Legacy STT plus TTS example:
12561258

12571259
```json5
12581260
{
12591261
channels: {
12601262
discord: {
12611263
voice: {
12621264
enabled: true,
1263-
mode: "talk-buffer",
1264-
model: "openai-codex/gpt-5.5",
1265-
realtime: {
1265+
mode: "stt-tts",
1266+
model: "openai/gpt-5.4-mini",
1267+
tts: {
12661268
provider: "openai",
1267-
model: "gpt-realtime-2",
1268-
voice: "cedar",
1269+
openai: {
1270+
model: "gpt-4o-mini-tts",
1271+
voice: "cedar",
1272+
},
12691273
},
12701274
},
12711275
},
@@ -1304,7 +1308,7 @@ Voice as an extension of an existing Discord channel session:
13041308
discord: {
13051309
voice: {
13061310
enabled: true,
1307-
mode: "bidi",
1311+
mode: "agent-proxy",
13081312
model: "openai-codex/gpt-5.5",
13091313
agentSession: {
13101314
mode: "target",
@@ -1314,16 +1318,14 @@ Voice as an extension of an existing Discord channel session:
13141318
provider: "openai",
13151319
model: "gpt-realtime-2",
13161320
voice: "cedar",
1317-
toolPolicy: "safe-read-only",
1318-
consultPolicy: "always",
13191321
},
13201322
},
13211323
},
13221324
},
13231325
}
13241326
```
13251327

1326-
In this mode the bot joins the configured voice channel, but OpenClaw agent turns use the target channel's normal routed session and agent. The realtime voice session speaks the returned result back into the voice channel. The supervisor agent can still use normal message tools according to its tool policy, including sending a separate Discord message if that is the right action.
1328+
In `agent-proxy` mode the bot joins the configured voice channel, but OpenClaw agent turns use the target channel's normal routed session and agent. The realtime voice session speaks the returned result back into the voice channel. The supervisor agent can still use normal message tools according to its tool policy, including sending a separate Discord message if that is the right action.
13271329

13281330
Useful target forms:
13291331

docs/cli/infer.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ This table maps common inference tasks to the corresponding infer command.
126126
- `openclaw infer ...` is the primary CLI surface for these workflows.
127127
- Use `--json` when the output will be consumed by another command or script.
128128
- Use `--provider` or `--model provider/model` when a specific backend is required.
129+
- Use `model run --thinking <level>` to pass a one-shot thinking/reasoning level (`off`, `minimal`, `low`, `medium`, `high`, `adaptive`, `xhigh`, or `max`) while keeping the run raw.
129130
- For `image describe`, `audio transcribe`, and `video describe`, `--model` must use the form `<provider/model>`.
130131
- For `image describe`, an explicit `--model` runs that provider/model directly. The model must be image-capable in the model catalog or provider config. `codex/<model>` runs a bounded Codex app-server image-understanding turn; `openai-codex/<model>` uses the OpenAI Codex OAuth provider path.
131132
- Stateless execution commands default to local.
@@ -136,6 +137,7 @@ This table maps common inference tasks to the corresponding infer command.
136137
- `model run --file` rejects non-image inputs. Use `infer audio transcribe` for audio files and `infer video describe` for video files.
137138
- `model run --gateway` exercises Gateway routing, saved auth, provider selection, and the embedded runtime, but still runs as a raw model probe: it sends the supplied prompt and any image attachments without prior session transcript, bootstrap/AGENTS context, context-engine assembly, tools, or bundled MCP servers.
138139
- `model run --gateway --model <provider/model>` requires a trusted operator gateway credential because the request asks the Gateway to run a one-off provider/model override.
140+
- Local `model run --thinking` uses the lean provider-completion path; provider-specific levels such as `adaptive` and `max` are mapped to the closest portable simple-completion level.
139141

140142
## Model
141143

@@ -145,6 +147,7 @@ Use `model` for provider-backed text inference and model/provider inspection.
145147
openclaw infer model run --prompt "Reply with exactly: smoke-ok" --json
146148
openclaw infer model run --prompt "Summarize this changelog entry" --model openai/gpt-5.4 --json
147149
openclaw infer model run --prompt "Describe this image in one sentence" --file ./photo.jpg --model google/gemini-2.5-flash --json
150+
openclaw infer model run --prompt "Use more reasoning here" --thinking high --json
148151
openclaw infer model providers --json
149152
openclaw infer model inspect --name gpt-5.5 --json
150153
```
@@ -157,6 +160,7 @@ openclaw infer model run --local --model anthropic/claude-sonnet-4-6 --prompt "R
157160
openclaw infer model run --local --model cerebras/zai-glm-4.7 --prompt "Reply with exactly: pong" --json
158161
openclaw infer model run --local --model google/gemini-2.5-flash --prompt "Reply with exactly: pong" --json
159162
openclaw infer model run --local --model groq/llama-3.1-8b-instant --prompt "Reply with exactly: pong" --json
163+
openclaw infer model run --local --model mistral/mistral-medium-3-5 --prompt "Reply with exactly: pong" --json
160164
openclaw infer model run --local --model mistral/mistral-small-latest --prompt "Reply with exactly: pong" --json
161165
openclaw infer model run --local --model openai/gpt-4.1 --prompt "Reply with exactly: pong" --json
162166
openclaw infer model run --local --model ollama/qwen2.5vl:7b --prompt "Describe this image." --file ./photo.jpg --json
@@ -165,6 +169,8 @@ openclaw infer model run --local --model ollama/qwen2.5vl:7b --prompt "Describe
165169
Notes:
166170

167171
- Local `model run` is the narrowest CLI smoke for provider/model/auth health because, for non-Codex providers, it sends only the supplied prompt to the selected model.
172+
- Local `model run --model <provider/model>` can use exact bundled static catalog rows from `models list --all` before that provider is written to config. Provider auth is still required; missing credentials fail as auth errors, not `Unknown model`.
173+
- For Mistral Medium 3.5 reasoning probes, leave temperature unset/default. Mistral rejects `reasoning_effort="high"` plus `temperature: 0`; use `mistral/mistral-medium-3-5` with default temperature or a non-zero reasoning-mode value such as `0.7`.
168174
- `openai-codex/*` local probes are the narrow exception: OpenClaw adds a minimal system instruction so the Codex Responses transport can populate its required `instructions` field, without adding full agent context, tools, memory, or session transcript.
169175
- Local `model run --file` keeps that lean path and attaches image content directly to the single user message. Common image files such as PNG, JPEG, and WebP work when their MIME type is detected as `image/*`; unsupported or unrecognized files fail before the provider is called.
170176
- `model run --file` is best when you want to test the selected multimodal text model directly. Use `infer image describe` when you want OpenClaw's image-understanding provider selection and default image-model routing.

docs/gateway/config-agents.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ Time format in system prompt. Default: `auto` (OS preference).
393393
- `params` merge precedence (config): `agents.defaults.params` (global base) is overridden by `agents.defaults.models["provider/model"].params` (per-model), then `agents.list[].params` (matching agent id) overrides by key. See [Prompt Caching](/reference/prompt-caching) for details.
394394
- `params.extra_body`/`params.extraBody`: advanced pass-through JSON merged into `api: "openai-completions"` request bodies for OpenAI-compatible proxies. If it collides with generated request keys, the extra body wins; non-native completions routes still strip OpenAI-only `store` afterward.
395395
- `params.chat_template_kwargs`: vLLM/OpenAI-compatible chat-template arguments merged into top-level `api: "openai-completions"` request bodies. For `vllm/nemotron-3-*` with thinking off, the bundled vLLM plugin automatically sends `enable_thinking: false` and `force_nonempty_content: true`; explicit `chat_template_kwargs` override generated defaults, and `extra_body.chat_template_kwargs` still has final precedence. For vLLM Qwen thinking controls, set `params.qwenThinkingFormat` to `"chat-template"` or `"top-level"` on that model entry.
396+
- `compat.thinkingFormat`: OpenAI-compatible thinking payload style. Use `"qwen"` for Qwen-style top-level `enable_thinking`, or `"qwen-chat-template"` for `chat_template_kwargs.enable_thinking` on Qwen-family backends that support request-level chat-template kwargs, such as vLLM. OpenClaw maps disabled thinking to `false` and enabled thinking to `true`.
396397
- `compat.supportedReasoningEfforts`: per-model OpenAI-compatible reasoning effort list. Include `"xhigh"` for custom endpoints that truly accept it; OpenClaw then exposes `/think xhigh` in command menus, Gateway session rows, session patch validation, agent CLI validation, and `llm-task` validation for that configured provider/model. Use `compat.reasoningEffortMap` when the backend wants a provider-specific value for a canonical level.
397398
- `params.preserveThinking`: Z.AI-only opt-in for preserved thinking. When enabled and thinking is on, OpenClaw sends `thinking.clear_thinking: false` and replays prior `reasoning_content`; see [Z.AI thinking and preserved thinking](/providers/zai#thinking-and-preserved-thinking).
398399
- Runtime policy belongs on providers or models, not on `agents.defaults`. Use `models.providers.<provider>.agentRuntime` for provider-wide rules or `agents.defaults.models["provider/model"].agentRuntime` / `agents.list[].models["provider/model"].agentRuntime` for model-specific rules. OpenAI agent models on the official OpenAI provider select Codex by default.
@@ -1378,6 +1379,8 @@ Defaults for Talk mode (macOS/iOS/Android).
13781379
},
13791380
system: {},
13801381
},
1382+
consultThinkingLevel: "low",
1383+
consultFastMode: true,
13811384
speechLocale: "ru-RU",
13821385
silenceTimeoutMs: 1500,
13831386
interruptOnSpeech: true,
@@ -1405,6 +1408,8 @@ Defaults for Talk mode (macOS/iOS/Android).
14051408
- `providers.*.voiceAliases` lets Talk directives use friendly names.
14061409
- `providers.mlx.modelId` selects the Hugging Face repo used by the macOS local MLX helper. If omitted, macOS uses `mlx-community/Soprano-80M-bf16`.
14071410
- macOS MLX playback runs through the bundled `openclaw-mlx-tts` helper when present, or an executable on `PATH`; `OPENCLAW_MLX_TTS_BIN` overrides the helper path for development.
1411+
- `consultThinkingLevel` controls the thinking level for the full OpenClaw agent run behind Control UI Talk realtime `openclaw_agent_consult` calls. Leave unset to preserve normal session/model behavior.
1412+
- `consultFastMode` sets a one-shot fast-mode override for Control UI Talk realtime consults without changing the session's normal fast-mode setting.
14081413
- `speechLocale` sets the BCP 47 locale id used by iOS/macOS Talk speech recognition. Leave unset to use the device default.
14091414
- `silenceTimeoutMs` controls how long Talk mode waits after user silence before it sends the transcript. Unset keeps the platform default pause window (`700 ms on macOS and Android, 900 ms on iOS`).
14101415

docs/gateway/config-tools.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ OpenClaw uses the built-in model catalog. Add custom providers via `models.provi
474474
- `models.providers.*.models.*.contextTokens`: optional runtime context cap. This overrides provider-level `contextTokens`; use it when you want a smaller effective context budget than the model's native `contextWindow`; `openclaw models list` shows both values when they differ.
475475
- `models.providers.*.models.*.compat.supportsDeveloperRole`: optional compatibility hint. For `api: "openai-completions"` with a non-empty non-native `baseUrl` (host not `api.openai.com`), OpenClaw forces this to `false` at runtime. Empty/omitted `baseUrl` keeps default OpenAI behavior.
476476
- `models.providers.*.models.*.compat.requiresStringContent`: optional compatibility hint for string-only OpenAI-compatible chat endpoints. When `true`, OpenClaw flattens pure text `messages[].content` arrays into plain strings before sending the request.
477+
- `models.providers.*.models.*.compat.thinkingFormat`: optional thinking payload hint. Use `"qwen"` for top-level `enable_thinking`, or `"qwen-chat-template"` for `chat_template_kwargs.enable_thinking` on Qwen-family OpenAI-compatible servers that support request-level chat-template kwargs, such as vLLM.
477478

478479
</Accordion>
479480
<Accordion title="Amazon Bedrock discovery">

docs/gateway/configuration-reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Moved to a dedicated page - see
4848
- `session.*` (session lifecycle, compaction, pruning)
4949
- `messages.*` (message delivery, TTS, markdown rendering)
5050
- `talk.*` (Talk mode)
51+
- `talk.consultThinkingLevel`: thinking level override for the full OpenClaw agent run behind Control UI Talk realtime consults
52+
- `talk.consultFastMode`: one-shot fast-mode override for Control UI Talk realtime consults
5153
- `talk.speechLocale`: optional BCP 47 locale id for Talk speech recognition on iOS/macOS
5254
- `talk.silenceTimeoutMs`: when unset, Talk keeps the platform default pause window before sending the transcript (`700 ms on macOS and Android, 900 ms on iOS`)
5355

0 commit comments

Comments
 (0)