Two new Settings → AI knobs that compose cleanly with what already shipped (aiTier, LLM model, translator prompt framing). **B.1 #15 — Named cleanup presets.** LlmPromptPreset enum (Default / Email / Notes / Code) appends a short context hint onto the CLEANUP_PROMPT just before generation. Presets shape tone and structure ("email paragraph", "bulleted meeting notes", "preserve technical terms") without licensing the content-editing the translator-not-editor framing forbids. cleanup_transcript_text_cmd now takes `preset: Option<String>` which runs through the new LlmPromptPreset::parse (normalises aliases like "meeting-notes", collapses unknown values to Default). **A.1 #28 — Sequential-GPU guard.** New LocalEngine::unload drops the backend + model_id so a subsequent load actually reclaims VRAM. load_llm_model, load_model, and load_parakeet_model Tauri commands grow an optional `concurrent: bool` argument. When concurrent is Some(false), loading LLM first unloads whisper+parakeet, and vice versa — prevents VRAM OOM on tight-VRAM setups. Default is the previous parallel behaviour so nothing changes for multi-GB cards. Transcribe-in-progress paths (transcribe_pcm, transcribe_file, live) pass None, so mid-dictation model loads don't accidentally tear down the LLM. Settings UI (AI section): - Cleanup preset segmented button + descriptive copy for each option. - GPU concurrency segmented button with explicit trade-off text ("faster transitions vs fits in tight VRAM"). Frontend wiring: - settings.llmPromptPreset flows from DictationPage's cleanupTranscriptIfEnabled into the Tauri command. - settings.aiGpuConcurrency flows from both DictationPage (auto-load on record) and SettingsPage (manual load/unload buttons) as `concurrent: "parallel" === true` to the load commands. Tests: three new preset cases in crates/ai-formatting/src/llm_client.rs (parse aliases, suffix non-empty for non-default, default suffix empty). All 139 existing lib tests still pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -56,6 +56,23 @@ impl LocalEngine {
|
||||
*id_guard = Some(model_id);
|
||||
}
|
||||
|
||||
/// Drop the loaded model and free its backing resources (GPU VRAM,
|
||||
/// CPU memory, mmap'd GGML tensors). Used by the sequential-GPU
|
||||
/// guard (brief item A.1 #28) so loading the LLM on a tight-VRAM
|
||||
/// system first frees the transcription engine, and vice versa.
|
||||
///
|
||||
/// No-op when nothing is loaded. Thread-safe — the internal Mutex
|
||||
/// serialises against concurrent transcribe_sync calls.
|
||||
pub fn unload(&self) {
|
||||
let mut guard = self.engine.lock().unwrap_or_else(|e| e.into_inner());
|
||||
*guard = None;
|
||||
let mut id_guard = self
|
||||
.loaded_model_id
|
||||
.lock()
|
||||
.unwrap_or_else(|e| e.into_inner());
|
||||
*id_guard = None;
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &EngineName {
|
||||
&self.engine_name
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user