Repository Public Research preview
1import { readFileSync } from "node:fs";23export const KB = JSON.parse(readFileSync(new URL("../knowledge.json", import.meta.url), "utf8"));4export const MODELS = KB.models;5const ALIAS = Object.fromEntries(Object.values(MODELS).filter((m) => m.alias).map((m) => [m.alias, m.id]));67/** Resolve an id or a documented alias. Returns null for anything the probes never saw. */8export function resolveModel(id) {9 if (typeof id !== "string") return null;10 return MODELS[id] ?? MODELS[ALIAS[id]] ?? null;11}1213/** Closest known ids, for "did you mean" on typos and invented date suffixes. */14export function suggestModels(id) {15 const base = String(id).toLowerCase().replace(/-\d{8}$/, "").replace(/@\d{8}$/, "");16 const ids = Object.keys(MODELS);17 if (ids.includes(base)) return [base];18 const exact = ids.filter((k) => k.startsWith(base + "-") || base.startsWith(k)).sort((x, y) => y.length - x.length);19 if (exact.length) return exact.slice(0, 3);20 const words = base.split(/[^a-z0-9]+/).filter(Boolean);21 return ids.map((k) => [k, words.filter((w) => k.includes(w)).length]).filter(([, n]) => n > 1).sort((a, b) => b[1] - a[1]).slice(0, 3).map(([k]) => k);22}2324export const CURRENT = { fable: "claude-fable-5-2", opus: "claude-opus-5-5", sonnet: "claude-sonnet-5-5", haiku: "claude-haiku-5-5" };25/** Observed in an API response header/warning on 2026-11-09. */26export const DEPRECATIONS = { "claude-sonnet-4-5-20250929": "deprecated; end-of-life 2026-11-30 (warning returned by the API)" };2728export function modelSummary(m) {29 const p = m.pricing_usd_per_mtok;30 return {31 id: m.id, alias: m.alias, display_name: m.display_name, tier: m.tier, context_window: m.max_input_tokens, max_output_tokens: m.max_output_tokens,32 price_usd_per_mtok: p ? { input: p.input, output: p.output, cache_read: p.cache_read, batch_input: p.batch_input, batch_output: p.batch_output } : null,33 thinking: m.thinking.adaptive ? (m.thinking.disabled === "accepted" ? "adaptive (can be disabled)" : m.thinking.disabled === "use_between_tools" ? "adaptive (off only via between_tools)" : "adaptive (always on)") : "enabled + budget_tokens",34 effort_levels: m.effort.levels, forced_tool_choice: m.forced_tool_choice, assistant_prefill: m.assistant_prefill,35 deprecation: DEPRECATIONS[m.id] ?? null,36 };37}38