Provider Routing

By default every agent runs on Anthropic Claude — no key, no config. The orchestrator mounts your host ~/.claude session into each container and that's the whole setup. When you want something else — the whole fleet on Grok, Codex, Gemini, or Kimi, a few agents on a self-hosted model, a cheaper model for mechanical low-complexity work, or a deliberate mix — you don't edit env files. You set it on Settings → AI Providers (/settings/ai-providers, linked from the sidebar footer), and the choice is stored server-side and resolved per agent at spawn.

The routing modes

The page has one global routing mode that decides which backend every agent uses unless you override it per agent:

ModeWhat it doesNeeds
AnthropicEvery agent runs on Claude via the mounted ~/.claude auth. The default.Nothing — the orchestrator's ~/.claude mount
GrokEvery agent runs on xAI Grok (grok-build).A saved Grok key or a SuperGrok login — see Run on Grok
CodexEvery delivery agent runs on OpenAI's Codex CLI (gpt-5.3-codex).A mounted ChatGPT-subscription ~/.codex login — see Run on Codex
GeminiEvery delivery agent runs on Google's Gemini CLI (gemini-2.5-pro).A mounted OAuth ~/.gemini login — see Run on Gemini
KimiEvery delivery agent runs on Moonshot's Kimi K3 (kimi-code/k3).A shared device-code OAuth ~/.kimi-code login — see Run on Kimi
OllamaEvery agent runs on Ollama Cloud.A saved Ollama Cloud key
Self-HostedEvery agent runs against your own OpenAI-compatible endpoint.A base URL with a successful Test Connection
MixPin individual agents to specific models; everything else inherits the global default.Whatever the pinned models need
Cost-TieredAdditive, not a full-fleet switch: touches nothing already routed. The mode itself ships with no day-1 seed — see the capability floor below for why.Nothing — re-runnable any time

Anthropic, Ollama Cloud, and self-hosted models all speak the Anthropic Messages wire protocol, so they run through the same Claude Code runtime — the orchestrator just injects the endpoint and key. Grok, Codex, Gemini, and Kimi each speak their own protocol and run in their own agent image, authenticated by a mounted CLI subscription/login rather than a key. You don't have to think about that distinction; it's just why each has its own setup page.

Codex, Gemini, and Kimi are V1: delivery roles only

All three providers back the developer/QA/documenter/PM delivery roles only — not the interactive Intake or Secretary chats, which stay on Anthropic even when the Codex, Gemini, or Kimi mode is applied fleet-wide. An explicit per-agent pin to any of the three on Intake or Secretary is refused at spawn, and the Mix-mode per-agent picker excludes all three entirely for that group.

The CEO seat is not an agent

Mix mode shows a per-agent table mirroring the org chart, but you (the CEO) are intentionally excluded — there's no model to assign to the human seat. The Intake (Prompter) and Secretary chats are in the table (routable to Anthropic, Grok, Ollama, or self-hosted — not Codex/Gemini/Kimi, per above).

How a route is resolved: agent > role(+complexity) > role > global

When the orchestrator spawns an agent, it picks the model by a precedence ladder, most specific first:

  1. Agent — a model pinned to that exact agent (set in Mix mode).
  2. Role + complexity — a model assigned to the agent's role at a specific task complexity (a complexity override — see below).
  3. Role — a model assigned to the agent's role, complexity-blind.
  4. Global — the global mode's default.

The first rung that has an assignment wins. So in Mix mode you can pin be-dev-1 to one model, leave the rest of the backend cell on the global default, and the dispatcher resolves each one independently at spawn time. Switching the global mode (Anthropic / Grok / Codex / Gemini / Kimi / Ollama / Self-Hosted) replaces the role and global rows, but keeps your per-agent pins and complexity overrides — the panel's confirmation says so explicitly. So flipping from, say, Grok back to Anthropic moves every un-pinned agent to Anthropic while a be-dev-1 pin set in Mix mode stays exactly where you put it; mixed-provider routing (some agents pinned, everything else on the mode's default) is a normal, supported state rather than something a mode switch undoes.

Cost-tiered routing: cheaper models for mechanical work

