// model gateway LIVE

OpenRouter

One key, every model, priced per token

OpenRouter is what keeps AgentOS cheap to run. One account unlocks a whole catalogue of AI models, paid per use with no subscriptions. If a model fails mid-job the work moves to the next one on the list, and every run is priced before it starts.

AgentOS is multi-provider by design, and OpenRouter is what keeps that cheap to run: one API key unlocks DeepSeek, Qwen, Kimi and the rest of the catalogue, paid per token with no subscriptions. The runtime treats models as ordered routes rather than fixed choices, so if a model fails mid-run the job moves to the next one on its list. Studio prices every run before it launches, one shared picker browses the live catalogue from inside VS Code, and the key lives in a user-scope environment variable, never in the repo.

one account, many models no subscriptions priced before it runs backup models on standby
01 api key 00 subscriptions 04 role profiles 6h catalogue cache
why_openrouter [01]

Multi-provider by design

The routing philosophy across AgentOS is not "use the strongest model everywhere". It is: use the cheapest capable model for each stage, keep repeatable work in code, and spend intelligence where it matters. That only works if switching models is trivial, and that is what OpenRouter provides: one endpoint, one key, one bill, and the whole catalogue behind it.

It started with Codex. Codex CLI is free open-source software, and with OpenRouter as its model provider there is no OpenAI account in the loop at all: planning, tool-calling, and agentic work route to DeepSeek, Qwen, and Kimi pay-per-token. The runtime followed with failover routes, then the picker, then the pricing.

Key handling follows the secrets guardrail (G10). The OPENROUTER_API_KEY lives in a user-scope environment variable, read at runtime, never stored in the repo, in config, in queue payloads, or in reports.

Multi-provider is a stance, not a bullet point: no single vendor decides what AgentOS can run, and no subscription decides what it costs.
Where it plugs in
01Codex role profiles: four jobs, four models
02Runtime model routes with failover
03The shared model picker in Studio
04Per-model cost tracking and pricing
Status

Live since Phase 17 (11/06/2026). Failover routes since Phase 20. Catalogue picker since v0.5.106. Four role profiles deployed through the managed Codex config block.

failover_routes [02]

Outages became architecture

Free-tier rate limits blocked the first portfolio-wide audit run. The fix was not a retry loop: it was making model choice a route instead of a value. Every model-backed stage names an ordered route: preferred model first, failovers behind.

Transient vs real
Code makes the call

A transient provider error (rate limit, timeout, outage) restarts the stage on the next model in the route. A real error is rethrown immediately. The distinction lives in code, not in model judgement.

Telemetry
The chain is recorded

Every run records the attempted-model chain, so a report always shows which model actually did the work, not just which one was asked first.

The fix route
No silent downgrades

The fix-proposal stage runs its own route: Claude Sonnet 4.5 first, with transport-only failover. A network blip can never quietly hand a code fix to a weaker model.

model_picker [03]

The catalogue, one keystroke away

One shared picker replaced every scattered model input in the dashboard: a native grouped, searchable QuickPick over the live OpenRouter /models catalogue, wired to the fix-proposal model and the per-stage pipeline defaults.

Curated groups
Claude, Codex/GPT, Other

A code-owned mapping folds OpenRouter's provider IDs into three tool groups, and the current selection is pinned at the top under its own heading, so the pick is one glance and a search away.

Never empty
Four layers of fallback

Live fetch first, a six-hour cache behind it, a stale cache behind that, and a curated built-in list as the floor. Offline or mid-outage, the picker still renders a full list.

No new surface
Metadata, not authority

The catalogue is fetched direct from the extension over a public GET: no API key needed for metadata, no new gateway endpoint, no new authority. The picker writes only config that was already writable.

Deterministic
23 checks on pure logic

The parse, group, free/paid and search logic is a pure module under test. Marking is conservative: only a model priced at exactly zero is marked free.

cost_and_policy [01][04]

Priced before it runs

Every run gets a cost estimate before I confirm the spend, and every token used is attributed to the model that actually did the work. Nothing runs blind, and nothing hides in the totals.

A shared pricing module estimates cost per model across Anthropic, OpenAI, and OpenRouter. Studio uses it to price a run from per-stage history before the spend confirmation; analytics use it to attribute real cost to real model IDs parsed from rollout logs.

Spending rule
Guardrail G1
No free models where it counts

The free tier is tightly rate-limited: fine for one-off cheap tasks, unusable for agentic loops. So the rule is written down: no free models for the runs that check and change code. Free models are flagged the moment they are chosen, and blocked from the runs that matter.

The free tier is rate-limited to roughly 20 requests a minute and 200 a day: fine for one-shot cheap tasks, unusable for agentic loops. So the rule is written down: no free models for reliability-critical audit, challenge, or apply runs. The picker marks free models at selection; the run layer enforces it downstream.

Attribution
Every token accounted for

Usage and cost for every model shows up on the dashboard. Building it surfaced a real counting bug that was inflating the totals. Fixed, and the totals are honest.

Per-model session and all-time totals in the dashboard, including OpenRouter model IDs with cost estimates, alongside Claude usage. Building it surfaced a real bug: cached and reasoning tokens were being double-counted as additions when they are subsets. Fixed, and the totals are honest.