Skip to content

dash: Slot swap popover + Create-slot modal were emitting fictional model_ids from HAL0_DATA mock #345

@thinmintdev

Description

@thinmintdev

Repro

  1. Click the inline swap chevron on any slot card (or open Create slot).
  2. Pick the first dropdown entry — e.g. qwen3.6-27b-mtp for an llm-type slot.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdashboard-v3Dashboard v3 React rewritev0.3v0.3 scope

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions