Router and fallbacks
The Router and fallbacks screen lets you write the routing rules and fallback chains of the Model Router, and simulate which model and which fallback chain the router selects for a request. Portal path: /llm/router. It is used by the AI platform administrators, who write the rules, and by every LLM reader who wants to understand a routing decision. The screen is built in portal/src/screens/llm.tsx (Router, routesCfg, routeSimulateCfg).
What the screen shows
The table Routing rules (GET /v1/routes, sorted by priority then name), with a refresh button and New rule for the administrators.
| Column | Content |
|---|---|
| Name | Name of the rule. |
| Priority | Lower values are evaluated first (default 100). |
| Match | JSON condition, for example {"task": "chat"}. |
| Strategy | priority, cost, latency or quality. |
| Target model | Model selected when the rule matches. |
| Candidates | Other models the strategy may choose from. |
| Fallbacks | Ordered fallback chain. |
| Enabled | Only enabled rules are evaluated. |
When there is no rule: "No routing rule. Without rules the router uses the requested model directly."
Under the table, the panel Simulate routing ("See which model and fallback chain the router selects for a request.") has a two column form: Model, Task (default chat), Purpose, Data classification (internal, public, confidential, restricted), Capabilities, Allowed regions, Allowed providers, Strategy, the button Run and the JSON Result.
Actions
| Button or action | What it does | API call | Roles |
|---|---|---|---|
| New rule | Drawer with Name, Priority, Match (JSON), Strategy, Target model, Candidates, Fallbacks, Enabled; Create saves it. | POST /v1/routes | tenant_admin, platform_admin, ai_platform_engineer |
| Edit (row menu) | Same form, pre-filled; replaces the rule. | PUT /v1/routes/{rid} | tenant_admin, platform_admin, ai_platform_engineer |
| Delete (row menu) | Deletes the rule after the destructive confirmation (type the resource name, then Confirm). | DELETE /v1/routes/{rid} | tenant_admin, platform_admin, ai_platform_engineer |
| Refresh button | Reads the rules again. | GET /v1/routes | LLM readers |
| Run (Simulate routing) | Runs the router on the request without calling any model and shows selected, fallbacks, strategy, rejected and the rule used (route_id). | POST /v1/routes/simulate | LLM readers |
Roles
- Reading and simulation (
GET /v1/routes,POST /v1/routes/simulate): the LLM readers ofportal/src/lib/kit.ts(ROLES.llmReaders), the same asREADinservices/control-plane/src/eai/domains/llm/__init__.py. - Writing (create, edit, delete):
tenant_admin,platform_admin,ai_platform_engineer(ROLES.llmAdmins). The New rule button and the row menu are hidden for the other roles. - Rules belong to a tenant: a principal without tenant gets
platform_onlyon creation.
Typical tasks
Add a routing rule with a fallback chain
- Open the form. Click New rule. Expected result: the drawer New rule with
{"task": "chat"}in Match. If it fails: the button is missing when your role cannot write rules. - Describe the rule. Type the Name, a Priority lower than the existing rules if it must win, the Match condition, the Target model and the Fallbacks (comma separated), so that a failure of the target falls back in order. Expected result: no Invalid JSON message under Match. If it fails: fix the JSON of Match.
- Create. Click Create. Expected result: toast Created and the new row in Routing rules. If it fails: the message of the API is shown in the drawer.
Check which model a request gets
- Describe the request. In Simulate routing, fill Task, Data classification and, if needed, Capabilities or Allowed regions, so that the simulation applies the same policies as a real call. Expected result: the form is complete. If it fails: leave optional fields empty rather than guessing.
- Run. Click Run. Expected result: the JSON Result shows
selected, the orderedfallbacks, thestrategy, therejectedcandidates with their reason and theroute_idof the matching rule. If it fails: "No model satisfies the policies of this request." (no_eligible_model, 422): the error details carry therejectedmodels; relax the classification or the allowlists, or approve a model.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
"No model satisfies the policies of this request." (no_eligible_model, 422) | Every candidate is rejected (status, kill switch, region, classification, allowlist). | Read the rejected details of the error, then fix the model or the rule. |
"Route not found." (route_not_found, 404) | The rule was deleted meanwhile, or the route_id is wrong. | Refresh the table. |
"Only a platform administrator can change platform level entries." (platform_only, 403) on Create | The principal has no tenant. | Sign in on a tenant. |
| Invalid JSON under Match | Match is not a JSON object. | Type a JSON object such as {"task": "chat"}. |
forbidden (403) | Role not allowed to write rules. | Ask a tenant_admin or an ai_platform_engineer. |