You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Click the inline swap chevron on any slot card (or open Create slot).
Pick the first dropdown entry — e.g. qwen3.6-27b-mtp for an llm-type slot.
The slot ERRORs with model.not_found:
[warning] hal0.error code=model.not_found message="model 'qwen3.6-27b-mtp' is not in the registry (slot 'hermes-agent' not touched)"
Root cause
ui/src/dash/slot-modals.jsx was sourcing both the CreateSlotModal model picker and the InlineSwapPopover from HAL0_DATA.models (ui/src/dash/data.jsx) — the dashboard's static seed data. Those rows include fictional ids that point at no real registry entry: qwen3.6-27b-mtp, qwen3-coder-30b, llama-3.2-3b-npu, etc. Clicking one tunnels straight into POST /api/slots/{name}/swap, where the orchestrator correctly bounces the bad id against the real registry.
The comment at slot-modals.jsx:54 acknowledged this — "Model catalogue still lives in HAL0_DATA — replaced when the models hook ships (parallel teammate)" — but the wire-up never landed.
Fix in this PR (already on disk on 10.0.1.142)
Add a normalizeApiModel() helper that maps the /api/models shape (capabilities, backends, size_bytes, name, hf_repo) onto the legacy seed shape (type, device, size, longName, repo) that the JSX expected.
CreateSlotModal + InlineSwapPopover now consume useModels() and useHardware() instead of HAL0_DATA.*. parseSizeGB keeps working because the normalizer still emits "18.8 GB"-style strings.
React hook-order kept legal in InlineSwapPopover by moving the if (!open) return null early-return after the hook calls.
Verified live on hal0 LXC: qwen3.6-27b-q5kxl swaps cleanly into hermes-agent (idle, lemonade backend).
Follow-ups (separate issues)
command-palette.jsx, extras.jsx, chrome.jsx, dashboard.jsx, chat.jsx, mcp-main.jsx, flow-modals.jsx, firstrun.jsx still read HAL0_DATA.host.* for name/uptime/ram and one reads HAL0_DATA.models for the command palette. Should track these — they're the same class of bug as dash: First-run downloads SSE still on mock (HAL0_DATA.downloads) #338 (Downloads SSE on mock).
Lemonade's server_models.json defines ~170 curated entries (incl. MTP variants) that aren't in hal0's registry.toml. The fixed dropdown won't show them. Discoverability story TBD — should the dashboard surface "available but unregistered" rows with a "register + pull" affordance?
When a registered model isn't yet on disk, swap should kick off a pull before / instead of returning slot.warming indefinitely. Right now the popover just shows "will pull" but /swap doesn't trigger one.
Repro
qwen3.6-27b-mtpfor an llm-type slot.model.not_found:Root cause
ui/src/dash/slot-modals.jsxwas sourcing both theCreateSlotModalmodel picker and theInlineSwapPopoverfromHAL0_DATA.models(ui/src/dash/data.jsx) — the dashboard's static seed data. Those rows include fictional ids that point at no real registry entry:qwen3.6-27b-mtp,qwen3-coder-30b,llama-3.2-3b-npu, etc. Clicking one tunnels straight intoPOST /api/slots/{name}/swap, where the orchestrator correctly bounces the bad id against the real registry.The comment at slot-modals.jsx:54 acknowledged this — "Model catalogue still lives in HAL0_DATA — replaced when the models hook ships (parallel teammate)" — but the wire-up never landed.
Fix in this PR (already on disk on 10.0.1.142)
normalizeApiModel()helper that maps the/api/modelsshape (capabilities,backends,size_bytes,name,hf_repo) onto the legacy seed shape (type,device,size,longName,repo) that the JSX expected.CreateSlotModal+InlineSwapPopovernow consumeuseModels()anduseHardware()instead ofHAL0_DATA.*.parseSizeGBkeeps working because the normalizer still emits"18.8 GB"-style strings.InlineSwapPopoverby moving theif (!open) return nullearly-return after the hook calls.Verified live on hal0 LXC:
qwen3.6-27b-q5kxlswaps cleanly intohermes-agent(idle, lemonade backend).Follow-ups (separate issues)
command-palette.jsx,extras.jsx,chrome.jsx,dashboard.jsx,chat.jsx,mcp-main.jsx,flow-modals.jsx,firstrun.jsxstill readHAL0_DATA.host.*forname/uptime/ramand one readsHAL0_DATA.modelsfor the command palette. Should track these — they're the same class of bug as dash: First-run downloads SSE still on mock (HAL0_DATA.downloads) #338 (Downloads SSE on mock).server_models.jsondefines ~170 curated entries (incl. MTP variants) that aren't in hal0'sregistry.toml. The fixed dropdown won't show them. Discoverability story TBD — should the dashboard surface "available but unregistered" rows with a "register + pull" affordance?slot.warmingindefinitely. Right now the popover just shows "will pull" but/swapdoesn't trigger one.