# multi — example config with every backend type and every field. # Real file: ~/.config/multi/config.toml. `scripts/setup.sh init` writes a # smaller default there; copy sections from here as you need them. # Keys are never in this file — see providers.example.env. default_profile = "normal" verbose_prompt = false # true: skills show each full prompt before sending, without waiting for approval # no_train = false # true: keep only models with training verdict no; unknown sits out too # Account overrides apply to every model of a backend, ahead of built-in rules. # Put trains = false under that backend only when your account does not train. # ---- backends: a name, a type, and what that type needs ------------------- [backends.codex] # type "codex": the Codex CLI, read-only sandbox type = "codex" models = [] # empty = the CLI's default; at most one model here timeout = 600 # seconds for one run; default 300 (claude-headless: 1800, a ceiling) # trains = false # e.g. ChatGPT with training off; true = may train, on any backend [backends.opencode] # type "opencode": OpenCode CLI, plugin's read-only agent type = "opencode" models = [] # empty = a free model from `opencode models`, others as fallback stall = 180 # opencode, kilo, claude-headless: seconds of silence before it counts as dead (headless default 600) [backends.kilo] # type "kilo": Kilo Code CLI (an opencode fork), same read-only agent; not in the default profile type = "kilo" models = [] # empty = a free kilo/...:free model from `kilo models` (never the kilo-auto / openrouter routers) [backends.opencode-paid] # the same type twice, under another name type = "opencode" models = ["opencode-go/deepseek-v4-flash", "opencode-go/qwen3.8-flash"] # first is tried first [backends.openrouter] # type "claude-headless": claude -p against an type = "claude-headless" # Anthropic-compatible endpoint. OpenRouter is one. base_url = "https://openrouter.ai/api" models = ["qwen/qwen3.8-flash", "deepseek/deepseek-v4-flash-0731", "z-ai/glm-5.2:free"] # api_key_env not set = OPENROUTER_API_KEY (backend name upper-cased + _API_KEY) [backends.glm] # a second endpoint: z.ai, 9router, Moonshot, self-hosted type = "claude-headless" base_url = "https://api.z.ai/api/anthropic" # https required; plain http only on localhost models = ["GLM-5.3-Flash"] api_key_env = "ZAI_API_KEY" # this backend reads its key from that variable [backends.local] # a router on this machine, like 9router or omnirouter type = "claude-headless" base_url = "http://localhost:4000/api" models = ["local/coder"] api_key_env = "LOCAL_ROUTER_KEY" timeout = 1200 [backends.deepseek] # DeepSeek's own Anthropic-compatible endpoint, key DEEPSEEK_API_KEY type = "claude-headless" base_url = "https://api.deepseek.com/anthropic" models = ["deepseek-flash"] # V4.1 Flash; claude-* names are mapped to it too # Exact model only; explicit --effort overrides every supporting backend. # No entry: Codex keeps medium, other harnesses decide. Gemini unsupported. # effort = { "deepseek-flash" = "low" } # Windows this backend sits out, in UTC only (the zone word is required). # DeepSeek bills double in these hours (its published peak, as of 2026-09-10 — # check api-docs.deepseek.com/quick_start/pricing, they moved on 2026-08-16). # Any backend can carry a list: "Sat-Sun 00:00-24:00 UTC", "22:00-02:00 UTC" # (every day, wraps midnight). Decided once, at launch: a run that starts in # an open hour finishes. Inside a window the backend is not launched and its # answer file says so — it is named in the report, not skipped in silence. avoid = ["Mon-Fri 01:00-04:00 UTC", "Mon-Fri 06:00-10:00 UTC"] [backends.gemini] # type "gemini": the Gemini CLI, key GEMINI_API_KEY type = "gemini" models = [] # empty = CLI default; at most one model here # ---- profiles: who runs, in parallel -------------------------------------- # An entry is a backend name (its whole models list, in order) or name:model # (exactly that model, no fallback). The same entry twice runs twice. # ask.sh --backend picks one; no --backend = default_profile; # --backend a,b:model is a one-off; `all` = every backend above. # OpenRouter's free and flash pools queue: measured 2026-09-06, 25–40 minutes # for one review while the same model on a direct key took 5. They belong in a # profile you pick on purpose, not in the one every review runs with. [profiles] normal = ["codex", "glm"] free = ["opencode", "openrouter:z-ai/glm-5.2:free"] # pinned: the bare backend walks its paid models first paid = ["codex", "opencode-paid", "deepseek"] # in deepseek's peak hours this runs two reviewers, and says so compare = ["openrouter:qwen/qwen3.8-flash", "openrouter:deepseek/deepseek-v4-flash-0731", "glm"] solo = ["codex"]