fix(core): stop offering deprecated models in fallback lists - #3494
Merged
Conversation
`fallbackModels` is a recommendation, not an inventory: everything in it lands in the catalog as available and default-capable, and its head is what a new connection defaults to and what the connection test probes. `toolCallingModelIds` filters on tool-calling capability only, so six providers still offered 28 models their vendors have deprecated. Apply the lifecycle filter the other eight derivations already use to xiaomi, nvidia, mistral, togetherai and deepinfra, and drop the one deprecated id from openai's hand-written list. Removal is from the offer only: an id a user already chose still sends (`authorizeConnectionModel` never reads this list), and all six do live protocol discovery, so the endpoint's own catalog still comes back on the first fetch. Every head is unchanged, so no connection default or probe model moves. The recorded boundary in the contract test empties and goes away with it, which is what it was built to do. Closes apache#3355 Generated-by: Claude Code (Opus 5) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The comment said the catalog marks whatever the list contains available and default-capable, then singled out `openai` — but `openai` is one of eight providers whose `CURATED_CATALOG_FALLBACK_MODELS` entry replaces the registry list before the catalog is built, so for those eight this list reaches CLI onboarding and the connection-test probe candidates rather than the picker. It also said each derivation drops deprecated ids at its call site; thirteen of twenty-seven do. Generated-by: Claude Code (Opus 5) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jackwener
approved these changes
Aug 22, 2026
jackwener
left a comment
Member
There was a problem hiding this comment.
Reviewed the exact head against the current base. The fallback lifecycle policy and scope are sound, the follow-up only corrects the contract comment, and I found no blocking correctness issue.
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.
Summary
fallbackModelsis a recommendation, not an inventory: everything in it lands in the catalog as available and default-capable, and its head is what a new connection defaults to and what the connection test probes.toolCallingModelIdsfilters on tool-calling capability only, so six providers still offered 28 models their vendors have deprecated.This applies the call-site lifecycle filter #3324 established for ZenMux to xiaomi, nvidia, mistral, togetherai and deepinfra, and drops the one deprecated id from openai's hand-written list. That empties
PROVIDERS_WITH_DEPRECATED_FALLBACKS, so the recorded boundary goes away with it and the remaining assertion becomes the unconditional invariant — which is what its comment says it was built to do.Removal is from the offer only. An id a user already chose still sends (
authorizeConnectionModelnever reads this list), and all six dokind: 'protocol'discovery, so the endpoint's own catalog returns on the first/modelsfetch. Every list head is unchanged, so no connection default or connection-test probe model moves.Reasoning for the offer-policy question the issue poses, and the measurements behind the notes below, are in #3355 (comment).
Fixes #3355
Review focus
CURATED_CATALOG_FALLBACK_MODELS.openaishadows the registry list atmodel-catalog.ts:239, sogpt-4-turbois in no picker today — removing it is hygiene for the non-catalog consumers (connection test, onboarding verify, CLI projection) and for the contract test, which reads the registry directly. And "discovery keeps only the fallback set" is thekind: 'fallback'branch; none of these six is on it, which is why the exclusion costs no reachability.open-mistral-nemo), and xiaomi is the largest proportional cut, 6 → 3. Both come straight back from live discovery.toolCallingModelIdswould be a no-op today — of 46 snapshots, the only ones carrying a tool-capable deprecated id are the nine now filtered at their call site plus openai, google and the three xiaomi-token-plan entries, which all use hand-written lists that never reach the helper. Happy to roll that in here or leave it as a follow-up; the wrinkle is placement, since ollama-cloud's pre-filter is what makes a deprecated recommended id throw at module load rather than vanish.CATALOG_PROVIDER_TYPES, which is 55 of 59 registry entries.xai-oauth,github-copilot,claude-subscriptionandopenai-codexsit outside it; I checked and none carries a deprecated id today.Verification
keeps deprecated snapshot models out of fallback listsfails naming all six providers and all 28 ids (togetherai 11, mistral 8, xiaomi 3, deepinfra 3, nvidia 2, openai 1)@maka/core588 pass;@maka/storage895 pass;@maka/runtime3066 pass with one environment failure (claude-subscription-usagecannot reach the OAuth token endpoint in my sandbox — fails identically on unmodifiedmain)lint,format:checkandtypecheckall passRUNTIME_HOST_COMPATIBILITY_EPOCHstays put.model-pricing.generated.tsstill carries rows for the removed ids and is deliberately untouched — it is generated and keyed independently.AI use
Select exactly one:
Tool(s) and scope: Claude Code (Opus 5) — implementation, tests and the supporting measurements, under my direction and review. The commit carries a Generated-by trailer.
Checklist
Does this PR entail a change in behavior?