feat: Tauri backend commands + wikipedia rewrite + github PR review pack
GUI integration
- crates/jarvis-gui/src/tauri_commands/backends.rs — 5 new Tauri commands:
get_active_backends() -> {tts, llm, llm_model, profile}
set_llm_backend(name) -> swap LLM hot, persists to DB
set_tts_backend(name) -> persist choice (effective on jarvis-app restart)
llm_reset_context() -> clear conversation history
llm_get_last_reply() -> last assistant message or null
- Registered in main.rs invoke_handler. Svelte side can now read active
backend + swap from a settings page / footer without env-var gymnastics.
Wikipedia pack rewritten (resources/commands/wikipedia/)
- Old `wiki/wiki.lua` (104 lines, hand-rolled Groq HTTP + inline SAPI PS) deleted.
- Replacement `wikipedia/summary.lua` (87 lines):
* REST summary endpoint (cleaner than opensearch+summary chain).
* Russian first, English fallback with LLM translation.
* Pure LLM fallback if Wikipedia has no article.
* Uses jarvis.cmd.{ok,error,not_found} + jarvis.llm + jarvis.speak (no
inline PowerShell SAPI). Phrases kept compatible with old pack.
GitHub PR voice review (resources/commands/github_pr/, 3 commands)
- "текущий репо bossiara13/J.A.R.V.I.S-rust" → github.set_repo
Persists repo via jarvis.memory.
- "какие пиары" / "открытые пиары" → github.list_prs
Calls `gh pr list --json number,title,author,createdAt --limit 10`.
Parses count + first 3 titles by regex from JSON.
- "разбери последний пиар" / "что в pr" → github.summarize_pr
`gh pr view N --json title,body,additions,deletions,changedFiles,author`,
sends to LLM with "senior reviewer" system prompt, speaks 3-5 sentence
review focusing on changes, risks, merge-readiness.
- Requires gh CLI installed and `gh auth login` done.
Tests: 52/52 jarvis-core unit tests pass (Wikipedia pack TOML/script auto-checked).
Build: cargo build --release -p jarvis-app -p jarvis-gui green.
This commit is contained in:
parent
385bd5c8ce
commit
b243e67870
11 changed files with 439 additions and 131 deletions
81
crates/jarvis-gui/src/tauri_commands/backends.rs
Normal file
81
crates/jarvis-gui/src/tauri_commands/backends.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
//! Tauri commands for backend introspection + hot-swap. Used by the GUI
|
||||
//! footer to display the active LLM/TTS and let the user change them.
|
||||
//!
|
||||
//! Note: `get_active_backends` doesn't initialise the LLM — if the user
|
||||
//! never spoke to it, `llm_backend` may be "none" until first chat. That's
|
||||
//! the trade-off for avoiding cold-start latency in the GUI.
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use jarvis_core::llm;
|
||||
use jarvis_core::tts;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ActiveBackends {
|
||||
pub tts: String,
|
||||
pub llm: String,
|
||||
pub llm_model: Option<String>,
|
||||
pub profile: String,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn get_active_backends() -> ActiveBackends {
|
||||
let llm_model = llm::current().map(|c| c.model().to_string());
|
||||
ActiveBackends {
|
||||
tts: tts::backend().name().to_string(),
|
||||
llm: llm::current_backend_name().to_string(),
|
||||
llm_model,
|
||||
profile: jarvis_core::profiles::active_name(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Hot-swap the LLM backend. Accepts "groq"/"ollama"/"cloud"/"local"/...
|
||||
/// Returns the new backend name on success, Err with reason on failure.
|
||||
#[tauri::command]
|
||||
pub fn set_llm_backend(name: String) -> Result<String, String> {
|
||||
let backend = llm::parse_backend(&name)
|
||||
.ok_or_else(|| format!("unknown backend: '{}'", name))?;
|
||||
// Ensure global is initialised first (so swap can read DB-persisted choice).
|
||||
if llm::current().is_none() {
|
||||
let _ = llm::init_global();
|
||||
}
|
||||
llm::swap_to(backend)
|
||||
.map(|n| n.to_string())
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Set TTS backend. Persists to settings DB. Effective on next jarvis-app start
|
||||
/// (TTS backend is OnceCell, can't hot-swap mid-process).
|
||||
#[tauri::command]
|
||||
pub fn set_tts_backend(name: String) -> Result<String, String> {
|
||||
let normalized = match name.trim().to_lowercase().as_str() {
|
||||
"" | "auto" => "".to_string(),
|
||||
"sapi" | "piper" | "silero" => name.to_lowercase(),
|
||||
other => return Err(format!("unknown TTS backend: '{}'", other)),
|
||||
};
|
||||
|
||||
if let Some(db) = jarvis_core::DB.get() {
|
||||
let snapshot = {
|
||||
let mut s = db.write();
|
||||
s.tts_backend = normalized.clone();
|
||||
s.clone()
|
||||
};
|
||||
jarvis_core::db::save_settings(&snapshot)
|
||||
.map_err(|e| format!("failed to persist: {}", e))?;
|
||||
Ok(if normalized.is_empty() { "auto".into() } else { normalized })
|
||||
} else {
|
||||
Err("settings DB not initialised".into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Reset conversation context (clears LLM history turns, keeps system prompt).
|
||||
#[tauri::command]
|
||||
pub fn llm_reset_context() {
|
||||
llm::history_clear();
|
||||
}
|
||||
|
||||
/// Return the most recent assistant message text (for "Repeat" button in GUI).
|
||||
#[tauri::command]
|
||||
pub fn llm_get_last_reply() -> Option<String> {
|
||||
llm::history_last_assistant()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue