返回 DeepSeek-Reasonix
GUIDE.md
根目录 / docs / GUIDE.md
1 # Reasonix Guide
2
3 Provider model capability metadata is documented in
4 [`MODEL_CAPABILITIES.md`](./MODEL_CAPABILITIES.md).
5
6 <a href="../README.md">README</a>
7 &nbsp;·&nbsp;
8 <a href="./GUIDE.zh-CN.md">简体中文</a>
9 &nbsp;·&nbsp;
10 <a href="./SPEC.md">Spec</a>
11
12 > Day-to-day configuration and usage. For the engineering contract and internals
13 > (data types, registries, package layout, roadmap), see the **[Spec](./SPEC.md)**.
14
15 ## Contents
16
17 - [Configuration](#configuration)
18 - [Billing and display currency](./BILLING.md)
19 - [CLI reference](./CLI.md)
20 - [Environment variables](#environment-variables)
21 - [Web frontend](#web-frontend)
22 - [Configuration paths](./CONFIG_PATHS.md)
23 - [Reasoning language](./REASONING_LANGUAGE.md)
24 - [Task contracts and pause policy](./TASK_CONTRACT.md)
25 - [Custom OpenAI-compatible providers](#custom-openai-compatible-providers)
26 - [Desktop hooks](#desktop-hooks)
27 - [Keyboard shortcuts](#keyboard-shortcuts)
28 - [Permissions & sandbox](#permissions--sandbox)
29 - [File deliverables and the `present` tool](./PRESENT_TOOL.md)
30 - [Capability diagnostics](#capability-diagnostics)
31 - [Plugins (MCP)](#plugins-mcp)
32 - [Slash commands](#slash-commands)
33 - [Embedded documentation retrieval](#embedded-documentation-retrieval)
34 - [@ references](#-references)
35 - [Two-model collaboration](#two-model-collaboration)
36
37 ## Configuration
38
39 Resolution order: **flag > `./reasonix.toml` > the user config file >
40 built-in defaults**. Starting with **Reasonix v1.8.1**, the user config lives at
41 `~/.reasonix/config.toml` on macOS/Linux and
42 `%AppData%\reasonix\config.toml` on Windows; see
43 [Configuration paths](./CONFIG_PATHS.md) for migration and related data paths.
44 Fields marked user/global only are not overridden by `./reasonix.toml`.
45 Provider entries name secrets with `api_key_env`, while the secret values live in
46 Reasonix's global `<Reasonix home>/.env`, shared by CLI and desktop. Project
47 `.env`, home `.env`, inherited shell environment variables, legacy credentials,
48 and the OS keyring are not provider-key runtime fallbacks; legacy credentials are
49 only migration sources. Project `.env` still feeds workspace-scoped,
50 non-provider `${VAR}` expansion for MCP/plugin settings without importing
51 provider keys or Reasonix control variables. See
52 [Configuration paths](./CONFIG_PATHS.md) for the full `config.toml` and `.env`
53 structure.
54
55 For the desktop and CLI usage of visible reasoning language, see
56 [Reasoning language](./REASONING_LANGUAGE.md).
57
58 ```toml
59 default_model = "deepseek-flash" # executor; set [agent].planner_model to add a planner
60 # language = "zh" # ui language; empty = auto-detect from $LANG / $REASONIX_LANG
61
62 [ui]
63 # shortcut_layout = "desktop" # classic|desktop; compatibility setting
64 # cursor_shape = "bar" # block|underline|bar; CLI/TUI text cursor
65 show_turn_usage = false # hide per-request token/cost receipts in the TUI; default true
66
67 [agent]
68 reasoning_language = "auto" # visible reasoning text: auto|zh|en
69 # plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash now uses Permissions
70 # planner_model = "deepseek-pro" # optional low-frequency planner
71 # subagent_model = "deepseek-pro" # optional default for runAs=subagent skills
72 # subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" }
73 # max_subagent_depth = 2 # nested delegation depth; set 1 for the old single-layer boundary
74 # max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills)
75 # max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths
76 # compact_ratio = 0.80 # sole auto trigger; presets 0.70 / 0.80 / 0.85
77 # max_output_tokens = 0 # auto: official DeepSeek omits the field (server 384K) until the window is tight
78 # max_output_tokens = 32768 # optional cost cap; still clipped to physical remaining
79 # max_output_tokens = 65536 # optional cost cap
80 # max_output_tokens = -1 # force-omit the wire field; compact if the known auto budget no longer fits
81 # max_output_tokens never changes compact_ratio; 0 is the provider auto value, not "skip local checks"
82
83 [[providers]]
84 name = "deepseek-flash"
85 kind = "anthropic"
86 base_url = "https://api.deepseek.com/anthropic"
87 model = "deepseek-v4-flash"
88 api_key_env = "DEEPSEEK_API_KEY"
89 web_search = true
90 # also preset: deepseek-pro
91
92 [tools]
93 enabled = [] # omit/empty = all built-ins
94 bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap
95 mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap
96 mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it
97
98 [environment]
99 enabled = true # inject a stable startup summary of OS, shell, and common tools
100 offline = false # set true when outbound network access is unavailable; prevents futile retries
101 # [environment.tools]
102 # go = "/opt/homebrew/bin/go" # optional explicit trusted path; workspace-local paths are not auto-executed
103
104 [skills]
105 # paths = ["~/my-skills", "../shared/skills"] # extra custom skill roots
106 # excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders
107 # disabled_skills = ["review"] # hide skills until /skill enable <name>
108
109 [permissions]
110 mode = "ask" # writer fallback when no rule matches: ask|allow|deny
111 deny = ["Bash(rm -rf*)", "Bash(git push*)"] # hard-blocked in every mode
112 allow = ["Bash(go test:*)"] # never prompted
113
114 [sandbox]
115 # workspace_root = "" # file-writers confined here; empty = current dir
116 # allow_write = ["/tmp"] # extra dirs write_file/edit_file/multi_edit/move_file may touch
117 # forbid_read = ["${HOME}/.ssh"] # paths the agent must not read or list
118
119 [serve]
120 auth_mode = "none" # none|token|password; use auth before binding beyond localhost
121 # token = "" # optional fixed token; empty token mode generates one at startup
122 # password_hash = "" # bcrypt hash generated with reasonix serve --hash-password --password '...'
123 # behind_proxy = false # true only behind a trusted reverse proxy
124
125 [[plugins]]
126 name = "example"
127 command = "reasonix-plugin-example"
128 startup_timeout_seconds = 60 # optional initialize + tools/list cap
129 call_timeout_seconds = 600 # optional per-server MCP call timeout
130 tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
131 ```
132
133 For the full schema and every field's contract, see [`SPEC.md` §5](./SPEC.md#5-configuration-toml).
134
135 Installed and project-configured MCP servers need no per-tool trust
136 list. The dedicated two-model Planner may use every non-destructive MCP tool,
137 even when the server omits `readOnlyHint`; strict read-only sub-agents still
138 require `readOnlyHint: true` and no `destructiveHint`.
139
140 `[agent].plan_mode_read_only_commands` is also retained for config round trips,
141 but the main Plan workflow no longer has a separate bash allowlist or trust
142 prompt. Bash classification and approval use the same Permissions rules in Plan
143 and Standard mode; the Sandbox remains the filesystem, process, and network
144 boundary. Dedicated planner and read-only subagent runners keep their own strict
145 read-only tool registry and foreground-command classifier.
146
147 ### Environment variables
148
149 Most day-to-day settings belong in `config.toml` or the global Reasonix `.env`
150 described above. The variables below are process-level advanced switches; set
151 them before launching Reasonix. Project `.env` files are not a runtime source for
152 Reasonix control variables.
153
154 ### CLI telemetry
155
156 The CLI can send a once-per-day anonymous active-install ping and bounded,
157 content-free event counters to `https://crash.reasonix.io`. Configure the
158 user-global policy with:
159
160 ```bash
161 reasonix config telemetry # print the effective mode
162 reasonix config telemetry auto # default: local interactive TTY only
163 reasonix config telemetry on # also allow local headless `reasonix run`
164 reasonix config telemetry off # disable and delete pending counter files
165 ```
166
167 On the first eligible release-build interactive session, Reasonix explains the
168 exact data boundary and asks once before any telemetry request. The prompt is
169 `[Y/n]`: pressing Enter, `y`, or `yes` stores `auto`; `n` or `no` stores `off`
170 and deletes pending counters. After the choice is saved, enabled reporting is
171 silent and the prompt is not shown again. If the preference cannot be saved,
172 nothing is uploaded.
173
174 Reporting is always disabled in CI, development builds, and when
175 `DO_NOT_TRACK` is set or `REASONIX_TELEMETRY=0`. Under `auto`, redirected/piped
176 or otherwise non-interactive sessions do not report. When no choice has been
177 saved yet, these ineligible sessions neither prompt nor report. Network failures
178 after consent are silent and never change stdout, stderr, or the process exit
179 code; unsent counters stay in a bounded local queue for a later invocation.
180
181 The ping contains a dedicated random 128-bit CLI install ID, CLI version, OS,
182 architecture, and the `cli` surface marker. Counter batches use that same ID for
183 daily active-install deduplication and contain only fixed buckets such as CLI
184 surface, permission/session mode, turn latency, finish reason, cache-hit
185 range, generic Provider/tool error class, compaction, recovery counters, and
186 normalized UI language. This ID is separate from the desktop install ID and is
187 not an account, hardware, repository, or session identifier.
188
189 Reasonix never uploads prompts, answers, reasoning, tool names/arguments/output,
190 paths, repositories/branches, session IDs, exact token or cost values,
191 Provider/model names, base URLs, or environment variables.
192
193 ### CLI crash reports
194
195 An unhandled Go panic that reaches the CLI entrypoint is saved locally as a sanitized report under
196 `<Reasonix home>/cli-crash-reports`. Reasonix keeps at most 10 files with owner-only
197 permissions. The panic value is never serialized. Absolute source paths become
198 `<path>/<file>.go:<line>`, function arguments are removed, and the same secret,
199 token, email, and long-identifier scrubbers run both when saving and immediately
200 before sending.
201
202 Crash reports are never uploaded automatically. Review and manage them with:
203
204 ```bash
205 reasonix report # preview newest; prompt before sending on a TTY
206 reasonix report list # list local reports
207 reasonix report show [ID] # preview without sending
208 reasonix report send [ID] # explicit send; delete locally only after success
209 reasonix report delete [ID] # delete without sending
210 ```
211
212 Piped or redirected `reasonix report` calls only preview and never prompt or
213 send. The CLI telemetry setting does not auto-send or auto-delete
214 these separately reviewed reports. Runtime fatal throws, operating-system kills,
215 and panics in unwrapped background goroutines cannot be recovered by Go and do
216 not produce this local report.
217
218 ## Web frontend
219
220 For local use, `reasonix web` starts the browser UI and opens it in your default
221 browser. Inside an interactive CLI session, `/web` snapshots the current session,
222 restores the terminal, and opens an explicit `/sessions/<id>#token=...` deep link.
223 Even a never-used session keeps its reserved ID without forcing an empty
224 transcript onto disk, so the first Web turn continues the same session identity.
225
226 ```bash
227 cd your-project
228 reasonix web
229 ```
230
231 Use `reasonix web --no-open` when you want to start the foreground Web server
232 and print its URL without opening a browser tab. The lower-level
233 `reasonix serve` command starts the same engine without opening a browser by
234 default. It remains the right entry point for remote development boxes,
235 supervisors, tunnels, reverse proxies, and shareable authenticated sessions.
236
237 `reasonix web` starts at `127.0.0.1:8787`, automatically tries 8788, 8789, and
238 so on when a port is busy (up to 100 retries), and defaults to a newly generated
239 token even when `[serve].auth_mode` is `none`. Each live process registers a
240 single-writer heartbeat file under `<Reasonix home>/server/instances/`; clean
241 shutdown removes its own file, while later instances lazily remove records whose
242 owner process is confirmed dead. Multiple Web instances can therefore share one
243 Reasonix home without overwriting registry state. The process stays attached to
244 the terminal; stop it with Ctrl-C.
245
246 An explicit `reasonix web --auth none` disables the default token and should be
247 used only when the listener is intentionally trusted. `reasonix serve` keeps its
248 backward-compatible, config-driven `auth_mode = "none"` default on
249 `127.0.0.1:8787`. If you bind Serve outside loopback, expose it through a tunnel,
250 or put it behind a reverse proxy, enable authentication before sharing the URL:
251
252 ```bash
253 reasonix serve --auth token
254 reasonix serve --addr 0.0.0.0:8787 --auth token
255 reasonix serve --auth password --password 'temporary-password'
256 ```
257
258 Token mode prints a share URL with `#token=...`; the Web page exchanges the
259 fragment for an HttpOnly cookie before starting API or SSE requests, keeping the
260 token out of request URLs, browser history, referrers, and access logs. Pass `--token` or set
261 `[serve].token` to reuse a stable token. Password mode requires either
262 `--password` at startup or a stored bcrypt hash:
263
264 ```bash
265 reasonix serve --hash-password --password 'strong-password'
266
267 # <Reasonix home>/config.toml
268 [serve]
269 auth_mode = "password" # none|token|password
270 password_hash = "$2a$12$..."
271 behind_proxy = true # only behind a trusted reverse proxy
272 ```
273
274 The web UI exposes chat, tool approvals, session history, rewind/fork/summarize,
275 model and reasoning-effort controls, Goal, a live todo panel fed by the
276 `todo_write` tool, extension status/card/form/notification surfaces, and
277 provider balance when configured. Extension-hosted providers appear in the
278 model picker. Serve can keep several sessions active at once: creating or
279 resuming another session detaches a busy turn instead of cancelling it, and the
280 session list continues to report that background activity. Run `/reload` while
281 idle to fail-atomically reload extension sidecars and the runtime generation
282 without restarting Serve. Use `--model`, `--max-steps`, or `--resume` for
283 one-off launches; otherwise `serve` uses the user-global `default_model`.
284
285 If the selected Provider has no saved API key, a loopback-bound Serve still
286 starts and shows a Provider setup page instead of failing before the browser can
287 connect. After authentication, enter the key there; Reasonix writes it to this
288 host's global credential file with restricted permissions, rebuilds the active
289 controller in the same process, and opens the normal UI. The credential-writing
290 endpoint is disabled for non-loopback listeners. For a remote SSH window,
291 "this host" means the remote host reached through the SSH tunnel; the key is
292 not copied from the desktop machine.
293
294 ## Editor integrations over ACP
295
296 `reasonix acp` exposes Reasonix as an ACP v1 stdio agent for editors and other
297 host clients. The dedicated **[ACP editor integration](./ACP.md)** guide covers
298 startup, capability negotiation, session lifecycle, independent model/work/
299 collaboration/approval controls, client filesystem and terminal capabilities,
300 MCP servers, permission requests, and the Reasonix mid-turn steering extension.
301
302 ## Remote SSH
303
304 The remote module runs Reasonix on a remote host and reaches it over your own
305 SSH connection — VS Code Remote-SSH style. It bootstraps a persistent headless
306 `reasonix serve` on the remote host, forwards a local loopback port to it, and
307 opens the existing serve web client through that tunnel. The agent, its tools,
308 and its files all live on the remote host at full fidelity; nothing runs through
309 a lossy file proxy. V1 supports Linux and macOS remote hosts.
310
311 The dedicated **[Remote sessions](./REMOTE_SESSIONS.md)** guide covers host
312 configuration (`[remote]` in `config.toml`), SSH-config resolution and import,
313 the `reasonix remote` CLI, the remote serve bootstrap and its install ladder,
314 the remote session lifecycle and takeover, the desktop remote workspace, the
315 `remote` and `local-proxy` credential modes, connection failure semantics, and
316 troubleshooting.
317
318 ## Custom OpenAI-compatible providers
319
320 In the desktop app, open **Settings -> Model -> Access -> Add model service ->
321 Custom provider** for proxies, aggregators, or self-hosted services that speak
322 the OpenAI-compatible chat API or Anthropic-compatible Messages API.
323
324 For common providers, choose **Add model service -> Recommended preset** instead.
325 New official DeepSeek entries use the Anthropic-compatible Messages endpoint by
326 default and enable provider-side `web_search`; the same `DEEPSEEK_API_KEY` works
327 for both protocols. On startup, Reasonix upgrades unmodified legacy
328 `deepseek-flash` / `deepseek-pro` entries that still use the official endpoint
329 and standard key/model settings. Customized official Chat Completions entries
330 stay unchanged and show an **Upgrade protocol** action in Settings. Proxy
331 endpoints, custom headers, model lists, and capability overrides are never
332 migrated automatically. Existing
333 separately named `deepseek-anthropic` entries remain compatible, but that
334 redundant preset is no longer offered for new access. Reasonix can prefill editable custom-provider entries for Kimi CN,
335 Kimi Global,
336 Kimi Coding Plan, MiMo API, MiMo Anthropic, MiMo Token Plan CN/SGP/AMS and their
337 Anthropic-compatible variants, MiniMax CN/Global API, MiniMax CN/Global
338 Anthropic, GLM CN, Z.AI Global, GLM/Z.AI Coding Plan OpenAI-compatible and
339 Anthropic-compatible endpoints, OpenCode Go, OpenCode Go Anthropic, OpenCode Go
340 DeepSeek Anthropic, OpenCode Go DeepSeek Responses, OpenCode Zen
341 Anthropic, Qwen/DashScope CN/Global, Qwen Coding Plan CN/Global
342 OpenAI-compatible and Anthropic-compatible endpoints, StepFun OpenAI-compatible
343 and Anthropic-compatible endpoints, NovitaAI, GMI Cloud, Vercel AI Gateway,
344 HuggingFace Router, ModelScope, NVIDIA NIM, KiloCode, and Ollama Cloud. Plan names describe
345 the access/payment route; they include CN/Global only when the provider exposes
346 distinct regional endpoints. Kimi Coding Plan is therefore a dedicated plan
347 endpoint, while Kimi direct API is split into CN and Global. The preset path
348 usually needs only the provider API key: the key value is stored in Reasonix home
349 `.env`, while `config.toml` stores the endpoint, model list, key
350 environment-variable name, context window, model capability metadata, proxy bypass
351 for China-only endpoints, MiniMax `reasoning_split`, GLM/MiniMax thinking
352 heuristics, Anthropic-compatible Bearer auth where needed, Ollama Cloud
353 max-effort support, and OpenCode Go per-model reasoning overrides. Official DeepSeek Anthropic, Responses, and Chat Completions catalogs also
354 include the multimodal SKUs `deepseek-flash` and `deepseek-v4-flash-vision-exp`. Settings derives image support from
355 model capability metadata. Each model also has an Image input Auto / On / Off
356 selector. For an ID-only relay list, unknown means unrecognized, not confirmed
357 text-only: select On after confirming support with the relay, then save. See the
358 [image input guide](MODEL_CAPABILITIES.md#set-image-input-for-a-relay-model).
359 Composer
360 and `@` user images are sent as official visual input using the three documented
361 shapes: inline base64 `data:` URLs for local files, `http(s)` image URLs as-is,
362 and Files API `file-api-` ids (local images over 32 MiB on official DeepSeek are
363 uploaded automatically). Chat Completions uses `image_url` or `file`, Anthropic
364 uses `image`+`source.base64|url|file`, and Responses uses `input_image`.
365 Flash and Pro stay text-only on the wire even when legacy configuration lists them, and tool screenshots
366 are not forwarded as image parts. The vision SKU uses the Flash rate card. The dedicated
367 OpenCode Go DeepSeek Anthropic and DeepSeek Responses presets expose the verified
368 Flash routes and enable provider-side `web_search` by default; the Responses
369 variant uses stateless context replay. The existing mixed OpenCode Go Anthropic
370 preset remains scoped to Qwen and MiniMax so server tools are not sent to
371 unverified models. DeepSeek Pro remains on the Chat Completions preset because
372 live Anthropic and Responses requests currently fail in the OpenCode Go upstream
373 conversion. The OpenCode Go preset includes its native `kimi-k3` subscription
374 route with image input,
375 `high`/`max` reasoning effort, and a 1,048,576-token context window. Existing untouched
376 OpenCode Go preset installs are upgraded automatically; edited model catalogs
377 are preserved. The Kimi CN and Kimi Global direct-API presets also include
378 `kimi-k3` with image input, a 1,048,576-token context window, and the official
379 `low`/`high`/`max` effort scale (default `max`). For the official K3 endpoints,
380 Reasonix preserves complete assistant messages across turns, sends output limits
381 as `max_completion_tokens`, and omits K3's fixed sampling parameters. Untouched
382 legacy Kimi direct-API catalogs are upgraded automatically without changing the
383 default model; custom catalogs and endpoints are preserved. After adding a
384 preset, open its provider card if you need to change models, headers, endpoint,
385 or compatibility settings.
386
387 Fill **API address** with the provider endpoint that should receive the standard
388 chat path. In this mode Reasonix previews and sends chat requests to:
389
390 ```text
391 <API address>/chat/completions
392 ```
393
394 Enable **Full URL** when the service gives you a complete request URL, for
395 example `https://gateway.example.com/v1/chat/completions`. Reasonix then sends
396 chat requests directly to that URL and does not append `/chat/completions`. The
397 preview under the field shows the exact request URL that will be used.
398
399 Model discovery uses the API address to try likely model-list URLs such as
400 `/models` and `/v1/models`. If the gateway requires a separate model-list
401 endpoint, open **Compatibility settings** and set `models_url`, for example
402 `https://gateway.example.com/v1/models`. If discovery is not available, fill the
403 model list manually.
404
405 **Full URL** still uses the OpenAI-compatible chat request body. It does not
406 switch the request schema to the OpenAI Responses API.
407
408 ### Compatibility settings
409
410 The **Compatibility settings (usually leave unchanged)** section is for gateways
411 whose authentication, model-list endpoint, or reasoning/thinking request shape
412 differs from the normal OpenAI-compatible defaults. Leave these fields at their
413 defaults unless the provider documentation or a proxy error tells you otherwise.
414 For Anthropic-compatible services, such as some coding-plan endpoints, choose
415 **Anthropic-compatible** as the connection protocol before saving.
416
417 | Field | What it controls | When to change it |
418 | --- | --- | --- |
419 | `api_key_env` | The environment-variable name used for this provider's API key. Desktop-saved key values are stored in Reasonix home `.env` under this name; the TOML config stores only the name. | Change it when several providers need distinct keys, or leave it blank for a service that does not require an API key. |
420 | `models_url` | The URL used only for model discovery. Chat requests still use the API address or Full URL above. | Set it when `/models` or `/v1/models` is not where the gateway exposes its model list. |
421 | Extra request headers | Static HTTP headers, one `Header: value` per line. | Use for gateways such as OpenRouter that require `HTTP-Referer`, `X-Title`, or similar site headers. Keep bearer/API keys in the key field instead of duplicating them here. |
422 | Extra request body | A JSON object merged into the top-level chat request body. | Use only for provider-specific flags such as `{"enable_thinking": true}`. Reasonix still owns core fields such as `model`, `messages`, `tools`, `stream`, and `thinking`, and null values are rejected. |
423 | Authorization: Bearer | For Anthropic-compatible providers, sends the saved API key as `Authorization: Bearer <key>` instead of `x-api-key`. | Enable it only when the gateway documents Bearer auth, such as MiniMax Global or Vercel AI Gateway. |
424 | Model capability mode | Which reasoning request protocol Reasonix should use for this provider. | Keep **Auto-detect** unless the gateway is misdetected or the model docs require a specific reasoning format. |
425 | Thinking override | Provider-specific override for `thinking.type`. | Keep **Auto** unless the backend documents `enabled`, `disabled`, or `adaptive`. Unsupported values can make some OpenAI-compatible gateways reject the request. |
426 | Balance URL | Optional endpoint for wallet/balance lookup. | Set it when the provider exposes a balance endpoint and you want the desktop status bar to show it. |
427 | Context window | The provider-wide token budget Reasonix uses for automatic context cleanup. `0` disables automatic compaction. | Set it to the provider's model context limit; use a per-model override below when selected models differ. |
428
429 Each selected model also has an optional **Context window** input. Leave it blank
430 to inherit the provider-wide value, or enter a positive token count to override
431 that value for this model. This avoids premature compaction for long-context
432 models and provider errors for shorter-context models sharing the same endpoint.
433 Use the context-window limit from the model documentation, not the maximum output
434 tokens. For example, 128K commonly means `128000`; if the provider documents
435 `131072`, use that exact value. Values below 16384 show a non-blocking warning
436 because they can trigger frequent compaction and reduce cache hit rates.
437
438 Model capability mode options:
439
440 | Option | Effect |
441 | --- | --- |
442 | Auto-detect (recommended) | Reasonix chooses the request shape from model capability metadata and endpoint detection. |
443 | DeepSeek thinking | Uses DeepSeek-style thinking control, including `thinking.type` and DeepSeek-supported reasoning depth. |
444 | OpenAI reasoning | Uses the standard OpenAI-compatible `reasoning_effort` levels. |
445 | Plain chat | Sends no reasoning or thinking control fields. Use this for text-only proxies that reject reasoning parameters. |
446
447 Thinking override options:
448
449 | Option | Effect |
450 | --- | --- |
451 | Auto (provider default) | Does not write an explicit provider-level `thinking` override. Reasonix uses the provider/model default behavior. |
452 | Enabled | Sends `thinking.type = "enabled"` for compatible providers. |
453 | Disabled | Sends `thinking.type = "disabled"` for compatible providers. On DeepSeek-style providers this also avoids sending a reasoning depth hint. |
454 | Adaptive (self-adjusting) | Sends or preserves `thinking.type = "adaptive"` only for providers that document adaptive thinking, such as MiniMax-M3-style endpoints. |
455
456 Some OpenAI-compatible gateways require non-standard top-level request body
457 fields. Add them with `extra_body` on the provider entry:
458
459 ```toml
460 [[providers]]
461 name = "spark"
462 kind = "openai"
463 base_url = "https://maas-coding-api.cn-huabei-1.xf-yun.com/v2"
464 models = ["xopglm52"]
465 api_key_env = "SPARK_API_KEY"
466 extra_body = { enable_thinking = true }
467 ```
468
469 `extra_body` is merged into the chat JSON request body. Reasonix keeps core
470 fields such as `model`, `messages`, `tools`, `stream`, and `thinking` under its
471 own control.
472
473 ## Desktop hooks
474
475 Desktop hooks run local commands at lifecycle events such as `SessionStart`,
476 `UserPromptSubmit`, `PreToolUse`, and `PreCompact`. A successful `SessionStart`
477 hook may write plain text to stdout, or return JSON with
478 `hookSpecificOutput.additionalContext`; Reasonix injects that text once into the
479 next real user turn as `<hook-context event="SessionStart">...</hook-context>`.
480 This is intended for plugin or workflow bootstrap context, including
481 Superpowers-style startup instructions, without baking that workflow into
482 Reasonix's system prompt.
483
484 Plugin packages can provide this startup context through
485 `hooks/session-start-codex` or a plugin-root `CLAUDE.md`. Claude-style
486 `.claude/settings.json` command hooks are also mapped to matching Reasonix hook
487 events.
488
489 The injected hook context is dynamic current-turn context. It does not change
490 the stable system prompt, memory prefix, or tool schema, though dynamic content
491 can still reduce cache reuse for that turn. The detailed desktop hook schema and
492 loading model are documented in [the Chinese desktop hooks guide](./DESKTOP_HOOKS.zh-CN.md).
493
494 ## Keyboard shortcuts
495
496 Shortcuts are documented by client because users usually look for the keys that
497 work in the surface they are using. On Desktop, `Shift+Tab` toggles Plan and
498 permission presets stay in the composer menu. In the CLI, `Shift+Tab` cycles
499 Read only → Workspace write → YOLO → Plan, while `Ctrl+Y` toggles YOLO
500 directly. YOLO is the visible label for the canonical `danger-full-access`
501 permission preset. Desktop paste stays on the platform paste key; in the CLI,
502 terminal-native text paste and application-owned image paste use separate shortcuts.
503
504 `[ui].shortcut_layout` is still accepted for old configs, but the shortcut
505 behavior below is unified across layouts.
506
507 For CLI/TUI text input, `[ui].cursor_shape` accepts `underline`, `block`, or
508 `bar`. The default is `bar`: it remains easy to locate without covering
509 double-width CJK characters in mixed-language input. Set it to `block` for a
510 traditional terminal cursor or `underline` for a lower-profile cursor. This
511 setting does not change desktop or web text fields.
512
513 ### Desktop GUI
514
515 The Desktop Todo shelf derives its label from both `todo_write` and the owning
516 tab's runtime: active work is **In progress**, an approval or question is
517 **Waiting for input**, and an idle/restored current item is **Ready to continue**.
518 The latter exposes a **Continue** action that rechecks the captured tab before
519 sending, so a rapid tab switch cannot route stale work into another session.
520
521 Desktop shortcuts are managed from **Settings → Shortcuts**. Pick a configurable
522 row, press a new key combination, and Reasonix saves it for the desktop app.
523 Standard editing shortcuts such as Undo and Redo are shown as locked rows because
524 the WebView's native text history uses those platform chords. Conflicting
525 bindings are rejected so one shortcut never triggers two actions. Press `?` or
526 use the help button in the topic bar to open the shortcuts sheet; it is generated
527 from the same shortcut registry, so it reflects any custom bindings.
528
529 Global shortcuts:
530
531 | Key or control | What it does | Notes |
532 | --- | --- | --- |
533 | `Cmd+K` on macOS, `Ctrl+K` on Windows/Linux | Toggles the command palette | The palette focuses search when it opens; `Esc` closes it. |
534 | `Cmd+,` on macOS, `Ctrl+,` on Windows/Linux | Opens Settings | Use **Shortcuts** in Settings to customize desktop bindings. |
535 | `Cmd+W` on macOS, `Ctrl+W` on Windows/Linux | Closes the active top tab | The last tab is kept by the normal close-tab guard. |
536 | `Cmd+B` / `Ctrl+B` | Shows or hides the left sidebar | Same action as clicking the sidebar toggle. |
537 | `Cmd+Shift+B` / `Ctrl+Shift+B` | Expands or collapses the most recent shell output | Same action as clicking the collapsed shell-output hint. |
538 | `Cmd+1`-`Cmd+9` on macOS, `Ctrl+1`-`Ctrl+9` elsewhere | Jumps to the matching visible chat in the sidebar | Hold `Cmd`/`Ctrl` briefly to reveal the numbered badges. Existing custom shortcuts that already use the same key take precedence. |
539 | `Cmd++`, `Cmd+-`, `Cmd+0` on macOS; `Ctrl++`, `Ctrl+-`, `Ctrl+0` elsewhere | Increases, decreases, or resets text size | `=` is accepted for the plus key on keyboards that report it that way. |
540 | `?` | Opens the keyboard shortcuts sheet | The sheet shows the current effective desktop bindings. |
541
542 Composer shortcuts:
543
544 | Key or control | What it does | Notes |
545 | --- | --- | --- |
546 | `Enter` | Sends the current message | IME composition confirmation is left alone. |
547 | `Shift+Enter` | Inserts a newline | The composer keeps focus. |
548 | `Shift+Tab` | Toggles Plan on/off | Plan changes the workflow instruction while the selected permission preset remains active. |
549 | `Cmd+Z` on macOS, `Ctrl+Z` on Windows/Linux | Undoes the latest composer edit | Native typing stays in the WebView history; Reasonix-managed paste, cut, folded blocks, and structured tokens are restored as complete transactions. |
550 | `Cmd+Shift+Z` on macOS, `Ctrl+Shift+Z` on Windows/Linux | Redoes the latest composer edit | Uses the platform-native editing history. |
551 | `Cmd+V` on macOS, `Ctrl+V` on Windows/Linux | Pastes clipboard content | Clipboard images are attached; images can also be dropped into the composer. On official DeepSeek, `deepseek-flash` and `deepseek-v4-flash` accept images natively; V4 Pro stays text-only. |
552 | Plain `Up` / `Down` at the prompt boundary | Recalls older or newer submitted prompts | Modified arrows and native text navigation stay with the textarea. |
553 | `Esc` while a turn is running | Cancels the running turn | If the turn has not produced a response yet, the draft is restored. |
554
555 Menus and controls:
556
557 | Key or control | What it does | Notes |
558 | --- | --- | --- |
559 | `Up` / `Down` in slash, `@`, or past-chat menus | Moves the highlighted item | Past-chat search uses the same navigation keys. |
560 | `Enter` / `Tab` in those menus | Accepts the highlighted item | Directory-like entries can keep the menu open for the next level. |
561 | `Esc` in those menus | Closes the current menu or returns from past-chat search | Regular typing continues after the menu closes. |
562 | Read only / Workspace write / Full access | Selects the current session permission preset | Settings controls only the default for new sessions. |
563 | Tool approval card | `Left` / `Right`, `Enter`, `1`-`3`, `Esc` | Move between Allow once, Allow for this session, and Deny. The default is Allow once. |
564 | Plan approval card | `Left` / `Right`, `Enter`, `1`-`3`, `Esc` | Move between Revise plan, Start execution, and Exit plan. The default highlighted action is Start execution. |
565 | Plan control | Toggles Plan on/off | Same mode as `Shift+Tab`. |
566 | Goal item in the collaboration menu | Starts, views, or clears Goal | Goal is not in any keyboard cycle. |
567
568 ### CLI / TUI
569
570 The composer uses theme-coloured top and bottom borders and a slim bar cursor by
571 default. Long drafts grow to the available maximum height; once they overflow,
572 wheel events inside the composer scroll the draft without moving the insertion
573 cursor, while wheel events in the transcript keep scrolling the conversation.
574 Use `/theme auto|light|dark` to select the background mode, or `/theme <style>`
575 to select one of the named accent palettes shown by bare `/theme`.
576
577 The responsive footer keeps the active permission preset, Plan state, and current
578 interaction state on the left. On wider terminals, model and effort
579 stay together on the right; a second row shows available Git identity, cache hit
580 rate, context use, compaction headroom, jobs, and balance. `ready` is the idle
581 composer state, not a model-health check. Pickers, approvals, image paste, shell
582 mode, and other active interactions replace it. Narrow terminals move, wrap, or
583 compact whole groups; visible labels follow `/language`.
584
585 Chat and transcript shortcuts:
586
587 | Key or command | What it does | Notes |
588 | --- | --- | --- |
589 | `Enter` | Sends the current message | While a turn is running, non-empty input is durably queued as a follow-up before the composer clears. |
590 | `Ctrl+Enter` or `/steer <text>` | Adds guidance to the active turn | The guidance is persisted first; if the turn cannot accept it, it remains a normal follow-up. |
591 | `Shift+Enter`, `Alt+Enter`, or `Ctrl+J` | Inserts a newline | Plain `Enter` is reserved for send/confirm. |
592 | Plain `Up` / `Down` while idle | Recalls older or newer submitted prompts | In a running turn, the same keys navigate queued follow-up feedback. |
593 | `PageUp` / `PageDown` | Scrolls the transcript | Works regardless of the current chat state. |
594 | `Ctrl+Home` / `Ctrl+End` | Jumps to the top or bottom of the transcript | Useful after long tool output. |
595 | `Ctrl+L` or `/cls` | Clears only the visible transcript | The LLM context, session file, tools, memory, and plugins stay loaded. Use `/clear` when you want to discard the conversation context. |
596 | `Esc` | Backs out of the current action | It un-sends a just-submitted turn before any reply, cancels a running turn, or clears non-empty input. |
597 | Double `Esc` on an empty idle composer | Opens the rewind picker | Same entry point as `/rewind`. |
598 | Transcript text selection | Copies transcript text | Releasing an in-app drag writes through the verified native clipboard path in a local session (`pbcopy` on macOS, the available Wayland/X11 tool on Linux, or the Windows clipboard). SSH falls back to OSC 52 and labels the fallback instead of claiming native success. `Ctrl+C`/`Super+C`/`Meta+C` or right-clicking the active selection copies it again. |
599 | Composer text selection | Selects, copies, or replaces draft text | Releasing an in-app drag copies the selection through the same verified clipboard path as transcript text. Typing or pasting replaces the selection; arrow keys collapse it. |
600 | Right-click with no active selection | Pastes clipboard text locally | In a local session with in-app mouse capture on, Reasonix reads text only and routes it through the normal bracketed-paste handling. Over SSH, use the terminal paste shortcut because the remote process cannot read the local clipboard; `/mouse` restores the terminal's native right-click menu. Right-click with an active selection still copies that selection. |
601 | `/mouse` | Toggles in-app mouse capture | Off hands the mouse back to your terminal, restoring its native click-drag selection and right-click context menu, at the cost of in-app drag-select, the transcript scrollbar, and wheel-scroll. Set `REASONIX_DISABLE_MOUSE=1` to start every session with it off. Remote (SSH) sessions start with capture off so native selection works out of the box; `REASONIX_DISABLE_MOUSE=0` forces capture on everywhere. Over SSH the TUI also enables synchronized output (mode 2026) so repaints do not flicker on the round trip; set `REASONIX_DISABLE_SYNC_OUTPUT=1` to opt out. |
602 | `Ctrl+C` | Copies, cancels, clears, or quits | Copies an active transcript or composer selection first. Otherwise it cancels a running turn, clears non-empty input, or quits on a second empty-composer press. |
603 | `Ctrl+D` | Quits the TUI | Immediate quit. |
604 | Your terminal's text-paste shortcut | Pastes text | Text stays on the terminal's bracketed-paste path (`Cmd+V` on macOS, commonly `Ctrl+Shift+V` on Linux, and the terminal's configured shortcut elsewhere). Reasonix consumes the resulting paste event and never probes for an image first. |
605 | `Ctrl+V` on macOS/Linux; `Alt+V` on Windows | Pastes a clipboard image | Image paste is a separate application action. The footer shows `Pasting image…` while the clipboard is read, then inserts an editable `[image #N]` token at the cursor. |
606 | `/paste-image` | Pastes a clipboard image | Command form of the same image-only action. |
607 | A line starting with `!` | Runs a shell command directly | The command runs locally without asking the model. |
608
609 `/queue list` shows bounded previews without loading full bodies. Use `/queue
610 show|edit|delete|move`, `/queue pause|resume`, and `/queue retry|refresh` to
611 inspect or manage pending work. After crash recovery the inbox is paused, so
612 review it and run `/queue resume` before dispatch continues. Each item is
613 limited to 4 MiB; a session accepts at most 64 items and 64 MiB total.
614
615 Mode and display shortcuts:
616
617 | Key or command | What it does | Notes |
618 | --- | --- | --- |
619 | `Shift+Tab` | Cycles Read only → Workspace write → YOLO → Plan | YOLO applies `danger-full-access`; leaving Plan returns to Read only. |
620 | `Ctrl+Y` | Toggles YOLO | Entering YOLO applies `danger-full-access`; pressing it again restores the prior safe permission preset. |
621 | `--permission-mode read-only|workspace-write|danger-full-access` | Selects the initial permission preset | New sessions default to `workspace-write`. |
622 | `/theme [auto|light|dark|style]` | Shows or switches the CLI theme | Bare `/theme` lists background modes and named accent palettes. The choice is saved to the user config; `REASONIX_THEME` and `REASONIX_THEME_STYLE` can override it for one run. |
623 | `Ctrl+O` | Toggles verbose reasoning display | Also available through `/verbose`. |
624 | `Ctrl+B` | Expands or collapses long shell output | Long shell-output hint lines can also be clicked in the transcript; text selection is handled in-app while the full-screen TUI has mouse reporting enabled. |
625 | `/goal <objective>`, `/goal status`, `/goal pause`, `/goal resume`, `/goal clear` | Starts, checks, pauses, resumes, or clears Goal | A Goal is unbounded unless `[agent].goal_token_budget` is set. |
626 | `/migrate`, `/migrate --from <legacy-dir>` | Retries legacy migration or imports sessions from a chosen v0.x source | Use `--from` for custom Windows v0.52 install/data directories; it imports sessions only. See [Configuration paths](./CONFIG_PATHS.md). |
627
628 Picker and approval shortcuts:
629
630 | Context | Keys | What they do |
631 | --- | --- | --- |
632 | Slash or `@` completion | `Up` / `Down`, `Ctrl+P` / `Ctrl+N`, `Tab` / `Enter`, `Esc` | Move, accept, or close the completion menu. |
633 | Tool approval prompt | `y`/`1`, `a`/`2`, `p`/`3`, `n`/`4`, `Enter`, `Esc`, `Ctrl+C` | Allow once, allow for session, persist allow, deny, accept default allow once, deny, or cancel the turn. |
634 | Ask question card | `Up`/`Down` or `j`/`k`, `Left`/`Right` or `h`/`l`, `Space`, `Enter`, `1`-`9`, `Esc`, `Ctrl+C` | Navigate answers/tabs, toggle multi-select answers, submit/activate, pick numbered options, dismiss, or cancel the turn. |
635 | Rewind picker | `Up`/`Down` or `j`/`k`, `Enter`, `b`, `c`, `d`, `f`, `s`, `u`, `Esc` | Choose a turn, apply both/conversation/code/fork/summarize actions, or go back/close. |
636 | Model, provider, or resume picker | `Up`/`Down` or `Ctrl+P`/`Ctrl+N`; `j`/`k` while search is empty; type to filter; `Enter`; `Esc` | Search, select an item, or close the picker. Once search input starts, `j`/`k` become query text. `/provider` opens that provider's model list. |
637 | MCP import picker | `Up`/`Down` or `j`/`k`, `Space`, `Enter`, `Esc` / `Ctrl+C` | Move, select servers, import selected servers, or cancel. |
638 | MCP manager | `Up`/`Down` or `j`/`k`, `Enter`, `Left`/`Right` or `h`/`l`, `r`, number keys, `q` / `Ctrl+C` | Navigate server lists/details, refresh, choose actions, or close. |
639 | `/clear` confirmation | Arrow keys or `j`/`k` / `Tab`, `Enter`, `y`, `n`, `Esc` / `Ctrl+C` | Toggle Clear/Cancel, confirm clear, or cancel. |
640
641 Mode meanings:
642
643 | Mode | Meaning |
644 | --- | --- |
645 | Read only | Reads the workspace; writes and external side effects require a scoped authorization. |
646 | Workspace write | Writes inside the workspace and private session temporary directory. This is the default. |
647 | Full access | Runs as the current OS user without Reasonix filesystem or network sandboxing. Explicit host deny rules still apply before launch. |
648 | Plan | Plans before implementation. State-changing actions are blocked until approval, including Full access, proxy tools, and subagents. After approval, ordinary permissions and sandbox rules still apply. |
649 | Goal | Pursues a saved objective until complete, blocked, or cleared. |
650
651 ## Permissions & sandbox
652
653 The active permission preset supplies the enforced filesystem boundary for
654 Bash, file tools, background processes, and subagents. `workspace-write` runs
655 ordinary builds, tests, pipes, command substitutions, and inline scripts without
656 syntax-based prompts while confining writes to the workspace and private session
657 temporary directory. A write outside that boundary can be allowed once or for
658 the displayed directory during the current session. Permanent approval is not
659 offered.
660
661 Configured `deny` rules always win. Installed MCP servers and plugins are trusted
662 in `workspace-write`; unknown side-effect capabilities in `read-only` still need
663 authorization. If the platform sandbox is unavailable, restricted presets fail
664 closed instead of offering an unconfined retry.
665
666 Permissions are *policy* (which calls to allow / prompt). The **sandbox** is
667 *enforcement*: they are two layers. A permitted call still cannot write outside
668 the approved roots. The file-writers (`write_file` / `edit_file` / `multi_edit` / `move_file`)
669 refuse any path outside `[sandbox] workspace_root` (default: the current dir, so
670 edits stay in the project), resolving symlinks and `..` so a link can't tunnel
671 out. Writing outside the workspace is an interactive *extend write access*
672 approval (once / this session / add to project `reasonix.toml` / deny), not a
673 sandbox escape. Bash must name those directories with `additional_write_dirs`
674 plus a `justification`; the host does not infer paths from the command text.
675 Headless `reasonix run` does not prompt: pass `--add-dir` or configure
676 `[sandbox].allow_write`. The whole home directory can be approved with a
677 high-risk warning; the filesystem root and Reasonix session/state paths cannot. `forbid_read` optionally hides sensitive files or directories from the agent's
678 read/list/search tools; use absolute paths or `${HOME}` / `${VAR}` references,
679 not `~`, because config expansion is environment-variable based. `bash` is
680 itself jailed by default when an OS sandbox is available (`[sandbox] bash`,
681 Seatbelt on macOS and bubblewrap on Linux):
682 commands may write only those same roots plus platform-specific command
683 temp/cache roots, cannot read configured `forbid_read` roots while the OS
684 sandbox is active, and reach the network only when `[sandbox] network` is set.
685 Reasonix always removes saved provider and bot credential variables from tool
686 subprocess environments. On macOS and Linux it also automatically adds the
687 global credential `.env` to the runtime read-deny boundary. Windows does not:
688 it has no OS-level shell sandbox, and denying the current user would also deny
689 the host settings process. Project `.env` files keep their existing
690 workspace-scoped behavior.
691
692 **Session-private temporary directory.** Within one logical chat session, Bash
693 commands share a private temporary directory so consecutive calls can exchange
694 files through `$TMPDIR` (and, on Linux under bubblewrap, through literal
695 `/tmp`). No user setup is required: Reasonix automatically exports `TMPDIR`,
696 `TMP`, and `TEMP` for Bash and client-owned ACP terminals. The directory is
697 created lazily, is never the host public temporary root, and is rotated on
698 `/new`, `/clear`, resume of another session, and branch switches.
699 Model/settings hot rebuilds keep the same directory. Temporary files are not
700 durable storage: resume across process restarts does not restore them, and
701 scripts that need long-lived data should write into the workspace or a
702 user-specified path.
703
704 Reasonix-generated and project scripts should use the standard temporary
705 environment variables rather than hard-coding `/tmp`; users should not set
706 these variables themselves. For example:
707
708 ```sh
709 tmp_file="${TMPDIR:?}/result.json"
710 ```
711
712 ```powershell
713 $tmpFile = Join-Path $env:TEMP "result.json"
714 ```
715
716 | Platform | `$TMPDIR` / `$TMP` / `$TEMP` | Literal `/tmp` |
717 | --- | --- | --- |
718 | Linux + bubblewrap | Virtual `/tmp` (bound to the private dir) | Shared for the session (not a fresh empty tmpfs each call) |
719 | macOS Seatbelt | Host path of the private dir (allowed by policy) | Host macOS temporary directory; scripts should use `$TMPDIR` |
720 | Windows (no OS sandbox) | Host path of the private dir | Not promised to match (e.g. Git Bash `/tmp`) |
721
722 Independent sandboxes such as MCP servers keep their own isolation and do not
723 inherit the chat session's temporary directory. An approved sandbox-escape
724 command still receives the private temp environment variables, but on Linux its
725 literal `/tmp` is no longer mapped by bubblewrap.
726
727 **Windows note:** Windows has no OS-level shell sandbox. The restricted-token
728 backend is retired from enforcement because denying the current user's own SID
729 locked hosts out of their credential store and the token broke common
730 toolchains. Permission presets still apply as Reasonix tool-layer
731 boundaries: Read only refuses file writes and asks before every shell command,
732 and Workspace write keeps file tools inside `workspace_root` and `allow_write`
733 and asks before writing elsewhere. Shell commands in every preset run as the
734 current OS user without confinement, so `[sandbox] network` and shell-level
735 `forbid_read` are not enforced there; dedicated file tools still honor
736 `forbid_read`. Saved credential variables are removed from child environments,
737 but local tools run as the user and can deliberately read other user-readable
738 files. `[sandbox] bash = "enforce"` resolves to `off` on Windows and
739 `reasonix doctor` reports the ignored value.
740
741 When no OS sandbox backend is available, `bash = "enforce"` refuses bash
742 execution instead of running unconfined. Install the platform sandbox backend
743 (bubblewrap/`bwrap` on Linux, `sandbox-exec` on macOS) or set
744 `[sandbox] bash = "off"` to explicitly restore the pre-1.16 unconfined shell
745 behavior.
746
747 For coding-quality reports, run `reasonix doctor quality <branch-id-or-path>`
748 (add `--json` for structured output). This reads the selected session but emits
749 only content-free counts and profile categories: model family, runtime profile,
750 collaboration / approval modes, message and tool-call counts, verification and persisted
751 compaction-summary counts, plus desktop token/cache telemetry when available.
752 It omits transcript text, paths, session identifiers, tool arguments and output,
753 endpoints, and custom model names, so the result is suitable for a public issue
754 or Discussion. This differs from `reasonix doctor session`, whose support zip
755 contains the complete unredacted transcript and must remain in a trusted support
756 channel.
757
758 ## Capability diagnostics
759
760 Use this when a skill, slash command, hook, plugin package, MCP server, or
761 `AGENTS.md` is missing, shadowed, disabled, or fails to start. Full flag
762 reference, JSON schema, and issue codes:
763 **[Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)**.
764
765 ```bash
766 # Static (default): no network, no MCP child processes
767 reasonix doctor capabilities
768
769 # Machine-readable (stdout is pure JSON)
770 reasonix doctor capabilities --json
771
772 # Another workspace root
773 reasonix doctor capabilities --root /path/to/project
774
775 # Live MCP probe — only when you explicitly allow starting third-party servers
776 reasonix doctor capabilities --live --timeout 5s
777 ```
778
779 | Surface | How |
780 | --- | --- |
781 | CLI | `reasonix doctor capabilities` (above) |
782 | Desktop | **Settings → Diagnostics** — refresh, copy redacted JSON, optional “include current session runtime” (reads the active tab Host only; does **not** start MCP) |
783 | Agent | `/reasonix-guide` (built-in inline skill) or ask naturally; it prefers static doctor JSON before `--live` |
784
785 Exit code `0` allows warnings/info; `1` means at least one `error` (or a live
786 start failure); `2` is bad flags. This is separate from `reasonix doctor`
787 (providers/sandbox) and `reasonix plugin doctor <name>` (one package).
788
789 ## Plugins (MCP)
790
791 Reasonix is an MCP client. A `[[plugins]]` entry's `type` selects the transport:
792 `stdio` (default) launches a local subprocess (`command`/`args`/`env`); `http`
793 (Streamable HTTP) connects to a remote `url` with optional static `headers`
794 (`${VAR}` / `${VAR:-default}` expanded from the environment, so tokens stay out
795 of the file); `sse` connects to servers that still use the legacy persistent
796 GET + announced POST endpoint transport.
797
798 For a remote HTTP server without a static `Authorization` header, an
799 authentication challenge is shown as **Sign in**. Run
800 `reasonix mcp auth <name>` in the CLI, or click **Sign in** for that server in
801 the Desktop MCP panel. Reasonix performs OAuth metadata discovery, dynamic
802 client registration, PKCE S256 authorization, and refresh-token
803 rotation. Discovery and token requests use the same Reasonix network-proxy
804 settings as the MCP connection.
805
806 OAuth client and token state is kept outside the workspace in the server's
807 private Reasonix state directory, written with mode `0600`, and bound to the
808 full configured resource URL. An explicit static `Authorization` header always
809 takes precedence. **Clear authentication** removes only Reasonix's local OAuth
810 state; it does not sign out the third-party browser session. Reasonix opens the
811 browser only after an explicit sign-in action, never automatically from a
812 background tool-call failure. Removing the MCP server also removes its local
813 OAuth state unless a lower-priority declaration for the same resource becomes
814 effective.
815
816 Browse the official MCP Registry from **Settings → MCP servers → Browse
817 registry**, or use `reasonix mcp browse [query]` and
818 `reasonix mcp install <registry-name>`. Registry access is explicit and never
819 runs during startup. Entries that need secrets or required arguments are shown
820 as manual setup instead of being installed with an incomplete configuration;
821 query-specific cached results remain available during a registry outage.
822
823 The normal setup path is intentionally one step. Use Desktop's **Add and
824 connect**, `/mcp add`, or ask Reasonix to install a package or URL. These
825 explicit installs are saved to the user-global `config.toml` and are also
826 authorization: the server connects in the current session, and no second trust
827 step appears now or on the next startup. Servers declared by the current
828 project's `reasonix.toml` or `.mcp.json` remain in that project and are trusted
829 without a separate launch confirmation. Explicit deny rules still win. The
830 server's calls run
831 directly, including tools that declare `destructiveHint`. The dedicated Planner
832 still refuses destructive tools, and strict read-only sub-agents still expose
833 only hinted non-destructive readers.
834
835 MCP names are resolved once per workspace. Project declarations override
836 same-name global installs; inside a project, `reasonix.toml` overrides
837 `.mcp.json`. Editing updates the effective declaration in its original file,
838 and removing a higher-priority declaration reveals the next one instead of
839 deleting every same-name entry.
840
841 stdio servers keep one process for initialize, reads, and writes, so stateful
842 servers such as browsers retain sessions and open pages. Because an OS sandbox
843 is fixed when a process starts, this shared process uses the server's normal
844 process sandbox for every call; `readOnlyHint` and read-only sub-agent filtering
845 are dispatch policy, not a second per-call process sandbox.
846
847 Tools surface to the model as `mcp__<server>__<tool>`. A tool declaring MCP's
848 `readOnlyHint: true` joins parallel dispatch and the strict read-only tool
849 surfaces. Installing a server or declaring it in project configuration
850 authorizes the dedicated Planner to use all of its non-destructive
851 tools without another per-tool setting; strict read-only research sub-agents
852 receive only hinted non-destructive readers. Tools without the hint remain
853 write-capable for scheduling and mutation accounting. While planning, built-in
854 writers keep the ordinary permission posture. The dedicated Planner permits
855 authorized non-destructive MCP (including opaque writers) but hard-blocks
856 destructive or unauthorized targets; a single-model Plan without that dedicated
857 Planner keeps the older writer/destructive block until Plan exits.
858
859 Installing an MCP server is the authorization decision. After installation, all
860 of its tools run directly without a second server-level, per-tool, writer, or
861 destructive approval setting. Explicit global deny rules still win. The host
862 keeps `readOnlyHint` and `destructiveHint` internally for parallel scheduling,
863 Plan restrictions, strict read-only sub-agents, and cached-to-live safety
864 reclassification; these hints do not add user configuration.
865 Reasonix deliberately trusts an installed server to describe those hints
866 honestly. Planner/read-only filtering is therefore a workflow boundary for
867 trusted servers, not containment against a malicious MCP server; explicit deny
868 rules and the process sandbox remain host-controlled boundaries.
869
870 The retired `trusted_read_only_tools`, `default_tools_approval_mode`,
871 `tools.<raw>.approval_mode`, and `approvals_reviewer` fields are ignored when
872 loading older files and removed the next time Reasonix saves that MCP entry.
873
874 A server's **prompts** surface as `/mcp__<server>__<prompt>` slash commands
875 (positional args after the command); its **resources** are pulled in by writing
876 `@<server>:<uri>` in a message; `/mcp` lists connected servers and what each
877 exposes. `make build` also produces `bin/reasonix-plugin-example` — a runnable
878 reference stdio server (`echo`, `wordcount`, a `review` prompt, a style-guide
879 resource) you can copy.
880
881 ```toml
882 [[plugins]] # local stdio server
883 name = "example"
884 command = "reasonix-plugin-example"
885 # startup_timeout_seconds = 60 # optional initialize + tools/list cap
886 # call_timeout_seconds = 600 # optional per-server MCP call timeout
887 # tool_timeout_seconds = { "generate_video" = 1800 } # optional raw MCP tool names
888
889 [[plugins]] # remote server over Streamable HTTP
890 name = "stripe"
891 type = "http"
892 url = "https://mcp.stripe.com"
893 headers = { Authorization = "Bearer ${STRIPE_KEY}" }
894 ```
895
896 Enabled MCP servers start connecting automatically in the background after a
897 session begins, so chat stays usable while tools come online. Use `/mcp` or the
898 desktop MCP panel to refresh status, reconnect a server, inspect failures, or
899 disable a server for the current session. For a read-only config/runtime health
900 report across skills, hooks, packages, and MCP (without changing settings), see
901 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)
902 (`reasonix doctor capabilities` or **Settings → Diagnostics**).
903
904 An interactive caller waits only briefly for a cold server. If that wait ends,
905 the shared startup continues in the background rather than being killed and
906 restarted; retry the tool after it comes online. `mcp_startup_timeout_seconds`
907 (default `30`) bounds the full launch, authorization, initialize, and
908 `tools/list` sequence. `mcp_call_timeout_seconds` applies only after the server
909 is connected. Either value can be overridden per server.
910
911 **Already have an `.mcp.json`?** Drop it in the project root and Reasonix
912 reads it as-is — the `mcpServers` spec (`command`/`args`/`env`, `type`/`url`/
913 `headers`, `${VAR}` expansion) maps field-for-field onto `[[plugins]]`. Both
914 sources are merged; on a name collision `reasonix.toml` wins.
915
916 ```json
917 {
918 "mcpServers": {
919 "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path"] },
920 "stripe": { "type": "http", "url": "https://mcp.stripe.com", "headers": { "Authorization": "Bearer ${STRIPE_KEY}" } }
921 }
922 }
923 ```
924
925 **Upgrading from `0.x`?** Your old `~/.reasonix/config.json` is still read for its
926 `mcpServers` (honouring `mcpDisabled`) as a lowest-priority source, so MCP servers
927 keep working — move them into `reasonix.toml`'s `[[plugins]]` or a `.mcp.json` when
928 convenient.
929
930 ## Slash commands
931
932 In an interactive `reasonix` session, built-in commands (`/compact`, `/context`, `/new`, `/clear`, `/rewind`,
933 `/tree`, `/branch`, `/switch`, `/todo`, `/model`, `/mcp`, `/skills`, `/hooks`,
934 `/memory`, `/goal`, `/output-style`, `/sandbox`, `/language`,
935 `/reasoning-language`, `/help`) run
936 locally — `/help` lists them all. Built-in **skills** such as `/init`,
937 `/explore`, `/test`, and `/reasonix-guide` also appear in the slash menu and via
938 `run_skill` (bodies load on demand; only the index line is cache-stable). Use
939 `/reasonix-guide` when you need config or capability troubleshooting; it points
940 at `reasonix doctor capabilities` (see
941 [Capability diagnostics](./CAPABILITY_DIAGNOSTICS.md)). `/new` starts a new
942 session while saving the previous transcript for history/resume; `/clear`
943 discards the current context without saving it and asks for confirmation. `/tree`
944 shows saved conversation branches, `/branch [name]` forks the current
945 conversation tip, `/branch <turn> [name]` forks from an earlier checkpointed
946 turn, and `/switch <id|name>` loads another branch. **Custom commands** are
947 Markdown files under `.reasonix/commands/` (project) or `~/.reasonix/commands/`
948 (user) — `review.md` becomes `/review`, a subdirectory namespaces it
949 (`git/commit.md` → `/git:commit`). The body is a prompt template; invoking the
950 command sends it as a turn.
951
952 ### Subagent profiles
953
954 Subagent profiles are manual Skills with `runAs: subagent` and
955 `invocation: manual`. They are stored in the same project/global Skill roots as
956 the desktop settings page, so profiles created on either surface are immediately
957 available to the other after the session refreshes. In interactive chat, invoke
958 one with `/<name> <task>`; Reasonix runs an isolated child loop and keeps only
959 the task and final answer in the parent conversation.
960
961 The headless CLI provides explicit management and execution commands without
962 changing the ordinary `reasonix run` task semantics:
963
964 ```bash
965 reasonix subagent list
966 reasonix subagent create reviewer --description "Review changes" --prompt-file reviewer.md --tools read_file,grep,bash
967 reasonix subagent edit reviewer --effort high --model deepseek-pro
968 reasonix subagent try reviewer "review the current diff" # always read-only
969 reasonix subagent run reviewer "review and fix the current diff"
970 reasonix subagent delete reviewer --yes
971 ```
972
973 `create` defaults to project scope when a workspace is available and to global
974 scope otherwise; pass `--scope project|global` to choose explicitly. `edit`
975 changes only explicitly supplied fields, and an empty value such
976 as `--model=` or `--tools=` clears that field. The profile editors deliberately
977 refuse custom-path or richer hand-authored Skills so they cannot discard
978 frontmatter, references, or scripts; manage those files through the Skills
979 workflow instead. Built-in profiles have no editable file, so `edit` accepts
980 only `--model` and `--effort` for them and stores the same per-name overrides as
981 the desktop settings page.
982
983 See [Subagent profiles](./SUBAGENT_PROFILES.md) for the complete CLI reference,
984 Skill file format, model precedence, safety behavior, and troubleshooting.
985
986 Context Engine v2 separates two intentionally different layers:
987
988 - **Standing instructions** come from hierarchical `REASONIX.md`, `AGENTS.md`,
989 and `CLAUDE.md` files. Put rules here when they must be present on every
990 relevant turn. User-global files load first, then workspace and deeper target
991 directories; within one directory, `.local.md` variants win.
992 - **Background memory** stores one durable fact per Markdown file. Each fact has
993 an immutable ID, monotonic revision, timestamps, independent `type`
994 (`user`, `feedback`, `project`, `reference`) and `scope` (`project`,
995 `global`), plus freshness metadata. Facts may be stale, so they never outrank
996 the current request or standing instructions.
997
998 Reasonix automatically recalls a small set of relevant facts before each real
999 user turn. It searches the raw user message, suppresses generic requests such as
1000 "continue", prefers project facts over equivalent global fallbacks, down-ranks
1001 stale facts, and appends at most four facts / 2,400 characters to the user turn.
1002 This dynamic suffix does not rewrite the cache-stable system prompt or tool
1003 schemas. Use `/memory recall` to see the selected IDs, scores, reasons,
1004 freshness, budget, and suppression decision.
1005
1006 New, bounded, non-sensitive project/reference facts can be created
1007 automatically with no setup or approval click. Other memory changes follow the
1008 active permission preset and explicit `ask` / `deny` rules. The storage layer
1009 makes the automatic create grant create-only, so it cannot overwrite a fact
1010 that appears concurrently.
1011 A top-level headless controller may use the same one-shot low-risk create path;
1012 sub-agents and headless surfaces without the owning scoped controller fail closed.
1013
1014 `forget` archives rather than permanently deletes. Every update snapshots the
1015 previous revision; restore and archive recovery always create a higher revision
1016 instead of overwriting history:
1017
1018 ```text
1019 /memory instructions
1020 /memory recall
1021 /memory revisions <id-or-name>
1022 /memory restore <id-or-name> <revision>
1023 /memory archived
1024 /memory recover <archive-path>
1025 ```
1026
1027 The desktop Context Center shows the same provenance, conflicts, revision
1028 history, recall trace, and recovery actions. Opening its Suggestions tab scans
1029 recent local user turns automatically; candidates are deduplicated against both
1030 memory scopes and instruction bodies, but nothing is saved until the user
1031 accepts it. Remote workspaces never fall back to local desktop memory or
1032 sessions.
1033
1034 Legacy facts are upgraded in place with deterministic IDs and revision 1;
1035 missing scope is inferred from the containing directory. Migration is
1036 idempotent, old clients retain safe routing, and legacy Memory v5 transcripts
1037 remain readable. For the complete behavior and privacy/cache contract, see
1038 [`Context Engine v2`](SESSION_MEMORY_RETRIEVAL.md).
1039
1040 ```markdown
1041 ---
1042 description: Review the staged diff
1043 argument-hint: [focus-area]
1044 ---
1045 Review the staged diff. Focus on $ARGUMENTS, list bugs with file:line.
1046 ```
1047
1048 `$ARGUMENTS` expands to all space-separated args, `$1`…`$N` to positional ones.
1049 MCP prompts also appear here as `/mcp__<server>__<prompt>`.
1050
1051 ## Embedded documentation retrieval
1052
1053 Reasonix bundles the Markdown files from `docs/` and the reviewed
1054 `release-notes/releases.json` catalog into each CLI and Desktop build. The
1055 read-only `docs` tool searches that exact offline corpus with local BM25
1056 retrieval and can read a complete matching section with source provenance. It
1057 renders every release in both languages under paths such as
1058 `changelog/v1.19.5.md` and `changelog/v1.19.5.zh-CN.md`, so questions about a
1059 specific version, upgrades, fixes, or known risks work offline. The agent should
1060 use the tool before web search or assumptions when a question concerns Reasonix
1061 configuration, CLI/Desktop behavior, release history, permissions, MCP, memory,
1062 recovery, providers, or maintainer workflows.
1063
1064 No setup, network connection, vector database, or embedding service is needed.
1065 Search results prefer the query language while retaining explicit `en`,
1066 `zh-CN`, audience, and catalog filters. The docs capability is exposed through
1067 the unified `use_capability` surface for every task. Every result reports
1068 the product version, immutable source revision, and corpus SHA-256 digest. Release
1069 CI compiles the CLI and rejects publication unless that embedded manifest matches
1070 the candidate's `docs/*.md`, `release-notes/releases.json`, and build identity. A
1071 newer online `main-v2` page therefore cannot silently replace version-matched
1072 local guidance or release history.
1073
1074 Use `/docs` to inspect the bundled corpus identity and usage examples without
1075 calling a model. Use `/docs <question>` (for example,
1076 `/docs 1.19.5 changelog`) to make Reasonix search the corpus locally first and
1077 then pass the version-matched evidence to the currently configured AI for a
1078 sourced answer. This command path does not depend on the model deciding to call
1079 the `docs` tool, while ordinary natural-language questions may still use the
1080 tool automatically. Existing custom commands and compatible plugin or skill
1081 aliases keep ownership of `/docs`; when that happens, CLI and Desktop normally
1082 expose the built-in corpus as `/reasonix:docs` instead. If that qualified name is
1083 also already owned, Reasonix selects the next free `reasonix:`-qualified fallback
1084 without displacing it. A remote Desktop uses the host's resolved command catalog,
1085 so the displayed entry always matches what that host will execute.
1086
1087 Pull requests that change user-visible CLI, Desktop, configuration, provider,
1088 permission, or tool behavior must declare whether embedded documentation was
1089 updated. When no documentation change is needed, the declaration must explain
1090 why the existing version-matched guidance remains correct.
1091
1092 ## Goal
1093
1094 Goal is the unified runtime for long-running objectives. Reasonix keeps working
1095 until the goal is complete, blocked, paused, or cleared. Ordinary chat never
1096 changes collaboration mode implicitly; choose Goal in the composer or use
1097 `/goal` to start a long-running objective.
1098
1099 Goal has no default model-round, cross-Run turn, wall-clock, or numeric
1100 no-progress limit. It continues until completion, a genuine user/external
1101 blocker, manual stop/pause, an unrecoverable external error, or an explicit
1102 user-selected budget. To place an optional ceiling on an unattended loop, set:
1103
1104 ```toml
1105 [agent]
1106 goal_token_budget = 20000000
1107 ```
1108
1109 The default is `0` (off). Reaching a positive token budget produces one summary
1110 and a resumable `budget_spend` pause. `/goal resume` grants a fresh configured
1111 slice while cumulative Goal statistics remain intact. Explicit positive
1112 `max_steps`, task time, and task cost budgets remain available as well.
1113 Cumulative rounds, tokens and real provider requests are tracked and shown as
1114 statistics; a token limit appears only when explicitly configured. A paused
1115 goal keeps its objective and runtime history — use `/goal resume` to continue,
1116 or `/goal pause` to pause a running goal manually. `/goal status` shows rounds,
1117 requests and tokens. Exact consecutive tool calls receive reminders at the
1118 third, fifth, and eighth occurrence; the calls still execute. An active, armed
1119 goal continues after an ordinary model final through the runtime idle driver;
1120 there is no per-turn `continue` report. The model uses `update_goal(complete)`
1121 when it judges the whole objective finished and `update_goal(blocked)` for a
1122 concrete persistent blocker. No evaluator, todo percentage or host quality
1123 gate decides completion. Restoring, importing or forking loads the durable
1124 goal disarmed; a directly authorized user turn or explicit UI action must
1125 resume it.
1126
1127 For complex work, write the objective as a
1128 [task contract](./TASK_CONTRACT.md): Context, Request, Output format,
1129 Constraints, and Pause policy. Goal mode treats those sections as the boundary
1130 for autonomous work. It keeps going with sensible defaults unless the next step
1131 requires an irreversible or externally visible operation, a scope change, or
1132 information only the user can provide.
1133
1134 Legacy simple/write/research classes and Goal sidecars are read only at the
1135 explicit compatibility/import boundary. There is no separate research runtime
1136 to configure. Current Goal state is a versioned `goal/state` projection in the
1137 linear v3 session, and activation is process-local. Legacy
1138 `.reasonix/autoresearch/<task-id>/` archives remain read-only. Deprecated
1139 budget flags are accepted for compatibility but hidden from help and
1140 completion.
1141
1142 ### Model task progress
1143
1144 `todo_write` updates progress for the current top-level turn. A newly admitted
1145 Goal round starts with a fresh todo plan; compaction, steer and interactive
1146 answers inside that round keep the current list. The host does not finish todos
1147 when a turn or Goal ends. `complete_step` is absent from discovery; an old call
1148 returns a normal `tool_retired` result and never changes task state.
1149
1150 ## @ references
1151
1152 Embed `@` references in a message and Reasonix resolves them before sending, as
1153 tagged context blocks: `@path/to/file` (or `@dir`) injects a local file's
1154 contents (or a directory listing), and `@<server>:<uri>` injects an MCP
1155 resource. A local path is only treated as a reference when it actually exists,
1156 so ordinary `@mentions` stay literal. Typing `/` or `@` opens an autocomplete
1157 menu — slash commands, or hierarchical file navigation (one directory level at a
1158 time, descend into folders) plus MCP resources.
1159
1160 ## Two-model collaboration
1161
1162 `reasonix setup` manages providers, model lists, credentials, connection tests,
1163 and the default model. It stages changes until Save and exit, and synchronizes
1164 provider access with the desktop app. See the [CLI reference](./CLI.md#configure-providers).
1165 Running two models together (executor + planner, separate cache-stable sessions)
1166 is a one-line edit afterwards — set `planner_model` to any other enabled provider:
1167
1168 ```toml
1169 [agent]
1170 planner_model = "deepseek-pro" # used as the low-frequency planner
1171 ```
1172
1173 The planner sees loaded `REASONIX.md` / `AGENTS.md` memory and a small read-only
1174 research tool set, so it can inspect relevant files before handing a plan to the
1175 executor. Writer and workflow tools remain executor-only.
1176
1177 Reasonix routes each turn deterministically without another classifier model.
1178 Ordinary requests always stay with the executor. The dedicated planner runs
1179 only for an explicit `plan first` / `先规划` request, an explicit wait-for-
1180 approval boundary, an explicit `plan only` / `不要执行` request, or Goal
1181 start. Wording such as "complex refactor" or "fix login" does not start the
1182 planner. There is no automatic planning depth. Explicit Plan Mode
1183 remains a separate host workflow on the executor and is never planned twice.
1184 `just do it` / `直接改` also stays with the executor. Execution boundaries are
1185 recognized across the request, not only at its beginning, while quoted
1186 examples are ignored. Bare plan-first requests continue from the planner to
1187 the executor automatically. Requests that explicitly say to wait for
1188 confirmation pause at the host approval boundary and continue to the executor
1189 after approval. Only an explicit `plan only` / `不要执行` request ends the
1190 current turn with the plan persisted and no execution; a later user instruction
1191 can continue in the same session. The phase detail records a privacy-safe route
1192 and reason code for diagnosis without logging the user prompt.
1193
1194 The planner uses one stable system prompt. A small host-authored
1195 `<planner-turn>` block names the explicit route and preserves the planner
1196 prefix cache after the one-time prompt upgrade. The plan should separate
1197 verified from candidate touchpoints and include non-goals, risks, acceptance
1198 criteria, and command-level verification when evidence supports them. The
1199 planner must call `submit_plan`; a prose reply without a submitted plan is a
1200 protocol error. If a planner still does not finalize after its bounded
1201 research and finalization round, the turn fails closed on every route and the
1202 executor is not started. The incomplete planner turn is rolled back instead of
1203 leaving an unusable continuation tail.
1204
1205 Ordinary clean finals end the turn. Goal, review, and guardian flows keep
1206 their own continuation constraints. In Goal mode, if an active todo produces
1207 no new completion, unique read, command, or mutation past the stall threshold,
1208 the host forces a smaller step, different tool/approach, focused delegation,
1209 or a real blocker report, then execution continues. Exact repeats do not count
1210 as progress; new host-observed work renews the lease. Two-level task lists keep
1211 the same single-current contract: the active level-1 sub-step is the one
1212 `in_progress` item while its level-0 phase stays `pending`; sub-steps are worked
1213 and signed off in order, and once every sub-step has completed the phase itself
1214 becomes `in_progress` for its own final sign-off.
1215
1216 Existing `[agent].max_steps` and `planner_max_steps` keys remain syntactically
1217 accepted during upgrades, but their values are ignored and removed with a
1218 one-time notice. This prevents a stale hidden limit from truncating automatic
1219 progress or inherited subagent work. Use the one-off CLI `--max-steps` flag when
1220 an explicit run budget is needed; unattended bots retain `[bot].max_steps`,
1221 where `0` means continuous execution and a positive value is explicit.
1222
1223 **An ordinary chat task has no limit of any kind by default** — not rounds, not
1224 tokens, not time, not money. It runs until the model finishes, an adaptive
1225 guard decides it stopped making progress, or you stop it.
1226
1227 An optional spend gate is available when you want one. It bounds a whole task
1228 (every "continue" included, until you start unrelated work), and on crossing it
1229 the task produces one tool-free summary and pauses; the work is saved and the
1230 next message continues it.
1231
1232 ```toml
1233 [agent]
1234 task_cost_budget = 5.0 # in the model's pricing currency
1235 task_time_budget_minutes = 60 # wall clock across the whole task
1236 ```
1237
1238 Both are off unless set. In particular, `task_time_budget_minutes = 0` (and
1239 legacy negative values) disables the time gate; only a positive value enables
1240 it. Neither has a default, because a stop is a judgement
1241 only you can make: no amount of money is portable across models — a budget
1242 loose enough for a cheap model would land a frontier model within a couple of
1243 answers — and a long task is as often the job you asked for as it is a runaway.
1244
1245 Cost applies only to a priced model. Without a price table that axis stays
1246 inactive rather than reading the task as free; use the time axis for a free or
1247 local model.
1248
1249 Rounds are deliberately not an axis. A turn that reaches a high round count
1250 without spending much is one whose rounds are individually cheap and fast,
1251 which is the case least worth interrupting. Use the one-off `--max-steps` flag
1252 when you specifically want a run bounded by rounds.
1253
1254 Subagent skills inherit the executor model by default. Set `subagent_model` to
1255 run them on another configured model, or use `subagent_models` to override only
1256 specific skills such as `review` or `security_review`.
1257
1258 Subagents may delegate one more layer by default: the root session is depth 0,
1259 first-layer subagents are depth 1, and the maximum `max_subagent_depth = 2`
1260 means a depth-1 workflow can dispatch a depth-2 reviewer or implementer. Depth-2
1261 subagents do not receive recursive agent/skill tools. Set
1262 `agent.max_subagent_depth = 1` to restore the old single-layer boundary. This is
1263 intended for workflows such as Superpowers where a workflow skill may dispatch a
1264 reviewer subagent, while still avoiding unbounded recursion and background
1265 fanout.
1266
1267 Use `read_only_task` when planning needs isolated, deeper research without
1268 granting write-capable delegation. Use `read_only_skill` when the same need is
1269 best expressed through an existing skill. Both run ephemeral read-only
1270 subagents with only read-only research tools plus safe foreground bash, return
1271 only the final answer, and do not create resumable subagent transcripts.
1272 Read-only nested delegation may be available until `max_subagent_depth` is
1273 reached, but writer-capable `task` / `run_skill` remain unavailable inside these
1274 read-only child registries. Every task shares one tool surface: call
1275 `use_capability` for `read_only_skill` and other optional tools. Subsequent
1276 writer calls still pass through Permissions/Sandbox.
1277
1278 Every strict read-only child is built through one shared construction
1279 pairing — `RunReadOnlySubAgentWithSession` / `NewReadOnlyAgent` — which marks
1280 the child permanently read-only and applies a final registry filter. The filter
1281 removes writers, destructive MCP targets, readers from unauthorized servers,
1282 and every host-mutating tool. User-installed and project-configured servers are
1283 authorized immediately. Eligible readers may still start on demand. These are
1284 the strict read-only entrances:
1285
1286 | Entrance | Purpose |
1287 | --- | --- |
1288 | `read_only_task` | Isolated read-only research child from the main session |
1289 | `parallel_tasks` (read-only) | Concurrent read-only research children |
1290 | `fleet` with `read_only: true` | Parallel profile-aware batch (forced read-only per item) |
1291 | `read_only_skill` | The same isolation driving an existing skill |
1292 | `reasonix review` (CLI) | Read-only review of a diff or branch |
1293 | Desktop preview/review subagents | Read-only desktop analysis surfaces |
1294
1295 In persisted sessions, `parallel_tasks` and `fleet` return a bounded preview
1296 plus one `Subagent reference` per completed child instead of concatenating every
1297 full answer into a truncation-prone tool result. The parent can call
1298 `read_subagent_result` with that reference and page by `offset_bytes`; results
1299 are scoped to the current conversation lineage and workspace. Headless runs
1300 without a persisted parent session remain ephemeral and receive fair bounded
1301 previews, but cannot mint durable references.
1302
1303 Persisted child results include `status` (`completed`, `partial`, `failed`, or
1304 `cancelled`) and `retryable`. Partial or retryable failed runs retain a visible
1305 answer and reference so the parent can inspect them with `read_subagent_result`
1306 or continue the same `task`/`run_skill` transcript with `continue_from`.
1307
1308 The interactive two-model Planner uses a dedicated construction path
1309 (`NewPlannerAgent`): it still blocks bash, file writers, and ordinary writers,
1310 but may call authorized, non-destructive MCP through the fixed
1311 `use_capability` proxy without requiring `readOnlyHint`. Direct `mcp__*`
1312 schemas never enter the Planner tool list, so MCP install/connect churn does
1313 not change the Planner cache prefix after the one-time schema upgrade. Missing
1314 `readOnlyHint` no longer blocks the Planner; tools with `destructiveHint` are
1315 zero-exec and should be written into the plan for the Executor.
1316 In Balanced two-model sessions the Executor has its own frontend for the same
1317 stable proxy, so an `auto_start=false` or destructive capability discovered by
1318 the Planner remains callable by capability ID after handoff. Planner and
1319 Executor ledgers/audits stay isolated and only the Host connection is shared.
1320
1321 Ordinary `task` / `fleet` sub-agents also get the same fixed proxy (session-
1322 shared Host and connections, per-agent frontend/ledger) and may call installed
1323 or project-configured MCP without `readOnlyHint`. Those calls use the trusted
1324 MCP permission path (live authorization plus explicit deny only); writer and
1325 destructive calls are still serialized, recorded as mutations, and subject to
1326 closed-loop evidence/lease guards rather than Planner handoff. Strict
1327 `read_only_task` / `read_only_skill` / review sub-agents share the stable proxy
1328 schema and connection reuse but keep the strict execution gate
1329 (`authorized && readOnlyHint && !destructiveHint`). Profile `allowed-tools`
1330 MCP names convert to capability-id allowlists on the proxy; children never
1331 inherit dynamic `mcp__*` schemas.
1332
1333 Inside a strict child, `use_capability` re-checks the resolved target before
1334 commit/permission/hooks/execution. An unconnected eligible MCP reader may start
1335 on demand from the current schema cache. Before `tools/call`, cached
1336 `readOnlyHint`/`destructiveHint` facts are checked against the live
1337 initialize/tools-list result; a reader-to-writer change or destructive promotion
1338 means zero executions and a normal retry through the current boundary. A
1339 schema-only change refreshes the cache for the next session without interrupting
1340 the authorized call. Runtime enablement, authorization, and the complete
1341 connection identity are checked again immediately before dispatch, so a
1342 same-name client from another project/tab cannot be reused accidentally. An
1343 unauthorized server cannot raise privileges there. This strict-child boundary
1344 is narrower than the dedicated Planner: the Planner accepts authorized opaque
1345 non-destructive MCP, while a strict child requires an explicit reader hint and
1346 never exposes writers at all.
1347
1348 Reasonix uses **fact-driven execution**. Ordinary requests always enter the
1349 executor. There is no automatic task mode or selectable quality floor. Planner,
1350 Goal, permission, sandbox, and the task contract are independent states.
1351
1352 Ordinary turns end when the model ends normally, even with unfinished todos or failed checks. There are no quality retries or todo-driven continuation rounds. Active Goals alone drive automatic continuation; approved Plans execute as ordinary tasks. Historical checkpoints remain available through an explicit `Continue checks` request, without restoring quality gates. Protocol recovery, cancellation, and resource limits remain independent.
1353
1354 Every task shares the same provider-visible core tool surface: direct
1355 read/bash/edit/write, background-shell lifecycle tools, `ask`/`compress` when
1356 registered, and the stable `use_capability` proxy for optional tools (search,
1357 MCP, skills, subagents, docs, web_fetch, and so on). Calling `use_capability`
1358 never expands the top-level provider schema, so the prompt-cache tool prefix
1359 stays stable across every task. The Harness minimal preset is not a task
1360 complexity mode.
1361
1362 The model decides whether to investigate, update todos, verify changes, or request review. User and project instructions stay in task context. File counts, authentication paths, schemas, migrations, and explicit verification language do not create host acceptance obligations. The host retains action permissions, preapproval Plan write restrictions, sandboxing, workspace leases, and structured-file stale-version protection. An ordinary tool failure does not skip later independent calls in the same batch. Results show actual commands, failures, interruptions, and checks made stale by later edits; model completion reports are separate from these facts.
1363
1364 For interactive frontends, Plan Mode is always an explicit user choice. Select
1365 Plan in the desktop collaboration-mode control or cycle to Plan with
1366 `Shift+Tab` in the CLI. Reasonix first drafts a plan, then waits for approval
1367 before the workflow switches to implementation. Tool calls made while drafting
1368 still use the current Permissions and Sandbox. Legacy `agent.auto_plan` and
1369 `agent.auto_plan_classifier` values are ignored and removed from the user config
1370 during upgrade. The visible reasoning language can be changed with
1371 `/reasoning-language auto|zh|en` in the
1372 session, or `reasonix config reasoning-language auto|zh|en` in a shell/script.
1373 Pass `--local`
1374 to the reasoning-language shell command only when you intentionally want a
1375 project-local override.
1376
1377 The why behind separate sessions (keeping each model's prefix cache-stable) is in
1378 [`SPEC.md` §3.5](./SPEC.md#35-two-model-collaboration-coordinator).
1379
1379 lines MARKDOWN