mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-17 20:32:25 +03:00
fix(models): normalize media endpoint metadata (#11397)
Validado em lote combinado (batch-0824g) contra o tip de release/v3.8.50: typecheck:core limpo, gates estáticos OK, 62/62 testes focados passando (endpoint/parser/schema/static-model + catálogo). Canonicaliza metadados de endpoint legados (video/audio) para IDs específicos por operação, mantendo compatibilidade retroativa via `normalizeModelSupportedEndpoints` (valores antigos `audio`/`video` continuam válidos como entrada e são normalizados na escrita). Obrigado pela contribuição, primeira PR bem-vinda!
This commit is contained in:
@@ -69,6 +69,7 @@ import {
|
||||
import { createModelCapabilityResolutionSnapshot } from "@/lib/modelCapabilityResolutionSnapshot";
|
||||
import { getModelsDevPricing, getSyncedCapability } from "@/lib/modelsDevSync";
|
||||
import { getModelSpec } from "@/shared/constants/modelSpecs";
|
||||
import { classifyModelSupportedEndpoints } from "@/shared/constants/modelSupportedEndpoints";
|
||||
import { getModelsCatalogPrefixMode } from "@/shared/utils/featureFlags";
|
||||
import { buildReservedPrefixes, selectCompatibleNodeForPrefix } from "@/lib/providerNodePrefixes";
|
||||
import { applyCatalogPostFilters, finalizeCatalogResponse } from "./catalogResponse";
|
||||
@@ -1152,18 +1153,15 @@ async function buildUnifiedModelsResponseCore(
|
||||
const aliasId = `${alias}/${displayModelId}`;
|
||||
const endpoints = Array.isArray(sm.supportedEndpoints) ? sm.supportedEndpoints : ["chat"];
|
||||
const apiFormat = typeof sm.apiFormat === "string" ? sm.apiFormat : "chat-completions";
|
||||
let modelType: string | undefined;
|
||||
if (endpoints.includes("embeddings")) modelType = "embedding";
|
||||
else if (endpoints.includes("rerank")) modelType = "rerank";
|
||||
else if (endpoints.includes("images")) modelType = "image";
|
||||
else if (endpoints.includes("audio")) modelType = "audio";
|
||||
const classification = classifyModelSupportedEndpoints(endpoints);
|
||||
const modelType = classification.type;
|
||||
// Same owned_by the alias/canonical entries below will carry — computed once
|
||||
// so the effort_tiers exclusion (codex/glm/kimi) and the entries agree.
|
||||
const syncedOwnedBy = resolvePublicOwnerId(providerId, canonicalProviderId);
|
||||
const syncedFields = {
|
||||
...(modelType ? { type: modelType } : {}),
|
||||
...(apiFormat !== "chat-completions" ? { api_format: apiFormat } : {}),
|
||||
...(modelType === "audio" ? { subtype: "transcription" } : {}),
|
||||
...(classification.subtype ? { subtype: classification.subtype } : {}),
|
||||
...(sm.inputTokenLimit ? { context_length: sm.inputTokenLimit } : {}),
|
||||
...(typeof sm.outputTokenLimit === "number"
|
||||
? { max_output_tokens: sm.outputTokenLimit }
|
||||
@@ -1604,11 +1602,8 @@ async function buildUnifiedModelsResponseCore(
|
||||
: ["chat"];
|
||||
const apiFormat =
|
||||
typeof model.apiFormat === "string" ? model.apiFormat : "chat-completions";
|
||||
let modelType: string | undefined;
|
||||
if (endpoints.includes("embeddings")) modelType = "embedding";
|
||||
else if (endpoints.includes("rerank")) modelType = "rerank";
|
||||
else if (endpoints.includes("images")) modelType = "image";
|
||||
else if (endpoints.includes("audio")) modelType = "audio";
|
||||
const classification = classifyModelSupportedEndpoints(endpoints);
|
||||
const modelType = classification.type;
|
||||
if (
|
||||
modelType &&
|
||||
hasEquivalentSpecialtyModel(canonicalProviderId, modelId, modelType, aliasId)
|
||||
@@ -1631,6 +1626,7 @@ async function buildUnifiedModelsResponseCore(
|
||||
parent: null,
|
||||
custom: true,
|
||||
...(modelType ? { type: modelType } : {}),
|
||||
...(classification.subtype ? { subtype: classification.subtype } : {}),
|
||||
...(apiFormat !== "chat-completions" ? { api_format: apiFormat } : {}),
|
||||
...(endpoints.length > 1 || !endpoints.includes("chat")
|
||||
? { supported_endpoints: endpoints }
|
||||
|
||||
Reference in New Issue
Block a user