How Configuration Is Managed in DeepSeek-Reasonix

DeepSeek-Reasonix uses a layered TOML-based configuration system that merges command-line flags, project-level reasonix.toml, user-wide config.toml, and built-in defaults from the internal/config package, normalizing values and expanding environment variables for secrets.

DeepSeek-Reasonix centralizes its runtime options in the Config struct defined in internal/config/config.go. The configuration management system follows a strict resolution order, applies deep merging strategies, and provides normalization helpers to ensure the agent and desktop UI receive validated settings. Understanding how configuration is managed in DeepSeek-Reasonix allows developers to customize model providers, sandbox permissions, and interface themes without modifying the source code.

Configuration Resolution Order

The configuration loader implements a strict precedence hierarchy where higher-priority sources override lower ones. The system evaluates sources in the following order:

  1. Command-line flags – Runtime arguments passed to the binary take highest precedence.
  2. ./reasonix.toml – Project-level configuration located in the current working directory.
  3. User-wide config.toml – Located in the OS-specific configuration directory (e.g., ~/.config/reasonix/config.toml on Linux systems).
  4. Built-in defaults – Hardcoded values returned by the Default() function at lines 59-112 in internal/config/config.go.

Secrets such as API keys are never persisted in TOML files. Instead, the system uses *_env fields (e.g., api_key_env) to reference environment variables that are expanded during the ExpandEnv() phase.

Core Configuration Types

The Config struct defined at lines 44-64 in internal/config/config.go serves as the central registry for all runtime options. Key sub-structures include:

  • Config – The top-level container with fields for DefaultModel, UI, Desktop, Agent, Providers, Tools, Network, and Sandbox.
  • UIConfig – CLI appearance settings including Theme, ThemeStyle, ShortcutLayout, and ShowReasoning.
  • DesktopConfig – Desktop-specific preferences such as Language, LayoutStyle, CloseBehavior, and DisplayMode, independent of CLI settings.
  • AgentConfig – Agent behavior controls including MaxSteps, PlannerModel, AutoPlan, and ReasoningLanguage.
  • ProviderEntry – Model provider definitions with BaseURL, APIKeyEnv, ContextWindow, and pricing metadata (see default providers at lines 108-110).
  • ToolsConfig – Enabled tools and tuning parameters like BashTimeoutSeconds, BackgroundJobs, and Search engine settings.
  • NetworkConfig – Outbound HTTP proxy handling via ProxyMode, ProxyURL, and NoProxy lists (defined at lines 27-33 and 52-62).
  • SandboxConfig – File-writer confinement settings including WorkspaceRoot, AllowWrite, and Bash sandboxing rules (defined at lines 87-94).
  • PermissionsConfig – Per-tool permission policies using Mode, Allow, Ask, and Deny lists (defined at lines 57-60).

All structs use TOML tags for direct mapping from configuration files.

Default Configuration Values

When no user configuration files exist, the Default() function initializes a fully populated Config instance with the following sensible defaults:

  • DefaultModel: "deepseek-flash" – The fallback model for all operations.
  • CredentialsStore: CredentialsStoreAuto – Automatic secret handling.
  • UI.Theme and Desktop.Theme: "auto" – Adaptive light/dark theming.
  • Agent.AutoPlan: "off" – Manual planning mode unless explicitly enabled.
  • Sandbox.Bash: "enforce" – Bash sandboxing enabled by default (macOS only).
  • Network.ProxyMode: netclient.ModeAuto – Respects system proxy settings unless overridden.
  • Pre-registered providers: deepseek-flash and deepseek-pro with pricing and balance URLs.

Loading and Merging Process

The CLI entry point at cmd/reasonix/main.go orchestrates the configuration loading sequence:

