Releases: Hal0ai/hal0
Release list
hal0 v0.9.2
Hotfix: restore the full model listing in every slot's model picker.
Highlights
- Fix collapsed slot model dropdowns —
/api/modelsrows again advertise the dispatcher-vocabtype(llm/embedding/reranking) the pickers join on.
Fixed
- Slot model dropdowns (and the model→slot compatibility list) showed only the currently-assigned model.
/api/modelsstamped local- and upstream-registry rows'typewithclassify()'s coarse modality bucket (chat/embed/rerank) instead of the dispatcher vocabulary (llm/embedding/reranking) that the FLM path already emitted and that the UI joins on (model.type === slot.type), so every local model failed the picker filter and each dropdown collapsed to its default. Map the modality bucket → dispatcher type at both stamp sites; adds a local-row regression test (the FLM path was already covered, which is how this slipped through).
hal0 v0.9.1
ROCmFPX llama.cpp runner support, plus a safer notes-aware self-update.
Highlights
- ROCmFPX runner support: GGUF quant-family detection,
rocmfpx-rocm/vkfpx-moeseed profiles, and a build/quantize agent skill. hal0 updatenow shows cosign-verified release notes and asks before applying (staged prepare → commit).
Added
- Updater
prepare/commitsplit.hal0 updatedownloads + cosign-verifies + extracts a release and shows its notes — with breaking/migration callouts — before activating anything;--yesskips the prompt for headless/cron. AddsPOST /api/updates/prepare+/commit(#1075). - Release notes in the update. The release build bundles
RELEASE_NOTES.md+release.jsoninto the cosign-verified tarball; a CHANGELOG section's### Highlights/### Breaking/### Migrationssubsections become thehal0 updatecallouts (#1078). - ROCmFPX quant detection — the registry classifies the
ROCmFPX/ROCmFP{3,4,6,8}quant family from a GGUF filename so FPX slots resolve their launch command (#1068). - ROCmFPX seed profiles
rocmfpx-rocm(ROCm0 dense) andvkfpx-moe(Vulkan0 MoE) for the custom ROCmFPX runner (#1069, renamed in #1076). vkfpx-denseseed profile — the Vulkan0 lane for DENSE ROCmFP4, for prefill-bound dense workloads (Vulkan wins prompt-processing); complements the decode-optimal ROCm0rocmfpx-rocm.hal0-quantizeagent skill — build the ROCmFPX toolchain and quantize a model to ROCmFP4/FPX (#1071).- ROCmFPX bench tooling: server-ab (MTP / concurrency) aggregation in the benchmark SUMMARY, FPX sweep cells, run provenance (#1072).
- Continuous batching — per-slot
parallelfield. A slot can now set
llama-server's--parallel/-npsequence-slot count so concurrent
requests share the once-loaded weights instead of serializing through a
single sequence and thrashing one prompt cache (the win the shared-slot
architecture already earns but never harvested — every seed profile pins
--parallel 1).Noneinherits the profile; a value >1 also emits
--kv-unifiedso--ctx-sizestays a SHARED pool (each request may use the
full context) rather than being silently split to ctx/N per slot. Emitted as
a slot override (beats the profile, loses to hand-authoredextra_args);
surfaced in the slot drawer with a shared-pool hint. The dead haloai
workersfield is deprecated (inert; a non-default value now logs at
launch). MTP x batching runs but logsmtp.batched_speculation(unproven on
gfx1151, bench-gated). Seed-profile defaults stay--parallel 1pending the
on-box-npsweep (server_ab.py --mode batch). See the
concurrency-batching plan handoff.
Changed
- The plain
rocm/vulkanseed profiles are reduced to basic flags
(-ngl 999 -fa on --jinja); per-model KV/batch tuning now lives in the
model'sdefaults.extra_args(#1076). - Seed-profile
intentlabels normalised to terse structural tags
(e.g.ROCmFPX · DENSE · MTP,VULKFPX · MOE · MTP,ROCm,Embeddings) —
no served-model names, no filler. - Slot units are re-rendered through the new code during an update's
commit
step, so a subsequent restart uses current argv (#1075).
Removed
- Legacy MTP toolbox seed profiles
rocm-moeandrocm-dnse(superseded by the
ROCmFPX profiles);rocmfpx-moerenamed tovkfpx-moeto indicate its Vulkan
lane (#1076).
Migrations
- Slots pinned to a removed/renamed seed profile (
rocm-moe,rocm-dnse,rocmfpx-moe) auto-fall-back to the backend's basic profile (rocm/vulkan) on launch — existing slots keep working with no operator action (#1076).
hal0 v0.9.0
The first public-beta cut. hal0 graduates from the b-tagged 0.8.x
line: the dashboard gets its redesigned fixed-band layout and a live
telemetry header, seed profiles carry flags from a measured Strix Halo
bench matrix (plus a new per-model-family override layer), MCP servers
are manageable from the CLI, and the Memory view becomes a per-bank
workspace. Safe upgrade from v0.8.5b2 — no on-disk migrations in
this cut. Profile flag changes (re-tune, FAMILY_DEFAULTS) land on each
slot's next restart; thanks to the v0.8.5b2 auto unit re-render, any
restart path picks them up.
Added
- Dashboard redesign — fixed-band layout with swap-in-place widgets
(#1061). The free-form drag/resize grid is replaced by a fixed
vertical band stack: hero strip (steady-on + quick actions), 5-cell
health strip, a full-width Unified Memory hero (slot allocations
drawn inside the pool bar, striped system block, Proxmox-host block
when configured), Throughput / Utilization / Requests band, locked
dense slot rows, and an Activity / Services / Needs-Attention band
with inline actions. Customization is swap-in-place per cell (layout
v3 via the existingPUT /api/user/dashboard-layout, fail-soft to
defaults on old payloads). Ships a new Requests & Latency widget
against a new/api/stats/requestsendpoint (gates to "source
pending" until the dispatcher rollup ships). - Telemetry header on the Slots page (#1059, #1062, #1064). One
combined live-metrics card replaces the old hero band: throughput
hero + 20-bucket spark, GPU semicircle gauge (sclk/temp/watts), CPU +
memory gauge, and the NPU 4×8 occupancy grid with per-slot owner
hues — above a full-width memory rack ruler in the #1061 memory-hero
style (in-bar allocations, live tok/s on serving segments, click-through
to the slot). Honest-data rules throughout: missing metric → em-dash,
measured zero renders as 0.0 with the serving count, GPU util captioned
"pinned" when forced high. Container queries keep the 4→3→2→1 column
wrap gap-free. hal0 mcpCLI surface (#504) —hal0 mcp {list,status,install,uninstall,restart,catalog}
backed by the existing/api/mcp/*routes. Rich tables with--jsonflag for
machine output. Therestartsubcommand surfaces the 501 supervisor-stub
gracefully until ADR-0015 lands.FAMILY_DEFAULTS— per-model-family launcher-flag overrides. A new
resolution layer between a profile's generic flags and a slot's own
[model].defaults, keyed on model family (matched from the id/filename).
Applied automatically at slot resolution (launch + preview parity) and
collapsed bynormalize_argvlast-wins, so a family override beats the
profile but a per-slot[server].extra_argsstill beats the family. First
tenant: gemma →-ctk f16 -ctv f16 --cache-reuse 0— any gemma model on
any q8 profile is pinned back to f16 KV (gemma iSWA regresses on quantized KV:
measured -28.5% pp on RADV / -10% tg on rocm, plus SWA+cache-reuse bugs
#21468/#21749). This fixes the live gemma-on-rocm-dnseregression and makes
adopting Vulkan q8 KV safe as a follow-up.- Configurable slot publish host —
[slots].publish_host(#1058).
Slot containers published on 127.0.0.1 only; raw slot ports were
reachable solely through hal0-api/Traefik. A first-class, UI-settable
config key (default127.0.0.1, unchanged behavior) lets an operator
widen to0.0.0.0or a specific interface IP. Fail-soft: an
unresolvable value falls back to loopback, never opens the box. Baked
into ExecStart, so live slots re-bind on their next restart; the
Settings row carries a loud LAN-exposure warning.
Changed
- Memory Overview is a per-bank workspace (#1057). Selecting a bank
drives one combined primary card — retained-memories spark, graph
extraction panel, embedded Tools (recall · reflect · documents ·
mental models · directives), async operations, danger zone. The
standalone#memory/toolsroute is retired; documents paginate and
show composed titles instead of raw UUIDs; mental models and
directives gain create forms. - The MTP control is always visible on llm slots (#1054). Hiding the
row for ineligible models made the tri-state undiscoverable. The slot
drawer now always renders it, with a reason line for Auto·off ("model
has no MTP heads" / "profile doesn't enable MTP") and a
launch-will-fail warning when forcing On for a model without
advertised heads. Stack editor rows follow the same contract. - Activity sidebar rework (#1063). Taller pane, stacked
timestamp/actor meta reclaiming horizontal space, and the free-text
search replaced by a slot filter dropdown (exact target match,
server-side pre-narrowed). - Seed profiles: bench-driven flag re-tune (Strix Halo matrix, 2026-07-04).
rocm-moemicro-batch-ub 2048→-ub 1024(+30% prompt-processing on
Qwen3.6-35B-A3B-MTP: 1165 vs 895 t/s pp2048, consistent across all-b;
token-gen flat ~47).vulkan-ub 512→-ub 256(+5.4% pp; the reported
1024 sweet spot measured worse). Dropped--threads-batch 32and
--poll 100 --poll-batch 1from the rocm chat profiles (measured within noise
at full offload — simpler flags win ties). Added explicit-ngl 999to all
GPU LLM profiles (GTT/unified free-mem autodetect is unreliable) and--jinja
to all LLM profiles. Decode throughput is unchanged (all wins are prefill), so
PROFILE_BENCHhero numbers stand. MTP draft depth measuredn-max 4optimal
(+23% decode vs n-max 2 on dense MTP) — seeded default kept. - Vulkan seed adopts symmetric q8 KV (
-ctk q8_0 -ctv q8_0): +45% pp at 32k
depth on qwen (168 vs 116 t/s) and halves KV memory. It is the mirror image on
gemma (gemma-4-12B @32k: q8 costs -28.5% pp on RADV), so the vulkan profile is
no longer intrinsically gemma-safe — it relies onFAMILY_DEFAULTS["gemma"]
pinning gemma slots back to f16 KV. (The upstream "~10x pp cliff" did NOT
reproduce on this fork.)
Fixed
- OpenRouter OAuth callback route is gated behind
HAL0_OPENROUTER_OAUTH_ENABLED(#775). The callback endpoint no
longer registers unless the flow is explicitly enabled, closing an
unauthenticated surface on installs that never use OpenRouter OAuth. - Capability slot mini-cards regained Logs/Edit buttons (#1055). The
utility-tier (embedding/reranking/tts/transcription) cards rendered
compact controls with no way to edit or tail a capability slot created
via the UI. - Hermes memory identity defaults to
hermes(#1056). The upstream
plugin base defaulted tohermes-agenton env-less code paths,
spawning a stray duplicateprivate:hermes-agentbank alongside the
correctprivate:hermes. Reads/writes now consistently target
private:hermes. - Telemetry throughput no longer flaps to "source pending" on an idle
box (#1062). An empty 100-second history window is a measurement
(0.0 with the live serving count), and the spark keeps the last 20
measured buckets on screen; "source pending" is reserved for a
genuinely missing source. - Removed a dead duplicate
SELF_MANAGED_PROVIDERSconstant from
kokoro.py(#982).
hal0 v0.9.0-nightly.20260705084115
Nightly v0.9.0-nightly.20260705084115 — changes since v0.8.2b4-nightly.20260703085017:
- feat(registry): detect ROCmFPX / ROCmFP{3,4,6,8} quant family from GGUF filename (#1068) (1fbc2cf)
- feat(skills): add hal0-quantize ROCmFPX build+quantize agent-skill (#1071) (df8e67d)
- feat(profiles): ship rocmfpx-rocm / rocmfpx-moe seed profiles for the ROCmFPX runner (#1069) (c512842)
- Merge pull request #1067 from Hal0ai/claude/llamacpp-strix-halo-flags-cyzyo8 (b6e0973)
- feat(bench): ROCmFPX bench tooling — mtp mode, FPX cells, provenance (9195c45)
- docs(handoff): exploratory ROCmFPX profile-optimization bench runbook (a0e022a)
- docs(handoff): record live-slot np1 anchors + greedy-acceptance bench caveat (cb96447)
- docs(handoff): fold ROCmFPX superset runner into the batching plan (cd06b0d)
- Merge remote-tracking branch 'origin/main' into claude/llamacpp-strix-halo-flags-cyzyo8 (0d12d35)
- feat(batching): per-slot parallel field + kv-unified emission (P1) (0ff6018)
- handoff: concurrency & continuous-batching optimization plan (47413f3)
- docs: mirror from hal0-web@2bb122b (8bcac03)
- docs: mirror from hal0-web@07d7277 (da7aaf7)
- Correct formatting in Services section of README (bd465ee)
- docs: mirror from hal0-web@0171859 (ad8f0ef)
- release: v0.9.0 — first public beta (#1066) (a3f163b)
- docs(readme): two-up hero — Dashboard + Slots (a650e0c)
- docs(readme): add v0.9 flagship screens to the gallery (c6a1769)
- docs(readme): point roadmap link to /#roadmap; refresh roadmap items (a02eb9f)
- docs(readme): add a screenshot gallery (44bdc6e)
- docs(cli): document hal0 mcp command surface (cli.mdx parity) (ea58ba1)
- fix(lint): ruff check + format on mcp CLI and openrouter test (51e6231)
- release: v0.9.0 — first public beta (version bump + changelog cut) (b7e18c4)
- fix(openrouter): gate OAuth callback route behind HAL0_OPENROUTER_OAUTH_ENABLED (#775) (fe37e1f)
- cli: implement hal0 mcp {list,status,install,uninstall,restart,catalog} over /api/mcp/* (804e00d)
- fix(providers): remove dead duplicate SELF_MANAGED_PROVIDERS from kokoro.py (closes #982) (f39538e)
- profiles: bench-driven seed flag re-tune (Strix Halo matrix results) (#1060) (db330b6)
- feat(ui): activity sidebar — stacked meta, slot filter, taller pane (#1063) (0d0c1e0)
- fix(ui): telemetry header — ruler fills the blank cell in the 3-column band (#1064) (dfc4b1c)
- feat(ui): dashboard redesign — fixed-band layout with swap-in-place widgets (#1061) (8789a07)
- fix(ui): telemetry-header follow-ups — persistent throughput + #1061 memory-ruler styling (#1062) (e6fb1a6)
- feat(ui): telemetry-header handoff on the slots page (combined metrics card + NPU occupancy update) (#1059) (3b17729)
- feat(slots): configurable slot publish host ([slots].publish_host) (#1058) (f9056fb)
- fix(memory): default hermes plugin identity to
hermes, nothermes-agent(#1056) (edb9937) - feat(ui/memory): overhaul Memory Overview into a per-bank workspace (#1057) (9d05d91)
- fix(ui): add Logs/Edit buttons to capability slot mini-cards (#1055) (5be7a0a)
- ui: always show the MTP control on llm slots (reason line + force-on warning) (#1054) (825050e)
- release: v0.8.5b2 — hotfix cut (MTP defuse, unit re-render, /v1/rerank) (#1053) (0bdc8c9)
- gateway: serve POST /v1/rerank (alias of /v1/rerankings) (#1052) (ddc206c)
- slots/updater: MTP crash defuse + slot-unit re-render on update (#1049) (235ddbb)
- release: v0.8.5b1 — version bump + changelog cut (#1048) (dea8177)
- Merge pull request #1047 from Hal0ai/claude/docs-hal0-website-sync-1r1b6c (3309ce3)
- Merge remote-tracking branch 'origin/main' into claude/docs-hal0-website-sync-1r1b6c (3dc94df)
- profiles: virtual seeds, embed/rerank lanes, and MTP separation (+ tri-state UI) (#1045) (24b06c5)
- docs(changelog): catalogue the unreleased post-v0.8.4b1 work (0c3f9af)
- Merge pull request #1046 from Hal0ai/claude/docs-hal0-website-sync-1r1b6c (1eef441)
- docs(readme): add hal0 Discord link (header nav + Contributing) (25eb76e)
- docs: mirror from hal0-web@38dcc4e (ae2fbec)
- Merge pull request #1044 from Hal0ai/claude/docs-hal0-website-sync-1r1b6c (0b80706)
- Merge remote-tracking branch 'origin/main' into claude/docs-hal0-website-sync-1r1b6c (83684c0)
- Merge pull request #1043 from Hal0ai/claude/settings-ui-release-review-bva5wr (9337dbe)
- docs: mirror refreshed hal0.dev docs (v0.8.4b1 truth pass) (ca3b1ed)
- docs(readme): full accuracy pass against v0.8.4b1 source (f4b7f92)
- feat(comfyui): hot-reload idle_restore + workflow listing (settings P5) (bc039f2)
- docs(readme): re-baseline status to v0.8.4b1, agent/utility seeded slots (e9e5fd7)
- feat(models): finish catalog sort/tag/quant wiring + chat-template pick at pull (#1042) (2ca1028)
- Merge pull request #1040 from Hal0ai/claude/settings-ui-release-review-bva5wr (cb1e7ee)
- Merge branch 'main' into claude/settings-ui-release-review-bva5wr (d8cdefc)
- handoff: llama.cpp seed-profile evaluation + consolidation proposal for Strix Halo (#1041) (0dc4bf2)
- Merge pull request #1039 from Hal0ai/claude/new-session-09hvwe (faaf1bd)
- feat(settings): add NPU section (settings P4) (ccdc21a)
- Merge branch 'main' into claude/new-session-09hvwe (137ae3a)
- Merge pull request #1038 from Hal0ai/claude/settings-ui-release-review-bva5wr (a5c6134)
- feat: GPU generalization (CUDA/multi-GPU), dead-path retirement, catalog UX, multi-file pulls (5e25fc5)
- feat(voice): wire TTS request defaults + live voice list (settings P3) (c2f909a)
- Merge pull request #1036 from Hal0ai/claude/settings-ui-release-review-bva5wr (f7652f1)
- Merge remote-tracking branch 'origin/main' into HEAD (a208b84)
- Unified companion-service management: registry, /api/services, mDNS, dashboard Services page (#1037) (606e42f)
- docs(review): platform reliability/config/UI review handoff (#1010) (dc641e2)
- docs(handoffs): ONNX / Strix Halo NPU research and integration plan (#1034) (803b9fd)
- Merge pull request #1033 from Hal0ai/claude/new-session-09hvwe (8d57ad4)
- Merge remote-tracking branch 'origin/main' into HEAD (5d6af95)
- feat(dash): clearly identify upstream-advertised models as remote, not local (#1035) (f30d7e7)
- feat(settings): wire inert config keys + hindsight-era memory schema (350f797)
- Merge branch 'main' into claude/new-session-09hvwe (555a61d)
- Merge remote-tracking branch 'origin/claude/model-storage-ui-bguvd1' into claude/new-session-09hvwe (25e0fe4)
- feat(ui): consume /api/meta/enums — one taxonomy, stacks fixes, dialog guards (c2546ee)
- fix(board): Hermes-contract repairs, honest UI state, platform-assistant chat (#1032) (2b59647)
- refactor(meta): canonical device/backend taxonomy + GET /api/meta/enums (a073d75)
- docs(handoffs): execution plan for model pipeline + models UI fixes (6dd613c)
- fix(slots): API boundary validation, backend-switch completion, manager guards, guarded stack writes (ac75898)
- feat(dash): clearly identify upstream-advertised models as remote, not local (7514a6f)
- Merge pull request #1031 from Hal0ai/claude/settings-ui-release-review-bva5wr (ec754c2)
- chore: sync uv.lock self-version with pyproject 0.8.4b1 (1c6511d)
- style: ruff format settings apply-plan modules (abaf7c6)
- fix(settings): review fixes — truthful apply plan, safe engine picker, CI green (cfb1382)
- fix(ui): slot pipeline quick wins — normalizer bug, backend switch, dead code, a11y (011ce8b)
- style: ruff format for schema/container/test_schema (b79c283)
- refactor(slots): single argv assembler + model-defaults wiring + provider fixes (126052a)
- feat(ui): Advanced settings section — full hal0.toml parity, memory graph panel, API restart (ea4abcb)
- feat(ui): AWS secret-pair preset + reload-config-from-disk button (132385d)
- fix(ui): settings release cleanup — secret descriptions, rollback, palette ghosts (a22c85a)
- release: v0.8.4b1 — model profiles, persistent context, ComfyUI surface + logs/memory fixes (4f1d41b)
- fix(installer): make cosign optional for one-line install (3ef73d5)
- fix(memory): audit destructive ops + console shape guard (#1024, #1026) (#1030) (58bb5cb)
- fix(board): unwrap Hermes kanban task-detail envelope so the drawer renders (#1014) (ec2a498)
- docs: logs/events docs pass + operate/auth guide; ignore local artifacts (3e056de)
- style(tests): ruff format model-profiles test files (CI format check) (e2fb66d)
- feat(models): model-associated profiles, persistent slot context, ComfyUI model surface (10ef717)
- fix(logs): unify logs/events system — restore per-slot model-load logs, real source/slot, channel selector (48ddd3f)
- fix(memory): functional Memory tab + guard bank DELETE (incident #1024 fixes) (#1028) (53df88a)
- fix(ui): stack edit drawer — labeled multi-line slot cards + fix escaped toggle knob (#1023) (ab9ffc9)
- release: v0.8.3b1 — Waves 1-8 reliability + UI-completeness (#1022) (147e46f)
- feat(ui): edit-drawer completeness — all backend values editable (slot/model/profile) + UI-2/20 (#1020) (7aac39a)
- feat(settings): telemetry privacy toggle + surface image-gen defaults (#1021) (583ac95)
- feat(dashboard): surface live telemetry — default-on Power/Thermal + Per-Slot Throughput, MHz/temp on Utilization (#1019) (9793a8e)
- fix(platform-review): Wave 7 — UI honesty/safety (T6) + PS-5 part 2 (#1018) (465634f)
- fix(platform-review): Wave 6 — cross-process safety & housekeeping (MR-5/SC-10/MR-8/MR-9/MR-13/DR-12/MR-7) (#1017) (1e0d74e)
- refactor(ui): shared FormDrawer + useForm + dirty guard + compatibleModels + a11y (UI-1/3/12/14/19) (#1016) (a1c12d2)
- refactor(platform-review): Wave 4 — unify parallel implementations (PS-4, MR-3, DR-8, SC-11) (#1015) (aeb1d12)
- fix(platform-review): Wave 3 — write-time validation (SC-4, SC-5, MR-4, PS-5) (#1013) (57e5d0a)
- fix(platform-review): Wave 2 — install-path reliability (MR-1, MR-2, DR-2, DR-3) (#1012) (013fa04)
hal0 v0.8.5b2
Hotfix over v0.8.5b1, closing the three findings from the first live
update+verification pass on Strix Halo hardware (CT105): stale mtp = true
overrides crashing slots on re-render, slot units not re-rendering on update,
and the gateway missing POST /v1/rerank. Safe upgrade from v0.8.5b1 —
the one migration (crash-only MTP override defuse) touches exactly the slot
configs that could not have loaded anyway, with a loud per-slot log.
Added
- Slot units re-render automatically on update. A slot's systemd unit
bakes the launch argv at load time, so updating hal0 changed the code that
WOULD render but not the file that DID —systemctl restart, crash
restarts, and reboots kept running pre-update flags until an operator did a
hal0-level slot restart (field finding). The updater (post venv-reinstall,
via a fresh interpreter so the NEW code renders) andinstall.shnow
rewrite every existing unit through current code plus onedaemon-reload—
running services are never bounced; fresh argv applies on each slot's next
start from any path. Per-slot failures log and skip. The dashboard drift
indicator still covers the "process running old argv until next restart"
window.
Fixed
- Gateway now serves
POST /v1/rerank. The dispatcher's capability path
map already resolved/rerankto the rerank slot, but the gateway only
registered/v1/rerankings— so clients using llama-server's / Jina-style
/v1/rerankgot 405 and had to hit the slot port directly (field finding).
/v1/rerankis now an alias of/v1/rerankingsthrough the same dispatch
path. - Crash-only
mtp = trueoverrides are defused automatically. A forced
MTP override pointing at a model with no MTP heads crashes llama-server at
load once the slot's unit re-renders under the v0.8.5b1 MTP separation
(field-confirmed: pre-separationmtp = truedebris on a headless MoE
model). Two mechanisms now clear exactly that combination: an updater
migration over the slot TOMLs (updater.mtp_force_on_clearedlog; force-off,
eligible force-on, and unresolvable models untouched) and a swap-path guard
(swapping onto an ineligible model drops a forcedtrue→ AUTO, so the
staleness can't regenerate). The false-negative escape hatch — forcing MTP
on for an untagged-but-capable model — is preserved.
hal0 v0.8.5b1
Everything landed on main since the v0.8.4b1 cut. The headlines: hal0
generalizes beyond the Strix Halo iGPU (experimental CUDA + multi-GPU
pinning), companion services get one management surface (registry +
/api/services + mDNS + dashboard page), the settings-completeness plan
finishes (phases 3–5 + an Advanced section with full hal0.toml parity),
and seed profiles go virtual with dedicated embed/rerank lanes and a
proper model×profile×slot MTP decision (#1045). Safe upgrade from
v0.8.4b1 — the one on-disk migration (virtual-seed prune) backs up
profiles.toml first and rescues divergent operator content to -custom
names; note the MTP auto behaviour below if you run untagged local MTP
builds.
Upgrade note — re-render slot units after updating. A container
slot's systemd unit bakes the launch argv at load time, so after an
update the running slots (and their unit files) still carry the
PRE-update flags. A baresystemctl restart hal0-slot@<name>re-runs
the stale ExecStart — restart slots through hal0 (dashboard restart,
or unload→load) so the unit re-renders through the new code. The
dashboard's resolved-command drift indicator shows which slots are
stale. Automatic unit re-rendering on update (without bouncing serving)
is planned as the follow-up.
Added
- GPU generalization — experimental CUDA + multi-GPU. A dedicated
cudaseed profile (upstreamllama.cpp:server-cudaimage, preferred
by the installer when NVIDIA CDI is present, Vulkan fallback otherwise)
and per-slotgpu_indexpinning for multi-GPU hosts. Ships alongside
dead-path retirement and multi-file pulls (a model's mmproj/vision
sidecars download with the main GGUF in one job). - Unified companion-service management (#1037). A code-level service
registry (Open WebUI, ComfyUI, Hermes, Hindsight, n8n),GET /api/services+ allow-listed lifecycle actions, mDNS advertisement
of addon services (hal0-addon-<id>.servicefiles, avahi inotify
pickup,HAL0_HOSTNAMEprecedence), and a dashboard Services page
(cards, logs drawer, ComfyUI queue drawer, fail-soft probes). - Settings completeness, phases 3–5. TTS request defaults
(default_voice/default_speed/default_response_format) seeded
into/v1/audio/speechplus a live voice list proxied from thetts
slot (#1038); a Settings NPU section (#1040); ComfyUI
idle_restore_minuteshot-reload (no API restart) and a workflow
listing endpoint + dynamic strip (#1043). - Advanced settings section. Full
hal0.tomlparity in the dashboard
(every config key editable, grouped, with descriptions), a memory-graph
panel, and an API restart button; an AWS secret-pair preset and a
reload-config-from-disk button; previously-inert config keys wired
through, and the memory schema aligned to the Hindsight era. - Dedicated
embedandrerankseed profiles (#1045). GPU llama-server
templates that bake in the serving flags (--embedding/--reranking,
-ub 8192so a full input fits one physical batch) so an embedding or
reranking slot no longer hand-wires them inextra_args. On agpu-rocm
box, embed/rerank capabilities derive onto these lanes automatically
(install path and picker/apply fit path both updated); Vulkan/CPU boxes
keep falling back to thevulkan/cpu-llmprofile until
backend-specific variants ship. - Profile bench matrix tooling (#1045).
installer/bench/profile-matrix.sh
scripts the seed-profile re-tune matrix ashal0-benchctlseam sweeps, and
installer/bench/server_ab.pymeasures the server-level levers llama-bench
can't see — MTP draft depth (with acceptance %),--cache-reuseon a
shared-prefix trace, poll, and embed/rerank endpoint sanity — via hal0-api
as the unprivileged user, always restoring the slot's original config.
Supersedes the ad-hoc/root/bench_mtp.py; an on-box runbook ships at
handoffs/bench-profile-matrix-local-session-2026-07-04.md. - Catalog UX finish (#1042). Sort / tag-filter / quant chip wiring in
the Models view, and a chat-template pick at pull time. - Canonical device/backend taxonomy. One enum source at
GET /api/meta/enums(ETag/cache-friendly), consumed by the dashboard —
plus stacks fixes and dialog guards that rode the same change.
Changed
- Seed profiles are now virtual (#1045). The built-in profile catalog
(SEED_PROFILES) is overlaid from code on every load and never persisted to
/etc/hal0/profiles.toml. Previously the installer materialised every seed
inline and the loader only injected missing seeds, so a re-tuned seed (new
flags, a bumped toolbox image) never reached an existing install. Now the code
definition always wins:load_profiles_configoverlays seeds over any on-disk
copy,save_profiles_configstrips seeds before writing, and the updater's
ensure_seed_profiles()prunes any materialised seeds left by an older
install (self-heal on upgrade). Seed profiles remain immutable — clone to
customise. Operator (non-seed) profiles are untouched. Data-safe
migration: the pre-prune file is backed up once
(profiles.toml.pre-virtual-seeds.bak) and any seed-named entry whose
content differs from the code seed (a hand-edited seed table, or an operator
profile whose name only became a seed in this release, e.g.embed) is
rescued to<name>-custominstead of deleted, with a loud log. - MTP is now a model × profile × slot decision (#1045). Model
eligibility (mtpregistry tag or name marker) × profile opt-in
(profile.mtpnow means "enable for eligible models", not "append the
bundle regardless") × a tri-state per-slot override (Auto/On/Off, Auto
= profile opts in AND model eligible). A non-MTP model on an MTP
profile no longer launches with dead--spec-draft-*flags, and the
draft device tracks the profile backend (ROCm/Vulkan/CUDA) instead of
hardcoded ROCm. The slot drawer swaps the binary MTP pill for the
tri-state control with a live "Auto · active/inactive" hint; stack
editor rows default to Auto, and an Auto row now clears a forced
override on apply (the config write layer treats an explicitnullas
delete-key — TOML has no null — which is also what makes "back to
Auto" work from the dashboard instead of 500ing). Behaviour note:
an MTP-capable model that carries neither the registrymtptag nor an
MTP name marker stops speculating under Auto after this upgrade — tag
the model or force the slot On; the launch log says
mtp.auto_off_model_ineligiblewhen this bites.
Fixed
- MTP auto-off breadcrumb is launch-gated. The
mtp.auto_off_model_ineligiblehint lives inside the shared launch/preview
scalar resolver, so it fired on every dashboardGET /api/slotspoll
(~0.4/s per client, forever) for any AUTO slot pairing an MTP profile with a
non-MTP model. It now logs only on a real container launch; preview/status
renders stay silent, and launch/preview argv parity is unchanged. - Upstream-advertised models are clearly identified as remote (#1035),
not local, across the dashboard model surfaces. - Operator Board (#1032). Hermes-contract repairs, honest UI state,
and platform-assistant chat. - Slot pipeline hardening. API boundary validation, backend-switch
completion, manager guards, and guarded stack writes; a single argv
assembler with model-defaults wiring and provider fixes; normalizer
bug, dead-code removal, and a11y quick wins in the slot drawers. - Settings polish. Truthful apply plan, safe engine picker, secret
descriptions, rollback behaviour, and palette ghosts.
Docs
- README re-baselined to v0.8.4b1 + full accuracy pass (#1044, #1046):
canonicalagent/utilityseeded slots, real backend-profile and
hardware-tier tables (experimental CUDA row), removed the
no-longer-shippedHAL0_USERunprivileged mode, added the Discord
invite (header + Contributing). - hal0.dev docs mirror refreshed (#1044): new
operate/servicespage,
operate/authrewritten to the real ADR-0012 reverse-proxy model (the
fictional--auth=basic/ managed-Caddy docs from 3e056de removed
site-wide), plus the full v0.8.x feature-doc sweep. - Handoffs: platform reliability/config/UI review (#1010), ONNX / Strix
Halo NPU research and integration plan (#1034), llama.cpp seed-profile
evaluation + consolidation proposal (#1041).
hal0 v0.8.4b1
A models, logs & memory follow-up to v0.8.3b1. Models can now carry a
preferred runtime profile that loads with them, image-gen/ComfyUI models get
their own properly-tagged surface, the slot context window finally persists
across reloads, the logs/events system is unified, and the memory subsystem
gains a destructive-op audit trail plus console shape guards. Safe upgrade
from v0.8.3b1 — no breaking changes; all additions are additive.
Added
- Model preferred profile. A registry model can declare
defaults.profile
— the runtime profile it wants loaded with it. A slot adopts it on create
(when it has no explicit profile) and on every model swap, gated on
device/type compatibility (an incompatible preference is ignored and the slot
keeps its device-default profile; slot hardware is never flipped to satisfy a
model). Surfaced as a Preferred profile selector in the model recipe
editor. - ComfyUI / image-gen model surface. The Models view gains a Models |
Image/ComfyUI segmented toggle; image-gen models are grouped by their
models-tree category (checkpoints/loras/vae/upscale_models/…) and kept out of
the dispatcher list. ComfyUI models are correctly taggedimage/comfyuiat
every registration path, and/api/modelsself-heals rows an older pull
mis-tagged by deriving the ComfyUI category from the on-disk path (no
migration needed). - Memory: audit trail for destructive ops (#1024). Every destructive
/api/memory/*op — bank delete, and memories/config/document/directive/
operation/mental-model deletes, plus the namespacePOST /api/memory/delete
— now records a durable audit row (actor + target + truthful outcome) via the
sharedrecord_actionfacility, so a memory wipe is attributable after the
fact. Complements the bank-DELETE?confirm=guard shipped in #1028. - Memory: response-shape guard on the cognition consoles (#1026). The
recall/reflect/directives passthroughs now validate the load-bearing envelope
key (results/text/items); upstream Hindsight shape drift surfaces as a
loudmemory.engine_shape502 instead of a silently-blank console panel. The
two collidingrecallcontracts (namespace{items}vs bank{results}) are
now documented at both call sites.
Changed
- Unified logs/events. Restores per-slot model-load logs, real source/slot
attribution, and a channel selector across the logs/events surface. - Memory Overview UI. The graph-extraction gate now sits beside a shrunk
"memories retained" spark in the top row; card headings share one unified
"eyebrow" style; dropped the strayADR-0023label from the extraction title.
Fixed
- Persistent slot context. The slot edit drawer seeds the context field
from the persisted[model].context_size(not the live runtime metric or a
hardcoded 16384) and only writesctx_sizewhen it actually changed, so an
unrelated save no longer clobbers the stored context window with 16k on a cold
reload or swap. - Don't surface invisible models. FLM tags advertised by the composite
upstream before their weights are pulled are dropped from the catalog (the
dedicated probe still surfaces the genuinely installed ones); freshly-pulled
ComfyUI checkpoints are no longer mis-filed as chat models. - Memory tab functional; bank delete guarded (#1028). The Memory tab renders
its graph status/slot UI and consolidate/list actions correctly, and a bank
DELETEnow requires an explicit?confirm=guard. - Stack edit drawer (#1023). Slot cards render as labeled multi-line
entries and the escaped toggle-knob glyph is fixed. - Board: Hermes kanban task-detail drawer (#1014). The task-detail envelope
from Hermes is unwrapped so the board drawer renders instead of showing empty. - Installer: cosign optional for the one-line install. The bootstrap no
longer hard-requirescosign, so the one-line installer runs on hosts without
it (signature verification still applies wherecosignis present).
hal0 v0.8.3b1
A large reliability and UI-completeness release. The headline is a
72-finding platform-review remediation delivered as eight verified waves
(each finding regression-tested and gated by CI + Playwright), landing
alongside earlier staged fixes. It retires several silent-failure bugs,
adds cross-process safety and pull resumability, makes every
backend-supported value editable in the slot/model/profile drawers, and
surfaces live telemetry on the dashboard. Safe upgrade from v0.8.2b4 —
no breaking changes; all config/UI additions are additive.
The most user-visible behaviour changes: the dashboard now shows Power &
Thermal (live GPU clock/temp/power) and Per-Slot Throughput cards by
default; disabling a capability now genuinely stops it serving; and the
bge reranker is now classified and routed as a reranker.
Added
- Dashboard live telemetry, on by default. The Power & Thermal card
(GPU clock MHz, temp, power) and the Per-Slot Throughput card are now
default-on, and the Utilization card shows a live clock/temp caption.
(#1019) - Edit-drawer completeness. The model editor now exposes
capabilities,backends,rope_freq_base,mmproj, and
hf_repo/hf_filename; slots gain a per-slotvisiontoggle and NPU
asr/embedmodality toggles — all fields the API already accepted but
no drawer surfaced. (#1020) - Settings. An opt-in anonymous telemetry toggle and the image-gen
defaults (default_size,default_steps,idle_restore_minutes). (#1021) - Interrupted pulls resume via HTTP
Range(withIf-Range) instead
of re-downloading from zero; the on-disk prefix is re-hashed so the final
SHA-256 stays exact. (#1017) - Disk-space preflight before multi-GB pulls fails fast with a
structuredmodel.insufficient_diskerror instead of filling the disk.
(#1013) - Host-memory-pressure LRU eviction of idle slots. (#1003)
Changed
- Retired duplicated logic that had silently drifted: one
device→profile derivation, one filename→capability classifier, one
dispatchable-state predicate, and one slot-projection reconcile. (#1015) - Rebuilt the dash editing drawers on a shared
FormDrawer+useForm
with an unsaved-changes dirty guard, onecompatibleModelsfilter, a
focus trap and real<label>wiring (a11y), plus honest, confirmed
destructive actions (styled type-to-confirm deletes; no more "Pause"
that silently cancels; real "fits in memory" check). (#1016, #1018) - Cross-process safety: advisory file locks around registry and
capabilities writes; parent-directoryfsyncafter atomic writes. (#1017) - Housekeeping: startup GC of stale pull-job snapshots and orphaned
.partpartials. (#1017) - Extracted the capability-resolution heuristics out of
dispatcher/router.py.
(#1017)
Fixed
- Disabling a capability now sticks. The disable is written through to
the slot config, so a later request can no longer wake a "disabled" slot
and serve from it. (#1011) - The NPU trio is advertised on podman-only hosts — the picker probed
dockerand never offered it on the reference platform. (#1011) - GPU-less installs get a chat-capable primary slot instead of one
bound to the Kokoro TTS engine (cpunow defaults tocpu-llm). (#1011) - Idle-evicted embed/rerank/tts slots wake on request instead of
404'ing until a manual load. (#1011) - The
bgereranker is classified as a reranker (was mislabeled
chat) and is routable as one. (#1015) - Installer/bundle pulls survive an api restart — status/stream polls
no longer 404 mid-install. (#1012) - A completed pull is no longer reported "failed" after a restart. (#1012)
- The GpuArbiter drain no longer unloads a slot under an in-flight
request (image-mode switch race). (#1012) - Slots are no longer advertised READY on a health-probe timeout. (#1012)
- Write-time validation: a second
default=trueslot of a type is
refused at save;create()no longer clobbers an existing custom slot;
stack apply flags unresolved profile/model refs and reports degraded
(not "clean") when slots fail to load. (#1013, #1018) - The model editor no longer silently wipes unshown launcher defaults on
Save, and the ComfyUI image-profile control no longer corrupts
device_classon edit. (#1020) - Chat requests with mis-positioned or stacked
role='system'messages
no longer 500 the Qwen3.6-35B-A3B upstream. The OpenAI-compat
normaliser now collapses every system entry into one and hoists it to
position 0 (matching the OpenAI/Anthropic convention), so a stale
mid-array system message from the SPA/Open WebUI/LibreChat — or two
deliberately-stacked system blocks — no longer trips the Qwen3 Jinja
template'sSystem message must be at the beginning. No-system payloads
skip the copy. (#992) - Additional staged fixes from the assessment sweep: dead-port guard for
container slots (#1001),events.gapon subscriber-queue overflow
(#1000), non-retryableSlotLoadFailedfor ERROR slots (#999), bounded
httpx pool + tighter read timeout (#998), cold-slot 404 ordering (#996),
container slots entering SERVING and bumpinglast_used_at(#995),
installer port reachability when Docker is co-installed (#990), updater
rollback re-pip (#994), an in-memory PgVector write warning (#1008),
additive seed-profile merge (#1007), durable pull-job persistence (#1006),
canonical slot fields on npu/load + install model-update (#1009), and the
yellow-halo favicon restore (#991).
hal0 v0.8.2b4-nightly.20260703085017
hal0 v0.8.2b4-nightly.20260702084238
Nightly v0.8.2b4-nightly.20260702084238 — changes since v0.8.2b4-nightly.20260630085726:
- fix(api): canonical slot fields for npu/load and install slot model-update (#770) (#1009) (22e88cc)
- fix(api): persist model-pull jobs to disk so restart survives status poll (#626) (#1006) (cc0a81c)
- fix(memory): warn on in-memory PgVectorProvider writes and surface degraded status (#613) (#1008) (01b2348)
- fix(config): additively merge new SEED_PROFILES into existing profiles.toml (#838) (#1007) (1e068c5)
- fix(installer): add cpu-llm seed profile and fix cpu→vulkan derive incoherence (#834) (#1005) (ecc4193)
- fix(installer): retire comfy-up/down/logs/postinstall docker scripts (#984) (#1002) (a97a760)
- fix(slots): add host-memory-pressure LRU eviction (#903) (#1003) (3791547)
- fix(dispatcher): extend _guard_dead_port_image_mode to container slots (#997) (#1001) (28ec4c2)
- fix(events): emit events.gap on subscriber queue overflow (#793) (#1000) (9736e69)
- fix(dispatcher): raise SlotLoadFailed (non-retryable 502) for ERROR slots (#987) (#999) (fd91d22)
- fix(dispatcher): bound httpx pool and reduce direct read timeout (#415) (#998) (a406572)
- fix(images): move ensure_img() before dispatch() to fix cold-slot 404 (#725) (#996) (7571dfe)
- fix(dispatcher): container slots now enter SERVING and bump last_used_at (#746) (#995) (aa5bf8f)
- fix(installer): recognise agent.toml as canonical default slot in _has_default_slot() (#981) (#993) (fb9e19c)
- fix(updater): re-pip prior tree into venv on rollback (#980) (#994) (d2eef6d)
- fix(installer): keep podman-published ports reachable when Docker is co-installed (#990) (35ee23e)
- fix(ui): restore the yellow-halo favicon + brand icons on the dashboard (#991) (51056bb)
- fix(v1): canonicalise system messages — collapse + hoist to position 0 (#992) (498f972)