Skip to content

fix(dash): derive model.type at useModels so Load-now matches slots#353

Merged
thinmintdev merged 1 commit into
mainfrom
fix/models-load-now-type-derivation
May 27, 2026
Merged

fix(dash): derive model.type at useModels so Load-now matches slots#353
thinmintdev merged 1 commit into
mainfrom
fix/models-load-now-type-derivation

Conversation

@thinmintdev
Copy link
Copy Markdown
Contributor

Summary

Clicking Load now on any model in the catalog (whisper-tiny, embed,
chat, rerank, …) currently toasts:

No slot accepts type=? — create one in Slots

even when a compatible slot is running. Reproduces every time on a stock
v0.3 install (live API + local repro).

Root cause

/api/models rows ship capabilities: ['transcription' | 'chat' | 'embed' | …]
and leave type unset — the registry has no type field. Slots carry
the dispatcher vocabulary (llm | embedding | reranking | transcription | tts | image). The join in ui/src/dash/models.jsx:287:

const compatible = slots.filter(s => s.type === model.type);

…compares slot.type against undefined, so the filter is always empty
and the error fires regardless of how many compatible slots are running.

The exact mapping already exists, inlined in ui/src/dash/slot-modals.jsx
as a local normalizeApiModel — but models.jsx doesn't use it.

Fix

  • Extract normalizeApiModel to ui/src/lib/normalizeApiModel.ts
    (typed, with SlotType union + capability/backend derivation).
  • Apply it once inside useModels so every consumer sees type /
    device / size / longName / repo populated. Centralises the
    capability→slot-type mapping in one place — when a new capability
    lands, the join in models.jsx keeps working without touching it.

Kept in step with src/hal0/slots/manager.py:_VALID_SLOT_TYPES.

Test plan

  • `npm run typecheck` clean
  • `npm run build` clean
  • `npx playwright test` → 75 passed, 16 skipped, 0 failed
  • Manual: `curl /api/models` rows confirmed missing `type`; slot
    types confirmed `transcription | llm | embedding | reranking | tts`.

🤖 Generated with Claude Code

…s slots

The registry stores capabilities (chat / embed / rerank / transcription /
tts / vision / tool-calling / coding / image) and leaves `type` unset.
Slots index by the dispatcher vocabulary (llm / embedding / reranking /
transcription / tts / image), so the join `s.type === model.type` in
models.jsx silently produced zero matches for every model — clicking
"Load now" on whisper-tiny (or any other model) toasted "No slot accepts
type=?".

Pull the derivation into ui/src/lib/normalizeApiModel.ts and apply it
once inside `useModels` so every consumer sees a normalized type +
device + size + longName + repo. The same logic was already inlined in
slot-modals.jsx; centralising it keeps the mapping in one place when a
new capability lands.
@thinmintdev thinmintdev merged commit 32a8c4f into main May 27, 2026
4 checks passed
@thinmintdev thinmintdev deleted the fix/models-load-now-type-derivation branch May 27, 2026 21:44
thinmintdev added a commit that referenced this pull request May 28, 2026
…rough + gut installer auth section (#390)

- docs/operate/lemonade.md (new, .md canonical): operator reference for
  the v0.2 Lemonade runtime — what it is, where state lives, the /v1/*
  proxy + dispatcher fallthrough (PRs #248/#277), slot ↔ Lemonade
  model mapping (PRs #281/#282), max_loaded_models = 8 LRU cap (PR
  #283), per-type LRU eviction per ADR-0008 (supersedes nuclear-evict
  ADR-0007), OFFLINE-on-eviction (PR #276), and the three known v0.3
  caveats (Vulkan KV gauge missing, whisper RUNPATH workaround, GPU
  cleanup unload hang).

- docs/dashboard/v3.md (new, .md canonical, new docs/dashboard/ dir):
  page-by-page tour of the v3 React dashboard shipped in
  v0.3.0-alpha.1 (PR #235). Covers the shell + Mock-badge convention,
  /dashboard (system overview after #356), /chat (real surface per
  #309/#314/#315/#351), /slots (sidebar mirror per #357 + #344 UX
  sweep), /models (#313/#319/#353), /mcp (#304/#300), /agents (Peers
  per #299), /memory (graph #297, throughput #308), Settings (no Auth
  tab post-ADR-0012), and the footer journal (Epic #322 — PRs
  #321/#328/#329/#330/#332). Mock-fallback issues linked via the
  dashboard-v3 label, not enumerated.

- installer/README.md: gut ~95 lines of stale auth prose (Caddy,
  Bearer-token mint/use/revoke, first-run OTP claim wizard,
  HAL0_AUTH_ENABLED/HAL0_AUTH_DISABLED, password recovery, basic_auth
  upgrade path, the TLS recipe). Replace with one paragraph pointing
  at docs/operate/auth.mdx for the reverse-proxy recipe and
  docs/agents/identity.md for the X-hal0-Agent identity model. Auth
  was removed in v0.3.0-alpha.1 per ADR-0012; the README hadn't
  caught up.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant