fix(routing): re-sync Router Core to 5ee7c23, and rebuild the free tier from probed ids - #55
Merged
Merged
Conversation
…er from probed ids Router Core was two commits behind upstream. V3.5 rebuilds every tier chain around ids the public catalog actually lists, so the withheld kimi-k2.5/k2.6/ k2.7, both grok-4-fast pairs, grok-4-0709, claude-opus-4.6 and gemini-3-pro-preview leave every rung including the fallbacks. Measured against the live catalog, each profile carried 3-4 off-catalog rungs per decision before this; now every profile carries none. The newer generation the catalog already sells enters as fallback rungs (GPT-5.6 Luna/Terra, Gemini 3.6 Flash, GLM-5.3, Grok 4.3/4.5, Kimi K3, Qwen 3.7 Plus, MiniMax M3); primaries moved only where portfolio.py already holds calibration evidence for the successor. Priors come with it: 66 model profiles (was 30) and a 71-model capability snapshot. Two stale capability values had been reaching the hard filter, Haiku 4.5 at 8K max output (64K) and Sonnet 4.6 at 200K context (1M). config.py was not hand-transcribed. A TS->Python converter was validated by running it over config.ts at the OLD pin and checking it reproduced the current config.py tier chains line for line (223/223) before it was pointed at HEAD. Separately, routing_profile="free" had collapsed to one model with no fallbacks. Four of the five ids in the SDK-only FREE_TIERS table were retired by NVIDIA and they were every primary plus all but one fallback. Nothing looked broken because the gateway server-redirects a retired free id: the dead rung returns 200 and answers normally while serving a different model, which is the shape that defeats unavailable_models. The table is rebuilt from ids verified by a two-pass probe that reads back the response's own model field, since a 200 proves nothing. nemotron-3-ultra-550b and nemotron-3-nano-omni-30b-a3b-reasoning are excluded despite listing at $0 -- both answer as nemotron-3-nano-30b. Every tier is back to four candidates and the free tier is no longer NVIDIA-only. The new depth test asserts fallback depth per tier rather than membership: the table stayed internally consistent all through the rot, so a membership check could never have caught it. 669 unit tests pass, the 88 cross-language parity decisions included. mypy reports the same 198 baseline errors before and after.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Router Core was two commits behind upstream (
d7bc10c→5ee7c23), plus a separate bug in the SDK-onlyfreeprofile.Off-catalog routing
Upstream V3.5 rebuilds every tier chain around ids the public catalog actually lists. The withheld
kimi-k2.5/k2.6/k2.7, both grok-4-fast pairs,grok-4-0709,claude-opus-4.6andgemini-3-pro-previewleave every rung, fallbacks included.Measured against the live catalog, before and after:
The newer generation the catalog already sells enters as fallback rungs — GPT-5.6 Luna/Terra, Gemini 3.6 Flash and 3.5 Flash-Lite, GLM-5.3 and 5.3-Flash, Grok 4.3 and 4.5, Kimi K3, Qwen 3.7 Plus, MiniMax M3. Primaries moved only where
portfolio.pyalready holds calibration evidence for the successor. Promotion waits for a calibration run; version recency is not a quality signal.Priors come with it: 66 model profiles (was 30) and a 71-model capability snapshot. Two stale capability values had been reaching the hard filter — Haiku 4.5 at 8K max output (actually 64K), Sonnet 4.6 at 200K context (actually 1M).
config.pywas not hand-transcribed. A TS→Python converter was validated by running it overconfig.tsat the old pin and confirming it reproduced the currentconfig.pytier chains line for line (223/223) before being pointed at HEAD.routing_profile="free"had collapsed to one modelFour of the five ids in
FREE_TIERSwere retired by NVIDIA, and they were every primary plus all but one fallback. Every tier fell through to a single survivor with zero fallbacks.Nothing looked broken because the gateway server-redirects a retired free id — the dead rung returns 200 and answers normally while quietly serving a different model. That is the shape that defeats a host's
unavailable_models, and it is why the table rotted unnoticed:The table is rebuilt from ids verified by a two-pass probe that reads back the response's own
modelfield, since a 200 proves nothing. Two models the catalog still prices at $0 did not survive that check and are excluded —nemotron-3-ultra-550bandnemotron-3-nano-omni-30b-a3b-reasoningboth answer asnemotron-3-nano-30b. Worth reporting upstream:5ee7c23kept nano-omni as the one survivor of its own 2026-08-30 pass.Every tier is back to four candidates, and the free tier is no longer NVIDIA-only —
cohere/north-mini-codeandpoolside/laguna-xs-2.1serve at $0 and carry the free coding load.The new depth test asserts fallback depth per tier rather than membership. The table stayed internally consistent all through the rot, so a membership check could never have caught it.
Verification
black --checkandruff checkcleanmypyreports the same 198 baseline errors before and after — no regressionsmart_chat(routing_profile="free")returnsnemotron-3-nano-30bandnemotron-3.5-lightning,$0