Added
-
๐ Extended benchmark catalog (t4) โ a new
src/data/benchmarks.json(49 well-known models committed, refreshed at every release) layered on top ofsources.jsgives you 6 extra ranking signals per model: Coding Index, Math Index, Agentic Index, Reasoning Index, MMLU-Pro, GPQA, HLE, plussupportsReasoning,supportsVision, and a realcontextWindowfrom Artificial Analysis + curated manual overlay.- Lazy load via
Proxyโ the JSON is only parsed on first lookup, not at module load. Cold start stays at ~0 ms. - Prefix-indexed O(key length) lookup โ
lookupExtendedBenchmark('deepseek-ai/deepseek-v4-pro')is fast even on a 500-entry catalog. Falls back through the-//-prefixed segments (e.g.deepseek-aiโdeepseek-ai/deepseekโdeepseek-ai/deepseek-v4โdeepseek-ai/deepseek-v4-pro) and picks the best-scoring candidate. - Curated seed wins โ the
mergeExtendedBenchmarkoverlay only fills fields that are null insources.js. Your curatedsweScore/tier/ctxare never overwritten by the live data.
- Lazy load via
-
๐ฐ๏ธ Live
models.devenrichment (t5) โ the community-maintainedmodels.devcatalog is fetched in the background (5 min in-process cache, 3 retries ร 250 ms backoff, 8 s per-request timeout) and overlaid onto every merged model withmetaSource: 'models.dev' | 'sources.js'provenance.- Substring matches skipped for drift detection โ the indexer tries exact โ aliased โ substring, but the drift detector only counts exact + aliased matches (avoids the "DeepSeek Chat" vs "DeepSeek Reasoner" false positive).
- Provider aliases โ 40+ mappings bridge sources.js provider keys (
nvidiaNim,together,novita,kilocode, โฆ) to models.dev provider keys (nvidia,togetherai,novita-ai,kilo, โฆ). - Offline-safe โ if the fetch fails (3ร8 s = up to 24 s, capped to 12 s in the background task),
metaSourcestays at'sources.js'and the TUI keeps rendering. No crashes, no hangs.
-
๐
--check-driftCLI flag โ diffsources.jsagainstmodels.devand print a human-readable report grouped by model. Each row shows the field, the sources.js value, the models.dev value, and an action arrow (โ UPDATEorโ ADD).free-coding-models --check-drift # exit 1 on any drift free-coding-models --check-drift --drift-threshold 5 # only fail on 5+ mismatches pnpm check:drift # npm alias
Exit codes:
0no drift ยท1drift detected ยท2fetch failed ยท3invalid args. -
๐ค
pnpm update:benchmarksโ regeneratesrc/data/benchmarks.jsonfrom a fresh models.dev fetch. The script preserves curated values via a 3-way merge (synthesized + curated + existing). Wired into the release process and the weekly CI workflow. -
๐ฆพ TUI footer enrichment chip โ
๐ bench 49 (2026-07-25) ยท ๐ก 102 live ยท 62 curatedon the bottom line. Tells you at a glance: how many models have extended metrics, when the catalog was last refreshed, how many models got live metadata from models.dev vs staying at curated values. -
๐ Web Dashboard data exposure โ
/api/modelsnow includesextendedBench+metaSourceper row. Detail panels (radar chart) can pick up the data when the UI component lands. -
๐
.github/workflows/update-benchmarks.ymlโ weekly Monday 04:00 UTC job. Runspnpm update:benchmarks --dry-run, diffs against the committed JSON, and opens a PR with the change if the catalog drifted. Manual trigger viaworkflow_dispatch. -
๐ต๏ธ
.github/workflows/check-drift.ymlโ weekly Monday 05:00 UTC job. Runspnpm check:drift --no-fail. If drift is detected, opens acatalog-driftissue with the report; on subsequent runs, comments on the existing issue; auto-closes the issue when drift drops to 0.
Changed
- ๐ฆ CLI help (
--help) โ new flags--check-driftand--drift-threshold <N>documented under the Analysis Flags section, right next to the existing probe-cache flags. - ๐ง
src/core/utils.jsparseArgs()โ two new return fields:checkDriftMode(boolean) anddriftThreshold(number|null). The TUI'sbin/free-coding-models.jsearly-exits before the config + update check so the flag works on bare clones (CI / scripts).
Non-goals (explicit, tracked for follow-up)
- TUI detail-view benchmark block โ the chip is the visible surface for now. A full "Press
?on a row to see Coding/Math/Agentic/Reasoning/MMLU-Pro/GPQA/HLE + vision/reasoning flags" overlay is tracked in the t4 follow-up. The data layer + tests are ready. - 6 new sort keys for the benchmark indices โ the key map is already crowded (R/O/M/L/A/S/C/H/V/U/B/T/W/Z/E/F/Y/X/Q/G/N/P/I). Adding 6 more would conflict. Tracked for a "Sort by benchmark" submenu in the Command Palette.
- Web Dashboard radar chart component โ the data is exposed, the UI component is a separate task. The /api/models payload includes everything the chart needs.
Maintenance
- ๐งช +66 unit tests across 3 new files:
test/extended-benchmarks.test.js(31 tests, 9 suites) โ path resolution, lazy load + cache, prefix index build, exact + fallback + best-scoring lookup, overlay bag shape, performance (10k lookups in 3.3 ms, 1k cached in 1 ms).test/models-dev.test.js(35 tests, 8 suites) โ fetcher URL/TTL, normalizeModelDevEntry (flat + nested + malformed), buildModelIndex (auto-detect), lookupModelDevMeta (exact + alias + substring + unknown), detectDrift (drift + add + threshold), summarizeDrift, formatDriftReport (with/without color), parseCtxToNum (k/m/plain/edge), PROVIDER_ALIASES mappings.test/model-merger.test.js(extended to 12 tests) โ overlayExtendedBenchmarks, overlayModelsDevMetadata (sync + async + mutate), getEnrichmentStats.
- ๐งช 701 โ 779 tests passing (unchanged โ same code, only the files field changed) (
pnpm test), 134 โ 155 suites. - ๐ก๏ธ
pnpm startruns without runtime error (TUI, Web Dashboard, daemon all load the new modules cleanly). - ๐ Fixed a real freeze: the initial draft had a top-level
await importinsrc/tui/app.jsthat blocked module load. Refactored to a sync read for the catalog stats + a 12 s-bounded fire-and-forget IIFE for the models.dev fetch. The TUI now starts in <1 s even when the network is unreachable.
Inspiration
This implementation is informed by apmantza/pi-free's lib/model-metadata.ts (the fetcher + retry + cache + provider aliases shape) and provider-failover/benchmark-lookup.ts + hardcoded-benchmarks.ts (the prefix index + lazy Proxy load pattern). Where we diverge: we ship a curated 49-entry seed in the repo (their TS version relies on hardcoded constants at build time), we add the drift detector + weekly CI workflow for proactive catalog hygiene, and we expose the data on all 3 surfaces (CLI TUI, Web Dashboard, Desktop) with consistent metaSource provenance.
Files
- New:
src/core/extended-benchmarks.js(320 lines, 11 exports),src/core/models-dev-fetcher.js(180 lines, 7 exports),src/core/models-dev-index.js(290 lines, 5 exports),src/core/models-drift.js(320 lines, 6 exports),src/data/benchmarks.json(49 entries committed),scripts/update-benchmarks.mjs(220 lines, executable),scripts/check-drift.mjs(170 lines, executable),.github/workflows/update-benchmarks.yml,.github/workflows/check-drift.yml,test/extended-benchmarks.test.js(310 lines, 31 tests),test/models-dev.test.js(380 lines, 35 tests),changelog/v0.5.62.md. - Modified:
src/core/model-merger.js(+155 lines: 3 new exports + async overlay with mutate),src/core/utils.js(+14 lines: parseArgs + checkDriftMode/driftThreshold),src/tui/app.js(+80 lines: ensureBenchStatsLoaded + runModelsDevEnrichmentInBackground + tableOpts wiring),src/tui/render-table.js(+40 lines: enrichmentLabel chip),src/tui/cli-help.js(+2 lines: new flags in ANALYSIS_FLAGS),bin/free-coding-models.js(+19 lines: --check-drift early-exit),web/server.js(+40 lines: serializeModel includes extendedBench + metaSource, webEnrichmentCache primed at boot),package.json(+5 lines: test commands + scripts),test/model-merger.test.js(+100 lines: new test cases),tasks/t4.md,tasks/t5.md.