Files
moltbot/src/agents/model-ref-shared.ts
2026-05-08 06:08:58 +01:00

101 lines
3.2 KiB
TypeScript

import { normalizeGooglePreviewModelId } from "../plugin-sdk/provider-model-id-normalize.js";
import { normalizeProviderModelIdWithManifest } from "../plugins/manifest-model-id-normalization.js";
import type { PluginManifestRecord } from "../plugins/manifest-registry.js";
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
import { normalizeProviderId } from "./provider-id.js";
type StaticModelRef = {
provider: string;
model: string;
};
export function modelKey(provider: string, model: string): string {
const providerId = provider.trim();
const modelId = model.trim();
if (!providerId) {
return modelId;
}
if (!modelId) {
return providerId;
}
return normalizeLowercaseStringOrEmpty(modelId).startsWith(
`${normalizeLowercaseStringOrEmpty(providerId)}/`,
)
? modelId
: `${providerId}/${modelId}`;
}
export function normalizeStaticProviderModelId(
provider: string,
model: string,
options: {
allowManifestNormalization?: boolean;
manifestPlugins?: readonly Pick<PluginManifestRecord, "modelIdNormalization">[];
} = {},
): string {
const normalizedProvider = normalizeProviderId(provider);
if (options.allowManifestNormalization === false) {
return normalizeBuiltInProviderModelId(normalizedProvider, model);
}
const manifestModelId =
normalizeProviderModelIdWithManifest({
provider: normalizedProvider,
plugins: options.manifestPlugins,
context: {
provider: normalizedProvider,
modelId: model,
},
}) ?? model;
return normalizeBuiltInProviderModelId(normalizedProvider, manifestModelId);
}
function normalizeBuiltInProviderModelId(provider: string, model: string): string {
if (provider === "google" || provider === "google-gemini-cli" || provider === "google-vertex") {
return normalizeGooglePreviewModelId(model);
}
return model;
}
function parseStaticModelRef(raw: string, defaultProvider: string): StaticModelRef | null {
const trimmed = raw.trim();
if (!trimmed) {
return null;
}
const slash = trimmed.indexOf("/");
const providerRaw = slash === -1 ? defaultProvider : trimmed.slice(0, slash).trim();
const modelRaw = slash === -1 ? trimmed : trimmed.slice(slash + 1).trim();
if (!providerRaw || !modelRaw) {
return null;
}
const provider = normalizeProviderId(providerRaw);
return {
provider,
model: normalizeStaticProviderModelId(provider, modelRaw),
};
}
export function resolveStaticAllowlistModelKey(
raw: string,
defaultProvider: string,
): string | null {
const parsed = parseStaticModelRef(raw, defaultProvider);
if (!parsed) {
return null;
}
return modelKey(parsed.provider, parsed.model);
}
export function formatLiteralProviderPrefixedModelRef(provider: string, modelRef: string): string {
const providerId = normalizeProviderId(provider);
const trimmedRef = modelRef.trim();
if (!providerId || !trimmedRef) {
return trimmedRef;
}
const normalizedRef = normalizeLowercaseStringOrEmpty(trimmedRef);
const literalPrefix = `${providerId}/${providerId}/`;
if (normalizedRef.startsWith(literalPrefix)) {
return trimmedRef;
}
return normalizedRef.startsWith(`${providerId}/`) ? `${providerId}/${trimmedRef}` : trimmedRef;
}