feat(sidebar B.1 #31): visible LLM status chip with live state
The LLM runtime has been quiet since it shipped in Phase 3 — users had no surface-level signal that cleanup was loaded, warming, or actively generating. Settings has verbose status text internally, but a dictation-flow user never opens Settings during a run. New: a shared $state store drives a small chip in the sidebar that reflects the true LLM state in ≤500 ms of any transition (brief item #31 acceptance). Five states: off → hidden (user has aiTier === "off") warming → model download or first load in flight; amber pulse ready → loaded + idle; green dot generating → cleanup_transcript_text_cmd or extract_tasks_from_transcript_cmd in flight; accent pulse with Sparkles icon error → last operation failed; red dot with AlertTriangle The store exposes three calls: refreshLlmStatus(aiTier) (polls the backend), markGenerating(detail) / markGenerationDone(success). DictationPage wraps its cleanup + extract calls in mark-generating pairs. SettingsPage's LLM load / unload / delete / download paths also refresh the global store so Settings-initiated transitions surface in the sidebar immediately. The chip collapses to a dot-only compact form when the sidebar is collapsed. No backend changes — everything wires onto the existing `get_llm_status` Tauri command. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
import { Check, ChevronRight } from "lucide-svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
import { SUPPORTED_LOCALES, setLocale, currentLocale } from "$lib/i18n";
|
||||
// Aliased because SettingsPage has its own local refreshLlmStatus
|
||||
// that just mutates the page-local llmLoaded bool. The store
|
||||
// version drives the sidebar chip (brief item #31).
|
||||
import { refreshLlmStatus as refreshGlobalLlmStatus } from "$lib/stores/llmStatus.svelte.js";
|
||||
|
||||
const prefs = getPreferences();
|
||||
|
||||
@@ -515,6 +519,7 @@
|
||||
await invoke("download_llm_model", { modelId });
|
||||
llmDownloadingModel = "";
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
llmStatus = "Download complete";
|
||||
} catch (err) {
|
||||
llmDownloadingModel = "";
|
||||
@@ -528,6 +533,7 @@
|
||||
try {
|
||||
await invoke("load_llm_model", { modelId });
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
} catch (err) {
|
||||
llmStatus = typeof err === "string" ? err : "LLM load failed";
|
||||
}
|
||||
@@ -537,6 +543,7 @@
|
||||
try {
|
||||
await invoke("unload_llm_model");
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
llmStatus = "Model unloaded";
|
||||
} catch (err) {
|
||||
llmStatus = typeof err === "string" ? err : "LLM unload failed";
|
||||
@@ -548,6 +555,7 @@
|
||||
try {
|
||||
await invoke("delete_llm_model", { modelId });
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
llmStatus = "Downloaded model removed";
|
||||
} catch (err) {
|
||||
llmStatus = typeof err === "string" ? err : "Delete failed";
|
||||
@@ -574,6 +582,7 @@
|
||||
await unloadLlmModel();
|
||||
} else {
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
}
|
||||
llmStatus = llmModelDownloaded(modelId)
|
||||
? "Selected model changed. Load it to enable AI features."
|
||||
@@ -585,6 +594,7 @@
|
||||
if (openSection === 'ai') {
|
||||
await ensureRecommendedLlmTier();
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -594,6 +604,7 @@
|
||||
systemInfo = await invoke("probe_system").catch(() => null);
|
||||
await ensureRecommendedLlmTier();
|
||||
await refreshLlmStatus();
|
||||
await refreshGlobalLlmStatus(settings.aiTier);
|
||||
const loaded = await invoke("check_engine");
|
||||
engineOk = loaded;
|
||||
engineStatus = loaded ? "Model loaded" : "No model loaded";
|
||||
|
||||
Reference in New Issue
Block a user