feat(models): 统一模型规格价格与路由

This commit is contained in:
kinoko committed 2026-08-22 17:00:08 +08:00
1 parent d268a938e5
commit 236b850177
36 files changed
+3404 -421

No files matched your search

+13 -6
View File
@@ -145,7 +145,10 @@ function logicalModelCompatibilityError(spec: NonNullable<NonNullable<AiConfig["
}
function logicalOptionMatches(name: string, constraint: { values?: unknown[]; min?: number; max?: number; step?: number }, value: unknown) {
if (constraint.values?.length) return constraint.values.some((candidate) => logicalOptionValueMatches(name, candidate, value));
if (constraint.values?.length) {
const requested = normalizeLogicalOptionValue(name, value);
return constraint.values.some((candidate) => normalizeLogicalOptionValue(name, candidate) === requested);
}
const numeric = Number(value);
if (!Number.isFinite(numeric)) return false;
if (constraint.min !== undefined && numeric < constraint.min) return false;
@@ -154,11 +157,15 @@ function logicalOptionMatches(name: string, constraint: { values?: unknown[]; mi
return true;
}
function logicalOptionValueMatches(name: string, candidate: unknown, value: unknown) {
const left = String(candidate).trim().toLowerCase();
const right = String(value).trim().toLowerCase();
if (name === "vquality" || name === "resolution") return left.replace(/p$/, "") === right.replace(/p$/, "");
return left === right;
function normalizeLogicalOptionValue(name: string, value: unknown) {
const normalized = String(value).trim().toLowerCase();
if (name !== "vquality" && name !== "resolution") return normalized;
if (normalized === "low") return "480p";
if (["auto", "medium", "high"].includes(normalized)) return "720p";
if (normalized === "2k") return "1440p";
if (normalized === "4k") return "2160p";
const resolution = normalized.replace(/p$/i, "");
return resolution ? `${resolution}p` : "";
}
function logicalOptionError(name: string) {
+4
View File
@@ -81,6 +81,9 @@ function managedModelChannels(models: PublicLogicalModel[]) {
scope: "system",
enabled: true,
models: availableModels.map((item) => item.id),
modelAliases: Object.fromEntries(
availableModels.flatMap((item) => (item.legacyModelIds || []).map((legacyID) => [legacyID, item.id])),
),
modelCosts: availableModels.map((item) => ({
model: item.id,
displayName: item.name,
@@ -97,6 +100,7 @@ function managedModelChannels(models: PublicLogicalModel[]) {
logicalModelId: item.id,
logicalCapabilitySpec: item.capabilitySpec,
logicalCapabilityProfiles: item.capabilityProfiles,
logicalPriceTiers: item.priceTiers,
defaultOptions: item.defaultOptions,
})),
};