| 1 | # ╔══════════════════════════════════════════════════════════════════════════════╗ |
| 2 | # ║ DeepSeek TUI Configuration ║ |
| 3 | # ║ ║ |
| 4 | # ║ Unofficial CLI for DeepSeek Platform - Not affiliated with DeepSeek Inc. ║ |
| 5 | # ╚══════════════════════════════════════════════════════════════════════════════╝ |
| 6 | |
| 7 | # See `docs/CONFIGURATION.md` for how config is loaded (profiles, env overrides, etc.). |
| 8 | |
| 9 | # ───────────────────────────────────────────────────────────────────────────────── |
| 10 | # Active provider + DeepSeek defaults |
| 11 | # ───────────────────────────────────────────────────────────────────────────────── |
| 12 | # Choose which provider to use by default. Per-provider credentials live in the |
| 13 | # `[providers.*]` sections near the bottom of |
| 14 | # this file — keeping both stored at once means `/provider deepseek` and |
| 15 | # `/provider nvidia-nim` (or `--provider fireworks`, `/provider sglang`, `/provider vllm`) toggle without having to |
| 16 | # re-enter keys. Top-level `api_key` / `base_url` are still read as DeepSeek |
| 17 | # defaults when `[providers.deepseek]` is absent (backward compatibility). |
| 18 | provider = "deepseek" # deepseek | nvidia-nim | openrouter | novita | fireworks | sglang | vllm |
| 19 | api_key = "YOUR_DEEPSEEK_API_KEY" # must be non-empty |
| 20 | base_url = "https://api.deepseek.com" |
| 21 | # base_url = "https://api.deepseeki.com" # China users |
| 22 | # base_url = "https://api.deepseek.com/beta" # DeepSeek beta features such as strict tool mode |
| 23 | # Optional custom model request headers for OpenAI-compatible gateways. |
| 24 | # Authorization and Content-Type are managed by the client and cannot be overridden here. |
| 25 | # http_headers = { "X-Model-Provider-Id" = "your-model-provider" } |
| 26 | |
| 27 | # ───────────────────────────────────────────────────────────────────────────────── |
| 28 | # Default Models |
| 29 | # ───────────────────────────────────────────────────────────────────────────────── |
| 30 | # DeepSeek V4 family: |
| 31 | # deepseek-v4-pro — flagship reasoning model on DeepSeek Platform |
| 32 | # deepseek-v4-flash — fast, cost-efficient (legacy aliases: deepseek-chat, deepseek-reasoner) |
| 33 | # deepseek-ai/deepseek-v4-pro — NVIDIA NIM-hosted Pro model ID |
| 34 | # deepseek-ai/deepseek-v4-flash — NVIDIA NIM-hosted Flash model ID |
| 35 | # accounts/fireworks/models/deepseek-v4-pro — Fireworks AI Pro model ID |
| 36 | # deepseek-ai/DeepSeek-V4-Pro — SGLang self-hosted Pro model ID |
| 37 | # deepseek-ai/DeepSeek-V4-Flash — SGLang self-hosted Flash model ID |
| 38 | default_text_model = "deepseek-v4-pro" |
| 39 | |
| 40 | # ───────────────────────────────────────────────────────────────────────────────── |
| 41 | # Thinking Mode (DeepSeek V4 reasoning effort) |
| 42 | # ───────────────────────────────────────────────────────────────────────────────── |
| 43 | # "off" — disables chain-of-thought (thinking.type = disabled) |
| 44 | # "low" — compat-maps to "high" server-side |
| 45 | # "medium" — compat-maps to "high" server-side |
| 46 | # "high" — reasoning_effort = high (DeepSeek default) |
| 47 | # "max" — reasoning_effort = max (deepest reasoning) |
| 48 | # |
| 49 | # Shift+Tab in the TUI cycles between off / high / max. The header shows the |
| 50 | # current tier as a ⚡ chip. |
| 51 | reasoning_effort = "max" |
| 52 | |
| 53 | # ───────────────────────────────────────────────────────────────────────────────── |
| 54 | # Cost Display |
| 55 | # ───────────────────────────────────────────────────────────────────────────────── |
| 56 | # Display estimated usage in USD or CNY. Aliases `yuan` and `rmb` normalize to `cny`. |
| 57 | cost_currency = "usd" # usd | cny |
| 58 | |
| 59 | # ───────────────────────────────────────────────────────────────────────────────── |
| 60 | # Paths |
| 61 | # ───────────────────────────────────────────────────────────────────────────────── |
| 62 | skills_dir = "~/.deepseek/skills" |
| 63 | mcp_config_path = "~/.deepseek/mcp.json" |
| 64 | notes_path = "~/.deepseek/notes.txt" |
| 65 | |
| 66 | memory_path = "~/.deepseek/memory.md" |
| 67 | |
| 68 | # instructions = ["./AGENTS.md", "~/.deepseek/global.md"] |
| 69 | # |
| 70 | # Optional list of additional instruction files concatenated into the |
| 71 | # system prompt in declared order (#454). Useful for layering |
| 72 | # repo-specific rules on top of a global preferences file. Each entry |
| 73 | # is expanded so `~` and env vars work; missing files are skipped with |
| 74 | # a tracing warning. Files are capped at 100 KiB per entry. |
| 75 | # |
| 76 | # Project-level config (.deepseek/config.toml in the workspace) replaces |
| 77 | # the user-level array wholesale rather than merging — list `~/global.md` |
| 78 | # inside the project array if you want both. An explicit empty array |
| 79 | # (`instructions = []`) clears the user list for the current repo. |
| 80 | |
| 81 | # ───────────────────────────────────────────────────────────────────────────────── |
| 82 | # User memory (#489) — opt-in. When enabled, the TUI reads memory_path on |
| 83 | # startup and injects its contents into the system prompt as a |
| 84 | # <user_memory> block, intercepts `# foo` typed in the composer to append |
| 85 | # the line as a timestamped bullet, and registers a `remember` tool the |
| 86 | # model can call to add durable notes itself. |
| 87 | # ───────────────────────────────────────────────────────────────────────────────── |
| 88 | [memory] |
| 89 | # enabled = true # turn the feature on (default: false) |
| 90 | # Override the env-var equivalent: `DEEPSEEK_MEMORY=on` |
| 91 | |
| 92 | # Parsed but currently unused (reserved for future versions): |
| 93 | # tools_file = "./tools.json" |
| 94 | |
| 95 | # ───────────────────────────────────────────────────────────────────────────────── |
| 96 | # Security |
| 97 | # ───────────────────────────────────────────────────────────────────────────────── |
| 98 | allow_shell = true |
| 99 | approval_policy = "on-request" # on-request | untrusted | never |
| 100 | sandbox_mode = "workspace-write" # read-only | workspace-write | danger-full-access | external-sandbox |
| 101 | |
| 102 | # ───────────────────────────────────────────────────────────────────────────────── |
| 103 | # External Sandbox Backend (pluggable remote execution) |
| 104 | # ───────────────────────────────────────────────────────────────────────────────── |
| 105 | # When sandbox_backend is set to "opensandbox", all exec_shell calls are |
| 106 | # routed through an external OpenSandbox-compatible HTTP API instead of |
| 107 | # spawning a local process. The backend sends `POST {sandbox_url}/v1/sandbox/run` |
| 108 | # with `{"cmd": "...", "env": {...}}` and expects |
| 109 | # `{"stdout": "...", "stderr": "...", "exit_code": 0}`. |
| 110 | # |
| 111 | # sandbox_backend = "none" # "none" (default) or "opensandbox" |
| 112 | # sandbox_url = "http://localhost:8080" # OpenSandbox-compatible API base URL |
| 113 | # sandbox_api_key = "YOUR_API_KEY" # Optional Bearer token sent with requests |
| 114 | # |
| 115 | # Env-var overrides: |
| 116 | # DEEPSEEK_SANDBOX_BACKEND → sandbox_backend |
| 117 | # DEEPSEEK_SANDBOX_URL → sandbox_url |
| 118 | # DEEPSEEK_SANDBOX_API_KEY → sandbox_api_key |
| 119 | # |
| 120 | # Example OpenSandbox setup: |
| 121 | # |
| 122 | # sandbox_backend = "opensandbox" |
| 123 | # sandbox_url = "http://localhost:8080" |
| 124 | # sandbox_api_key = "sk-opensandbox-secret" |
| 125 | # |
| 126 | # The backend uses a 30-second HTTP timeout. Background, interactive, and |
| 127 | # TTY modes are not supported with external backends — all commands run |
| 128 | # synchronously via HTTP. |
| 129 | |
| 130 | # auto_allow entries match by command prefix, not raw string. |
| 131 | # See command_safety.rs for the prefix dictionary. |
| 132 | # |
| 133 | # Examples: |
| 134 | # auto_allow = ["git status"] # auto-approves: git status, git status -s, git status --porcelain |
| 135 | # # does NOT auto-approve: git push, git checkout |
| 136 | # auto_allow = ["cargo check", "npm run"] |
| 137 | # |
| 138 | # auto_allow = [] |
| 139 | max_subagents = 10 # optional (1-20) |
| 140 | |
| 141 | # Optional sub-agent tuning. max_concurrent overrides top-level max_subagents. |
| 142 | # [subagents] |
| 143 | # max_concurrent = 10 |
| 144 | |
| 145 | # Optional managed policy paths (defaults to /etc/deepseek/*.toml on unix): |
| 146 | # managed_config_path = "/etc/deepseek/managed_config.toml" |
| 147 | # requirements_path = "/etc/deepseek/requirements.toml" |
| 148 | |
| 149 | # ───────────────────────────────────────────────────────────────────────────────── |
| 150 | # Per-provider credentials (peer providers — NIM is first-class, not a flag) |
| 151 | # ───────────────────────────────────────────────────────────────────────────────── |
| 152 | # Providers can be stored at once; `provider = "..."` (top of file) or |
| 153 | # `/provider deepseek` / `/provider nvidia-nim` / `/provider fireworks` switches between them without |
| 154 | # having to re-enter keys. Env vars override anything set here: |
| 155 | # DeepSeek: DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, DEEPSEEK_MODEL |
| 156 | # NIM: NVIDIA_API_KEY (or NVIDIA_NIM_API_KEY), NIM_BASE_URL |
| 157 | # (or NVIDIA_NIM_BASE_URL / NVIDIA_BASE_URL), NVIDIA_NIM_MODEL |
| 158 | # Fireworks: FIREWORKS_API_KEY, FIREWORKS_BASE_URL |
| 159 | # SGLang: SGLANG_BASE_URL, SGLANG_MODEL, optional SGLANG_API_KEY |
| 160 | # vLLM: VLLM_BASE_URL, VLLM_MODEL, optional VLLM_API_KEY |
| 161 | |
| 162 | # DeepSeek Platform (https://platform.deepseek.com) |
| 163 | [providers.deepseek] |
| 164 | # api_key = "YOUR_DEEPSEEK_API_KEY" |
| 165 | # base_url = "https://api.deepseek.com" |
| 166 | # model = "deepseek-v4-pro" |
| 167 | # http_headers = { "X-Model-Provider-Id" = "your-model-provider" } # optional custom request headers |
| 168 | |
| 169 | # NVIDIA NIM-hosted DeepSeek V4 (https://build.nvidia.com) |
| 170 | [providers.nvidia_nim] |
| 171 | # api_key = "YOUR_NVIDIA_API_KEY" |
| 172 | # base_url = "https://integrate.api.nvidia.com/v1" |
| 173 | # model = "deepseek-ai/deepseek-v4-pro" # or deepseek-ai/deepseek-v4-flash |
| 174 | |
| 175 | # Fireworks AI-hosted DeepSeek V4 (https://fireworks.ai) |
| 176 | [providers.fireworks] |
| 177 | # api_key = "YOUR_FIREWORKS_API_KEY" |
| 178 | # base_url = "https://api.fireworks.ai/inference/v1" |
| 179 | # model = "accounts/fireworks/models/deepseek-v4-pro" |
| 180 | |
| 181 | # Self-hosted SGLang OpenAI-compatible server |
| 182 | [providers.sglang] |
| 183 | # api_key = "OPTIONAL_SGLANG_TOKEN" |
| 184 | # base_url = "http://localhost:30000/v1" |
| 185 | # model = "deepseek-ai/DeepSeek-V4-Pro" # or deepseek-ai/DeepSeek-V4-Flash |
| 186 | |
| 187 | # Self-hosted vLLM OpenAI-compatible server |
| 188 | [providers.vllm] |
| 189 | # api_key = "OPTIONAL_VLLM_TOKEN" |
| 190 | # base_url = "http://localhost:8000/v1" |
| 191 | # model = "deepseek-ai/DeepSeek-V4-Pro" # or deepseek-ai/DeepSeek-V4-Flash |
| 192 | |
| 193 | # ───────────────────────────────────────────────────────────────────────────────── |
| 194 | # Network Policy (#135) |
| 195 | # ───────────────────────────────────────────────────────────────────────────────── |
| 196 | # Per-domain allow/deny rules for outbound network calls made by the TUI's |
| 197 | # tools (`fetch_url`, `web_search`) and the MCP HTTP transport. Stdio MCP |
| 198 | # servers and direct LLM API calls are unaffected. |
| 199 | # |
| 200 | # Precedence: deny wins. A host listed in both `allow` and `deny` is denied. |
| 201 | # |
| 202 | # Host-matching rules: |
| 203 | # - Exact match: `api.deepseek.com` matches only `api.deepseek.com`. |
| 204 | # - Subdomain wildcard: an entry starting with `.` (e.g. `.example.com`) |
| 205 | # matches `api.example.com` and `a.b.example.com` but not the apex |
| 206 | # `example.com`. To cover both, list both. `*.example.com` is also accepted. |
| 207 | # |
| 208 | # Defaults are intentionally conservative: when this section is absent, no |
| 209 | # policy is enforced (mirrors pre-v0.7.0 behavior). To opt in: |
| 210 | # |
| 211 | # [network] |
| 212 | # default = "prompt" # allow | deny | prompt |
| 213 | # allow = ["api.deepseek.com", "github.com", ".githubusercontent.com"] |
| 214 | # deny = [] |
| 215 | # audit = true # one line per call to ~/.deepseek/audit.log |
| 216 | |
| 217 | # ───────────────────────────────────────────────────────────────────────────────── |
| 218 | # Skills (#140) |
| 219 | # ───────────────────────────────────────────────────────────────────────────────── |
| 220 | # Settings for the `/skill install <spec>` community-skill installer. |
| 221 | # * registry_url — curated index.json that resolves bare names to |
| 222 | # `github:owner/repo` specs. Override to point at |
| 223 | # a private fork or internal mirror. |
| 224 | # * max_install_size_bytes — per-skill uncompressed size cap. Tarballs that |
| 225 | # exceed this limit are rejected during validation. |
| 226 | # Default: 5 MiB. |
| 227 | # |
| 228 | # `/skill install` is gated by `[network]`. Make sure `github.com` and |
| 229 | # `raw.githubusercontent.com` are reachable (default `prompt` is fine — you'll |
| 230 | # be asked once and can persist) before running it. |
| 231 | # |
| 232 | # [skills] |
| 233 | # registry_url = "https://raw.githubusercontent.com/Hmbown/deepseek-skills/main/index.json" |
| 234 | # max_install_size_bytes = 5_242_880 |
| 235 | |
| 236 | # ───────────────────────────────────────────────────────────────────────────────── |
| 237 | # TUI |
| 238 | # ───────────────────────────────────────────────────────────────────────────────── |
| 239 | [tui] |
| 240 | alternate_screen = "auto" # auto | always | never |
| 241 | mouse_capture = true # true copies only transcript user/assistant text; false uses raw terminal selection/copy |
| 242 | terminal_probe_timeout_ms = 500 # optional startup terminal-mode timeout (100-5000ms) |
| 243 | osc8_links = true # emit OSC 8 escapes around URLs (Cmd+click in iTerm2/Ghostty/Kitty/WezTerm/Terminal.app 13+); set false for terminals that misrender |
| 244 | # notification_condition = "always" # always | never — overrides [notifications].threshold_secs. |
| 245 | # "always" = notify on every successful turn (no threshold); |
| 246 | # "never" = suppress all turn-completion notifications; |
| 247 | # unset = use [notifications] defaults (recommended). |
| 248 | # locale = "auto" # UI chrome language: auto | en | ja | zh-Hans | pt-BR |
| 249 | # # "auto" reads LC_ALL → LC_MESSAGES → LANG; falls back to English. |
| 250 | # # Override: `locale = "zh-Hans"` for Simplified Chinese regardless of OS locale. |
| 251 | # # Also settable at runtime: /config locale zh-Hans |
| 252 | # # Note: this only affects TUI labels/chrome — it does NOT change model output language. |
| 253 | |
| 254 | # ───────────────────────────────────────────────────────────────────────────────── |
| 255 | # Feature Flags |
| 256 | # ───────────────────────────────────────────────────────────────────────────────── |
| 257 | [features] |
| 258 | shell_tool = true |
| 259 | subagents = true |
| 260 | web_search = true # enables canonical web.run plus the compatibility web_search alias |
| 261 | apply_patch = true |
| 262 | mcp = true |
| 263 | exec_policy = true |
| 264 | |
| 265 | # ───────────────────────────────────────────────────────────────────────────────── |
| 266 | # Retry Configuration |
| 267 | # ───────────────────────────────────────────────────────────────────────────────── |
| 268 | [retry] |
| 269 | enabled = true |
| 270 | max_retries = 3 |
| 271 | initial_delay = 1.0 |
| 272 | max_delay = 60.0 |
| 273 | exponential_base = 2.0 |
| 274 | |
| 275 | # ───────────────────────────────────────────────────────────────────────────────── |
| 276 | # Context Compaction |
| 277 | # ───────────────────────────────────────────────────────────────────────────────── |
| 278 | # Auto-compaction is a saved UI setting edited with `/config` (`auto_compact`). |
| 279 | # There is no config-file `[compaction]` table yet; detailed thresholds are |
| 280 | # chosen by the TUI from the active model/context budget. |
| 281 | |
| 282 | # Append-only Flash seams are experimental and opt-in while the v0.7.5 |
| 283 | # context/cache audit validates prefix-cache behavior. |
| 284 | [context] |
| 285 | enabled = false |
| 286 | verbatim_window_turns = 16 |
| 287 | # Thresholds are based on the active request input estimate, not lifetime |
| 288 | # summed API usage. |
| 289 | l1_threshold = 192000 |
| 290 | l2_threshold = 384000 |
| 291 | l3_threshold = 576000 |
| 292 | # Hard cycle also reserves the normal 262144-token output budget plus 1024 |
| 293 | # safety tokens against the model window. |
| 294 | cycle_threshold = 768000 |
| 295 | seam_model = "deepseek-v4-flash" |
| 296 | |
| 297 | # ───────────────────────────────────────────────────────────────────────────────── |
| 298 | # Workshop / Large-Output Routing (#548) |
| 299 | # ───────────────────────────────────────────────────────────────────────────────── |
| 300 | # Tool outputs exceeding `large_output_threshold_tokens` are routed through a |
| 301 | # V4-Flash synthesis sub-agent. Only the synthesis reaches the parent context; |
| 302 | # the raw text is stored in the workshop variable `last_tool_result` so the |
| 303 | # parent can call `promote_to_context` later if it needs the full content. |
| 304 | # |
| 305 | # Per-tool overrides let high-volume tools (e.g. exec_shell) use tighter |
| 306 | # thresholds without changing the global default. |
| 307 | # |
| 308 | # Add `raw = true` to any tool call to bypass routing for that invocation. |
| 309 | # |
| 310 | # [workshop] |
| 311 | # large_output_threshold_tokens = 4096 |
| 312 | # [workshop.per_tool_thresholds] |
| 313 | # exec_shell = 2048 # shell output synthesised aggressively |
| 314 | # grep_files = 2048 |
| 315 | # web_search = 8192 # web results can be large; give them more room |
| 316 | |
| 317 | # ───────────────────────────────────────────────────────────────────────────────── |
| 318 | # Capacity Controller (runtime pressure guardrails) |
| 319 | # ───────────────────────────────────────────────────────────────────────────────── |
| 320 | [capacity] |
| 321 | enabled = false |
| 322 | low_risk_max = 0.50 |
| 323 | medium_risk_max = 0.62 |
| 324 | severe_min_slack = -0.25 |
| 325 | severe_violation_ratio = 0.40 |
| 326 | refresh_cooldown_turns = 6 |
| 327 | replan_cooldown_turns = 5 |
| 328 | max_replay_per_turn = 1 |
| 329 | min_turns_before_guardrail = 4 |
| 330 | profile_window = 8 |
| 331 | deepseek_v3_2_chat_prior = 3.9 |
| 332 | deepseek_v3_2_reasoner_prior = 4.1 |
| 333 | deepseek_v4_pro_prior = 3.5 |
| 334 | deepseek_v4_flash_prior = 4.2 |
| 335 | fallback_default_prior = 3.8 |
| 336 | |
| 337 | # ───────────────────────────────────────────────────────────────────────────────── |
| 338 | # Profile Example (for multiple environments) |
| 339 | # ───────────────────────────────────────────────────────────────────────────────── |
| 340 | # Select a profile with `deepseek --profile <name>` or `DEEPSEEK_PROFILE=<name>`. |
| 341 | [profiles.work] |
| 342 | api_key = "WORK_DEEPSEEK_API_KEY" |
| 343 | base_url = "https://api.deepseek.com" |
| 344 | |
| 345 | [profiles.dev] |
| 346 | api_key = "DEV_DEEPSEEK_API_KEY" |
| 347 | allow_shell = true |
| 348 | |
| 349 | [profiles.nvidia-nim] |
| 350 | provider = "nvidia-nim" |
| 351 | api_key = "YOUR_NVIDIA_API_KEY" |
| 352 | base_url = "https://integrate.api.nvidia.com/v1" |
| 353 | default_text_model = "deepseek-ai/deepseek-v4-pro" |
| 354 | |
| 355 | # ───────────────────────────────────────────────────────────────────────────────── |
| 356 | # Desktop Notifications (OSC 9 / BEL on long agent-turn completion) |
| 357 | # ───────────────────────────────────────────────────────────────────────────────── |
| 358 | # Emits an escape sequence to the terminal when a turn **completes successfully** |
| 359 | # and took longer than `threshold_secs`. Failed or cancelled turns are |
| 360 | # intentionally silent. Useful when you tab away from the TUI and want an alert |
| 361 | # for "your task is ready". |
| 362 | # |
| 363 | # method = "auto" # auto | osc9 | bel | off |
| 364 | # auto: OSC 9 for iTerm.app / Ghostty / WezTerm. |
| 365 | # On macOS / Linux, falls back to BEL. |
| 366 | # On Windows, falls back to "off" — BEL maps to the |
| 367 | # system error chime (SystemAsterisk / MB_OK), which |
| 368 | # sounds like an error popup. Set method = "bel" |
| 369 | # explicitly to opt back in (#583). |
| 370 | # osc9: \x1b]9;<msg>\x07 (iTerm2-style; shows macOS notification) |
| 371 | # bel: plain \x07 beep |
| 372 | # off: disable entirely |
| 373 | # threshold_secs = 30 # only notify when the turn took >= this many seconds |
| 374 | # include_summary = false # include elapsed time + cost in the notification body |
| 375 | [notifications] |
| 376 | # method = "auto" |
| 377 | # threshold_secs = 30 |
| 378 | # include_summary = false |
| 379 | |
| 380 | # ───────────────────────────────────────────────────────────────────────────────── |
| 381 | # Workspace Snapshots (#137) |
| 382 | # ───────────────────────────────────────────────────────────────────────────────── |
| 383 | # Each turn the TUI takes a `pre-turn:<seq>` and `post-turn:<seq>` snapshot of |
| 384 | # your workspace into a side-git repo at: |
| 385 | # |
| 386 | # ~/.deepseek/snapshots/<project_hash>/<worktree_hash>/.git |
| 387 | # |
| 388 | # Your own `.git` is never touched — `--git-dir` and `--work-tree` are always |
| 389 | # set together when shelling out to git. Use `/restore N` (slash command) or |
| 390 | # the `revert_turn` tool to roll the working tree back. Conversation history |
| 391 | # is unaffected. |
| 392 | # |
| 393 | # Disk footprint: ~1-2 GB worst case for a 100 MB workspace × 12 turns/day, |
| 394 | # typically far less thanks to git's content-addressed storage. The session |
| 395 | # boot prunes anything older than `max_age_days` (default 7). |
| 396 | # |
| 397 | # [snapshots] |
| 398 | # enabled = true # Snapshot workspace pre/post each turn for /restore |
| 399 | # max_age_days = 7 # Older snapshots pruned at session start |
| 400 | |
| 401 | # ───────────────────────────────────────────────────────────────────────────────── |
| 402 | # LSP Diagnostics (post-edit) (#136) |
| 403 | # ───────────────────────────────────────────────────────────────────────────────── |
| 404 | # After every successful file edit (`edit_file`, `apply_patch`, `write_file`), |
| 405 | # the engine asks an LSP server for diagnostics on the file and injects them |
| 406 | # as a synthetic system message before the next API call. This lets the agent |
| 407 | # see compile breaks immediately without round-tripping through the user. |
| 408 | # |
| 409 | # Enabled by default. Failure modes are non-blocking: a missing LSP binary, |
| 410 | # a crashed server, or a timeout simply skips the post-edit hook for that |
| 411 | # turn — the agent's work is never blocked. |
| 412 | # |
| 413 | # Built-in language → server defaults: |
| 414 | # rust → rust-analyzer |
| 415 | # go → gopls serve |
| 416 | # python → pyright-langserver --stdio |
| 417 | # typescript → typescript-language-server --stdio |
| 418 | # c, cpp → clangd |
| 419 | # |
| 420 | # Override the defaults via the `servers` table below. |
| 421 | [lsp] |
| 422 | # enabled = true |
| 423 | # poll_after_edit_ms = 5000 |
| 424 | # max_diagnostics_per_file = 20 |
| 425 | # include_warnings = false |
| 426 | # [lsp.servers] |
| 427 | # rust = ["rust-analyzer"] |
| 428 | # go = ["gopls", "serve"] |
| 429 | |
| 430 | # ───────────────────────────────────────────────────────────────────────────────── |
| 431 | # Hooks (optional) |
| 432 | # ───────────────────────────────────────────────────────────────────────────────── |
| 433 | # Hooks run shell commands on lifecycle events (session start/end, tool calls, etc.). |
| 434 | # Configure as `[[hooks.hooks]]` under a `[hooks]` table. |
| 435 | # |
| 436 | # Available events: session_start, session_end, message_submit, |
| 437 | # tool_call_before, tool_call_after, mode_change, on_error, shell_env. |
| 438 | # |
| 439 | # `shell_env` (#456) is special: the hook runs immediately before each |
| 440 | # `exec_shell` invocation and its stdout is parsed as `KEY=VALUE\n` lines. |
| 441 | # Those vars are merged into the spawned process environment (later hooks |
| 442 | # override earlier ones). Use this for ephemeral credentials, per-skill |
| 443 | # PATH adjustments, or short-lived tokens. The resolved KEY names (NEVER |
| 444 | # values) are written to `~/.deepseek/audit.log` so each session can be |
| 445 | # reconciled later. Hook failure / timeout simply contributes no vars — |
| 446 | # it does not abort the shell call. |
| 447 | # |
| 448 | # [hooks] |
| 449 | # enabled = true |
| 450 | # default_timeout_secs = 30 |
| 451 | # |
| 452 | # [[hooks.hooks]] |
| 453 | # event = "session_start" |
| 454 | # command = "echo 'DeepSeek TUI session started'" |
| 455 | # |
| 456 | # # Inject ephemeral creds into every shell call. Output one |
| 457 | # # KEY=VALUE per line on stdout (export prefix optional). |
| 458 | # [[hooks.hooks]] |
| 459 | # name = "aws-creds" |
| 460 | # event = "shell_env" |
| 461 | # command = "aws-vault export my-profile --format=env" |
| 462 | # # Optionally limit to specific tool names / categories: |
| 463 | # # condition = { type = "tool_category", category = "shell" } |
| 464 | |
| 465 | # ───────────────────────────────────────────────────────────────────────────────── |
| 466 | # Runtime API (`deepseek serve --http`) (#561) |
| 467 | # ───────────────────────────────────────────────────────────────────────────────── |
| 468 | # Tuning knobs for the local HTTP/SSE daemon. The server binds to 127.0.0.1 |
| 469 | # by default and is intended for local UIs (whalescale-desktop, dashboards, |
| 470 | # automation scripts). Today this section only controls the CORS allow-list; |
| 471 | # host/port/workers stay on `--host`, `--port`, and `--workers` flags. |
| 472 | # |
| 473 | # Built-in defaults always include: |
| 474 | # http://localhost:3000 http://127.0.0.1:3000 |
| 475 | # http://localhost:1420 http://127.0.0.1:1420 |
| 476 | # tauri://localhost |
| 477 | # |
| 478 | # Use `cors_origins` to add extra dev origins (e.g. Vite's default `:5173`). |
| 479 | # User entries STACK on top of the defaults — they do not replace them. The |
| 480 | # CLI flag `--cors-origin URL` (repeatable) and env var |
| 481 | # `DEEPSEEK_CORS_ORIGINS=url1,url2` resolve to the same merged list. |
| 482 | # |
| 483 | # [runtime_api] |
| 484 | # cors_origins = ["http://localhost:5173", "http://127.0.0.1:5173"] |
| 485 | |
| 486 | # ───────────────────────────────────────────────────────────────────────────────── |
| 487 | # Requirements (admin constraints) example file |
| 488 | # ───────────────────────────────────────────────────────────────────────────────── |
| 489 | # allowed_approval_policies = ["on-request", "untrusted", "never"] |
| 490 | # allowed_sandbox_modes = ["read-only", "workspace-write"] |
| 491 |