# Reasonix configuration. # Resolution order: flag > ./reasonix.toml > ~/.reasonix/config.toml > built-in defaults. # Fields marked user/global only are not overridden by ./reasonix.toml. # Secrets are named via api_key_env and stored in Reasonix's global .env; never put keys here. config_version = 5 # schema marker for diagnostics; old versions may ignore it default_model = "deepseek-flash/deepseek-v4-flash" language = "EN" # ui/model language; empty = auto-detect from $LANG / $REASONIX_LANG credentials_store = "auto" # legacy compatibility; provider keys are saved in Reasonix's global .env [ui] theme = "auto" # auto|dark|light; CLI colors only; REASONIX_THEME can override per run # theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases # shortcut_layout = "desktop" # classic|desktop; compatibility setting; Shift+Tab toggles Plan, Ctrl+Y toggles YOLO # cursor_shape = "bar" # block|underline|bar; text input cursor shape # show_reasoning = true # CLI: show thinking text by default; false = collapsed (toggle with Ctrl+O) [desktop] language = "en" # desktop UI language; empty/auto = browser/OS auto-detect # currency = "USD" # official pricing currency: CNY|USD; empty/auto follows language layout_style = "workbench" # desktop layout: classic|workbench|creation theme = "auto" # desktop only: auto|dark|light terminal_theme = "auto" # integrated terminal: auto|dark|light; auto follows the desktop app # theme_style = "graphite" # graphite|aurora|slate|carbon|nocturne|amber and legacy aliases # external_opener = "vscode" # desktop Open control: installed application id close_behavior = "background" # desktop: quit|background when the window close button is clicked status_bar_style = "text" # desktop: icon|text metric labels in the bottom status bar status_bar_items = ["model", "workspace", "git_branch", "cache", "cache_avg", "session_tokens", "turn_tokens", "turn_cost", "session_turns", "context", "compact", "cost", "balance"] # desktop: ordered visible bottom status bar items default_tool_approval_mode = "auto" # desktop: Ask/Auto/YOLO default for newly-created sessions check_updates = true # desktop: check for new versions on startup telemetry = true # desktop: anonymous launch ping + scrubbed next-launch native crash diagnostics; never content metrics = true # desktop: aggregate quality/lifecycle metrics (anonymous signal/bucket counts); never content expand_thinking = false # desktop: show reasoning text expanded by default; false = collapsed display_mode = "standard" # desktop: standard|compact transcript display mode [telemetry] cli_metrics = "auto" # CLI content-free usage metrics: auto|on|off; auto requires a local interactive terminal [notifications] enabled = false # system notifications for CLI and desktop turns; default off turn_done = true # notify when a turn finishes approval_request = true # notify when a tool approval is waiting ask_request = true # notify when a question is waiting [network] proxy_mode = "auto" # auto|env|custom|off; auto currently uses env proxy # proxy_url = "socks5://127.0.0.1:7890" # optional custom override # no_proxy = "localhost,127.0.0.1,.local" # honored for proxy_mode = "custom" [network.proxy] type = "socks5" # http|https|socks5|socks5h # server = "127.0.0.1" # port = 7890 # username = "" # password = "${REASONIX_PROXY_PASSWORD}" # optional; supports ${VAR} expansion [environment] enabled = true # inject a stable startup environment summary into the model prompt # [environment.tools] # go = "/opt/homebrew/bin/go" # trusted executable path; workspace-local paths are not auto-executed [agent] # system_prompt = """...""" # omit to use the built-in prompt for this version # system_prompt_file = "prompts/system.md" # project paths stay in ; user paths may fall back to temperature = 0.0 # recovery_model = "deepseek-pro" # optional; falls back to guardian then main model # reasoning_language = "zh" # visible reasoning language: auto|zh|en soft_compact_ratio = 0.5 # notice only; keeps cache-first prefix intact tool_result_snip_ratio = 0.6 # snip stale tool results at this fraction before summary compaction compact_ratio = 0.8 # try compacting when prompt reaches this fraction compact_force_ratio = 0.9 # force compacting at this high-water mark # keep = ["errors"] # compaction keep policy: errors, user_marked # recent_keep = 2 # minimum recent messages kept verbatim cold_resume_prune = true # elide stale tool results when reopening a session past the provider cache window # plan_mode_read_only_commands = ["gh issue view"] # legacy compatibility only; Plan bash uses Permissions # planner_model = "deepseek-pro" # optional: enable two-model collaboration # subagent_model = "deepseek-pro" # optional default for runAs=subagent skills # subagent_models = { review = "deepseek-pro", security_review = "deepseek-pro" } # per-skill overrides # subagent_effort = "high" # optional default effort for subagents # subagent_efforts = { review = "max", task = "high" } # per-tool/skill effort overrides # max_subagent_depth = 2 # nested subagent delegation depth; set 1 to disable nested delegation # max_subagent_concurrency = 6 # session-wide sub-agent concurrency (task/fleet/skills) # max_parallel_writers = 3 # concurrent writers with non-overlapping write_paths # output_style = "explanatory" # explanatory | learning | concise | custom; empty = default [[providers]] name = "deepseek-flash" kind = "openai" base_url = "https://api.deepseek.com" model = "deepseek-v4-flash" api_key_env = "DEEPSEEK_API_KEY" balance_url = "https://api.deepseek.com/user/balance" # optional; wallet-balance endpoint shown in the status bar context_window = 1000000 # tokens; compaction triggers near this limit price = { cache_hit = 0.0028, input = 0.14, output = 0.28, currency = "$" } # provider-wide fallback, per 1M tokens [[providers]] name = "deepseek-pro" kind = "openai" base_url = "https://api.deepseek.com" model = "deepseek-v4-pro" api_key_env = "DEEPSEEK_API_KEY" balance_url = "https://api.deepseek.com/user/balance" # optional; wallet-balance endpoint shown in the status bar context_window = 1000000 # tokens; compaction triggers near this limit price = { cache_hit = 0.003625, input = 0.435, output = 0.87, currency = "$" } # provider-wide fallback, per 1M tokens [tools] enabled = [] # empty = all built-in tools bash_timeout_seconds = 120 # foreground safety cap; set 0 for no tool-local cap mcp_startup_timeout_seconds = 30 # background initialize + tools/list safety cap; per-plugin overrides may raise it mcp_call_timeout_seconds = 300 # default MCP call safety cap; per-plugin/tool overrides may raise it [tools.background_jobs] stalled_warning_seconds = 900 # warn once per background job after this many quiet seconds; 0 disables [tools.shell] # prefer = "auto" # auto|bash|powershell|pwsh; empty/default = auto-detect # path = "/opt/homebrew/bin/bash" # absolute path to the shell executable; empty = PATH lookup [lsp] enabled = true # language server tools; servers launch lazily when used # [lsp.servers.go] # command = "gopls" # args = [] # extensions = [".go"] [skills] # paths = ["~/my-skills", "../shared/skills"] # extra custom skill roots # excluded_paths = ["~/.agents/skills"] # hide convention roots without deleting folders # max_depth = 3 # nested scan depth; set 1 for legacy root-only discovery # disabled_skills = ["review"] # hide noisy or unwanted skills [permissions] # Per-call gating. mode = writer fallback when no rule matches: ask|allow|deny. # Readers always default to allow. Precedence: deny > ask > allow > fallback. # Rules are "Tool" or "Tool(specifier)"; e.g. Bash(go test:*), Edit(src/**). mode = "ask" # allow_dynamic_bash = false # advanced opt-in; deny/ask and exact rules still take precedence # deny = ["Bash(rm -rf*)", "Bash(git push*)"] # hard-blocked in every mode # allow = ["Bash(go test:*)", "Bash(git status:*)"] # never prompted # ask = ["Edit(src/**)"] # force a prompt even if otherwise allowed [sandbox] # Confine tool blast radius. File-writers (write_file/edit_file/multi_edit/move_file) # may only write under workspace_root (empty = current dir) and allow_write extras. # bash = "enforce" jails each command in an OS sandbox when available; # without one, bash execution is refused. Empty defaults to enforce on macOS/Linux. # Windows has no OS-level Bash sandbox and fixes bash = "off". # network allows sandboxed bash egress. # workspace_root = "" # default: current working directory # allow_write = ["/tmp"] # extra dirs writers may also modify # forbid_read = [] # dirs the agent cannot read or list bash = "enforce" network = true [statusline] # A custom status line: a command whose first stdout line replaces the built-in # data row. It receives {"model","contextUsed","contextWindow","cwd"} as JSON on stdin. # command = "my-statusline.sh" # Bot gateway: multi-channel IM bot for QQ, Feishu/Lark, and WeChat. [bot] enabled = false # model = "" # empty = default_model tool_approval_mode = "ask" # ask|auto|yolo; yolo skips tool approvals only max_steps = 25 debounce_ms = 1500 queue_mode = "steer" # steer|followup|collect|interrupt queue_cap = 20 queue_drop = "summarize" # summarize|old|new ignore_self_messages = true # ignore bot echo by returned message_id and configured self user ids [bot.self_user_ids] qq = [] feishu = [] weixin = [] [bot.control] enabled = false # local loopback HTTP API for status/send; requires Bearer token addr = "127.0.0.1:37913" token_env = "REASONIX_BOT_CONTROL_TOKEN" [bot.pairing] enabled = true request_ttl_minutes = 60 max_pending_per_platform = 3 [bot.allowlist] enabled = true allow_all = false qq_users = [] feishu_users = [] weixin_users = [] qq_approvers = [] feishu_approvers = [] weixin_approvers = [] qq_admins = [] feishu_admins = [] weixin_admins = [] qq_groups = [] feishu_groups = [] weixin_groups = [] [bot.qq] enabled = false app_id = "" app_secret_env = "QQ_BOT_APP_SECRET" sandbox = false [bot.feishu] enabled = false app_id = "" domain = "feishu" app_secret_env = "FEISHU_BOT_APP_SECRET" verification_token = "" mode = "webhook" webhook_port = 8080 require_mention = true [bot.weixin] enabled = false account_id = "default" token_env = "WEIXIN_BOT_TOKEN" api_base = "https://ilinkai.weixin.qq.com" [secrets] # credential protection; user/global only, ./reasonix.toml cannot override # filter_subprocess_env = false # opt-in; stripping tokens breaks gh, HTTPS git push, npm publish # protect_sensitive_files = false # opt-in; hiding credential files can break legitimate edit workflows # External MCP servers. type: "stdio" (default, a subprocess) | "http" | "sse". # ${VAR} / ${VAR:-default} are expanded from the environment in command/args/env/url/headers. # [[plugins]] # name = "example" # command = "reasonix-plugin-example" # startup_timeout_seconds = 60 # optional initialize + tools/list cap # call_timeout_seconds = 600 # optional per-server MCP call timeout # tool_timeout_seconds = { "generate_video" = 1800 } # raw MCP tool names # [[plugins]] # a remote server over Streamable HTTP # name = "stripe" # type = "http" # url = "https://mcp.stripe.com" # headers = { Authorization = "Bearer ${STRIPE_KEY}" }