From 5f0a39409111ab2d67d3feea54e50e4537271090 Mon Sep 17 00:00:00 2001 From: ritheshcn25 Date: Thu, 13 Aug 2026 00:43:38 -0300 Subject: [PATCH] Hide health-check excluded models from /v1/models catalog (#10026) Mirror the request-time exclusion rule (provider_specific_data.excludedModels) in the unified catalog builder: a model is hidden when its provider has connections but none of them is eligible for it. Applied across the PROVIDER_MODELS, synced, custom, alias-backed, and managed-fallback loops so ghost models no longer appear as available. Co-authored-by: ritheshcn25 --- src/app/api/v1/models/catalog.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/app/api/v1/models/catalog.ts b/src/app/api/v1/models/catalog.ts index 34ccbdfbaf..07d29b07a8 100644 --- a/src/app/api/v1/models/catalog.ts +++ b/src/app/api/v1/models/catalog.ts @@ -332,6 +332,18 @@ async function buildUnifiedModelsResponseCore( return collected; }; + // Health-check exclusions (provider_specific_data.excludedModels) are enforced + // at request time in getProviderCredentials(); mirror the same rule in the + // catalog so ghost models do not appear as available. A model is hidden when + // the provider HAS connections but NONE of them is eligible for it. + const isExcludedByProviderConnections = (providerKey: string, modelId: string) => { + const providerId = aliasToProviderId[providerKey] || providerKey; + const alias = providerIdToAlias[providerId] || providerKey; + const providerConnections = getConnectionsForProvider(providerId, alias, providerKey); + if (providerConnections.length === 0) return false; // noAuth / no DB row: keep + return !hasEligibleConnectionForModel(providerConnections, modelId); + }; + const providerSupportsModel = (providerKey: string, modelId: string) => { const providerId = aliasToProviderId[providerKey] || providerKey; const alias = providerIdToAlias[providerId] || providerKey; @@ -703,6 +715,7 @@ async function buildUnifiedModelsResponseCore( if (!providerSupportsModel(canonicalProviderId, model.id)) continue; const aliasId = `${alias}/${model.id}`; if (getModelIsHidden(canonicalProviderId, model.id)) continue; + if (isExcludedByProviderConnections(canonicalProviderId, model.id)) continue; if (shouldHidePaid(canonicalProviderId, model.id, (model as { pricing?: unknown }).pricing)) continue; @@ -797,6 +810,7 @@ async function buildUnifiedModelsResponseCore( continue; } if (getModelIsHidden(providerId, sm.id)) continue; + if (isExcludedByProviderConnections(canonicalProviderId, sm.id)) continue; // #6457: some upstream discovery catalogs (e.g. HuggingFace's live // `/v1/models`) return image/diffusion models with no modality info, // so `endpoints` below would default to ["chat"] and misrepresent @@ -1173,6 +1187,7 @@ async function buildUnifiedModelsResponseCore( if (!modelId) continue; if (model.isHidden === true) continue; if (getModelIsHidden(canonicalProviderId, modelId)) continue; + if (isExcludedByProviderConnections(canonicalProviderId, modelId)) continue; // #6328: apply hidePaidModels to user-defined custom rows too. // Custom entries do not carry pricing, so shouldHidePaid() decides // via FREE_MODEL_IDS_BY_PROVIDER — matches synced/PROVIDER_MODELS. @@ -1305,6 +1320,7 @@ async function buildUnifiedModelsResponseCore( } if (getModelIsHidden(canonicalProviderId, modelId)) continue; + if (isExcludedByProviderConnections(canonicalProviderId, modelId)) continue; // #6328: apply hidePaidModels to alias-backed rows too. Alias mappings // point at providerKey/modelId with no pricing, so shouldHidePaid() // decides via the FREE_MODEL_IDS_BY_PROVIDER catalog tier. @@ -1377,6 +1393,7 @@ async function buildUnifiedModelsResponseCore( const modelId = typeof model.id === "string" ? model.id : null; if (!modelId) continue; if (getModelIsHidden(canonicalProviderId, modelId)) continue; + if (isExcludedByProviderConnections(canonicalProviderId, modelId)) continue; // #6328: apply hidePaidModels to managed-fallback rows too. Compatible // provider fallbacks lack pricing; shouldHidePaid() decides via the // FREE_MODEL_IDS_BY_PROVIDER catalog tier.