mirror of
https://github.com/Nezumi-2711/9router.git
synced 2026-09-22 13:38:31 +00:00
- Add providers/models/schema.js (MODEL_DEFAULTS + field resolvers) - Accessors getModelTargetFormat/QuotaFamily/Strip use shared default resolvers - getModelType keeps null contract unchanged; behavior verified equal - No catalog forced into registry (models stay self-contained per docs decision) Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
3.1 KiB
JavaScript
100 lines
3.1 KiB
JavaScript
import { PROVIDERS } from "./providers.js";
|
|
// PROVIDER_MODELS now built from providers/registry (transport + models co-located)
|
|
import { PROVIDER_MODELS } from "../providers/index.js";
|
|
import { modelQuotaFamily, modelStrip, modelTargetFormat } from "../providers/models/schema.js";
|
|
|
|
export { PROVIDER_MODELS };
|
|
|
|
const CODEX_REVIEW_SUFFIX = "-review";
|
|
|
|
|
|
// Helper functions
|
|
export function getProviderModels(aliasOrId) {
|
|
return PROVIDER_MODELS[aliasOrId] || [];
|
|
}
|
|
|
|
export function getDefaultModel(aliasOrId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
return models?.[0]?.id || null;
|
|
}
|
|
|
|
export function isValidModel(aliasOrId, modelId, passthroughProviders = new Set()) {
|
|
if (passthroughProviders.has(aliasOrId)) return true;
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
if (!models) return false;
|
|
return models.some(m => m.id === modelId);
|
|
}
|
|
|
|
export function findModelName(aliasOrId, modelId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
if (!models) return modelId;
|
|
const found = models.find(m => m.id === modelId);
|
|
return found?.name || modelId;
|
|
}
|
|
|
|
export function getModelTargetFormat(aliasOrId, modelId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
if (!models) return null;
|
|
return modelTargetFormat(models.find(m => m.id === modelId));
|
|
}
|
|
|
|
export function getModelType(aliasOrId, modelId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
if (!models) return null;
|
|
const found = models.find(m => m.id === modelId);
|
|
return found?.type || null;
|
|
}
|
|
|
|
export function getModelUpstreamId(aliasOrId, modelId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
const found = models?.find(m => m.id === modelId);
|
|
if (found?.upstreamModelId) return found.upstreamModelId;
|
|
if (aliasOrId === "cx" && typeof modelId === "string" && modelId.endsWith(CODEX_REVIEW_SUFFIX)) {
|
|
return modelId.slice(0, -CODEX_REVIEW_SUFFIX.length);
|
|
}
|
|
return modelId;
|
|
}
|
|
|
|
export function getModelQuotaFamily(aliasOrId, modelId) {
|
|
const models = PROVIDER_MODELS[aliasOrId];
|
|
return modelQuotaFamily(models?.find(m => m.id === modelId));
|
|
}
|
|
|
|
// OAuth providers that use short aliases (everything else: alias = id)
|
|
// Single source of canonical id→alias; services/model.js derives the reverse.
|
|
export const OAUTH_ALIASES = {
|
|
claude: "cc",
|
|
codex: "cx",
|
|
"gemini-cli": "gc",
|
|
qwen: "qw",
|
|
iflow: "if",
|
|
antigravity: "ag",
|
|
github: "gh",
|
|
kiro: "kr",
|
|
cursor: "cu",
|
|
"kimi-coding": "kmc",
|
|
kilocode: "kc",
|
|
cline: "cl",
|
|
opencode: "oc",
|
|
qoder: "qd",
|
|
"mimo-free": "mmf",
|
|
vertex: "vertex",
|
|
"vertex-partner": "vertex-partner",
|
|
};
|
|
|
|
// Derived from PROVIDERS — no need to maintain manually
|
|
export const PROVIDER_ID_TO_ALIAS = Object.fromEntries(
|
|
Object.keys(PROVIDERS).map(id => [id, OAUTH_ALIASES[id] || id])
|
|
);
|
|
|
|
export function getModelsByProviderId(providerId) {
|
|
const alias = PROVIDER_ID_TO_ALIAS[providerId] || providerId;
|
|
return PROVIDER_MODELS[alias] || [];
|
|
}
|
|
|
|
// Get strip list for a model entry (explicit opt-in only)
|
|
// Returns array of content types to strip, e.g. ["image", "audio"]
|
|
export function getModelStrip(alias, modelId) {
|
|
return modelStrip(PROVIDER_MODELS[alias]?.find(m => m.id === modelId));
|
|
}
|