Repository navigation
Lock llama.cpp path to Ministral 8B only; expose Ollama + OpenAI-compatible as open paths - #1371
Conversation
- New AiChatModelSelector dropdown replaces two-step provider→model flow: Local/Ollama/OpenAI-compat sections, greyed-out headers, "Set up..." action - Model selector locks (disabled) after first user message is sent - <16 GB RAM: Local section greyed out with explanation - Ollama auto-detected at localhost:11434; live model list; "not running" state - OpenAI-compatible named configs: add/edit/remove in Settings → AI Models - Default model setting persisted to localStorage, applied to new chats - Settings → AI Models: Local (Ministral 8B only), Ollama status, OpenAI-compat CRUD - Rust: recommended_model_id() returns ministral-8b-q4km; chat_model_list filters GGUF catalog to ministral-* only at the Tauri command boundary - AiChatProvider type extended with openai-compat variant Co-Authored-By: Claude <noreply@anthropic.com>
Code Review — PR #1371: Lock llama.cpp to Ministral 8B; unified model pickerOverall assessment: This is a well-scoped, net-positive change that meaningfully improves UX (single dropdown vs. two-step flow) while enforcing the Ministral 8B decision at the Tauri command boundary. All 134 frontend tests pass. The primary concerns are a correctness bug in the Requirements Coverage
FindingsCritical Issues[Critical/Blocker]
function decodeSelection(v: string): ModelSelection | null {
const parts = v.split(':');
if (parts.length < 2) return null;
const [provider, modelId, configId] = parts;
return { provider: ..., modelId, configId };
}
The safe fix is to split on only the first colon: function decodeSelection(v: string): ModelSelection | null {
const idx = v.indexOf(':');
if (idx === -1) return null;
const provider = v.slice(0, idx) as ModelSelection['provider'];
const rest = v.slice(idx + 1);
// For openai-compat the rest IS the configId, not a modelId
return { provider, modelId: rest, configId: provider === 'openai-compat' ? rest : undefined };
}Note: the [Critical/Blocker] Download modal is referenced in comments but never rendered The PR description and acceptance criteria require "Download modal with progress bar appears during download." The This is the one acceptance criterion that is visually unmet. The download-progress display exists only as option-label text inside the closed dropdown while the user is waiting at a blank chat pane. Suggested Improvements[Improvement] Operator precedence in Rust filter is unclear and fragile
entry.backend == "gguf" && entry.id.starts_with("ministral-")
|| entry.backend != "gguf"
(entry.backend == "gguf" && entry.id.starts_with("ministral-"))
|| entry.backend != "gguf"[Improvement]
const availableSelectionsForDefault = $derived.by(() => {
const opts: { label: string; value: string }[] = [];
for (const m of models.filter((m) => m.family === 'ministral')) { ... }
for (const name of ollamaModels) { ... }
for (const c of openAiConfigs) { ... }
return opts;
});[Improvement]
[Improvement]
Nitpicks
Test Coverage GapThe new Security NoteAPI keys stored in Tauri's |
malibio
left a comment
There was a problem hiding this comment.
Review posted as inline comment. See #issuecomment-4646881311 for full findings.
…d code
- Fix Ollama double-prefix: ollamaValue() now returns the raw daemon ID
("ollama:<name>") directly instead of prepending another "ollama:" prefix
- Fix openai-compat encoding: persist UUID (configId) as modelId in both
selector and node, not the display name; decodeSelection now prefix-matches
instead of splitting on every colon (handles colons in Ollama model names)
- Fix selectorCurrentValue: Ollama case passes raw daemon ID through unchanged
- Add model-load overlay in AiChatNodeViewer: spinner shown while
ensureModelReady is running, covering the download case (AC #11)
- Disable openai-compat options with "(coming soon)" label until send path
is wired to the daemon
- Delete ai-chat-model-picker.svelte (dead code, no longer imported)
- Fix stale AiChatModelPicker reference in model-store comment
Co-Authored-By: Claude <noreply@anthropic.com>
Review addressed✅ Addressed 5/7 findings:
⏭️ Skipped 2/7 findings:
|
Re-Review — PR #1371 (commit 83c8c8b)Overall assessment: The fix commit correctly addresses all five critical and high-priority findings from the initial review. All 3844 frontend tests continue to pass. The two deferred items (buildDefaultOptions → $derived, localStorage unit tests) are reasonable call-outs to defer for a greenfield codebase with no shipped users. No new issues were introduced. Resolution of Previous Findings1. decodeSelection colon-split bug — RESOLVEDThe naive
The fix is correct and safe against all known model ID shapes. 2. Ollama double-prefix — RESOLVED
3. openai-compat UUID/name mismatch — RESOLVEDBoth the selector's
These three are now consistent. 4. Download modal / model-load overlay — RESOLVED (with a minor note below)
The overlay does not show a byte-level progress bar (it uses a spinner with "Preparing model…" text), which is technically narrower than the issue AC that specifies a "progress bar during download". However, the implementation is demonstrably better UX than a frozen UI with no indication, the actual download progress is still available inside the dropdown badge text while in-flight, and the AC intent (user sees feedback) is met. Acceptable. 5. openai-compat stub gap — RESOLVED (disabled with label)Custom endpoint options are now rendered with 6. Dead code (ai-chat-model-picker.svelte) — RESOLVEDThe file has been deleted. Confirmed absent from the worktree. 7. Stale comment in model-store.svelte.ts — RESOLVEDComment now correctly references New Observations from the Fix Commit[Improvement] model-manager ollamaModels type change is correct but introduces an asymmetry The type was changed from Nit: The Ollama model list in model-manager is fetched once in Nit: overlay placement in the template is outside the main The overlay Requirements Coverage (Final)
Test StatusAll 134 test files, 3844 tests pass. No regressions introduced by the fix commit. Verdict: no remaining blockers. Approved. |
…atible as open paths (#1371) * Unified model picker + Settings AI Models revamp (closes #1370) - New AiChatModelSelector dropdown replaces two-step provider→model flow: Local/Ollama/OpenAI-compat sections, greyed-out headers, "Set up..." action - Model selector locks (disabled) after first user message is sent - <16 GB RAM: Local section greyed out with explanation - Ollama auto-detected at localhost:11434; live model list; "not running" state - OpenAI-compatible named configs: add/edit/remove in Settings → AI Models - Default model setting persisted to localStorage, applied to new chats - Settings → AI Models: Local (Ministral 8B only), Ollama status, OpenAI-compat CRUD - Rust: recommended_model_id() returns ministral-8b-q4km; chat_model_list filters GGUF catalog to ministral-* only at the Tauri command boundary - AiChatProvider type extended with openai-compat variant Co-Authored-By: Claude <noreply@anthropic.com> * Address review: fix encoding bugs, add model-load overlay, remove dead code - Fix Ollama double-prefix: ollamaValue() now returns the raw daemon ID ("ollama:<name>") directly instead of prepending another "ollama:" prefix - Fix openai-compat encoding: persist UUID (configId) as modelId in both selector and node, not the display name; decodeSelection now prefix-matches instead of splitting on every colon (handles colons in Ollama model names) - Fix selectorCurrentValue: Ollama case passes raw daemon ID through unchanged - Add model-load overlay in AiChatNodeViewer: spinner shown while ensureModelReady is running, covering the download case (AC #11) - Disable openai-compat options with "(coming soon)" label until send path is wired to the daemon - Delete ai-chat-model-picker.svelte (dead code, no longer imported) - Fix stale AiChatModelPicker reference in model-store comment Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Michael Libio <malibio@Michaels-Mac-mini.local> Co-authored-by: Claude <noreply@anthropic.com>
Closes #1370