Commit graph

297 commits

Author SHA1 Message Date
acidburn
2aa176be96
Merge pull request #138: llm-checker 3.8.2
Some checks failed
Policy Gate / Full test suite (Node 18) (push) Has been cancelled
Policy Gate / Full test suite (Node 20) (push) Has been cancelled
Policy Gate / Full test suite (Node 22) (push) Has been cancelled
Policy Gate / policy-gate (push) Has been cancelled
Policy Gate / windows-ui-smoke (push) Has been cancelled
Larger, exact model database: Hugging Face, ModelScope, Ollama, Docker Hub, benchmarks in the seed
2026-10-13 13:12:46 +02:00
signerless
aa72bea010 chore(release): prepare 3.8.2
Exact catalog metadata (#138) plus the fixes merged since 3.8.1
(#113, #114, #116, #117, #119, #127-#129, #131-#136).
2026-10-13 13:04:30 +02:00
signerless
67fa1fb7f8 test: give the CPU-only CLI runs a 120 s budget
Each case spawns the real CLI with live hardware detection. Alone a run
takes about 20 s, but inside the full suite on a loaded laptop it went
past the 45 s limit, which failed npm test and therefore npm publish.
2026-10-13 13:04:30 +02:00
signerless
012dd5a9c9 test: pin Linux platform in the integrated-memory and Strix Halo fixtures
Both tests describe Linux hosts, but UnifiedDetector only collects the
generic GPU inventory on Linux and Windows, so on macOS systemGpu stayed
null and the suite failed. Force process.platform to linux for the
duration of each fixture and restore it afterwards.
2026-10-13 12:50:53 +02:00
signerless
37a4900465 fix(deps): update @modelcontextprotocol/sdk and proxy-addr for new advisories
npm audit --omit=dev now reports GHSA-6qxp-vccf-f47h (@modelcontextprotocol/sdk
<= 1.30.1) and GHSA-jqcg-44mw-7w3h (proxy-addr <= 2.0.7). Lockfile-only update
within the declared ranges: sdk 1.32.1, proxy-addr 2.0.8, plus brace-expansion
and js-yaml patch releases.
2026-10-13 10:44:14 +00:00
signerless
2a7f20d618 chore(seed): regenerate the packaged model database
Built with the new pipeline (sync --exact, task-planned Hugging Face
listings with official publishers and per-repo enrichment, ModelScope,
Docker Hub, and benchmark scores):

- Ollama: 230 local models, 7,392 tags with exact sizes, quantizations,
  parameter counts, context windows, inputs and licenses
- Registry: 10,965 repos, 55,064 artifacts (Hugging Face 39,640,
  ModelScope 7,914, Ollama 6,425, Docker 1,053, GPT4All 32); every artifact
  has an observed size
- Quality: 6,619 benchmark scores from 7 sources

The file grows from 43 MB to 92 MB (npm tarball ~14.5 MB).
2026-10-04 16:43:32 +00:00
signerless
ab16036537 docs: update the packaged registry totals in the README 2026-10-04 16:43:30 +00:00
signerless
7de5f3bb3b perf(quality): index benchmark rows by checkpoint label
lookup() scanned every quality row for every candidate. With benchmark
scores present (now shipped in the snapshot, previously after any
`quality-sync`), `recommend --no-registry` evaluated ~7k variants x 7
categories x ~6.6k rows and took ~52 s. sameCheckpoint requires equal
labels, so rows are indexed by label and the result is unchanged: the same
command takes ~3 s.

The base-variant ranking test compares estimates only, since the local
catalog may hold measured scores.
2026-10-04 16:43:30 +00:00
signerless
9b1b8d655b docs: describe the ModelScope and Docker registry sources in the usage guide 2026-10-04 16:12:53 +00:00
signerless
8306cee107 perf(db): copy a newer packaged snapshot with INSERT ... SELECT
With native SQLite the snapshot is attached and each table copied in one
statement over the columns both schemas share, instead of ~50k row-by-row
upserts: a first run after an upgrade drops from ~10 s to ~2.6 s. The
sql.js backend keeps the row path. The packaged file is never written.
2026-10-04 16:12:27 +00:00
signerless
68dffe567d fix(ollama): classify more model licenses and skip acceptable-use policies
Recognise the Stability AI non-commercial and community licenses, the
Microsoft Research license, the GLM-4 license, Mistral's non-production
license, NVIDIA's AI Foundation Models license, EXAONE, Databricks Open
Model, Health AI Developer Foundations, Yi and Falcon licenses, which were
reported as 'other'. An acceptable-use policy layer is not a license and no
longer stands in for one.
2026-10-04 16:09:50 +00:00
signerless
db670fb53e feat(registry): add ModelScope as a registry source
ModelScope publishes the same repo layout as Hugging Face and is the hub
reachable where huggingface.co is not. `registry-sync --sources modelscope`
(and the seed build, 1500 repos by default) lists repos per language task
by downloads, reads each repo's file list (sizes, SHA-256) and config.json
(context window, quantization, vision tower), and normalises them with the
Hugging Face rules (shard sets, exclusions, size checks). Artifacts download
from ModelScope: `modelscope download --model` commands, `resolve/master`
URLs, and `VLLM_USE_MODELSCOPE=True` for vLLM. Loose `chunks/` files are no
longer treated as models.
2026-10-04 16:08:33 +00:00
signerless
23def65379 fix(catalog): make check, ai-check and ai-run read the synced catalog
- `check` on Apple Silicon ranked only the 26 static definitions; it now
  ranks the same static + SQLite pool as other platforms (extracted into
  buildCombinedModelPool).
- `check` built catalog models from family guesses (llama3 -> 8B, gemma ->
  7B, phi -> 3B); it reads the default tag's parameter count and size.
- `ai-check` ignored variants and assumed 7B / params x 0.6 / Q4_K_M; it
  reads the default tag's parameters, size, context window and inputs.
- `ai-run` scored catalog models through a 14-model table and a 7B
  estimate; the selector now takes the catalog's per-tag facts and keeps
  the table only for curated quality scores.
- Refresh the curated fallback catalog from registry data: qwen3/phi4/
  deepseek-r1 families, real sizes and context windows, llama3.3:70b and
  granite3.3:8b instead of tags that do not exist.
- Fix static definitions (Llama 3.2 context windows, Qwen 2.5 7B
  specialization, Mistral Small 3.1 tag and size) and remove
  scripts/update-models.js, unused, which injected invented models.
2026-10-04 15:59:58 +00:00
signerless
7cfe8613ef feat(registry): add Docker Model Runner as a source and runtime
Docker Hub's official `ai/` namespace publishes ~105 language models with
exact sizes per tag (GGUF, safetensors for vLLM, MLX).

- `registry-sync --sources docker` (now in the default and seed sources)
  reads the namespace and each repo's tags in both name orders, since
  anonymous reads stop at offset 100, and waits out 429 responses.
- Tags sharing a digest are one artifact with aliases; a re-pushed
  capitalisation keeps the newest push. Image, video and speech repos are
  skipped, and the size/parameter consistency check applies.
- New `docker` runtime: `docker model pull` / `docker model run` commands,
  install hints for Docker Desktop and the Linux plugin, a llama.cpp-like
  MoE profile, and format-aware hardware support (MLX tags on Apple Silicon,
  safetensors/vLLM tags on NVIDIA, GGUF everywhere).
2026-10-04 15:52:04 +00:00
signerless
a750b2b0d7 fix(deps): update fast-uri, hono and ip-address for new advisories
`npm audit --omit=dev` fails CI with advisories published after the last
green run on main (GHSA-hrr3-gc8f-f4qj, GHSA-gqvv-2mrq-wpjv and others,
GHSA-rpw4-54j3-4h4q and others). `npm audit fix` moves the three transitive
dependencies of @modelcontextprotocol/sdk to patched releases within the
existing ranges; package.json is unchanged.
2026-10-04 15:43:43 +00:00
signerless
2bfd8fdc4c feat(quality): ship benchmark scores in the snapshot and add model-card results
- `sync:seed` runs scripts/update-quality-seed.js, which refreshes every
  quality source inside the snapshot (a failed source keeps its previous
  scores). A fresh install had no benchmark data and ranked every model by
  parameter count until the user ran `quality-sync`.
- Existing databases import a snapshot's quality source when it is newer
  than their own copy, and rebuild the catalog cohort.
- New `hf_eval_results` source: GPQA, MMLU-Pro, HLE, SWE-bench,
  Terminal-Bench, GSM8K, AIME/HMMT, IFEval and MMMU results attached to Hub
  repos. Self-reported, marked not independent, last in each category's
  metric preference.
- LiveBench discovers releases from the site bundle and adds those newer
  than the curated list; older question sets stay out.
2026-10-04 15:38:10 +00:00
signerless
65f72266cf feat(ollama): record each tag's license from its manifest
`sync --exact` reads the manifest's license layer once per distinct blob
and classifies it (Llama community licenses, Gemma terms, Qwen and Qwen
Research, Apache-2.0, MIT, CC BY-NC, ...). Licenses are per tag:
qwen2.5:3b ships under the non-commercial Qwen Research License while its
other sizes are Apache-2.0. The model and registry rows take the license
instead of 'unknown'; an unrecognised text is 'other', never guessed.
2026-10-04 15:34:36 +00:00
signerless
73e4d1fe3d fix(ranking): rank base checkpoints below instruct builds and dedupe aliases
- Base/pretrained variants (`-base`, `-text`, `-Base`, `-pt`) lose 15
  quality points in every generation category. Base coder variants carried
  the `coder` tag, so the existing non-instruct coding penalty skipped them
  and `deepseek-coder-v2:16b-lite-base` led coding recommendations.
- Ollama tags sharing a digest become one registry artifact with the
  others recorded as aliases, and the exact registry parameter count beats
  the nominal size in the tag. `:latest` and `:16b` were listed twice.
- Quantizations of one base checkpoint (bartowski, unsloth,
  lmstudio-community, ...) collapse into one distinct recommendation.
- The calibration end-to-end test builds its own catalog instead of
  depending on the packaged snapshot and the host's hardware.
2026-10-04 15:32:33 +00:00
signerless
2f4fe90e18 fix(registry): reject artifacts whose size contradicts their parameters
Exact sizes exposed artifacts that were never the model they claimed:
- collection repos (cortexso/deepseek-r1) gave every distill the
  largest model's 70B; the size in a file's own name now wins unless the
  header count agrees with it
- speculative-decoding heads (MTP, DFlash, DSpark, EAGLE, draft), LoRA in
  GGUF, vision/audio towers, training checkpoints, adapters and per-layer
  splits were stored as full models
- `qwen2-1_5b` parsed as 5B
- Kimi-K2's `model-1-of-61` shards were not recognised as one set

A file below a quarter of its precision's nominal bytes per parameter
cannot hold the stated model and is skipped. The seed build also vacuums
the snapshot so replaced rows do not ship as free pages.
2026-10-04 14:14:13 +00:00
signerless
ae611b15d0 chore(seed): build the packaged snapshot with exact metadata
- `sync:seed` runs the Ollama sync with `--exact` (registry byte sizes,
  quantizations and parameter counts).
- The registry seed sweeps official publishers and enriches each Hugging
  Face repo with tree sizes, hashes and config.json context windows; the
  default Hugging Face budget is 6000 repos split by task.
- The weekly workflow passes the optional HF_TOKEN secret for a larger
  rate-limit window and allows the longer build.
- Document what the snapshot contains, the new sync flags, and the
  changes in the changelog.
2026-10-04 13:53:02 +00:00
signerless
7d6a98799b fix(mcp): pass the recommend category as an option
`recommend` reads `--category`; the positional value the MCP `recommend`
and `project_recommend` tools passed was ignored, so every category
returned general recommendations.
2026-10-04 13:50:26 +00:00
signerless
eb6b43b69a fix(data): ingest exact model metadata from Hugging Face and Ollama
Hugging Face
- List per language task (text-generation, image-text-to-text, embeddings)
  instead of the global download ranking, which is mostly ASR, diffusion and
  classifiers: the 3000-repo limit kept ~1,400 usable repos and the weekly
  seed build failed its 2,500-repo floor every week since July.
- Request `expand[]` metadata (full=true omits it): exact parameter counts and
  dtypes from safetensors headers, GGUF parameters/architecture/context, card
  license and base-model lineage.
- Sweep official model publishers by author, and accept repos without a
  pipeline tag that ship for vLLM/mistral-common (official Mistral releases
  were all rejected).
- Optional enrichment (`registry-sync --deep`): tree API file sizes and
  SHA-256, config.json context window, quantization and vision tower. Honors
  the Hub RateLimit header and HF_TOKEN.
- One artifact per complete shard set (including 0-based gpt-oss shards);
  drop mmproj/imatrix companions, OpenVINO/ONNX/original/metal exports and
  duplicate .bin/consolidated weight sets; store compact metadata.
- Bound the task/modality patterns: `vllm` tagged repos as vision, `encoder`
  as coding and every nomic-ai repo as embeddings.

Ollama
- Parse each tags-page row: digest, size (stored in GiB), context window and
  input types. Skip cloud-only tags. Aliases sharing a digest share params
  and quantization, so `:latest` is no longer params=null/Q4_0.
- Stop fabricating values: no params x 0.5 sizes, no Q4_0 or 4096 defaults;
  fix q4_1/q5_1/bf16/mxfp4 mapping and MoE totals (8x7b).
- Capabilities from Ollama's badges instead of whole-page regexes; library
  models are official; decode numeric HTML entities.
- `sync --exact` reads registry.ollama.ai manifests and config blobs for exact
  bytes, file_type, parameter count, MoE family and vision projectors.
- variants gain digest/size_bytes/blob_sha256 columns (migrated in place).

Consumers
- The deterministic selector reads each tag's own context window and inputs
  (it used a model-level field that is never set, so every tag got 4096).
- An existing user database adopts a newer packaged snapshot per part; before,
  only the first run ever saw the snapshot.
- A catalog sync rebuilds the registry's Ollama rows; `sync` deleted them and
  registry recommendations lost every Ollama model until registry-sync.
2026-10-04 13:50:25 +00:00
acidburn
145ac14ecc Merge pull request #136 from signerless/fix/ranking-contracts
Fix ranking artifacts, benchmark identity and desktop compatibility
2026-09-06 15:44:58 +02:00
signerless
42e6e87484 fix: remove fabricated precision and size fallbacks from Ollama metadata 2026-09-06 15:40:12 +02:00
signerless
d0c5a414d0 fix: enforce artifact and checkpoint contracts in model rankings 2026-09-06 15:28:57 +02:00
acidburn
9d4d31366b Merge pull request #129 from signerless/feat/benchmark-backed-quality
feat(quality): connect all six benchmark sources to model recommendations
2026-09-06 13:09:45 +02:00
signerless
9b8e8ee52a Merge remote-tracking branch 'origin/main' into fix/issue-126-benchmark-sources 2026-09-06 13:04:51 +02:00
signerless
5075dc8b94 feat(quality): ingest official HF and LMArena benchmark snapshots 2026-09-06 13:02:53 +02:00
acidburn
5470b43345 Merge pull request #135 from signerless/fix/issue-123-runtime-commands
fix(runtime): honor llama.cpp, Transformers, and explicit runtime choices
2026-09-06 13:00:36 +02:00
signerless
5ea88d1e31 Merge branch 'fix/issue-123-runtime-commands' into fix/issue-126-benchmark-sources 2026-09-06 12:55:04 +02:00
signerless
c46292cdac fix(runtime): honor llama.cpp and Transformers command selection 2026-09-06 12:54:51 +02:00
acidburn
d6f9455b0c Merge pull request #134 from signerless/fix/issue-130-integrated-memory
fix: stop interpreting 256 MB iGPU apertures as 256 GB
2026-09-06 12:52:58 +02:00
acidburn
6ce5da63e1 Merge pull request #127 from signerless/fix/124-parallel-hardware-probes
perf: run independent hardware probes asynchronously
2026-09-06 12:52:54 +02:00
signerless
547e5c848b Merge branch 'fix/124-parallel-hardware-probes' into fix/issue-130-integrated-memory 2026-09-06 12:46:01 +02:00
signerless
667b900280 test: make parallel probe fixture independent of host GPUs 2026-09-06 12:45:58 +02:00
signerless
b775b8f0e3 fix: interpret integrated GPU apertures in MB and cap shared memory 2026-09-06 12:45:30 +02:00
acidburn
7b09df7047 Merge pull request #133 from signerless/fix/issue-125-native-sqlite
perf: use native SQLite with an older-Node WASM fallback
2026-09-06 12:44:43 +02:00
signerless
452ee9bb20 test: verify concurrent hardware child processes and probe deadlines 2026-09-06 12:42:32 +02:00
acidburn
78403a008b Merge pull request #128 from signerless/fix/122-preserve-speed-benchmarks
fix: preserve local speed telemetry across catalog rebuilds
2026-09-06 12:42:13 +02:00
signerless
48c363e9e8 Merge branch 'fix/issue-125-native-sqlite' into fix/124-parallel-hardware-probes 2026-09-06 12:40:35 +02:00
signerless
1cb8b99e70 perf: use native SQLite when available with a WASM fallback 2026-09-06 12:40:04 +02:00
acidburn
4cf3193a27 Merge pull request #132 from signerless/fix/issue-121-category-counts
fix: report category-specific model evaluation counts
2026-09-06 12:39:29 +02:00
acidburn
bd069ac2ec Merge pull request #131 from signerless/fix/issue-120-model-ingestion
fix: exclude non-language repositories from recommendations
2026-09-06 12:39:14 +02:00
signerless
84acb59397 fix: retain speed telemetry through failed and incomplete catalog syncs 2026-09-06 12:37:35 +02:00
signerless
cdc51ca82b Merge branch 'fix/issue-121-category-counts' into fix/122-preserve-speed-benchmarks 2026-09-06 12:35:27 +02:00
signerless
4f9498604b Merge branch 'fix/issue-120-model-ingestion' into fix/issue-121-category-counts 2026-09-06 12:35:13 +02:00
signerless
5e0949f2cd chore: patch transitive dependencies required by CI audit 2026-09-06 12:35:07 +02:00
signerless
b215dc5ea6 fix: report actual evaluation counts for each category 2026-09-06 12:34:33 +02:00
signerless
1e65cd812b fix: exclude non-language repositories from model recommendations 2026-09-06 12:33:24 +02:00
signerless
7a47eb227c Score model quality from public benchmarks instead of parameter count
`calculateQualityPrior` treated quality as a lookup table on parameter count
(0.5B->45, 7B->75, 70B->95), plus hand-written family bumps and a
`name.includes('code')` match for the coding category. Nothing measured
anything, and four of the seven categories — reasoning, creative, talking,
reading — had no task signal at all, so they ranked purely by size. A coding
model came first for "Creative".

quality-evals.js ingests four public leaderboards into new tables and
`lookupMeasuredQuality` uses them where they exist:

  BigCodeBench  pass@1, instruct and complete prompt modes
  EvalPlus      HumanEval+, MBPP+
  LiveBench     per-category scores that map onto our own categories
  MMMU          multimodal, val and pro kept apart

Coverage is 54 of 239 models. The rest still fall back to the size estimate and
say so: every recommendation carries a `qualitySource` of either
`{kind:'measured', metric, rawScore, source}` or
`{kind:'estimated', basis:'parameter count'}`, so a guess is never presented as
a measurement.

Three things this gets right that are easy to get wrong:

- New tables rather than the existing `benchmarks` one, which holds local speed
  telemetry and is emptied by `ModelDatabase.clear()` on every `fullSync()`.
  Quality data stored there would be wiped by a routine catalog refresh.
- The join key is (family_key, params_b), never a variant id: a board measures
  an fp16 base checkpoint while a variant is a local Q4 build. A benchmark row
  that publishes a size which disagrees is refused rather than attributed, so a
  7B build can never inherit a 70B score. Rows with no published size match the
  family and are flagged `sizeUnknown`.
- Percentiles rank within the local catalog cohort, not the whole board.
  Ranking open models against frontier hosted ones puts every one of them in the
  bottom percentile: qwen3@30B measured scored 20.8 against deepseek-r1@14B
  estimated at 88.0, so a model was punished for having been benchmarked. The
  percentile is then mapped onto the same 45-95 band the size estimator uses, so
  measured and estimated stay comparable.

25 new tests cover family normalisation, the size-mismatch refusal, each source
parser, and the cohort. Full suite: 58/58.
2026-09-03 23:21:51 +02:00