Model roles¶
The gateway exposes four model roles. Two of them are exposed as public aliases; one is invoked internally only; one is reserved for emergencies.
Roles at a glance¶
| Role | Real OpenRouter ID | Cost class | Allow sensitive | Public alias |
|---|---|---|---|---|
| Scout / critic / free | nvidia/nemotron-3-ultra-550b-a55b:free |
free |
false |
smart-router-free |
| Default worker | deepseek/deepseek-v4-flash-0731 |
very_low |
true |
smart-router-flash |
| Senior solver | deepseek/deepseek-v4-pro-0813 |
high_relative_to_stack |
true |
smart-router-pro |
| Emergency fallback | z-ai/glm-5.2 |
unknown |
true |
(no alias) |
The values are taken verbatim from
frozen-v3/config/models.yaml.
Aliases¶
The four aliases (smart-router, smart-router-flash,
smart-router-pro, smart-router-free) are translated into
internal alias keys (deepseek_v4_flash, etc.) before the routing
pipeline runs. The internal alias keys are what you see in routing
logs and /v1/route/decision responses.
| Public alias | Internal alias key | Real OpenRouter ID |
|---|---|---|
smart-router |
(chosen by policy) | (chosen by policy) |
smart-router-flash |
deepseek_v4_flash |
deepseek/deepseek-v4-flash-0731 |
smart-router-pro |
deepseek_v4_pro |
deepseek/deepseek-v4-pro-0813 |
smart-router-free |
nemotron_ultra |
nvidia/nemotron-3-ultra-550b-a55b:free |
The translation happens in src/smart_gateway/app.py::_resolve_openrouter_id.
The mapping is read from the same models.yaml file.
DeepSeek V4 Flash — worker¶
The cheap, fast default. Used for:
- ordinary coding,
- tool loops,
- tests,
- small refactors,
- ordinary reasoning where the budget allows Pro to be skipped.
The OpenRouter ID is deepseek/deepseek-v4-flash-0731. The
gateway sends Authorization: Bearer $OPENROUTER_API_KEY and the
standard upstream headers unchanged.
DeepSeek V4 Pro — senior solver¶
The expensive, careful choice. Used when:
- an explicit Pro override is set,
- the instruction contains a high-reasoning marker,
- the task is
SECURITY/AUTH/PAYMENT/DESTRUCTIVE_MIGRATION, - the risk or blast radius is
CRITICAL, - the same error has occurred twice or more,
- the last failure was
STRUCTURAL, - files touched ≥ 20 or tool depth ≥ 16,
- the complexity score is ≥ 65.
The OpenRouter ID is deepseek/deepseek-v4-pro-0813.
Nemotron 3 Ultra — Scout / critic / bounded free¶
Used for two narrow jobs:
- Scout in the gray zone — recommend Pro or Flash based on a single-word reply. The recommendation is advisory; the policy can still override.
- Direct execution for
SUMMARIZE,CLASSIFY, andPUBLIC_REVIEWtasks that are non-sensitive and (if repo context is present) explicitly opted in viarepo_free_opt_in=true.
allow_sensitive: false in the registry. The privacy hard gate
enforces this: a Scout call or a direct free call on a sensitive
task returns 403.
The OpenRouter ID is nvidia/nemotron-3-ultra-550b-a55b:free.
Nemotron's public terms explicitly warn against confidential /
personal data; the gateway treats that as a hard architectural
boundary, not a cost preference.
GLM-5.2 — emergency fallback¶
Used only when a call to Pro fails end-to-end after the gateway's internal retry policy. The gateway:
- Tries Pro up to 3 times with exponential backoff.
- On persistent failure, logs
FALLBACK_TRYand rewrites the request toz-ai/glm-5.2. - Logs
FALLBACK_GLM_INVOKE. - If GLM-5.2 also fails, logs
FALLBACK_GLM_FAILand returns 500.
GLM-5.2 is not exposed as an alias. You cannot ask for it directly. This prevents accidental use of a model that has not been promoted through the normal change process.
The OpenRouter ID is z-ai/glm-5.2. The cost class is unknown
because the registry does not have a verified price snapshot; the
advisory note in models.yaml (pricing_is_advisory: true) flags
this explicitly.
Cross-family fallback candidates¶
If Pro is unhealthy and GLM-5.2 is also unhealthy, the policy tries a small hardcoded list:
These are evaluated in order; the first healthy model wins. None of them are exposed as aliases. To promote a new candidate into this list you must:
- Update
frozen-v3/config/models.yamlwith the new model and role. - Update
src/smart_gateway/routing.py::senior_fallbacks. - Update the cross-family spec at
frozen-v3/08-cross-family-fallback-spec.md. - Issue a new freeze and release.
Why aliases instead of real IDs¶
You should always send aliases. The gateway absorbs:
- a provider rotating endpoints,
- a model being retired,
- a model being substituted by a successor,
all without breaking your client. See User guide → Model aliases for the client-side guidance.
What "allow_sensitive" means¶
The allow_sensitive flag in models.yaml is the single source of
truth for whether a model can receive sensitive content. The policy
treats it as advisory — the actual deny is enforced by the privacy
gate's free_model_fail_closed rule — so flipping the flag in the
registry does not by itself make free models safe on private code.
Treat the registry and the privacy policy as a pair; change both
together or not at all.