






























1+import { normalizeProviderModelIdWithManifest } from "../plugins/manifest-model-id-normalization.js";
12import {
2-normalizeGooglePreviewModelId,
3-normalizeTogetherModelId,
4-} from "../plugin-sdk/provider-model-id-normalize.js";
5-import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js";
6-import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
7-import type { PluginManifestModelIdNormalizationProvider } from "../plugins/manifest.js";
8-import { resolvePluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js";
3+collectManifestModelIdNormalizationPolicies,
4+type ManifestModelIdNormalizationRecord,
5+ normalizeBuiltInProviderModelId,
6+ normalizeConfiguredProviderCatalogModelRef,
7+ normalizeConfiguredProviderCatalogModelId as normalizeConfiguredProviderCatalogModelIdShared,
8+ normalizeStaticProviderModelIdWithPolicies,
9+} from "../shared/provider-model-id-normalization.js";
910import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
1011import { normalizeProviderId } from "./provider-id.js";
1112@@ -16,85 +17,9 @@ type StaticModelRef = {
16171718export type ProviderModelIdNormalizationOptions = {
1819allowManifestNormalization?: boolean;
19-manifestPlugins?: readonly Pick<PluginManifestRecord, "modelIdNormalization">[];
20+manifestPlugins?: readonly ManifestModelIdNormalizationRecord[];
2021};
212222-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-9823export function modelKey(provider: string, model: string): string {
9924const providerId = provider.trim();
10025const modelId = model.trim();
@@ -120,69 +45,42 @@ export function normalizeStaticProviderModelId(
12045if (options.allowManifestNormalization === false) {
12146return normalizeBuiltInProviderModelId(normalizedProvider, model);
12247}
123-const manifestPlugins = resolveManifestNormalizationPlugins(options);
124-const manifestModelId = manifestPlugins
125- ? normalizeProviderModelIdWithManifestPlugins({
48+if (options.manifestPlugins) {
49+return normalizeStaticProviderModelIdWithPolicies(
50+normalizedProvider,
51+model,
52+collectManifestModelIdNormalizationPolicies(options.manifestPlugins),
53+);
54+}
55+const manifestModelId =
56+normalizeProviderModelIdWithManifest({
57+provider: normalizedProvider,
58+context: {
12659provider: normalizedProvider,
127-plugins: manifestPlugins,
12860modelId: model,
129-})
130- : undefined;
131-return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId ?? model);
132-}
133-134-function normalizeBuiltInProviderModelId(provider: string, model: string): string {
135-if (provider === "google" || provider === "google-gemini-cli" || provider === "google-vertex") {
136-return normalizeGooglePreviewModelId(model);
137-}
138-if (provider === "openrouter") {
139-const trimmed = model.trim();
140-return trimmed && !trimmed.includes("/") ? `openrouter/${trimmed}` : model;
141-}
142-if (provider === "nvidia") {
143-const trimmed = model.trim();
144-return trimmed && !trimmed.includes("/") ? `nvidia/${trimmed}` : model;
145-}
146-if (provider === "xai") {
147-const xaiAliases: Record<string, string> = {
148-"grok-4-fast-reasoning": "grok-4-fast",
149-"grok-4-1-fast-reasoning": "grok-4-1-fast",
150-"grok-4.20-experimental-beta-0304-reasoning": "grok-4.20-beta-latest-reasoning",
151-"grok-4.20-experimental-beta-0304-non-reasoning": "grok-4.20-beta-latest-non-reasoning",
152-"grok-4.20-reasoning": "grok-4.20-beta-latest-reasoning",
153-"grok-4.20-non-reasoning": "grok-4.20-beta-latest-non-reasoning",
154-};
155-return xaiAliases[normalizeLowercaseStringOrEmpty(model)] ?? model;
156-}
157-if (provider === "together") {
158-return normalizeTogetherModelId(model);
159-}
160-return model;
61+},
62+}) ?? model;
63+return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId);
16164}
1626516366export function normalizeConfiguredProviderCatalogModelId(
16467provider: string,
16568model: string,
16669options: ProviderModelIdNormalizationOptions = {},
16770): string {
168-const providerModel = normalizeStaticProviderModelId(provider, model, options);
169-const googlePrefix = "google/";
170-if (!providerModel.startsWith(googlePrefix)) {
171-const slash = providerModel.indexOf("/");
172-if (slash <= 0 || slash >= providerModel.length - 1) {
173-return providerModel;
174-}
175-const prefix = providerModel.slice(0, slash + 1);
176-const suffix = providerModel.slice(slash + 1);
177-if (!suffix.startsWith(googlePrefix)) {
178-return providerModel;
179-}
180-const normalizedSuffix = normalizeGooglePreviewModelId(suffix);
181-return normalizedSuffix === suffix ? providerModel : `${prefix}${normalizedSuffix}`;
71+if (options.allowManifestNormalization === false) {
72+return normalizeConfiguredProviderCatalogModelIdShared(provider, model, new Map());
18273}
183-const modelId = providerModel.slice(googlePrefix.length);
184-const normalizedModelId = normalizeGooglePreviewModelId(modelId);
185-return normalizedModelId === modelId ? providerModel : `${googlePrefix}${normalizedModelId}`;
74+if (options.manifestPlugins) {
75+return normalizeConfiguredProviderCatalogModelIdShared(
76+provider,
77+model,
78+collectManifestModelIdNormalizationPolicies(options.manifestPlugins),
79+);
80+}
81+return normalizeConfiguredProviderCatalogModelRef(
82+normalizeStaticProviderModelId(provider, model, options),
83+);
18684}
1878518886function parseStaticModelRef(raw: string, defaultProvider: string): StaticModelRef | null {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。