// Conceptual flow from the implementation
func LoadConfig() (*config.Config, error) {
    // 1. Start with built-in defaults (lines 59-112)
    cfg := config.Default()
    
    // 2. Overlay user-wide config if present
    if userCfg, _ := config.LoadUserFile(); userCfg != nil {
        cfg = cfg.Merge(userCfg)
    }
    
    // 3. Overlay project-level reasonix.toml if present
    if projCfg, _ := config.LoadProjectFile(); projCfg != nil {
        cfg = cfg.Merge(projCfg)
    }
    
    // 4. Apply CLI flags (highest precedence)
    cfg.ApplyFlags(flagSet)
    
    // 5. Expand environment variables
    cfg.ExpandEnv()
    
    // 6. Validate identifiers
    cfg.Validate()
    
    return cfg, nil
}

The Merge() method performs deep merging respecting TOML tags, while Validate() checks identifiers such as skill names and provider names.

Normalization and Helper Methods

The internal/config package provides normalization methods that convert raw TOML values into canonical forms:

  • UITheme() and UIThemeStyle() – Map user strings like "dark" or "workbench" to fixed identifiers.
  • DesktopTheme() and DesktopLayoutStyle() – Resolve desktop UI preferences into validated values.
  • NetworkProxySpec() – Builds a netclient.ProxySpec from proxy fields, expanding ${VAR} placeholders.
  • WriteRoots() – Resolves workspace and extra write directories for sandbox confinement.
  • SkillCustomPaths(), SkillExcludedPaths(), and DisabledSkillNames() – Handle skill-discovery configuration.

These helpers ensure the rest of the system always receives clean, validated data regardless of input formatting.

Environment Variables and Secrets

Sensitive values use indirect references to prevent credential leakage. Fields ending in _env specify the environment variable name containing the actual secret:

[providers.deepseek]
api_key_env = "DEEPSEEK_API_KEY"

During the ExpandEnv() phase, the loader replaces ${VAR} placeholders and resolves *_env fields. This design keeps secrets out of version-controlled TOML files while maintaining full configurability.

Accessing Configuration in Code

Application code retrieves settings through the centralized Config API without parsing TOML directly:

cfg, err := config.LoadConfig()
if err != nil {
    log.Fatalf("failed to load config: %v", err)
}

// Retrieve resolved proxy specification
proxySpec := cfg.NetworkProxySpec()
fmt.Printf("Proxy mode: %s, URL: %s\n", proxySpec.Mode, proxySpec.URL)

// Check desktop update preferences
if cfg.DesktopCheckUpdates() {
    fmt.Println("Will check for updates on startup")
}

// Access agent step limits
maxSteps := cfg.Agent.MaxSteps

Summary

  • DeepSeek-Reasonix uses a four-layer resolution order: CLI flags override project reasonix.toml, which overrides user config.toml, which overrides Default() values from internal/config/config.go.
  • The Config struct (lines 44-64) aggregates all settings via tagged sub-structures for UI, Desktop, Agent, Providers, Tools, Network, and Sandbox.
  • Secrets use *_env fields rather than hardcoded values, expanded during the ExpandEnv() phase.
  • Helper methods like NetworkProxySpec() and UITheme() normalize raw values into canonical forms.
  • The CLI entry point at cmd/reasonix/main.go orchestrates loading, merging, validation, and environment expansion.

Frequently Asked Questions

Where does DeepSeek-Reasonix store its configuration files?

Project-level settings reside in ./reasonix.toml in the current working directory. User-wide settings are stored in config.toml within the OS-specific configuration directory, such as ~/.config/reasonix/ on Linux or ~/Library/Application Support/reasonix/ on macOS.

How do I add a custom model provider without modifying the source code?

Add a new [[providers]] entry to your reasonix.toml file. Specify the Name, Kind, BaseURL, Model, and APIKeyEnv fields. The system automatically validates the provider entry during the Validate() phase and makes it available to the agent runtime.

Why are my API keys not showing up in the configuration file?

DeepSeek-Reasonix never stores API keys in TOML files for security reasons. Instead, set the api_key_env field to reference an environment variable (e.g., api_key_env = "DEEPSEEK_API_KEY"), and ensure that variable is set in your shell before launching the application.

How do I override a specific setting for a single command?

Use command-line flags, which have the highest precedence in the resolution order. The CLI parser in cmd/reasonix/main.go applies flag values after loading all configuration files, allowing temporary overrides without editing persistent configuration files.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →