J.A.R.V.I.S-rust/crates/jarvis-gui/src/tauri_commands/builder.rs

69 lines
2.4 KiB
Rust
Raw Normal View History

fix: TTS hot-swap actually works + GUI max-width + Python builder discoverable ROOT CAUSE ANALYSIS User reported: (a) TTS dropdown doesn't apply, (b) GUI feels stretched, (c) no link to command builder, (d) Python doesn't even start. Issues (a), (b), (c) addressed here. (d) addressed in python repo. === Fix A: TTS hot-swap (was completely broken) === Two distinct bugs: 1. `tts::init_backend()` only read JARVIS_TTS env var, NEVER consulted `Settings.tts_backend` in the DB. So saving "Silero" in the GUI dropdown changed nothing — not even on restart. 2. `BACKEND: OnceCell<...>` couldn't be replaced at runtime, so even if init had picked the right backend, the dropdown was useless mid-session. Fixed: - `tts::BACKEND` is now `Lazy<RwLock<Option<Arc<dyn TtsBackend>>>>`. - `choose_backend_name()` resolves from DB → env → auto-detect. - New `swap_to(name)` replaces the live backend atomically. - IPC: new `IpcAction::SwitchTts { backend }`. jarvis-app reacts to it the same way it reacts to SwitchLlm. - GUI's `set_tts_backend` now persists + hot-swaps GUI's TTS + Svelte page also fires `switchDaemonTts()` over WS so the running daemon installs the new backend. - Removed "Применится при следующем запуске" hint — now applies immediately. RU + EN locale strings updated. === Fix B: GUI max-width === main + #header had no max-width, so on a 1920px monitor the labels sprawled across 1860px of space, which felt stretched. Added max-width: 1280px + margin: 0 auto + box-sizing: border-box. Smaller windows are unaffected. Also added the same cap on .app-container.assist-page so the home screen arc reactor centres properly. === Fix C: Command builder discoverable === The Python fork ships a separate yaml-editing tool at `python/tools/command_builder/` (pywebview GUI). No way to find it from the main Rust GUI. Fixed: - New tauri command `open_command_builder` (crates/jarvis-gui/src/ tauri_commands/builder.rs). Locates the Python fork via $JARVIS_PYTHON_DIR → sibling python/ → C:\Jarvis\python, prefers the project's .venv, spawns `python -m tools.command_builder`. - New blue "Конструктор команд (Python)" button on /settings page near the Save / Back buttons. Tests: 140 rust + 104 python all pass. Release builds of jarvis-app and jarvis-gui both green.
2026-05-24 22:12:04 +03:00
//! Tauri command for launching the Python `command_builder` GUI.
//!
//! The Python fork ships a separate yaml-editing tool at
//! `python/tools/command_builder/` (a pywebview-based GUI). Without a launcher
//! button in the main Tauri GUI the user has no easy way to find it.
//!
//! Resolution order for the python checkout:
//! 1. `JARVIS_PYTHON_DIR` env override
//! 2. Sibling `python/` directory next to this jarvis-rust checkout
//! 3. `C:\Jarvis\python` (the dev box default)
//!
//! We don't ship the Python fork inside the Rust binary — this launcher just
//! tries to spawn it. If Python isn't installed, we open the docs URL instead.
use std::path::{Path, PathBuf};
use std::process::Command;
fn locate_python_dir() -> Option<PathBuf> {
if let Ok(p) = std::env::var("JARVIS_PYTHON_DIR") {
let pp = PathBuf::from(p);
if pp.is_dir() {
return Some(pp);
}
}
if let Ok(exe) = std::env::current_exe() {
let mut dir = exe.parent().map(|p| p.to_path_buf());
for _ in 0..6 {
if let Some(d) = &dir {
let candidate = d.join("python");
if candidate.join("tools").join("command_builder").is_dir() {
return Some(candidate);
}
dir = d.parent().map(|p| p.to_path_buf());
}
}
}
let fallback = PathBuf::from(r"C:\Jarvis\python");
if fallback.join("tools").join("command_builder").is_dir() {
return Some(fallback);
}
None
}
/// Find a python interpreter to run the builder with. Prefers the project's
/// `.venv\Scripts\python.exe` (where all deps are installed), then `python`.
fn python_bin(py_dir: &Path) -> PathBuf {
let venv = py_dir.join(".venv").join("Scripts").join("python.exe");
if venv.is_file() {
venv
} else {
PathBuf::from("python")
}
}
#[tauri::command]
pub fn open_command_builder() -> Result<String, String> {
let py_dir = locate_python_dir()
.ok_or_else(|| "Python fork not found. Set JARVIS_PYTHON_DIR or install at C:\\Jarvis\\python.".to_string())?;
let py = python_bin(&py_dir);
Command::new(&py)
.args(["-m", "tools.command_builder"])
.current_dir(&py_dir)
.spawn()
.map_err(|e| format!("Failed to launch command builder: {} (using {})", e, py.display()))?;
Ok(format!("Launched from {}", py_dir.display()))
}