fix(dash): derive model.type at useModels so Load-now matches slots#353
Merged
Conversation
…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
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Clicking Load now on any model in the catalog (whisper-tiny, embed,
chat, rerank, …) currently toasts:
even when a compatible slot is running. Reproduces every time on a stock
v0.3 install (live API + local repro).
Root cause
/api/modelsrows shipcapabilities: ['transcription' | 'chat' | 'embed' | …]and leave
typeunset — the registry has notypefield. Slots carrythe dispatcher vocabulary (
llm | embedding | reranking | transcription | tts | image). The join inui/src/dash/models.jsx:287:…compares
slot.typeagainstundefined, so the filter is always emptyand the error fires regardless of how many compatible slots are running.
The exact mapping already exists, inlined in
ui/src/dash/slot-modals.jsxas a local
normalizeApiModel— butmodels.jsxdoesn't use it.Fix
normalizeApiModeltoui/src/lib/normalizeApiModel.ts(typed, with
SlotTypeunion + capability/backend derivation).useModelsso every consumer seestype/device/size/longName/repopopulated. Centralises thecapability→slot-type mapping in one place — when a new capability
lands, the join in
models.jsxkeeps working without touching it.Kept in step with
src/hal0/slots/manager.py:_VALID_SLOT_TYPES.Test plan
types confirmed `transcription | llm | embedding | reranking | tts`.
🤖 Generated with Claude Code