Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.
transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
-> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
as immutable audit trail). Includes architecture-map references
to magnotia_core::*, magnotia_storage::*, etc. now pointing at
lumotia_*; dev-setup.md tracing output examples (lumotia_startup
target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
("lumotia_task_sync"); magnotia_locale i18n localStorage key
renamed + migration shim added; CSS keyframe names
magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
to "lumotia era" earlier — restored).
Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
legacy detection strings in legacy_and_target_paths() so the
migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
— migration call sites reference the legacy magnotia keys
deliberately.
- docs/handovers/ — historical audit trail.
cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
9.9 KiB
name, type, slice, last_verified
| name | type | slice | last_verified |
|---|---|---|---|
| Model registry and runtime | architecture-map-page | 02-tauri-runtime | 2026/05/09 |
commands::models
Where you are: Architecture map → Tauri runtime → Commands → Models
Plain English summary. Owns the Whisper and Parakeet model lifecycle: download with progress events, presence checks, list, load (with optional sequential-GPU coordination against the LLM), and the runtime-capabilities snapshot that Settings consumes (accelerators list, active compute device, CPU features, parallel-mode availability). Also owns the silent warm-up pass that pre-allocates the Whisper context window so the user's first transcription is fast. Emits runtime warnings on startup when the CPU lacks AVX2 / FMA or the Vulkan loader is absent.
At a glance
- Path:
src-tauri/src/commands/models.rs. - LOC: 691.
- Tauri commands exposed (13 total):
- Whisper:
download_model(size),check_model(size),list_models(),load_model(size, concurrent),prewarm_default_model_cmd(),check_engine(),get_runtime_capabilities(). - Parakeet:
download_parakeet_model(name),check_parakeet_model(name),list_parakeet_models(),load_parakeet_model(name, concurrent),check_parakeet_engine().
- Whisper:
- Public Rust helpers (used by other command modules):
default_model_id_for_engine,ensure_model_loaded,prewarm_default_model,load_model_from_disk,detect_active_compute_device,emit_runtime_warnings. - Events emitted:
model-download-progress(whisper),parakeet-download-progress,runtime-warning(tagged enum:Avx2Missing,VulkanLoaderMissing, futureCudaFallback). - Depends on:
lumotia_transcription::{model_manager, load_whisper, load_parakeet, LocalEngine, Transcriber},lumotia_core::{model_registry, hardware, constants, types}. - Called from frontend at: Settings → Models page (download, load, status), the dictation page boot path (
prewarm_default_model_cmd), Settings → About (runtime capabilities).
What's in here
Model id mapping
whisper_model_id(size)(src-tauri/src/commands/models.rs:18) — maps legacy size strings ("tiny","base","small","distil-small","medium","distil-large-v3") to canonicalModelIds used bymodel_registry.parakeet_model_id(name)(src-tauri/src/commands/models.rs:32) — maps"ctc-int8"toparakeet-ctc-0.6b-int8.
load_model_from_disk (src-tauri/src/commands/models.rs:77)
Looks up the registry entry, picks the engine path:
Engine::Whisper(gated onfeature = "whisper") callsload_whisper(&model_file). Without the feature, returns a clear error explaining the feature is off.Engine::Parakeetcallsload_parakeet(&dir).Engine::Moonshinereturns "not yet supported".
Returns a Box<dyn Transcriber + Send>.
default_model_id_for_engine (src-tauri/src/commands/models.rs:111)
Returns parakeet-ctc-0.6b-int8 for "parakeet", whisper-base-en for everything else. Used by commands::transcription, commands::live, and prewarm_default_model.
ensure_model_loaded (src-tauri/src/commands/models.rs:118)
The shared model-load gateway used by both whisper and parakeet command paths. Validates the engine matches the model, checks the model is downloaded, and short-circuits if the engine already has the right model loaded. Implements the Phase A.1 sequential-GPU guard (brief item #28): when concurrent == Some(false) and the LLM is loaded, unloads the LLM before loading the transcription engine. The inverse guard lives in commands::llm::load_llm_model. Loads run inside spawn_blocking.
prewarm_default_model (src-tauri/src/commands/models.rs:180)
Loads the default Whisper model (if downloaded and not already loaded) plus runs a 1-second silence pass through transcribe_sync. The silence run pre-allocates the Whisper context window and warms GPU shader caches so the first real user transcription completes in ≤ 1.5× steady-state latency rather than the 4–5 s cold-start path documented in ufal/whisper_streaming issues #96 and #135. All errors are logged, never panic.
prewarm_default_model_cmd (src-tauri/src/commands/models.rs:225)
Tauri command wrapper. ensure_main_window. Triggers the warm-up. The frontend invokes this after the dictation page mounts, so warm-up runs in parallel with the first paint.
Runtime-capabilities reporting
RuntimeCapabilities(src-tauri/src/commands/models.rs:237) — frontend-facing struct. Containsaccelerators: Vec<String>,engines: Vec<EngineRuntimeCapabilities>,active_compute_device,cpu_features,parallel_mode_available.ActiveComputeDevice(:259) —kind,label, optionalreason(set when we fell back from a richer backend).CpuFeaturesInfo(:270) — avx2 / avx512f / fma / sse4_2 / neon plus ahas_ggml_baselineshortcut.EngineRuntimeCapabilitiesandModelRuntimeCapabilitiescarry per-engine and per-model status (downloaded, loaded, language support, default model id).compose_accelerators(:337) — pure helper combining whisper-feature flag + Vulkan-loader-availability + target family. Always starts with"cpu", appends"metal"(macOS) or"vulkan"(other) only when whisper is compiled in AND the loader resolves. Replaces the old hard-coded["cpu", "vulkan"](RB-07).detect_active_compute_device(:369) — returns theActiveComputeDevicesnapshot. macOS gets"metal"(via MoltenVK) or a CPU-fallback message; everything else gets"vulkan"or a CPU-fallback message naming the missing loader package.emit_runtime_warnings(:428) — called fromlib.rs::runsetup. Emitsruntime-warningevents for theAvx2MissingandVulkanLoaderMissingcases. The frontend renders a one-line banner.get_runtime_capabilities(:454) — assembles and returns theRuntimeCapabilitiessnapshot. Called by Settings.
Whisper commands (src-tauri/src/commands/models.rs:515)
download_model(size) -> Result<String, String>— main-window only. Callsmodel_manager::downloadwith a closure that emitsmodel-download-progress.check_model(size) -> Result<bool, String>—model_manager::is_downloaded.list_models() -> Result<Vec<String>, String>— returns human-readable size names of currently-downloaded whisper models.load_model(size, concurrent) -> Result<String, String>— main-window only. Callsensure_model_loaded.check_engine(state) -> Result<bool, String>— returns whether the whisper engine has any model loaded.
Parakeet commands (src-tauri/src/commands/models.rs:576)
Same shape as whisper, prefixed parakeet_ and emitting parakeet-download-progress.
Tests (src-tauri/src/commands/models.rs:631)
Five compose_accelerators permutations cover the RB-07 regression. Confirm:
- Whisper disabled + loader present →
["cpu"]. - Whisper enabled + loader missing →
["cpu"]. - Whisper enabled + loader present + macOS →
["cpu", "metal"]. - Whisper enabled + loader present + Linux/Windows →
["cpu", "vulkan"]. "cpu"is always first (frontend index-0 contract).
Data flow
- Download: frontend invokes
download_model(size)→model_manager::downloadstreams bytes → progress events fire on each chunk → frontend renders progress bar. - Load: frontend invokes
load_model(size, concurrent)→ensure_model_loadedvalidates and unloads LLM ifconcurrent=false→load_model_from_diskruns inspawn_blocking→LocalEngine.load(model, model_id)stashes the model on the engine. - Transcribe: every transcription path calls
ensure_model_loadedfirst. Idempotent when the right model is already loaded. - Runtime warnings: fired once at startup via
lib.rs::runsetup → frontend listens forruntime-warningand shows a banner in Settings.
Watch-outs
- The
concurrentflag is a tri-state.NoneandSome(true)keep the legacy parallel-residency behaviour. OnlySome(false)triggers the unload-the-other-engine guard. Live transcription explicitly passesNone. If you ever ship a 4 GB-VRAM Settings preset that flipsconcurrent=falseby default, also test the live transcription path. parallel_mode_availableis hard-wired tofalseuntil Phase A.4 lands a real GPU VRAM probe (src-tauri/src/commands/models.rs:509). Today's frontend reads this and disables the toggle. Flag for follow-up.prewarm_default_modelonly runs whisper. Parakeet has no warm-up. The Parakeet model is also smaller and loads faster, so the cold-start gap is less obvious. If you swap Lumotia's default to Parakeet, add an equivalent warm-up.- Vulkan loader detection is per-platform (
lumotia_core::hardware::vulkan_loader_available). The CPU-fallbackreasonstrings are user-visible; keep them actionable (the Linux one nameslibvulkan1, the macOS one names the Vulkan SDK runtime). - Whisper feature gating.
--no-default-featuresbuilds compile butload_model_from_diskreturns a runtime error when the user requests a Whisper model.list_modelswill still show whisper models that happened to be downloaded already; consider hiding them when the feature is off if a no-whisper build ever ships to users. - Download progress events fire from a closure inside
model_manager::download. That closure is called from inside an asyncspawn_blocking-equivalent. Thelet _ = app_clone.emit(...)pattern silently drops emit errors; if a window has been closed mid-download the progress events stop landing but the download itself completes.
See also
- Transcription — the consumer of
ensure_model_loaded. - Live transcription — also calls
ensure_model_loaded(withconcurrent=None). - LLM — the inverse sequential-GPU guard lives in
commands::llm::load_llm_model. - App lifecycle —
emit_runtime_warningsis called from setup. - Cargo and features —
feature = "whisper"is what gatesload_model_from_disk.