Argus multi-model code review

Configuration

View config.yaml

Everything about Argus — the reviewer registry, profiles, host rules, routing, CLI commands, and cost gates — lives in config.yaml. API keys are the one thing that is not in config: they come from environment variables only.

config.yaml at a glance

SectionWhat it holds
defaultsGlobal knobs: route_preference, confidence threshold, corroboration boost, merge_line_tolerance, default profile.
reviewersThe registry — one entry per reviewer with its route(s), model IDs, context window, tier, and cost.
profilesNamed rosters (quick, standard, panel, security, deep, favorites, direct, leaderboard-top5).
host_rulesPer-host skip / add rules for host-CLI awareness.
costWarn / hard-block thresholds for review and benchmark modes.

Routing preference new

A single knob, route_preference under defaults:, decides which provider a dual-route reviewer tries first:

ValueOrderWhen to use
openrouter public defaultOpenRouter first, direct API as fallback.The simplest setup — one OPENROUTER_API_KEY covers most reviewers.
directEach provider’s own API first, OpenRouter as fallback.Cheaper / use your own subscriptions, or when your OpenRouter balance is depleted.

Only dual-route reviewers are reordered by this knob: glm-5.2, minimax-m3, deepseek-v4-pro, and the custom-only hermes-4.3. CLI reviewers (Codex / Claude / OpenCode / Gemini) are never reordered — their CLI subscription stays primary and OpenRouter stays a true fallback.

Override precedence

Precedence is CLI flag > env var > config:

# 1. CLI flag on dispatch.py / verify.py / benchmark.py / estimate_cost.py
python scripts/dispatch.py ... --route-pref direct
python scripts/verify.py --all --prefer-direct        # shorthand
python scripts/dispatch.py ... --prefer-openrouter    # shorthand

# 2. Environment variable
export ARGUS_ROUTE_PREF=direct

# 3. config.yaml default
#    defaults:
#      route_preference: openrouter
🧰
The direct profile

For when your OpenRouter balance is depleted, pair route_preference: direct with the direct profile (direct-API subs only, no Gemini): glm-5.2, minimax-m3, deepseek-v4-pro, codex, claude, opencode.

Environment variables

API keys live in the environment, never on disk. aichat reads AICHAT_<CLIENT>_API_KEY, which Argus forwards from $<PROVIDER>_API_KEY at subprocess dispatch time. The Claude CLI uses its own auth.

VariablePurposeRequired?
ARGUS_HOMEPath to the Argus checkoutrequired (set to repo root)
OPENROUTER_API_KEYOpenRouter — covers most reviewersrecommended (public default route)
ZAI_API_KEYz.ai Coding Plan endpoint (GLM direct)optional
MINIMAX_API_KEYMiniMax directoptional
DEEPSEEK_API_KEY newDeepSeek direct (api.deepseek.com)optional
KIMI_API_KEYConsumer-scoped (not Moonshot Platform)optional
GEMINI_API_KEYGeminioptional
OPENAI_API_KEYUsed by the Codex CLI fallbackoptional
NOUSRESEARCH_API_KEYHermes directoptional
ARGUS_ROUTE_PREFopenrouter | direct route overrideoptional
ARGUS_YES_COST=1Downgrade a cost hard-block to a warningoptional

aichat clients

Run python scripts/install_aichat.py --merge to generate ~/.config/aichat/config.yaml with a client definition per provider route. No keys are written — each client reads its AICHAT_<CLIENT>_API_KEY from the environment, which Argus sets at dispatch. The universal aichat adapter handles all of the OpenRouter and direct-API routes.

Cost gates

Before any spend, Argus estimates cost and applies a warn / hard-block gate.

ModeWarnHard blockOverride
review$0.50$2.00--yes-cost / ARGUS_YES_COST=1
benchmark$10$30--yes-cost / ARGUS_YES_COST=1
OR balanceauto warn (review)blocks (benchmark) when available < safety×estimate--skip-balance-check

Paid-CLI reviewers (Gemini / Codex / Claude / OpenCode / Copilot) have cost_per_m: null, so they count as $0 in the estimate.

Cost-gate flow

flowchart TD A[Resolve roster] --> B[Estimate $ per reviewer] B --> C{Total > hard block?} C -- yes --> D{--yes-cost or ARGUS_YES_COST?} D -- no --> X[Abort: cost block] D -- yes --> E[Warn and continue] C -- no --> F{Total > warn threshold?} F -- yes --> E F -- no --> G[Proceed silently] E --> H{OpenRouter balance < safety x estimate?} G --> H H -- yes, benchmark --> X2[Abort: low balance] H -- yes, review --> I[Warn and continue] H -- no --> J[Dispatch reviewers] I --> J