diff --git a/src-tauri/src/commands/data_commands.rs b/src-tauri/src/commands/data_commands.rs index f8b4c9f..5610849 100644 --- a/src-tauri/src/commands/data_commands.rs +++ b/src-tauri/src/commands/data_commands.rs @@ -3,11 +3,8 @@ use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; use tauri::Manager; use tauri_plugin_store::StoreExt; - -// ponytail: the data-dir pref store + key are defined in lib.rs; mirror them -// here so this module is self-contained for reads/writes. -const PREFS_STORE: &str = "dm-pal-prefs.json"; -const DATA_DIR_KEY: &str = "dataDir"; +use crate::{DATA_DIR_KEY, PREFS_STORE}; +// PREFS_STORE / DATA_DIR_KEY live in lib.rs (pub) — single source of truth. #[derive(Debug, Serialize)] pub struct DataDirInfo { diff --git a/src-tauri/src/commands/llm_commands.rs b/src-tauri/src/commands/llm_commands.rs index d84ecb0..337babc 100644 --- a/src-tauri/src/commands/llm_commands.rs +++ b/src-tauri/src/commands/llm_commands.rs @@ -3,6 +3,7 @@ use crate::llm::{self, AppState, ChatMessage, ChatResponse, GenerateRequest, Llm use serde_json::json; use tauri::ipc::Channel; use tauri::AppHandle; +use tauri_plugin_store::StoreExt; // ─── Simple (non-streaming) generate ───────────────────────── @@ -95,9 +96,18 @@ pub fn get_llm_config(state: tauri::State<'_, AppState>) -> Result, config: crate::llm::LlmConfig) -> Result<(), String> { - let mut lock = state.config.lock().map_err(|e| e.to_string())?; - *lock = config; +pub fn set_llm_config( + app: AppHandle, + state: tauri::State<'_, AppState>, + config: crate::llm::LlmConfig, +) -> Result<(), String> { + let stored = serde_json::to_value(&config).map_err(|e| e.to_string())?; + *state.config.lock().map_err(|e| e.to_string())? = config; + // Persist so Settings survive restart. Same prefs store as dataDir; + // load_llm_config in lib.rs falls back to defaults if this ever unparses. + let store = app.store(crate::PREFS_STORE).map_err(|e| e.to_string())?; + store.set(crate::CONFIG_KEY, stored); + store.save().map_err(|e| e.to_string())?; Ok(()) } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 01fe0f1..6a5e879 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -12,8 +12,11 @@ use tauri_plugin_store::StoreExt; // ponytail: the data-dir preference lives in a tiny store at the OS default // app_data_dir so it's always discoverable at startup, even before we know the // custom location. Key: `dataDir` (absolute path). Empty/missing → default. -const PREFS_STORE: &str = "dm-pal-prefs.json"; -const DATA_DIR_KEY: &str = "dataDir"; +// The persisted LLM config lives here too (key `llmConfig`) so Settings +// survive restarts. pub: commands modules read/write through crate::. +pub const PREFS_STORE: &str = "dm-pal-prefs.json"; +pub const DATA_DIR_KEY: &str = "dataDir"; +pub const CONFIG_KEY: &str = "llmConfig"; /// Resolve the data dir: the configured one if set and usable, else the /// default `$APPDATA/dm-toolkit`. @@ -34,6 +37,15 @@ fn resolve_data_dir(app: &tauri::AppHandle) -> std::path::PathBuf { default } +/// Load the persisted LLM config (Settings). Falls back to defaults when +/// missing or unparsable — a future config-shape change never bricks startup; +/// the DM just re-enters Settings once. +fn load_llm_config(app: &tauri::AppHandle) -> llm::LlmConfig { + let Ok(store) = app.store(PREFS_STORE) else { return llm::LlmConfig::default() }; + let Some(v) = store.get(CONFIG_KEY) else { return llm::LlmConfig::default() }; + serde_json::from_value(v).unwrap_or_default() +} + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() @@ -48,7 +60,7 @@ pub fn run() { let gen = generations::GenerationStore::open(&data_dir) .expect("open generations db"); app.manage(AppState { - config: Mutex::new(llm::LlmConfig::default()), + config: Mutex::new(load_llm_config(&app.handle())), rag, gen, data_dir,