95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { normalizeGoogleModelId } from "./google-model-id.js";
|
|
import { normalizeProviderId } from "./provider-id.js";
|
|
|
|
export type ModelRef = {
|
|
provider: string;
|
|
model: string;
|
|
};
|
|
|
|
export function modelKey(provider: string, model: string) {
|
|
const providerId = provider.trim();
|
|
const modelId = model.trim();
|
|
if (!providerId) {
|
|
return modelId;
|
|
}
|
|
if (!modelId) {
|
|
return providerId;
|
|
}
|
|
return modelId.toLowerCase().startsWith(`${providerId.toLowerCase()}/`)
|
|
? modelId
|
|
: `${providerId}/${modelId}`;
|
|
}
|
|
|
|
export function legacyModelKey(provider: string, model: string): string | null {
|
|
const providerId = provider.trim();
|
|
const modelId = model.trim();
|
|
if (!providerId || !modelId) {
|
|
return null;
|
|
}
|
|
const rawKey = `${providerId}/${modelId}`;
|
|
const canonicalKey = modelKey(providerId, modelId);
|
|
return rawKey === canonicalKey ? null : rawKey;
|
|
}
|
|
|
|
function normalizeAnthropicModelId(model: string): string {
|
|
const trimmed = model.trim();
|
|
if (!trimmed) {
|
|
return trimmed;
|
|
}
|
|
const lower = trimmed.toLowerCase();
|
|
switch (lower) {
|
|
case "opus-4.6":
|
|
return "claude-opus-4-6";
|
|
case "opus-4.5":
|
|
return "claude-opus-4-5";
|
|
case "sonnet-4.6":
|
|
return "claude-sonnet-4-6";
|
|
case "sonnet-4.5":
|
|
return "claude-sonnet-4-5";
|
|
default:
|
|
return trimmed;
|
|
}
|
|
}
|
|
|
|
function normalizeProviderModelId(provider: string, model: string): string {
|
|
if (provider === "anthropic") {
|
|
return normalizeAnthropicModelId(model);
|
|
}
|
|
if (provider === "vercel-ai-gateway" && !model.includes("/")) {
|
|
const normalizedAnthropicModel = normalizeAnthropicModelId(model);
|
|
if (normalizedAnthropicModel.startsWith("claude-")) {
|
|
return `anthropic/${normalizedAnthropicModel}`;
|
|
}
|
|
}
|
|
if (provider === "google" || provider === "google-vertex") {
|
|
return normalizeGoogleModelId(model);
|
|
}
|
|
if (provider === "openrouter" && !model.includes("/")) {
|
|
return `openrouter/${model}`;
|
|
}
|
|
return model;
|
|
}
|
|
|
|
export function normalizeModelRef(provider: string, model: string): ModelRef {
|
|
const normalizedProvider = normalizeProviderId(provider);
|
|
const normalizedModel = normalizeProviderModelId(normalizedProvider, model.trim());
|
|
return { provider: normalizedProvider, model: normalizedModel };
|
|
}
|
|
|
|
export function parseModelRef(raw: string, defaultProvider: string): ModelRef | null {
|
|
const trimmed = raw.trim();
|
|
if (!trimmed) {
|
|
return null;
|
|
}
|
|
const slash = trimmed.indexOf("/");
|
|
if (slash === -1) {
|
|
return normalizeModelRef(defaultProvider, trimmed);
|
|
}
|
|
const providerRaw = trimmed.slice(0, slash).trim();
|
|
const model = trimmed.slice(slash + 1).trim();
|
|
if (!providerRaw || !model) {
|
|
return null;
|
|
}
|
|
return normalizeModelRef(providerRaw, model);
|
|
}
|