fix(api): honor model-hidden overrides across provider key variants (#11300) - #11308
jonlwheat2-gif wants to merge 2 commits into
Conversation
…iegosouzapw#11300) Visibility overrides are persisted under whatever provider key the dashboard route carried (node UUID, route alias like cc/gh/xao, or canonical id), but catalog lookups queried a single exact key, so hidden models kept leaking into GET /v1/models. Add a shared equivalence-set resolver (key + canonical + alias + connection-family ids + caller extras such as node prefixes) and wire it into getModelIsHidden and the catalog's bulk isModelHiddenBulk path; the codex-native loop now also consults the openai family page.
|
Closing as already covered: #11309 (merged before this PR was opened) fixed the same underlying issue #11300 — a hidden-model override written under a dashboard route key (alias/canonical/node UUID) not being honored by a catalog loop that only checked one key shape. I verified against the pristine release/v3.8.50 tip: |
Fixes #11300
Summary
Models toggled Hidden on provider pages kept appearing in
GET /v1/modelswhenever the storage key differed from the key a catalog loop queried. Root cause verified line-by-line at base527da6565: the write path persists{isHidden:true}under whatever provider key the dashboard route carried — node UUID (openai-compatible-chat-<uuid>), route alias (cc/gh/cx/xao), or canonical id (claude/github/xai) — while every read path used exactly one key.Before → After (precise)
catalog.ts[providerIdToAlias[key], providerIdToPrefix[key]]; all 16 call sites unchangedcatalog.ts"codex"only, :1020-1021openaifamily page, :1030-1031getModelIsHidden,db/models.tsproviderKeysToCheck()[key, canonical=resolveProviderId(key), getProviderAlias(canonical), …getProviderConnectionFamilyIds(canonical), …extras]— family ids coverxai ↔ xao/xai-oauth,magnific ↔ freepikisModelHiddenInBulkMap()localDb.tsLoop-key mismatch table being fixed (base line numbers): static loop queried canonical (:958) missing alias/UUID-stored hides; synced loop queried raw connection id (:1082); custom loop canonical (:1501/:1685/:1759); media loops
model.provider(:1336-1455). Secondary blast radius closed: per-key public filtering (apiKeys.ts:1541) usesgetModelIsHidden.TDD evidence (hard rule #18)
New suite
tests/unit/model-hide-multikey-11300.test.ts:RED against unfixed base — pass 4 / fail 3:
Honest note: two cases passed pre-fix because
readCompatList()internally resolves some aliases via open-sse'sresolveProviderAlias— but thecustomModelsnamespace, connection-family aliases (xao), and the entire catalog bulk map did not. That patchwork is why existing tests (which only cover same-key hides) never caught it.GREEN post-fix: 7/7.
Regression sweep — issue-named tests + full
/v1/modelsfamily (synced-model-hide-persist-3782,model-catalog-policy-invalidation-8728,aliases-included,auth-leak-9320,catalog-generation-race,catalog-ttl,concurrent-6408,discovery-conformance): 39 pass / 0 fail; re-run green after rebase onto current tip. Independently reproduced in a detached clean worktree (no caches): same results.Gates:⚠️ Inherited: repo-wide lint reports 34 pre-existing errors in files this PR does not touch (present at base; tracked by the base-red cluster #9985).
npm run typecheck:coreclean.Scope boundary (matches the reporter's own proposal)
Cross-family bridging with no alias/family/prefix relationship (e.g. bare UUID vs unrelated canonical) would require a reverse node-family index; every combination reachable via canonical resolution, registered aliases, connection-family ids, and node prefixes — i.e., all four cases enumerated in the issue — is covered.
Diff: 4 files changed, +191/−10.