A role's plain default is one model, complexity-blind. Complexity overrides let you pin developer, qa, or documenter to a cheaper model specifically for tasks a PM estimated as LOW or HIGH complexity — reusing the same precedence rung a task's estimated_complexity resolves against at spawn.

  • Downgrade-only, enforced server-side. An override can never point to a costlier tier than that role's own baseline model — this lever only saves cost, it never spends more. Attempting an upgrade is rejected.
  • Coordinator and Board/CEO-facing roles aren't offered a row at all. cell_pm, main_pm, pr_reviewer, and every Board/CEO-facing role are deliberately excluded — a coordinator is the last place to gamble a downgrade.
  • The one-click "Cost-Tiered" button is a day-1 seed, not a mode switch — currently an empty one. Unlike every other mode button, clicking it never wipes existing routing. It used to additively seed developer:low → Haiku, but that seed is retired: Haiku can't reliably emit the structured envelopes the lifecycle now runs on (per-criterion QA verification, delegation's parent-criteria mapping, the findings ledger), so the seed would have been immediately upgraded back to Sonnet by the capability floor below anyway. The mode stays wired for a genuinely-above-floor tier you add yourself in the Complexity overrides table.
  • Edit any role/complexity cell directly in the Complexity overrides section below the mode buttons — a blank cell means no override at that complexity for that role.
Haiku is retired from every delivery-lifecycle role

QA, PM, and reviewer roles run on structured verbspass_review's per-criterion criteria_verified, delegate's covers_parent_criteria mapping, the revision-findings ledger — that Haiku-class models can't reliably emit. A Haiku QA or PM claims a task, fails validation, idles, respawns, and loops without ever advancing it. QA and Documenter's role defaults now run on Sonnet, not Haiku, and a capability floor at resolution time upgrades any Anthropic assignment that resolves to a Haiku-class model — a stray per-agent pin, a role row, or a future map edit — back up to Sonnet, whatever its source. This is an Anthropic-tier floor, not a provider policy: Grok, Codex, Gemini, Kimi, and self-hosted assignments are untouched. pr_reviewer and the Auditor stay on Opus, unaffected either way.

Routing presets: save and swap whole setups

A routing preset snapshots the entire current routing state — the applied mode, every per-agent pin, every role row, and every complexity override — under a name you pick, so you can swap between whole configurations (e.g. "everything on Grok" vs. "cost-optimized mix") in one click instead of re-picking every field.

  • Save as preset… captures exactly what the card currently shows.
  • Apply performs a full swap: it replaces every current assignment with the preset's snapshot, not a merge — the confirmation dialog says so. Unlike a mode-button switch (which preserves pins/overrides), applying a preset can move pins and overrides too, because the preset is a full state capture including those.
  • Applying a preset validates every entry before touching anything — an invalid saved entry (e.g. a role no longer eligible for a complexity override) is skipped and reported, but never triggers a partial wipe.
  • Delete removes the saved snapshot only; it has no effect on whatever routing is currently applied.

Presets are stored server-side, so they persist across restarts and are available to whoever operates the panel.

Saving keys and endpoints

Three secrets live on this page, all stored Fernet-encrypted server-side and never returned by the API — the panel only ever sees a has_key / has_token boolean, so you re-enter (you can't read back) a key:

  • Grok (xAI) key — only needed if you authenticate Grok with a key rather than a SuperGrok login.
  • Ollama Cloud key — required before any agent can route to Ollama Cloud.
  • Self-hosted endpoint — a base URL plus an optional auth token. Hit Test Connection to confirm reachability and auto-discover the model list; Refresh re-discovers it. A self-hosted assignment won't save until the connection tests clean.

The panel guards you client-side: it blocks saving a Grok / Ollama / self-hosted assignment when the matching key or connection is missing, and warns when an Ollama-routed agent has no key (see below). Codex, Gemini, and Kimi need no key on this page at all — they authenticate from a mounted CLI login on the host, set up once as described on their own pages, so the Codex/Gemini/Kimi mode buttons are always clickable regardless of anything saved here.

Fail-soft: misconfig falls back to Anthropic

Routing is deliberately fail-soft. A stalled spawn is worse than a wrong model, so on any of these the orchestrator silently degrades that agent to Anthropic Claude rather than refusing to start it:

  • no assignment found for the agent, its role, or the global default;
  • a self-hosted or Ollama endpoint that's unreachable (the orchestrator probes /api/tags before committing to it);
  • a stored key or token that fails to decrypt.
A quiet fallback can look like success

Because the fallback is silent, an agent you think is on your self-hosted model may actually be running on Claude — for example if the endpoint went unreachable after you tested it. The fallback is logged in the orchestrator (docker compose logs orchestrator shows the warning). If you're routing away from Anthropic, watch the per-model breakdown on the usage dashboard to confirm the traffic is landing where you intended.

Providers are seeded by the migrations

The Anthropic, Grok, Codex, Gemini, Kimi, Ollama Cloud, and self-hosted provider rows are all created by alembic upgrade head, which the stack runs for you on boot. The AI Providers page only sets keys, mode, and assignments — it never creates providers. If you skipped migrations you'll see "provider not seeded" errors here.

Next

llms.txt