Routing overview
A concise but current summary of how the reference router filters, scores, ties, and explains a decision.
Routing in role-model is deterministic and explainable.
The goal is not only to choose an endpoint, but to produce answers to two questions:
- which endpoints were valid candidates?
- why was the final endpoint chosen over the others?
The routing order
The baseline router applies this order:
- normalize request intent into an effective policy snapshot
- reject candidates that fail hard constraints
- score the remaining candidates across quality, latency, throughput, cost, reliability, and preference
- redistribute weight when an entire metric is unknown for every eligible candidate
- break near-ties by higher quality, lower latency, higher reliability, then stable
endpoint_id - emit a
RouterDecisionwith ranked fallbacks and reason codes
Eligibility comes first
Before scoring, the router filters out endpoints that cannot legally or practically satisfy the request.
Baseline exclusion families include:
CAPABILITY_MISSINGMODALITY_UNSUPPORTEDCONTEXT_TOO_SMALLTOOLS_UNSUPPORTEDPOLICY_DENY_ENDPOINTPOLICY_DENY_REMOTEBUDGET_EXCEEDEDPROVIDER_OFFLINE
This matters because the router should never "score its way out of" a hard incompatibility.
Measured evidence beats declarations
After eligibility, the router prefers measured evidence when it exists:
- latency and throughput
- failure behavior
- quality signals
- freshness and confidence
- cost estimates
Catalog-derived cost data and declared profiles still matter, but measured evidence wins when it is present.
Worked example: the gateway smoke route
The smoke request asks for:
code.edit- text output
- tool support
- balanced strategy
- local preference
- a strict per-request budget cap
The candidate set contains three endpoints:
| Endpoint | Result |
|---|---|
cli.local.coder | eligible |
acp.remote.general | excluded |
mcp.remote.embedder | excluded |
Why the exclusions happen:
acp.remote.generaldoes not provide the requiredcode.editcapabilitymcp.remote.embedderdoes not provide the requiredcode.editcapability
Both exclusions are recorded as CAPABILITY_MISSING.
That leaves cli.local.coder as the only eligible candidate. The router then records the final decision
with selection reasons such as:
BEST_TOTAL_SCOREDECLARED_PROFILE_USEDMEASURED_PROFILE_USEDLOCAL_PREFERENCE_APPLIED
Why the artifacts matter
The decision is only one artifact in the routing story.
The baseline can also emit:
trace-spans.jsonto show routing phases such as eligibility, scoring, and selectionusage-events.jsonlto show request and accounting metadataobserved-performance.jsonto show measured endpoint behavior
That artifact set is what makes routing explainable after the fact.