





















@@ -2,8 +2,10 @@ import {
22normalizeGooglePreviewModelId,
33normalizeTogetherModelId,
44} from "../plugin-sdk/provider-model-id-normalize.js";
5-import { normalizeProviderModelIdWithManifest } from "../plugins/manifest-model-id-normalization.js";
5+import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js";
66import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
7+import type { PluginManifestModelIdNormalizationProvider } from "../plugins/manifest.js";
8+import { resolvePluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
79import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
810import { normalizeProviderId } from "./provider-id.js";
911@@ -17,6 +19,82 @@ export type ProviderModelIdNormalizationOptions = {
1719manifestPlugins?: readonly Pick<PluginManifestRecord, "modelIdNormalization">[];
1820};
192122+function collectManifestModelIdNormalizationPolicies(
23+plugins: readonly Pick<PluginManifestRecord, "modelIdNormalization">[],
24+): Map<string, PluginManifestModelIdNormalizationProvider> {
25+const policies = new Map<string, PluginManifestModelIdNormalizationProvider>();
26+for (const plugin of plugins) {
27+for (const [provider, policy] of Object.entries(plugin.modelIdNormalization?.providers ?? {})) {
28+policies.set(normalizeLowercaseStringOrEmpty(provider), policy);
29+}
30+}
31+return policies;
32+}
33+34+function hasProviderPrefix(modelId: string): boolean {
35+return modelId.includes("/");
36+}
37+38+function formatPrefixedModelId(prefix: string, modelId: string): string {
39+return `${prefix.replace(/\/+$/u, "")}/${modelId.replace(/^\/+/u, "")}`;
40+}
41+42+function normalizeProviderModelIdWithManifestPlugins(params: {
43+provider: string;
44+plugins: readonly Pick<PluginManifestRecord, "modelIdNormalization">[];
45+modelId: string;
46+}): string | undefined {
47+const policy = collectManifestModelIdNormalizationPolicies(params.plugins).get(
48+normalizeLowercaseStringOrEmpty(params.provider),
49+);
50+if (!policy) {
51+return undefined;
52+}
53+54+let modelId = params.modelId.trim();
55+if (!modelId) {
56+return modelId;
57+}
58+59+for (const prefix of policy.stripPrefixes ?? []) {
60+const normalizedPrefix = normalizeLowercaseStringOrEmpty(prefix);
61+if (normalizedPrefix && normalizeLowercaseStringOrEmpty(modelId).startsWith(normalizedPrefix)) {
62+modelId = modelId.slice(prefix.length);
63+break;
64+}
65+}
66+67+modelId = policy.aliases?.[normalizeLowercaseStringOrEmpty(modelId)] ?? modelId;
68+69+if (!hasProviderPrefix(modelId)) {
70+for (const rule of policy.prefixWhenBareAfterAliasStartsWith ?? []) {
71+if (normalizeLowercaseStringOrEmpty(modelId).startsWith(rule.modelPrefix.toLowerCase())) {
72+return formatPrefixedModelId(rule.prefix, modelId);
73+}
74+}
75+if (policy.prefixWhenBare) {
76+return formatPrefixedModelId(policy.prefixWhenBare, modelId);
77+}
78+}
79+80+return modelId;
81+}
82+83+function resolveManifestNormalizationPlugins(
84+options: ProviderModelIdNormalizationOptions,
85+): readonly Pick<PluginManifestRecord, "modelIdNormalization">[] | undefined {
86+if (options.manifestPlugins) {
87+return options.manifestPlugins;
88+}
89+return (
90+getCurrentPluginMetadataSnapshot({
91+allowWorkspaceScopedSnapshot: true,
92+requireDefaultDiscoveryContext: true,
93+})?.plugins ??
94+resolvePluginMetadataSnapshot({ config: {}, allowWorkspaceScopedCurrent: true }).plugins
95+);
96+}
97+2098export function modelKey(provider: string, model: string): string {
2199const providerId = provider.trim();
22100const modelId = model.trim();
@@ -42,16 +120,15 @@ export function normalizeStaticProviderModelId(
42120if (options.allowManifestNormalization === false) {
43121return normalizeBuiltInProviderModelId(normalizedProvider, model);
44122}
45-const manifestModelId =
46-normalizeProviderModelIdWithManifest({
47-provider: normalizedProvider,
48-plugins: options.manifestPlugins,
49-context: {
123+const manifestPlugins = resolveManifestNormalizationPlugins(options);
124+const manifestModelId = manifestPlugins
125+ ? normalizeProviderModelIdWithManifestPlugins({
50126provider: normalizedProvider,
127+plugins: manifestPlugins,
51128modelId: model,
52-},
53-}) ?? model;
54-return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId);
129+})
130+: undefined;
131+return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId ?? model);
55132}
5613357134function normalizeBuiltInProviderModelId(provider: string, model: string): string {
@@ -62,6 +139,10 @@ function normalizeBuiltInProviderModelId(provider: string, model: string): strin
62139const trimmed = model.trim();
63140return trimmed && !trimmed.includes("/") ? `openrouter/${trimmed}` : model;
64141}
142+if (provider === "nvidia") {
143+const trimmed = model.trim();
144+return trimmed && !trimmed.includes("/") ? `nvidia/${trimmed}` : model;
145+}
65146if (provider === "xai") {
66147const xaiAliases: Record<string, string> = {
67148"grok-4-fast-reasoning": "grok-4-fast",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。