// Picks the probe models from out/models.json (written by 00-models.ts). import { readFileSync } from "node:fs"; import { OUT } from "./lib.ts"; const listing: any[] = JSON.parse(readFileSync(`${OUT}models.json`, "utf8")).data; export const byId = new Map(listing.map((m) => [m.id, m])); function pick(preferred: string, fallback: (m: any) => boolean) { if (byId.has(preferred)) return preferred; const alt = listing .filter(fallback) .filter((m) => !m.id.includes(":")) .sort((a, b) => Number(a.pricing.prompt) - Number(b.pricing.prompt))[0]; if (!alt) throw new Error(`no model for ${preferred}`); console.log(`(${preferred} missing → using ${alt.id})`); return alt.id as string; } export const OPENAI = pick("openai/gpt-5.4-nano", (m) => m.id.startsWith("openai/gpt-5") && m.id.includes("nano")); export const ANTHROPIC = pick("anthropic/claude-haiku-4.5", (m) => m.id.startsWith("anthropic/claude-haiku")); export const GOOGLE = pick("google/gemini-3.5-flash-lite", (m) => m.id.startsWith("google/gemini-3") && m.id.includes("lite")); export const DEEPSEEK = pick("deepseek/deepseek-v4-flash", (m) => m.id.startsWith("deepseek/deepseek-v4")); export const XAI = pick("x-ai/grok-4.20-0309-non-reasoning", (m) => m.id === "x-ai/grok-4.20" || (m.id.startsWith("x-ai/grok-4") && m.reasoning?.default_enabled === false)); export const MODELS = [OPENAI, ANTHROPIC, GOOGLE, DEEPSEEK, XAI]; export const VISION_MODELS = MODELS.filter((id) => (byId.get(id)?.architecture?.input_modalities ?? []).includes("image")); console.log("probe models:", MODELS.join(", ")); for (const id of MODELS) { const m = byId.get(id); console.log(` ${id}: in=${m.pricing.prompt} out=${m.pricing.completion} ctx=${m.context_length} maxout=${m.top_provider?.max_completion_tokens} mods=${m.architecture.input_modalities} reasoning=${JSON.stringify(m.reasoning)} params=${m.supported_parameters.join(",")}`); }