9RouterX

Combos

A combo is a named chain of models the router walks when a request arrives. It is the mechanism behind "never stop coding": the first candidate is your subscription, the next is cheap, the last is free.

Strategies

Strategy Behaviour
Fallback Try candidates in order until one succeeds
Round-robin Rotate across candidates
Sticky Hold the same candidate while it succeeds
Capacity Reorder capability-aware — a model that cannot serve the request is skipped rather than tried
Fusion Combine several models into one panel

Creating a combo

Dashboard → Combo & Vision Adapter → Create.

Two shortcuts build a chain for you:

Presets (GET /api/combos/presets) offer the Cursor and Claude default lists. Every preset is derived, never hard-coded: the Claude items are whatever the cc registry row currently holds plus the Claude Code aliases, so adding a model to the provider registry adds a preset with no second edit.

Smart combos

Smart combos keep a combo's membership in step with the models the gateway actually knows about. Instead of listing model ids by hand, you write rules and the router maintains the list.

The two ideas a rule separates

Notion Meaning
Addable A model a rule may put into the combo. Gated by reachability (a provider with a connection, a node that still exists) and by kind.
Live A model that still exists. A member that is no longer live is pruned whatever the pattern says.

A provider that loses its connection keeps its members — they are live, just unreachable — but stops contributing new ones. Absence from a catalogue is weak evidence of death, so a member is never pruned for being unreachable.

Rule shape

Field Meaning
pattern Glob, keyword, or regex (re: prefix required for regex)
mode glob (default), keyword, regex
effect include or exclude — an exclude rule always wins
maxMembers How many models one rule may contribute. Default 20. 0 = unlimited, an explicit choice.
allKinds Match non-LLM kinds too. Off by default: embedding, image, TTS and STT models cannot serve a chat turn.
enabled Rule on/off

Rules match against both spellings of a model — alias/model and bare model — the same way the per-key allowlist does. A second qualified spelling (AltID) means a member is never pruned for being spelled the other way round, and the membership it adds still lands under one id, so a rule cannot create two slots for one model.

What survives a reconcile

Known limitation: a model id you pinned by hand and a rule claims is owned by the rule, so editing the pattern removes it. The dashboard prevents the common path, but the API cannot tell a pin from a claim when both spell the same id.

Working with rules

POST /api/combos/reconcile               Apply every combo's rules
POST /api/combos/{id}/smart/preview      Dry-run one combo — nothing is written
POST /api/combos/{id}/smart/load         Apply one combo's rules

A preview reports what would change before anything is committed:

{
  "models":  ["ag/gemini-3-flash", "oc/free-model"],
  "added":   ["oc/free-model"],
  "removed": [],
  "rules":   [{ "id": "r1", "matched": 41, "applied": 20, "capped": true }]
}

matched is what the pattern selected; applied is what actually landed after the cap; capped tells you the cap bit.

Timeout and grace period

Set Model response timeout per combo in the Edit dialog (seconds, decimals such as 5.3 are allowed; empty or 0 disables), or from the compact field on the combo card. The timer covers each model candidate except the last, including connection selection and waiting for a usable response. The last candidate keeps the gateway's normal deadline, so the setting never makes a combo fail sooner than it would without it (#744). An active stream is not cut off by this setting; for non-streaming requests the timer covers the wait for the complete response.

When it fires, the candidate is cancelled and the next is tried; the timed-out model is then left out of that combo for a grace period — default 5 minutes, set per combo under the timeout in the Edit dialog, 0 re-includes it on the next request — before rejoining the chain. Fusion panel timing is separate: a model that times out there is benched by the same grace logic, and if every model in the chain is inside its grace period, the full chain is used. The pause is held in memory and resets on restart.

Where the value is stored: the dashboard shows seconds; the setting is stored in milliseconds as comboStrategies[comboName].firstTokenTimeoutMs, with the grace period next to it as firstTokenGraceMs.

Where it lives