Skip to content

Configuration

cybersenses edited this page Nov 15, 2026 · 1 revision

Configuration

Everything user-level lives in ~/.codingdude/ (override with CODEDUDE_HOME). The main file is config.toml, created with defaults on first use. Edit it by hand or through the Config panel — the panel writes the same file. Either way, changes apply from the next run; no server restart.

Full reference: docs/manual/configuration.md.

Models and providers

Model names are always provider:model. The provider is either a built-in (deepseek, zai, openai, anthropic, google, github, groq, mistral, ollama, bedrock) or any name you define.

[models]
main = "deepseek:deepseek-v4-pro"      # primary agent loop
subagent = "deepseek:deepseek-v4-flash" # delegated sub-agents
fallback = "zai:glm-5.3"                # automatic failover when main errors

Any OpenAI-compatible provider is config-only — no code:

[providers.openrouter]
api_key = "sk-or-..."
base_url = "https://openrouter.ai/api/v1"
# env_var = "OPENROUTER_API_KEY"   # default is <NAME>_API_KEY

[models]
main = "openrouter:anthropic/claude-sonnet-4"

A provider with a base_url routes every name:model binding to that endpoint. Without one, built-in names resolve through pydantic-ai's native support. http:// base URLs are accepted for localhost only; remote endpoints must be https://.

API keys

  • Environment wins over a stored api_key.
  • Env var names: ZAI_API_KEY, DEEPSEEK_API_KEY, GITHUB_PAT (built-ins); custom providers default to <NAME>_API_KEY, overridable with env_var.
  • Keys stored in config.toml are reported back as presence only — never as text — by both the UI and the API.
  • Verify keys sends one minimal request per provider. For GitHub it checks api.github.com/user; for chat providers any of 200/400/404 counts as authenticated (a 400 only means the smoke model name is not on your plan).

Z.AI GLM coding plan

Coding-plan keys are rejected by the standard Z.AI API; they work only against the coding-plan endpoint:

[models]
main = "zai:glm-5.3"
subagent = "zai:glm-5.3-flash"
fallback = "zai:glm-5.3-flash"
fallback_base_url = "https://api.z.ai/api/coding/paas/v4"
thinking = "low"

Despite the name, fallback_base_url routes every zai: binding to that endpoint. If fallback is a zai: model and the URL is unset, the Config panel warns you.

[models] reference

Key Default Purpose
main / subagent / fallback see above model slots
fallback_base_url (unset) endpoint override for zai: bindings
vision (unset) vision-capable model for image input; unset disables images
thinking (unset) reasoning depth: minimal–xhigh, or off
max_tokens provider default raise if responses get truncated
context_limit inferred from the model name context-window override; drives compaction and the meter
compact_per_request true model-free compaction before every request while a run is live
prompt_cache "1h" true, false, or a retention tier (5m/30m/1h/12h)
prompt_cache_messages true also cache the growing conversation (main loop only)
prompt_cache_settings {} provider-specific cache knobs; keys validated at load
request_limit 500 max model requests per run
max_cost_usd (unset) hard USD ceiling per agent.run() — see Spend and Context
max_total_tokens (unset) hard token ceiling per agent.run()
pricing (unset) cost rates, USD per 1M tokens

[shell], [delegation], [planning], [trace]

[shell]
default = "bash"        # or "powershell"

[delegation]           # how much MORE one delegate call may spend
max_requests = 40
# max_cost_usd = 1.00

[planning]
github_mirror = true   # mirror tickets/roadmap items to GitHub issues via gh

[trace]
deltas = "compact"     # or "full"

max_requests and max_cost_usd under [delegation] are a slice beyond what the session already spent, bounded by the session's request_limit — a ceiling enforced before the call, not a receipt afterwards.

[telemetry]

[telemetry]
enabled = false                         # off by default
otlp_endpoint = "http://127.0.0.1:4318" # any local OTLP/HTTP collector
service_name = "codingdude"

Local only (send_to_logfire=False) — no token, no account, nothing leaves the machine, because prompts contain your code. Every malformed value is logged once and turns tracing off rather than failing a run. See Observability for the OpenLIT walkthrough.

Staffing by function

Delegations can name one of six fixed functions, and each staffs from its own profile. Only model and thinking are configurable — the tool policy is registry-locked in code, which is the safety property.

[models.functions.evaluator]
model = "zai:glm-5.3-flash"
thinking = "low"
Function Staffs Recommended
architect plan-level seam work strongest model, max thinking — used rarely
designer user-facing behaviour before code strong model, high thinking
coder the bulk of implementation strong model, medium thinking
debugger probe loops fast model, medium thinking
evaluator boundary-based grading cheap model, low thinking
researcher web / primary-source reads cheap model, low thinking

An unknown function name, a model without its provider: prefix, or any other key fails fast at load.

Per-project overrides: .codingdude.toml

# myproject/.codingdude.toml
shell = "powershell"

[models]
main = "openrouter:anthropic/claude-sonnet-4"   # this project only

[kickoff]
existing = """
Our pipeline: plan first, implement, run `uv run pytest -q` plus ruff and mypy,
then request review. Never push without an explicit "push" from me.
"""

The [models] overlay is a field-wise merge, validated; an invalid override logs a warning and the global lineup is used unchanged. [kickoff] overrides the bundled orientation prompt that runs on a session's first turn (existing for a populated project, new for a greenfield one).

Pricing

[models]
pricing = { deepseek-v4-pro = { input = 0.27, output = 1.1 } }

USD per 1M tokens, matched by model name or substring (so glm-5 covers glm-5.3 and glm-5.3-flash). Unpriced models are accounted tokens-only in the Cost panel.

Save semantics worth knowing

  • The Config panel's save is a merge: only fields you changed are written; an explicit clear is needed to empty one. A partial save can never wipe fallback_base_url.
  • Stored keys round-trip as a sentinel, so saving the panel verbatim cannot overwrite a real key with a placeholder.
  • A payload that fails validation is rejected before any write — a bad save cannot brick the next boot.
  • [telemetry] is global only; it is not honoured in a project file.

Clone this wiki locally