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); }