import type { Api, Model } from "@earendil-works/pi-ai"; import type { NormalizedRouteCandidate, RouteThinkingLevel, RouteTier } from "./types.js"; export function normalizeRouteCandidates(models: Model[]): NormalizedRouteCandidate[] { return models.map((model) => { const provider = String(model.provider); const modelId = model.id; const fullId = `${provider}/${modelId}`; const tags = deriveCandidateTags(model); return { authenticated: true, available: true, contextWindow: model.contextWindow, costKnown: hasKnownCost(model), fallbackGroups: deriveFallbackGroups(model), family: deriveCandidateFamily(model), fullId, input: [...model.input], label: model.name || fullId, maxThinkingLevel: deriveMaxThinkingLevel(model), maxTokens: model.maxTokens, model, modelId, provider, reasoning: model.reasoning, tags, tier: deriveCandidateTier(model), }; }); } export function deriveMaxThinkingLevel(model: Model): RouteThinkingLevel { if (!model.reasoning) { return "off"; } const id = model.id.toLowerCase(); if (id.includes("gpt-5") || id.includes("opus-4.6") || id.includes("opus-4-6")) { return "xhigh"; } return "high"; } export function deriveCandidateTier(model: Model): RouteTier { const id = model.id.toLowerCase(); const name = model.name.toLowerCase(); if (id.includes("gpt-5.4") || id.includes("opus-4.6") || id.includes("opus-4-6") || name.includes("ultra")) { return "peak"; } if (id.includes("opus") || id.includes("sonnet") || id.includes("pro") || id.includes("gpt-5")) { return "premium"; } if (id.includes("flash") || id.includes("mini")) { return "cheap"; } return "balanced"; } export function deriveCandidateTags(model: Model): string[] { const tags = new Set(); const provider = String(model.provider); const id = model.id.toLowerCase(); const name = model.name.toLowerCase(); const tier = deriveCandidateTier(model); tags.add(provider); tags.add(tier); if (model.reasoning) { tags.add("reasoning"); } if (model.input.includes("image")) { tags.add("multimodal"); } if (tier === "premium" || tier === "peak") { tags.add("premium"); } if (tier === "cheap") { tags.add("cheap"); } if (provider === "anthropic" || name.includes("claude")) { tags.add("design"); } if (provider === "openai" || id.includes("gpt-5")) { tags.add("architecture"); } if (provider === "cursor-agent") { tags.add("architecture"); tags.add("premium"); } return [...tags]; } export function deriveCandidateFamily(model: Model): string | undefined { const provider = String(model.provider); const tier = deriveCandidateTier(model); if (provider === "anthropic") { return `anthropic-${tier}`; } if (provider === "openai") { return `openai-${tier}`; } if (provider === "cursor-agent") { return `cursor-${tier}`; } if (provider === "google") { return `google-${tier}`; } return undefined; } export function deriveFallbackGroups(model: Model): string[] { const provider = String(model.provider); const id = model.id.toLowerCase(); const groups = new Set(); const tier = deriveCandidateTier(model); if (tier === "cheap") { groups.add("cheap-router"); } if ( (provider === "anthropic" && (id.includes("opus") || id.includes("sonnet"))) || (provider === "openai" && id.includes("gpt-5.4")) ) { groups.add("design-premium"); } if ((provider === "anthropic" && id.includes("opus")) || (provider === "openai" && id.includes("gpt-5.4"))) { groups.add("peak-reasoning"); } if (provider === "cursor-agent") { groups.add("peak-reasoning"); } return [...groups]; } export function matchesModelRef( reference: string, candidate: Pick, ): boolean { const normalized = reference.trim(); return normalized === candidate.fullId || normalized === candidate.modelId; } function hasKnownCost(model: Model): boolean { return Object.values(model.cost).some((value) => Number(value) > 0); }