Model strength table and fleet.json override (kyhae)
Cyberine ships a sourced answer to "which model is strong and which is weak": every model id the fleet can run has a coarse rank from 1 to 5 (5 = strongest) and a cost class from 1 to 3, keyed by model id rather than by provider, because one provider serves many models. The table is MODEL_STRENGTH_TABLE in src/core/modelStrengthTable.ts; resolveModelStrength in src/core/modelStrength.ts answers a lookup. Every row, its benchmark numbers, its sources with retrieval dates and its VERIFIED or UNVERIFIED tag are in docs/providers/model-strength.md (snapshot of 2026-09-17). You never have to declare strength yourself; fleet.json lets you correct the table where you disagree.
Precedence, highest first: a strength on the fleet.json model entry, a strength on the provider entry, the shipped table, and finally rank 3 for a model the table does not know.
Run recipe
# See the rank each routed worker got and where it came from (dry run, nothing dispatched)
cyberine route "Refactor the entire authentication module across every file in the repo and add tests."
# - claude preferred: strength=4 (strength table claude-sonnet-5=4) suits code-large task
# - codex preferred: strength=4 (model '(default)' is not in the strength table; profile tier=strong stands in as 4) suits code-large task
# ...and after codex has reported a real model in a run.json (krcz0), the same placeholder resolves through it instead:
# - codex preferred: strength=5 (strength table gpt-6-astra=5; run.json last reported "gpt-6-astra" for placeholder "(default)") suits code-large task
# List the enabled models the table cannot rank (a warning, never an error)
cyberine fleet doctor
# warn provider "codex" model "(default)" has no strength row — ranked 3 (middle) for routing; add "strength" (1-5) to providers.codex or to the model entry in fleet.json, or see docs/providers/model-strength.md; the last run.json for codex reports model "gpt-6-astra", which the table ranks 5
# fleet list also names the reported model next to any placeholder model it stands in for
cyberine fleet list
# reported models (last run.json for a placeholder model):
# codex:default (default) -> gpt-6-astra (rank 5)What the router does with the rank: on a code-large or complex task, workers whose model ranks 4 or 5 move to the front of the already-selected pool; on a qa or trivial task, workers ranking 2 or lower, or with cost class 1, move to the front and the rest of the 4-and-5 group moves to the back. A worker whose model has no row (the placeholder ids such as (default), (account-configured), or the gateway aliases anthropic/claude and openai/gpt) keeps its profile tier as the stand-in (strong 4, standard 3, flash 2), so its position is what it was before the table existed — UNLESS that worker is a cli-agent and the most recent run.json in the global registry reported a real model for it (workerRuns[].model, scanning the 50 most recent runs), in which case resolveWorkerStrength in src/core/modelStrength.ts (krcz0) ranks the REPORTED model instead of standing in on tier, and basis names both the reported model and the placeholder it replaced. The lookup runs once per process (primeReportedWorkerModels in src/store/reportedWorkerModels.ts, memoized) and every router/fleet list/fleet doctor strength read shares that one cached map — cyberine route and cyberine fleet list (below) prime it themselves; the real dispatch path primes it in resolveBuildFleetRoute. With no run.json to report from, nothing changes: the profile-tier stand-in above still applies exactly as before krcz0.
Extend recipe: override a rank in fleet.json
Add an integer strength from 1 to 5 to a provider entry, to a model entry, or both, in whichever fleet.json is in effect (the project .cyberine/fleet.json wholly replaces the global one, and both accept the field):
{
"version": 1,
"providers": {
"codex": {
"kind": "cli-agent", "workerId": "codex", "enabled": true, "default": false,
"strength": 5,
"models": { "default": { "id": "(default)" } }
},
"deepseek": {
"kind": "key-loop", "workerId": "loop-deepseek-build", "enabled": true, "default": true,
"models": { "flash": { "id": "deepseek-flash", "strength": 3 } }
}
}
}- A model entry's
strengthapplies when that entry'sidis the model being ranked. It beats the provider'sstrength, which beats the table. - Any other value (0, 6, 2.5,
"5",null) is a structural error: the file is unusable until fixed, exactly like any other invalid field, andcyberine fleet doctornames it and exits 1:
cyberine fleet doctor
# ERRORS (structural):
# error fleet.json: provider "claude".strength must be an integer from 1 to 5 (5 = strongest), got 7- The router ranks worker profiles, not individual seat lanes. When several entries bind the same
workerId(claude-ktandclaude-ftboth bindclaude), a matching model-entrystrengthwins first, then the first provider-levelstrengthin file order. - To add or re-rank a model in the shipped table, edit
src/core/modelStrengthTable.tsanddocs/providers/model-strength.mdtogether, following that page's "Refresh procedure". The table refuses to load with a duplicate id, a rank outside 1 to 5, or a row that cites no source.
No environment variable is involved.
Known limitations and deferred work
- The router only partitions by rank (4 and above is strong, 2 and below is weak). It does not yet sort the strong group strongest-first, nor pick the planner, the task splitter or the judges by rank; that is the separate follow-up khv45.
- A placeholder model is resolved through the last reported model only for a
cli-agentworker (codex, cursor-agent, crush, amp, goose, openhands, aider, ...); akey-loopworker's placeholder (e.g. the Command Code free lane's(live-catalog-free)) is never substituted this way. An explicitfleet.jsonstrengthstill wins over either. - The reported-model cache is primed once per process at the start of
cyberine route,cyberine fleet listand a real dispatch'sresolveBuildFleetRoute; a run that finishes mid-process is not picked up until the next process starts. With no run.json in the global registry to report from, the profile-tier stand-in is unchanged. - The rank is a dated snapshot (2026-09-17), refreshed by hand under the R02 upstream sweep. Nothing fetches benchmarks at runtime.
- A rank describes the model at the reasoning effort its source row was measured at (the highest AA publishes, or
highfor themuseworker). A run at a lower effort performs below its rank. - Namespaced ids such as
deepseek/deepseek-v4-flashmean different builds on different routes; the table ranks the OpenRouter meaning. A lookup with no exact row retries once without a singlevendor/prefix. - The cost class is the model's metered list price. It does not describe how a particular worker is billed.
- The LLM smart router's prompt (
CYBERINE_SMART_ROUTER) still describes workers by profile tier, not by rank.
Router eval — compare routing strategies on the corpus (T66)
Replays .local/runs/ offline and compares three routing strategies against each step's recorded judge verdict:
Fleet bench — solve rate and dollars per task (kvxah)
cyberine eval bench scores every available worker, and the judged winner, on a versioned suite of coding tasks with programmatic pass/fail. Router eval above compares routing decisions against...