diff --git a/src/backend/src/lib.rs b/src/backend/src/lib.rs index 6c66862..14e50fe 100644 --- a/src/backend/src/lib.rs +++ b/src/backend/src/lib.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use tauri::menu::{Menu, MenuItem}; use tauri::tray::{TrayIconBuilder, TrayIconEvent}; -use tauri::{Emitter, Manager}; +use tauri::Manager; use std::sync::atomic::AtomicUsize; @@ -96,18 +96,28 @@ if let Some(p) = config.get("database").and_then(|d| d.get("path")).and_then(|p| p.as_str()) { let mut candidate = PathBuf::from(p); if candidate.is_relative() { - if let Ok(exe_path) = env::current_exe() { - if let Some(exe_dir) = exe_path.parent() { - let mut pr = exe_dir.to_path_buf(); - for _ in 0..4 { - if pr.join("config.json").exists() { candidate = pr.join(p); break; } - if !pr.pop() { break; } + if cfg!(debug_assertions) { + if let Ok(exe_path) = env::current_exe() { + if let Some(exe_dir) = exe_path.parent() { + let mut pr = exe_dir.to_path_buf(); + for _ in 0..4 { + if pr.join("config.json").exists() { candidate = pr.join(p); break; } + if !pr.pop() { break; } + } } } + } else { + let mut p_base = app_handle.path().app_data_dir().expect("App data dir not found"); + p_base.push("data"); + let _ = std::fs::create_dir_all(&p_base); + p_base.push("vector.db"); + candidate = p_base; } } return candidate.to_string_lossy().to_string(); } + + // Default fallback if cfg!(debug_assertions) { "data/vector.db".to_string() } else { let mut p = app_handle.path().app_data_dir().expect("App data dir not found"); p.push("data"); @@ -118,17 +128,34 @@ } fn resolve_extension_path(app_handle: &tauri::AppHandle) -> String { + let mut candidates = vec![]; + + if !cfg!(debug_assertions) { + if let Ok(res_dir) = app_handle.path().resource_dir() { + candidates.push(res_dir.join("vec0.dll")); + // Also look in resources root in case it's placed there by bundle.resources + candidates.push(res_dir.join("bin").join("vec0.dll")); + } + } + let exe_dir = env::current_exe().map(|p| p.parent().unwrap().to_path_buf()).unwrap_or_else(|_| env::current_dir().unwrap()); - let mut candidates = vec![ - exe_dir.join("vec0.dll"), - exe_dir.join("../node_modules/sqlite-vec-windows-x64/vec0.dll"), - exe_dir.join("../../node_modules/sqlite-vec-windows-x64/vec0.dll"), - exe_dir.join("../../../node_modules/sqlite-vec-windows-x64/vec0.dll"), - exe_dir.join("../../../../node_modules/sqlite-vec-windows-x64/vec0.dll"), - PathBuf::from("node_modules/sqlite-vec-windows-x64/vec0.dll"), - ]; - if let Ok(res_dir) = app_handle.path().resource_dir() { candidates.insert(0, res_dir.join("vec0.dll")); } - for cand in candidates { if cand.exists() { return cand.to_str().unwrap().to_string(); } } + candidates.push(exe_dir.join("vec0.dll")); + candidates.push(exe_dir.join("../node_modules/sqlite-vec-windows-x64/vec0.dll")); + candidates.push(exe_dir.join("../../node_modules/sqlite-vec-windows-x64/vec0.dll")); + candidates.push(exe_dir.join("../../../bin/vec0.dll")); + + for cand in &candidates { + if cand.exists() { + if let Ok(canon) = cand.canonicalize() { + let s = canon.to_string_lossy().to_string(); + if s.starts_with(r"\\?\") { + return s[4..].to_string(); + } + return s; + } + return cand.to_string_lossy().to_string(); + } + } "vec0.dll".to_string() } @@ -136,27 +163,39 @@ let model_path = if let Ok(p) = env::var("LLAMA_CPP_MODEL_PATH") { PathBuf::from(p) } else if let Some(p) = config.get("model").and_then(|m| m.get("path")).and_then(|p| p.as_str()) { let mut candidate = PathBuf::from(p); if candidate.is_relative() { - if let Ok(exe_path) = env::current_exe() { - if let Some(exe_dir) = exe_path.parent() { - let mut pr = exe_dir.to_path_buf(); - for _ in 0..4 { - if pr.join("config.json").exists() { candidate = pr.join(p); break; } - if !pr.pop() { break; } + if cfg!(debug_assertions) { + if let Ok(exe_path) = env::current_exe() { + if let Some(exe_dir) = exe_path.parent() { + let mut pr = exe_dir.to_path_buf(); + for _ in 0..4 { + if pr.join("config.json").exists() { candidate = pr.join(p); break; } + if !pr.pop() { break; } + } } } + } else { + if let Ok(res_dir) = app_handle.path().resource_dir() { + candidate = res_dir.join(p); + } } } candidate } else { let mut found = None; - if let Ok(exe_path) = env::current_exe() { - if let Some(exe_dir) = exe_path.parent() { - let mut pr = exe_dir.to_path_buf(); - for _ in 0..4 { - if pr.join("models").exists() { found = Some(pr.join("models").join("embeddinggemma-300m-q4_0.gguf")); break; } - if !pr.pop() { break; } + if cfg!(debug_assertions) { + if let Ok(exe_path) = env::current_exe() { + if let Some(exe_dir) = exe_path.parent() { + let mut pr = exe_dir.to_path_buf(); + for _ in 0..4 { + if pr.join("models").exists() { found = Some(pr.join("models").join("embeddinggemma-300m-q4_0.gguf")); break; } + if !pr.pop() { break; } + } } } + } else { + if let Ok(res_dir) = app_handle.path().resource_dir() { + found = Some(res_dir.join("models").join("embeddinggemma-300m-q4_0.gguf")); + } } found.unwrap_or_else(|| PathBuf::from("models/embeddinggemma-300m-q4_0.gguf")) }; @@ -166,19 +205,45 @@ if p.ends_with(format!("src{}backend", std::path::MAIN_SEPARATOR)) { p.pop(); p.pop(); } p.join("bin").join("llama-server-x86_64-pc-windows-msvc.exe") } else { - app_handle.path().resource_dir().unwrap().join("_up_").join("_up_").join("bin").join("llama-server-x86_64-pc-windows-msvc.exe") + // In Tauri 2, sidecar is managed via tauri-plugin-shell-sidecar. + // But if you're spawning manually, you need the absolute path in Resources. + let res_dir = app_handle.path().resource_dir().expect("Failed to get resource dir"); + // Binaries are typically in resources/bin or root resources + let candidate_a = res_dir.join("bin").join("llama-server-x86_64-pc-windows-msvc.exe"); + let candidate_b = res_dir.join("llama-server-x86_64-pc-windows-msvc.exe"); + if candidate_a.exists() { candidate_a } else { candidate_b } }; let mut cmd = std::process::Command::new(&sidecar_exe); - cmd.args(&["--model", &model_path.to_string_lossy(), "--port", "8080", "--embedding", "--host", "127.0.0.1"]); + cmd.args(&["--model", &model_path.to_string_lossy(), "--port", "8080", "--embedding", "--host", "127.0.0.1", "-c", "8192", "-b", "8192", "-ub", "8192", "--parallel", "1"]); + + // Add bin dir to PATH so DLLs in the same folder are found if let Some(bin_dir) = sidecar_exe.parent() { let path = env::var("PATH").unwrap_or_default(); cmd.env("PATH", format!("{};{}", bin_dir.display(), path)); cmd.current_dir(bin_dir); } + + // Also check resource_dir for DLLs + if let Ok(res_dir) = app_handle.path().resource_dir() { + if let Some(old_path) = cmd.get_envs().find(|(k, _)| k == "PATH").and_then(|(_, v)| v) { + cmd.env("PATH", format!("{};{}", res_dir.display(), old_path.to_string_lossy())); + } + } + + println!("DEBUG: Spawning llama-server: {:?}", cmd); match cmd.spawn() { - Ok(child) => { let pid = child.id(); println!("llama-server started (PID: {})", pid); std::thread::spawn(move || { let _ = child.wait_with_output(); }); } - Err(e) => eprintln!("Failed to spawn llama-server: {}", e), + Ok(child) => { + let pid = child.id(); + println!("llama-server started (PID: {})", pid); + std::thread::spawn(move || { + match child.wait_with_output() { + Ok(out) => println!("llama-server exited (OK): {:?}", out.status), + Err(e) => eprintln!("llama-server error during wait: {}", e), + } + }); + } + Err(e) => eprintln!("CRITICAL: Failed to spawn llama-server: {}. Exe path: {:?}", e, sidecar_exe), } } @@ -203,7 +268,7 @@ tauri::async_runtime::block_on(async move { let db_path = resolve_db_path(&app_handle, &config); let ext_path = resolve_extension_path(&app_handle); - let vec_dim = env::var("VEC_DIM").unwrap_or_else(|_| "384".to_string()).parse::().unwrap_or(384); + let vec_dim = env::var("VEC_DIM").unwrap_or_else(|_| "768".to_string()).parse::().unwrap_or(768); let conn = db::init_db(&db_path, &ext_path, vec_dim).await.expect("Failed to init db"); let state = Arc::new(AppState { diff --git a/src/backend/tauri.conf.json b/src/backend/tauri.conf.json index b65e60e..91a2aaa 100644 --- a/src/backend/tauri.conf.json +++ b/src/backend/tauri.conf.json @@ -27,7 +27,7 @@ "bundle": { "active": true, "targets": "all", - "externalBin": ["../../bin/llama-server"], + "externalBin": ["../../bin/llama-server-x86_64-pc-windows-msvc"], "resources": ["../../resources/*", "../../bin/*.dll"], "icon": [ "../../resources/icons/32x32.png",