From ef42c950000cca31f18563837150a9d7228ef84d Mon Sep 17 00:00:00 2001 From: Jake Date: Sat, 25 Apr 2026 00:03:38 +0100 Subject: [PATCH] feat(phase9): extract_content_tags_cmd Tauri wrapper Bridges LlmEngine::extract_content_tags to the frontend with the same spawn_blocking + PowerAssertion guard the cleanup_text command uses. Returns a ContentTags object serialised to camelCase JSON. Errors surface as readable strings so the frontend toast shows actionable text on the rare grammar-bypass path. Co-Authored-By: Claude Opus 4.7 (1M context) --- src-tauri/src/commands/llm.rs | 25 ++++++++++++++++++++++++- src-tauri/src/lib.rs | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src-tauri/src/commands/llm.rs b/src-tauri/src/commands/llm.rs index 361f97c..e83183a 100644 --- a/src-tauri/src/commands/llm.rs +++ b/src-tauri/src/commands/llm.rs @@ -6,7 +6,7 @@ use crate::AppState; use kon_ai_formatting::{llm_cleanup_text, LlmPromptPreset}; use kon_core::hardware; use kon_llm::model_manager::{self, model_info}; -use kon_llm::LlmModelId; +use kon_llm::{ContentTags, LlmModelId}; #[derive(Debug, serde::Serialize)] #[serde(rename_all = "camelCase")] @@ -398,3 +398,26 @@ pub async fn cleanup_transcript_text_cmd( .map_err(|e| e.to_string())? .map_err(|e| e.to_string()) } + +/// Phase 9 LLM-powered content tags. On-demand from the History page; +/// never auto-runs. Heavy work (LlmEngine::extract_content_tags is +/// synchronous llama-cpp inference) is wrapped in spawn_blocking so it +/// does not stall the Tauri runtime, with the same App-Nap power +/// assertion the other LLM commands use. +#[tauri::command] +pub async fn extract_content_tags_cmd( + state: State<'_, AppState>, + transcript: String, +) -> Result { + if !state.llm_engine.is_loaded() { + return Err("LLM not loaded. Download an AI model in Settings.".to_string()); + } + let engine = state.llm_engine.clone(); + tokio::task::spawn_blocking(move || { + let _power_guard = PowerAssertion::begin("kon LLM content-tag extraction"); + engine.extract_content_tags(&transcript) + }) + .await + .map_err(|e| e.to_string())? + .map_err(|e| e.to_string()) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index e382ec6..6cd810c 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -373,6 +373,8 @@ pub fn run() { commands::clipboard::copy_to_clipboard, // Filesystem (Phase 9 save-dialog path) commands::fs::write_text_file_cmd, + // LLM content tags (Phase 9) + commands::llm::extract_content_tags_cmd, // Paste (auto-insert at cursor) commands::paste::paste_text, commands::paste::paste_text_replacing,