Commit graph

943 commits

Author SHA1 Message Date
Alex Jones
c4ed14f70d docs(api): show populated gpus[] with memory_bandwidth_gbps in /api/v1/system example
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 23:16:22 +01:00
Alex Jones
9933cbdeec
Merge pull request #751 from AlexsJones/ci/docker-lowercase-image
ci(docker): lowercase image name for digest push
2026-07-14 15:22:50 +01:00
Alex Jones
26d8e4caf5 ci(docker): lowercase image name for digest push
github.repository is mixed-case (AlexsJones/llmfit) and OCI repository
names must be lowercase. metadata-action lowercased it implicitly in the
old single-job flow, but the push-by-digest output and imagetools create
use the raw env var — both platform builds failed at export with
"invalid reference format".

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:22:44 +01:00
Alex Jones
bba8582373
Merge pull request #750 from AlexsJones/ci/docker-native-arm64
ci(docker): build arm64 image natively instead of under QEMU
2026-07-14 15:18:07 +01:00
Alex Jones
e4d05b7873 ci(docker): build arm64 image natively instead of under QEMU
The single-job buildx setup compiled the arm64 Rust binary under QEMU
emulation on an x86 runner, dominating the ~50 min image publish and
delaying the amd64 image behind it. Split into per-platform jobs
(linux/amd64 on ubuntu-latest, linux/arm64 on ubuntu-24.04-arm) pushing
by digest, with a merge job assembling the multi-arch manifest — same
tags and platforms, no emulation.

workflow_dispatch now takes a required release tag so an existing
release's image can be rebuilt on demand.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:17:46 +01:00
Alex Jones
ff3e81564d
Merge pull request #727 from AlexsJones/release-please--branches--main
chore(main): release 1.1.3
2026-07-14 14:57:39 +01:00
github-actions[bot]
0a11fb4b4f chore: update Cargo.lock 2026-07-14 13:57:30 +00:00
Alex Jones
ab5c117eaa chore(main): release 1.1.3 2026-07-14 14:57:22 +01:00
Alex Jones
ce3f7bfccc
Merge pull request #749 from AlexsJones/fix/api-system-gpu-bandwidth
fix(serve): include per-GPU memory_bandwidth_gbps in /api/v1/system
2026-07-14 14:56:42 +01:00
Alex Jones
8b9b7aa3c2 fix(serve): include per-GPU memory_bandwidth_gbps in /api/v1/system
The REST API and `llmfit system --json` had drifted: the CLI's private
system_json copy in display.rs gained memory_bandwidth_gbps but the
serve_shared copy used by /api/v1/system, MCP, and SSE events never did.
Consumers that treat the API as authoritative (e.g. llmfit-dra) saw GPU
bandwidth zero out and rejected every bandwidth-bounded claim.

Add the field to serve_shared::system_json and make display.rs delegate
to it so the two serializers cannot drift again. Cover the field with
unit tests (known GPU -> value, unknown GPU -> null) and assert its
presence in the existing /api/v1/system route test.

Fixes #747

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:50:57 +01:00
dependabot[bot]
72dae3ad8f
chore(deps): bump serde_json from 1.0.149 to 1.0.150 (#595)
Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.149 to 1.0.150.
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.149...v1.0.150)

