import { generateModels, generateAliasMap, type RegistryModel } from "./providerRegistry.ts"; // Provider models - Generated from providerRegistry.js (single source of truth) export const PROVIDER_MODELS = generateModels(); // Provider ID to alias mapping - Generated from providerRegistry.js export const PROVIDER_ID_TO_ALIAS = generateAliasMap(); // Helper functions export function getProviderModels(aliasOrId: string): RegistryModel[] { return PROVIDER_MODELS[aliasOrId] || []; } export function getDefaultModel(aliasOrId: string): string | null { const models = PROVIDER_MODELS[aliasOrId]; return models?.[0]?.id || null; } export function getProviderModel(aliasOrId: string, modelId: string): RegistryModel | undefined { const models = PROVIDER_MODELS[aliasOrId]; if (!models) return undefined; return models.find((model) => model.id === modelId); } export function isValidModel( aliasOrId: string, modelId: string, passthroughProviders = new Set() ): boolean { if (passthroughProviders.has(aliasOrId)) return true; const models = PROVIDER_MODELS[aliasOrId]; if (!models) return false; return models.some((m) => m.id === modelId); } export function findModelName(aliasOrId: string, modelId: string): string { const models = PROVIDER_MODELS[aliasOrId]; if (!models) return modelId; const found = models.find((m) => m.id === modelId); return found?.name || modelId; } export function getModelTargetFormat(aliasOrId: string, modelId: string): string | null { const models = PROVIDER_MODELS[aliasOrId]; if (!models) return null; const found = models.find((m) => m.id === modelId); return found?.targetFormat || null; } export function getModelStripTypes(aliasOrId: string, modelId: string): string[] { const models = PROVIDER_MODELS[aliasOrId]; if (!models) return []; const found = models.find((m) => m.id === modelId); return Array.isArray(found?.strip) ? [...found.strip] : []; } export function getModelsByProviderId(providerId: string): RegistryModel[] { const alias = PROVIDER_ID_TO_ALIAS[providerId] || providerId; return PROVIDER_MODELS[alias] || []; } const CLAUDE_MODEL_PATTERN = /(?:^|[\/._-])claude(?:[._-]|$)/; const CLAUDE_MAX_EFFORT_UNSUPPORTED_FAMILY_PATTERNS = [/(?:^|[\/._-])haiku(?:[._-]|$)/] as const; export function supportsClaudeMaxEffort(modelId: string | null | undefined): boolean { if (typeof modelId !== "string" || modelId.length === 0) return false; const normalized = modelId.toLowerCase(); const claudeMatch = normalized.match(CLAUDE_MODEL_PATTERN); if (!claudeMatch) return false; const claudeScopedId = normalized.slice(claudeMatch.index ?? 0); return !CLAUDE_MAX_EFFORT_UNSUPPORTED_FAMILY_PATTERNS.some((pattern) => pattern.test(claudeScopedId) ); } export function supportsXHighEffort(aliasOrId: string, modelId: string): boolean { const alias = PROVIDER_ID_TO_ALIAS[aliasOrId] || aliasOrId; const providerModels = PROVIDER_MODELS[alias] || PROVIDER_MODELS[aliasOrId]; // Unknown provider (not in registry) — pass through unchanged. if (!providerModels) return true; const model = getProviderModel(alias, modelId); // Claude Code models default to supporting extra-high effort. Keep explicit // false entries as the unsupported-model list so newly added Claude models do // not need opt-in flags. if (alias === "cc") { return model?.supportsXHighEffort !== false; } return model?.supportsXHighEffort === true; }