mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-21 22:52:19 +03:00
fix(providers): treat a degraded cached catalog as a failed model sync (#10862)
Obrigado — root cause preciso: a rota sync-models só reconhecia a degradação para local_catalog, não para o fallback de cache com warning, então uma chave expirada (401) virava silenciosamente "Nenhum modelo novo foi adicionado" em vez de um erro visível. Validação (worktree combinado a partir de origin/release/v3.8.50, 0 conflitos): - typecheck:core limpo, complexity/cognitive-complexity dentro do baseline - tests/unit/sync-models-degraded-cached-catalog-9683.test.ts — 6/6 passando (payloads reais do models/route.ts) - Suítes model-sync/provider-models/sync-models/siliconflow — 181/181 passando, incluindo as 3 asserções pré-existentes #5460/#5465
This commit is contained in:
@@ -19,3 +19,44 @@ export function isDegradedLocalCatalog(modelsData: {
|
||||
typeof modelsData?.source === "string" ? modelsData.source.trim().toLowerCase() : "";
|
||||
return source === "local_catalog" && modelsData?.intentional !== true;
|
||||
}
|
||||
|
||||
/**
|
||||
* #9683 — the same degradation, one branch further up.
|
||||
*
|
||||
* When remote discovery fails, the models route falls back to the CACHED
|
||||
* catalog if it has one and only falls back to the local catalog when it does
|
||||
* not (`buildDiscoveryFallbackResponse`). A provider that was imported
|
||||
* successfully once therefore has a cache, so an expired key produced
|
||||
* `source: "cache"` + a warning and HTTP 200 — model-sync treated that as a
|
||||
* successful discovery, found every cached model already imported, and reported
|
||||
* "No new models were added" instead of the credential error. Retest, which
|
||||
* does not go through this path, failed correctly, which is what made the
|
||||
* import look like a real "nothing to do".
|
||||
*
|
||||
* The discriminator is the warning: the fallback builder always attaches one,
|
||||
* while the ordinary cache hit (`maybeReturnCachedDiscovery`, a non-refresh
|
||||
* read) attaches none. Model-sync always requests `refresh=true`, so the one
|
||||
* warning-carrying cache response it can observe is a degraded one.
|
||||
*/
|
||||
export function isDegradedCachedCatalog(modelsData: {
|
||||
source?: unknown;
|
||||
warning?: unknown;
|
||||
}): boolean {
|
||||
const source =
|
||||
typeof modelsData?.source === "string" ? modelsData.source.trim().toLowerCase() : "";
|
||||
if (source !== "cache") return false;
|
||||
return typeof modelsData?.warning === "string" && modelsData.warning.trim().length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Either degraded shape. Model-sync must refuse to treat these as a successful
|
||||
* discovery: persisting them would silently pin a stale catalog and hide the
|
||||
* real failure from the operator.
|
||||
*/
|
||||
export function isDegradedDiscovery(modelsData: {
|
||||
source?: unknown;
|
||||
intentional?: unknown;
|
||||
warning?: unknown;
|
||||
}): boolean {
|
||||
return isDegradedLocalCatalog(modelsData) || isDegradedCachedCatalog(modelsData);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import { autoSyncCodexProfilesFromLiveCatalog } from "@/lib/cli-helper/codexProf
|
||||
import { autoSyncClaudeProfilesFromLiveCatalog } from "@/lib/cli-helper/claudeProfileAutoSync";
|
||||
import { providerUsesCuratedModelsOnly } from "@/lib/providers/modelListingCapability";
|
||||
import { GET as getProviderModels } from "../models/route";
|
||||
import { isDegradedLocalCatalog } from "./degradedLocalCatalog";
|
||||
import { isDegradedDiscovery } from "./degradedLocalCatalog";
|
||||
import { sanitizeErrorMessage } from "@omniroute/open-sse/utils/error";
|
||||
|
||||
type JsonRecord = Record<string, unknown>;
|
||||
@@ -465,9 +465,9 @@ export async function POST(request: Request, { params }: { params: Promise<{ id:
|
||||
|
||||
const modelSource = toNonEmptyString(modelsData.source)?.toLowerCase() || "unknown";
|
||||
const modelWarning = toNonEmptyString(modelsData.warning);
|
||||
if (isDegradedLocalCatalog(modelsData)) {
|
||||
if (isDegradedDiscovery(modelsData)) {
|
||||
const responseError =
|
||||
modelWarning || "Remote model discovery failed; local catalog fallback not synced";
|
||||
modelWarning || "Remote model discovery failed; catalog fallback not synced";
|
||||
await saveCallLog({
|
||||
method: "GET",
|
||||
path: `/api/providers/${id}/models`,
|
||||
|
||||
Reference in New Issue
Block a user