---
updated-dependencies:
- dependency-name: serde_json
  dependency-version: 1.0.150
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 15:57:04 +01:00
Alex Jones
57fa5949b9
Merge pull request #741 from AlexsJones/dependabot/github_actions/docker/metadata-action-6.2.0
chore(deps): bump docker/metadata-action from 6.0.0 to 6.2.0
2026-07-13 15:49:59 +01:00
Alex Jones
061c8cc4a4
Merge pull request #743 from octo-patch/octo/20260713-correct-minimax-m27-context-recvoLayrMvttV
Correct MiniMax M2.7 context window
2026-07-13 15:49:27 +01:00
octo-patch
1854973810
Correct MiniMax M2.7 context window
Signed-off-by: octo-patch <266937838+octo-patch@users.noreply.github.com>
2026-07-13 22:17:33 +08:00
Alex Jones
ba96f4c3cb
Merge pull request #742 from AlexsJones/fix/amd-apu-gpu-name-detection
fix: name AMD unified APUs when rocm-smi reports "N/A", gate junk shares
2026-07-13 11:44:16 +01:00
dependabot[bot]
d464688fb8
chore(deps): bump actions/cache from 5.0.5 to 6.1.0 (#694)
Bumps [actions/cache](https://github.com/actions/cache) from 5.0.5 to 6.1.0.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](27d5ce7f10...55cc834586)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 6.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:25:44 +01:00
dependabot[bot]
fbf3894287
chore(deps): bump unicode-segmentation from 1.13.2 to 1.13.3 (#646)
Bumps [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation) from 1.13.2 to 1.13.3.
- [Commits](https://github.com/unicode-rs/unicode-segmentation/commits)

---
updated-dependencies:
- dependency-name: unicode-segmentation
  dependency-version: 1.13.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:25:40 +01:00
dependabot[bot]
75d6b221b9
chore(deps): bump assert_cmd from 2.2.1 to 2.2.2 (#579)
Bumps [assert_cmd](https://github.com/assert-rs/assert_cmd) from 2.2.1 to 2.2.2.
- [Changelog](https://github.com/assert-rs/assert_cmd/blob/master/CHANGELOG.md)
- [Commits](https://github.com/assert-rs/assert_cmd/compare/v2.2.1...v2.2.2)

---
updated-dependencies:
- dependency-name: assert_cmd
  dependency-version: 2.2.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 11:25:38 +01:00
Three Foxes (in a Trenchcoat)
eda9649d53 style: rustfmt wrap in is_placeholder_identity
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 11:20:32 +01:00
Three Foxes (in a Trenchcoat)
e282011f58 fix: name AMD unified APUs when rocm-smi reports "N/A", gate junk shares
On AMD Ryzen AI MAX (Strix Halo) systems missing libdrm_amdgpu.so,
`rocm-smi --showproductname` prints `Card Series: N/A`. llmfit took that
literally as the GPU name, which cascaded into three problems:

- the leaderboard hardware identity became "N/A" (meaningless `bench/n-a-…`
  PRs);
- the APU-unify step (which matches a GPU whose name contains "amd"/
  "radeon") never matched, so the machine was classed DISCRETE_GPU with the
  64 GB shared pool recorded as dedicated VRAM instead of UNIFIED;
- any such machine would keep contributing unusable results.

Detection (hardware.rs):
- Treat rocm-smi "N/A"/empty product names as a generic "AMD GPU" rather
  than a literal identity, in both block and tabular parse paths.
- On a recognised unified APU, upgrade a generic GPU name to the APU model
  (e.g. "AMD Ryzen AI MAX+ 395 w/ Radeon 8060S (integrated)"), which names
  the iGPU and gives a stable leaderboard identity. This also lets the
  APU-unify step flag unified memory correctly.

Sharing (share.rs):
- Refuse to submit a stored benchmark whose hardware is still a placeholder
  (GPU name "N/A" for a GPU machine, or an unknown CPU for CPU-only). The
  community board groups by hardware, so an unidentified machine is noise —
  results stay stored locally with a clear message instead.

Verified on a real Strix Halo box: gpu_name now resolves to the APU model,
unified_memory=true, class UNIFIED.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-13 11:16:30 +01:00
dependabot[bot]
4ba29021c1
chore(deps): bump docker/metadata-action from 6.0.0 to 6.2.0
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 6.0.0 to 6.2.0.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](030e881283...dc80280410)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-13 00:55:31 +00:00
Alex Jones
9bbaa8d054
Merge pull request #733 from AlexsJones/fix/intel-arc-dgpu-vram
fix(hardware): read discrete Intel Arc VRAM from sysfs (xe/i915)
2026-07-11 21:17:13 +01:00
Alex Jones
bdbf338010
Merge pull request #658 from wklee610/add_model
feat: add NCAI VAETKI model to curated model database
2026-07-11 21:16:58 +01:00
Hajun Lee
8424aba9fd Merge upstream main into add_model 2026-07-11 21:10:56 +09:00
Alex Jones
bca491e380
Merge pull request #734 from AlexsJones/fix/lmstudio-docker-installed-detection
fix(providers): show LM Studio/Docker Desktop as installed when idle
2026-07-11 10:37:16 +01:00
Alex Jones
5a22add226 fix(providers): show LM Studio/Docker Desktop as installed when idle
LM Studio and Docker Model Runner were detected purely by probing
their local HTTP APIs, which are only up while LM Studio's server or
Docker Desktop is running. Installed-but-idle copies rendered as
"not detected" in the TUI provider bar.

Add install-location detection (pure candidate builders + exists()
wrappers): LM Studio via Program Files/LocalAppData exe paths, the
lms CLI, ~/.lmstudio and macOS app bundles; Docker Desktop via the
classic and frontend\ exe layouts, app bundles, /opt/docker-desktop,
~/.docker/desktop and the docker-model CLI plugin. The TUI now shows
a warning-colored "installed (not running)" / "installed (server
off)" state, matching the existing MLX/llama.cpp cached idiom, and
Ollama's header now uses the already-tracked binary_available signal
the same way. llmfit doctor gains a "Provider app installs" section
so future reports carry the evidence.

Fixes #731

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:45:31 +01:00
Alex Jones
8198cc4c02 test(hardware): use Windows-safe dir names in Intel sysfs fixture
PCI-address colons in the fake sysfs paths are invalid Windows
filenames, so create_dir_all failed the test on windows-latest. The
function under test only reads the tree layout, not the dir name.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 10:32:06 +01:00
Alex Jones
9fbbcb8312 fix(hardware): read discrete Intel Arc VRAM from sysfs (xe/i915)
Discrete Arc cards were detected by name but always reported no VRAM:
the lspci path left vram_gb as None for "the Vulkan fallback to fill
in", but detect_vulkan_gpu_info() only parses device names and never
reads memory heaps, so the merge condition adopting Vulkan VRAM could
never fire. Fit scoring then saw 0 GB and recommended CPU-class models
unless the user overrode memory manually.

Read dedicated VRAM directly from sysfs instead, keyed by the card's
PCI address from lspci -nnD:

- xe driver: sum of tileN/physical_vram_size_bytes under the PCI
  device directory
- i915 discrete: drm/cardN/lmem_total_bytes

(mem_info_vram_total is amdgpu-only, which is where the old comment's
"no sysfs VRAM file" claim came from.)

Also fix GPU-name deduplication for the Arc Pro series: is_same_gpu_name
matched Intel entries only on 3-5 digit model numbers, so two-digit Pro
models ("B70") never merged with their Vulkan/Level Zero names — and
worse, fell through to the no-model-number rule that swallowed them into
the iGPU entry. Letter-prefixed model tokens (a770, b580, b70) are now
compared as well.

Verified on a Lunar Lake iGPU machine (integrated path unchanged) and
with fake xe/i915 sysfs trees in tests; dual-card B70 lspci fixture
covers the reporter's setup.

Fixes #609

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 22:00:27 +01:00
Alex Jones
b3de39dac4
Merge pull request #729 from AlexsJones/fix/unsloth-ud-gguf-matching
fix: match Unsloth `-UD` dynamic GGUFs to catalog models
2026-07-10 21:36:50 +01:00
Three Foxes (in a Trenchcoat)
e9b66be150 fix: match Unsloth -UD dynamic GGUFs to catalog models
Unsloth "Dynamic" GGUFs embed a `-UD` marker between the model name and
the quant suffix (e.g. `Qwen3.6-35B-A3B-UD-Q4_K_M.gguf`). `strip_gguf_quant_suffix`
only removed the quant token, so the stem reduced to `qwen3.6-35b-a3b-ud`
and never matched the catalog id `qwen3.6-35b-a3b`.

As a result a model served by llama-server (or present on disk) read as
neither served nor installed: benchmarking reported "installed but not
served by any running provider", and the installed column/detail panel
omitted it.

Strip a trailing `-ud` marker alongside the quant so the stem reduces to
the canonical model name. Fixes both the benchmark-target match
(`tag_matches_model`) and the installed-set detection
(`is_model_installed_llamacpp`), which share this helper. Non-Unsloth
files are unaffected.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 13:21:34 +01:00
Alex Jones
5bef0b2e49
Merge pull request #700 from Olawoyin007/feat/ramalama-detection-provider
feat: add RamaLama as a detection provider
2026-07-10 11:44:55 +01:00
Alex Jones
f649952c39
Merge pull request #701 from CN-Scars/fix/detect-omlx-runtime
fix(providers): detect oMLX as an MLX runtime
2026-07-10 11:44:32 +01:00
Alex Jones
5b36992259
Merge pull request #726 from AlexsJones/release-please--branches--main
chore(main): release 1.1.2
2026-07-10 11:40:47 +01:00
github-actions[bot]
bb332243b3 chore: update Cargo.lock 2026-07-10 10:40:29 +00:00
Alex Jones
104cee22e3 chore(main): release 1.1.2 2026-07-10 11:40:21 +01:00
Alex Jones
a94ffcbe94
Merge pull request #724 from AlexsJones/feat/oauth-client-id
feat(share): ship the registered OAuth App client id — interactive login enabled
2026-07-10 11:39:59 +01:00
Alex Jones
325f8a3ff3 feat(share): ship the registered OAuth App client id — interactive login enabled
Sets DEFAULT_CLIENT_ID to the registered llmfit OAuth App (device flow
enabled; a public client id is not a secret — the device flow needs no
client secret, which is why it was chosen). oauth_client_id() no longer
treats the default as an unregistered placeholder: the shipped id is
used unless LLMFIT_GH_CLIENT_ID overrides it, and an explicitly empty
override opts out of interactive login (restricted CI).

Verified live: with no GITHUB_TOKEN/GH_TOKEN, no cached token, and no
env override, `llmfit bench --share` presents a real GitHub device
code. Completes the last item on #712's pre-merge checklist.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 12:02:40 +01:00
Alex Jones
386bf7889e
Merge pull request #725 from AlexsJones/bench/intel-arc-graphics-130v-140v-integrated-6a44491e
bench: community results for intel-arc-graphics-130v-140v-integrated
2026-07-10 11:39:26 +01:00
Alex Jones
57d9e39017 data: community benchmark (intel-arc-graphics-130v-140v-integrated) 2026-07-10 11:36:42 +01:00
Alex Jones
d4a60a46f2
Merge pull request #723 from AlexsJones/release-please--branches--main
chore(main): release 1.1.1
2026-07-10 11:26:47 +01:00
github-actions[bot]
318a211be4 chore: update Cargo.lock 2026-07-10 10:20:07 +00:00
Alex Jones
f28602e960 chore(main): release 1.1.1 2026-07-10 11:20:01 +01:00
Alex Jones
f2fd47672f
Merge pull request #721 from AlexsJones/feat/community-read
feat(bench): ship merged community benchmarks to every user in the next release
2026-07-10 11:19:40 +01:00
Alex Jones
5c46f92a24 feat(bench): ship merged community benchmarks to every user in the next release
Closes the read side of the contribution loop (RFC #710): community
submissions merged under llmfit-core/data/community/ are aggregated by a
new llmfit-core build.rs into an embedded JSON array — a merged
benchmark ships in the next release with no CI step or network fetch.

On hardware identical to a submission's (CPU + GPU fingerprint):
- benchmark page shows the runs as 'llmfit community' rows (distinct
  color), pinned below the user's own 'you (local)/(shared)' rows and
  deduped against them (your own shared runs also live in the embed)
- fit rows get measured tok/s from a new CommunityBenchIndex, slotted
  between the user's own runs and localmaxxing preset medians; a new
  MeasuredSource::CommunityLlmfit variant keeps provenance visible
  ('Measured on Identical Hardware' in the estimate detail)
- community anchors feed estimate calibration, so a fresh install gets
  corrected estimates before its user ever benchmarks anything

hardware_payload_matches moves to benchmarks.rs and is shared with the
local store's matches_hardware. Verified end-to-end: with a temp
submission for llama3.1:8b @ 4.0 tok/s and an empty local store
(simulated fresh machine), the fit table shows 4.0 measured
(community_llmfit) and every estimate calibrated x0.37.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 11:49:18 +01:00
Alex Jones
eeb28558fe
Merge pull request #722 from AlexsJones/docs/readme-bench-motd
docs: README top story — benchmark & share
2026-07-10 11:18:07 +01:00
Alex Jones
f9b3e9aa29 docs: README top story — benchmark & share, with getting-started link
Replaces the 1.0 banner (kept as a 'previously' link) with the
benchmark-sharing story in all three languages, linking to the
'Contributing benchmarks' guide in docs/cli.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 11:51:39 +01:00
Alex Jones
62dab6f2ed
Merge pull request #720 from AlexsJones/chore/release-patch-cadence
chore: release-please — patch bumps by default (next release 1.1.1)
2026-07-10 11:07:22 +01:00
Alex Jones
cc715d1b9e chore: slow release cadence — patch bumps by default
Post-1.1.0, feat commits no longer drive minor bumps on every release:
versioning switches to always-bump-patch, so the next release is 1.1.1
regardless of commit types. Minor/major releases become deliberate
decisions via a Release-As footer (same mechanism used to cut 1.0.0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 11:41:55 +01:00
Alex Jones
eb080b71c5
Merge pull request #719 from AlexsJones/feat/community-ci
ci: validate community benchmark submissions
2026-07-10 11:04:21 +01:00
Alex Jones
7b9cc973ae ci: validate community benchmark submissions on PR
Adds the Community Benchmarks workflow: any PR touching
llmfit-core/data/community/ runs scripts/validate_community_benchmarks.py,
which checks JSON schema conformance (schema.json, draft-07),
path/naming conventions (community/<slug>/<timestamp>-<hash>.json), file
size caps, and cross-field sanity the schema can't express (tps
ordering, plausible hardware bounds, submission timestamps within the
feature's lifetime). Whole-directory validation, so repo integrity is
re-checked on every touch; also runs on push to main.

Seeds the directory with the first genuine submission (Intel Arc 140V /
Core Ultra 7 258V, gemma-3 Q8 via llama-server, 3.8 tok/s) — previously
attempted in #713/#716 — which also exercises the workflow on this PR.

Closes the CI-validation follow-up named in #712.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 11:33:44 +01:00