| 1 | # Reasonix configuration. |
| 2 | # Resolution order: flag > ./reasonix.toml > <Reasonix home>/config.toml > built-in defaults. |
| 3 | # Fields marked user/global only are not overridden by ./reasonix.toml. |
| 4 | # Provider entries name secrets via api_key_env; saved key values live in |
| 5 | # Reasonix's global <Reasonix home>/.env. Never put API key values here. |
| 6 | |
| 7 | default_model = "deepseek" # a provider name (→ its default model) or "provider/model" |
| 8 | # language = "zh" # ui language; empty = auto-detect from $LANG / $REASONIX_LANG |
| 9 | |
| 10 | [ui] |
| 11 | theme = "auto" # auto|dark|light; controls CLI colors only; REASONIX_THEME can override per run |
| 12 | # theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases |
| 13 | # shortcut_layout = "desktop" # classic|desktop; compatibility setting; Shift+Tab toggles Plan, Ctrl+Y toggles YOLO |
| 14 | # cursor_shape = "bar" # block|underline|bar; text input cursor shape; slim default avoids covering CJK characters |
| 15 | show_turn_usage = true # CLI/TUI: show per-request token and cost receipts in transcript scrollback |
| 16 | |
| 17 | [desktop] |
| 18 | # language = "auto" # auto|en|zh; auto follows the browser/OS locale |
| 19 | # currency = "auto" # auto|CNY|USD; explicitly set it independently from language |
| 20 | layout_style = "classic" # classic|workbench|creation; desktop layout style |
| 21 | # theme = "auto" # desktop only: auto|dark|light |
| 22 | # terminal_theme = "auto" # integrated terminal: auto|dark|light; auto follows the desktop app |
| 23 | # theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases |
| 24 | |
| 25 | [notifications] |
| 26 | enabled = false # system notifications for CLI and desktop turns; default off |
| 27 | turn_done = true # notify when a turn finishes |
| 28 | approval_request = true # notify when a tool approval is waiting |
| 29 | ask_request = true # notify when a question is waiting |
| 30 | |
| 31 | [agent] |
| 32 | # system_prompt = "You are ..." # custom persona/prompt; unset or empty = built-in default |
| 33 | # system_prompt_file = "prompts/system.md" # project paths stay in <workspace>; user paths may fall back to <reasonix home> |
| 34 | temperature = 0.0 |
| 35 | # recovery_model = "" # optional reviewer for low-risk automatic recovery; falls back to guardian_model then main model |
| 36 | # reasoning_language = "auto" # visible reasoning text: auto|zh|en |
| 37 | # plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash uses Permissions |
| 38 | soft_compact_ratio = 0.5 # notice only; keeps the cache-first prefix intact |
| 39 | tool_result_snip_ratio = 0.6 # snip stale tool results before summary compaction |
| 40 | compact_ratio = 0.8 # try compacting when prompt reaches this fraction |
| 41 | compact_force_ratio = 0.9 # force compacting at this high-water mark |
| 42 | # planner_model = "deepseek-pro" # optional: enable two-model collaboration |
| 43 | # subagent_model = "deepseek-pro" # optional default for runAs=subagent skills |
| 44 | # subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" } # per-skill overrides |
| 45 | # max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills) |
| 46 | # max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths |
| 47 | # output_style = "explanatory" # persona/tone folded into the prompt: explanatory | learning | concise, |
| 48 | # or a custom .reasonix/output-styles/<name>.md ; empty = default |
| 49 | |
| 50 | # A provider is a vendor endpoint (one base_url + key) that offers one or more |
| 51 | # models. Use `models = [...]` to expose several under a single entry — switching |
| 52 | # models reuses the same connection; no need to re-declare base_url/api_key. |
| 53 | # In the desktop app, Settings -> Model -> Access -> Add provider includes |
| 54 | # recommended editable presets for Kimi CN/Global, Kimi Coding Plan, MiMo API |
| 55 | # and Anthropic/token-plan regions, MiniMax CN/Global API and Anthropic routes, |
| 56 | # GLM/Z.AI CN/Global API and coding-plan routes, OpenCode Go/Zen, Qwen/DashScope |
| 57 | # CN/Global API and coding-plan routes, Token Rhythm (基元律动), StepFun, |
| 58 | # NovitaAI, GMI, Vercel AI Gateway, HuggingFace, NVIDIA, KiloCode, and Ollama Cloud. |
| 59 | [[providers]] |
| 60 | name = "deepseek" |
| 61 | kind = "openai" |
| 62 | base_url = "https://api.deepseek.com" |
| 63 | models = ["deepseek-v4-flash", "deepseek-v4-pro"] |
| 64 | default = "deepseek-v4-flash" # optional; defaults to the first of `models` |
| 65 | api_key_env = "DEEPSEEK_API_KEY" |
| 66 | context_window = 1000000 |
| 67 | # Optional per-model context budgets. Omitted models inherit context_window. |
| 68 | # model_overrides = { "deepseek-v4-flash" = { context_window = 1000000 } } |
| 69 | # Official DeepSeek providers use CNY or USD regional prices from |
| 70 | # [desktop].currency; auto follows the selected language and defaults to USD. |
| 71 | # Set prices explicitly only when you want to pin custom rates. |
| 72 | # prices = { "deepseek-v4-flash" = { cache_hit = 0.02, input = 1, output = 2, currency = "¥" }, "deepseek-v4-pro" = { cache_hit = 0.025, input = 3, output = 6, currency = "¥" } } # per 1M tokens |
| 73 | # DeepSeek thinking is always on; effort: high | max. Omit for auto (provider default). |
| 74 | effort = "high" |
| 75 | |
| 76 | # A single-model provider still works (use `model = "..."`) — pick this form when |
| 77 | # a model needs its own base_url. Use model_overrides when models share an endpoint |
| 78 | # but need distinct context windows or capability settings. |
| 79 | |
| 80 | # Custom /effort levels for a provider. When supported_efforts is set, the |
| 81 | # /effort command exposes these levels; default_effort is what "/effort auto" |
| 82 | # (or unset) resolves to. Leave both commented to keep the built-in defaults |
| 83 | # (DeepSeek models: high|max; Anthropic: low|medium|high|xhigh|max). DeepSeek |
| 84 | # models behind a proxy are detected by model name; set reasoning_protocol = |
| 85 | # "none" to disable that or "openai" to force ordinary reasoning_effort. |
| 86 | # Other OpenAI-compatible providers don't expose /effort unless you opt in here. |
| 87 | # |
| 88 | # [[providers]] |
| 89 | # name = "openai-compatible-custom" |
| 90 | # kind = "openai" |
| 91 | # base_url = "https://api.example.com/v1" |
| 92 | # model = "example-reasoning-model" |
| 93 | # api_key_env = "EXAMPLE_API_KEY" |
| 94 | # reasoning_protocol = "openai" # auto|deepseek|openai|none |
| 95 | # supported_efforts = ["low", "medium", "high"] |
| 96 | # default_effort = "high" |
| 97 | |
| 98 | # Anthropic (Claude) — the "anthropic" kind speaks the Messages API directly (no |
| 99 | # OpenAI shim). base_url is optional (defaults to https://api.anthropic.com). Note: |
| 100 | # this provider does not enable extended thinking and does not send temperature — |
| 101 | # current Claude models reject sampling params (see internal/provider/anthropic). |
| 102 | # Some Anthropic-compatible gateways use Bearer auth instead of x-api-key; set |
| 103 | # auth_header = true for those (for example MiniMax Global or Vercel AI Gateway). |
| 104 | [[providers]] |
| 105 | name = "claude" |
| 106 | kind = "anthropic" |
| 107 | model = "claude-opus-4-8" |
| 108 | api_key_env = "ANTHROPIC_API_KEY" |
| 109 | context_window = 1000000 |
| 110 | price = { cache_hit = 0.5, input = 5, output = 25, currency = "$" } # per 1M tokens |
| 111 | # Extended thinking (anthropic kind only; round-trips the signed reasoning block |
| 112 | # across tool calls). Omit to disable. effort: low | medium | high | xhigh | max. |
| 113 | thinking = "adaptive" |
| 114 | effort = "high" |
| 115 | |
| 116 | [environment] |
| 117 | enabled = true # inject a stable startup summary of OS, shell, and common tools into the prompt |
| 118 | # [environment.tools] |
| 119 | # go = "/opt/homebrew/bin/go" # optional trusted executable path; workspace-local paths are not auto-executed |
| 120 | |
| 121 | [tools] |
| 122 | enabled = [] # empty = all built-in tools |
| 123 | bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap |
| 124 | mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap; per-server overrides may raise it |
| 125 | mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it |
| 126 | |
| 127 | [tools.background_jobs] |
| 128 | stalled_warning_seconds = 900 # warn once per background job after this many quiet seconds; 0 disables |
| 129 | |
| 130 | # Sandbox confinement bounds the blast radius of tool calls. Writers may only |
| 131 | # modify workspace_root (empty = current directory) plus allow_write. forbid_read |
| 132 | # hides sensitive directories from read/list/search tools and from sandboxed bash |
| 133 | # while OS-level sandboxing is active. Use absolute paths or ${HOME}; "~" is not |
| 134 | # expanded in config values. |
| 135 | # [sandbox] |
| 136 | # workspace_root = "" |
| 137 | # allow_write = ["/tmp"] |
| 138 | # forbid_read = ["${HOME}/.ssh"] |
| 139 | # bash = "enforce" # enforce (default on macOS/Linux) | off; Windows fixes this to off because it has no OS-level Bash sandbox |
| 140 | # network = true |
| 141 | |
| 142 | # Skills are invokable playbooks (SKILL.md / <name>.md with frontmatter), found |
| 143 | # under .reasonix/skills, .agents/skills, .agent/skills, .claude/skills (project) |
| 144 | # and the same dirs under ~ (global). Built-ins (explore/research/review/security-review/test) |
| 145 | # ship out of the box. The model invokes them via run_skill / explore / …; you |
| 146 | # invoke them via /<name>. Manage with /skill (list, show, enable, disable, new, paths). |
| 147 | # [skills] |
| 148 | # paths = ["~/my-skills", "../shared/skills"] # extra "custom"-scope skill roots |
| 149 | # excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders |
| 150 | # disabled_skills = ["review"] # hide from prompt, slash invocation, and skill tools |
| 151 | |
| 152 | # Hooks run shell commands around the loop (PreToolUse / PostToolUse / |
| 153 | # PermissionRequest / UserPromptSubmit / Stop). They are NOT configured here — put them in |
| 154 | # settings.json: <Reasonix home>/settings.json (global, always on) and |
| 155 | # <project>/.reasonix/settings.json (project, loaded automatically). |
| 156 | # Exit 0 = pass, exit 2 = block (PreToolUse / UserPromptSubmit only). Example |
| 157 | # <Reasonix home>/settings.json: |
| 158 | # { "hooks": { |
| 159 | # "PreToolUse": [ { "match": "bash", "command": "my-guard.sh" } ], |
| 160 | # "PermissionRequest": [ { "match": "bash", "command": "notify-send 'approval needed'" } ], |
| 161 | # "PostToolUse": [ { "match": ".*file", "command": "gofmt -w ." } ], |
| 162 | # "Stop": [ { "command": "notify-send 'turn done'" } ] } } |
| 163 | |
| 164 | # A custom status line: a command whose first stdout line replaces the built-in |
| 165 | # data row. It receives {"model","contextUsed","contextWindow"} as JSON on stdin. |
| 166 | # [statusline] |
| 167 | # command = "my-statusline.sh" |
| 168 | |
| 169 | # External stdio plugins (MCP-compatible); each is a standalone executable. |
| 170 | # [[plugins]] |
| 171 | # name = "example" |
| 172 | # command = "reasonix-plugin-example" |
| 173 | # # Startup may continue in the background after the first caller stops waiting. |
| 174 | # # startup_timeout_seconds = 60 |
| 175 | # # Per-server MCP call timeout; 0 keeps the global/default cap. |
| 176 | # # call_timeout_seconds = 600 |
| 177 | # # Raw MCP tool names with per-tool call timeouts. |
| 178 | # # tool_timeout_seconds = { "generate_video" = 1800 } |
| 179 | # # Enabled MCP servers connect automatically in the background after session |
| 180 | # # start. Use /mcp or the desktop MCP panel to refresh, reconnect, or disable. |
| 181 | |
| 182 | # Bot gateway: multi-channel IM bot for QQ, Feishu, and WeChat. |
| 183 | # Start with `reasonix bot start --channels qq,feishu,weixin`. |
| 184 | # All secrets are read from environment variables; never put keys here. |
| 185 | # [bot] |
| 186 | # enabled = false |
| 187 | # model = "" # 用于 bot 的模型,空则用 default_model |
| 188 | # max_steps = 25 |
| 189 | # debounce_ms = 1500 # 消息合并窗口(毫秒) |
| 190 | # queue_mode = "steer" # steer|followup|collect|interrupt |
| 191 | # queue_cap = 20 # 每个会话最多保留的排队消息数 |
| 192 | # queue_drop = "summarize" # summarize|old|new |
| 193 | # ignore_self_messages = true # 忽略 bot 自己发出的回声消息 |
| 194 | # |
| 195 | # [bot.self_user_ids] |
| 196 | # qq = [] # 可选:各平台 bot 自己的 user/open id |
| 197 | # feishu = [] |
| 198 | # weixin = [] |
| 199 | # |
| 200 | # [bot.control] |
| 201 | # enabled = false # 本机 loopback HTTP API:GET /status, GET /metrics, POST /send |
| 202 | # addr = "127.0.0.1:37913" |
| 203 | # token_env = "REASONIX_BOT_CONTROL_TOKEN" |
| 204 | # |
| 205 | # [[bot.routes]] |
| 206 | # connection_id = "feishu-lark" # 可选;空字段表示通配 |
| 207 | # chat_type = "group" |
| 208 | # chat_id = "oc_xxx" |
| 209 | # workspace_root = "/path/to/project" |
| 210 | # model = "deepseek-pro" |
| 211 | # tool_approval_mode = "ask" |
| 212 | # |
| 213 | # [bot.pairing] |
| 214 | # enabled = true |
| 215 | # request_ttl_minutes = 60 |
| 216 | # max_pending_per_platform = 3 |
| 217 | # |
| 218 | # [bot.allowlist] |
| 219 | # enabled = true |
| 220 | # allow_all = false # true 会允许所有可触达用户远程触发 bot,仅限受控环境 |
| 221 | # qq_users = [] |
| 222 | # feishu_users = [] |
| 223 | # weixin_users = [] |
| 224 | # qq_approvers = [] # 为空时沿用 allowlist 用户可审批的兼容行为 |
| 225 | # feishu_approvers = [] |
| 226 | # weixin_approvers = [] |
| 227 | # qq_admins = [] # 配置后 /yolo 和 /mode 仅限 admin |
| 228 | # feishu_admins = [] |
| 229 | # weixin_admins = [] |
| 230 | # qq_groups = [] |
| 231 | # feishu_groups = [] |
| 232 | # weixin_groups = [] |
| 233 | # |
| 234 | # [bot.qq] |
| 235 | # enabled = false |
| 236 | # app_id = "" |
| 237 | # app_secret_env = "QQ_BOT_APP_SECRET" |
| 238 | # sandbox = false # true 使用 QQ 沙箱 API / gateway |
| 239 | # |
| 240 | # [bot.feishu] |
| 241 | # enabled = false |
| 242 | # app_id = "" |
| 243 | # app_secret_env = "FEISHU_BOT_APP_SECRET" |
| 244 | # verification_token = "" |
| 245 | # mode = "webhook" # webhook | websocket(websocket 需接官方 SDK 长连接) |
| 246 | # webhook_port = 8080 |
| 247 | # require_mention = true |
| 248 | # |
| 249 | # [bot.weixin] |
| 250 | # enabled = false |
| 251 | # account_id = "default" |
| 252 | # token_env = "WEIXIN_BOT_TOKEN" |
| 253 | # api_base = "https://ilinkai.weixin.qq.com" # Tencent iLink Bot API base URL |
| 254 | |
| 255 | [serve] |
| 256 | # Authentication for the HTTP serve frontend (reasonix serve). |
| 257 | # auth_mode = "none" # none | token | password |
| 258 | # token = "" # pre-shared token for auth_mode = "token" (auto-generated if empty) |
| 259 | # password_hash = "" # bcrypt hash for auth_mode = "password". Generate with: reasonix serve --hash-password <password> |
| 260 | # behind_proxy = false # set true when behind a trusted reverse proxy (nginx, Caddy, etc.) that sets X-Forwarded-* headers |
| 261 |