feat(gui): /macros + /scheduler pages + README rewrite
Surfaces voice macros and scheduled tasks in the GUI, so the user doesn't
have to remember voice commands or grep schedule.json by hand.
Tauri commands (crates/jarvis-gui/src/tauri_commands/)
- macros.rs: macros_list, macros_replay, macros_delete, macros_is_recording,
macros_recording_name, macros_start_recording, macros_save_recording,
macros_cancel_recording (8 commands).
- scheduler.rs: scheduler_list, scheduler_remove, scheduler_clear (3 commands).
- Both exposed in main.rs invoke_handler.
GUI pages (frontend/src/routes/)
- macros/index.svelte:
* Lists all macros with name, steps_count, first 5 step previews,
created/last_run timestamps.
* Top: TextInput + "Начать запись" button. While recording shows orange
banner with "Сохранить"/"Отменить" buttons + polls is_recording every 2s.
* Per-card: "Запустить" (with busy state for replay duration), "Удалить".
* confirm() before delete.
- scheduler/index.svelte:
* Lists tasks with name, schedule_human (e.g. "каждые 2 ч"), action body,
ID, timestamps, action_kind badge.
* "Отменить" per task + "Очистить всё (N)" bottom button.
* Auto-polls every 5s (so the list updates as scheduler ticks fire tasks).
Header (frontend/src/components/Header.svelte)
- Two new buttons: "Макросы" → /macros, "Расписание" → /scheduler.
- Beside existing /commands and /settings buttons.
i18n
- ru/en/ua FTL: settings-ai-backends, settings-llm-*, settings-tts-*,
settings-profile, header-macros, header-scheduler.
- Re-applied AI Backends keys for ua.ftl (earlier edit hadn't taken).
README.md (full rewrite)
- Old README was 178 lines mostly explaining LLM-trigger flow and VAD config.
- New README is ~190 lines covering: features (LLM hot-swap, memory, profiles,
vision, scheduler, macros, utilities table), quick start, env vars table,
build steps with vcvars setup, test command, structure tree, voice workflow
diagram, license, roadmap.
- Up to date for 59 packs and all new infra.
Build: cargo build --release -p jarvis-gui green (2m). 55/55 tests pass.
This commit is contained in:
parent
c7ab751e39
commit
c22a24ccd8
11 changed files with 998 additions and 167 deletions
|
|
@ -107,6 +107,21 @@ fn main() {
|
|||
tauri_commands::set_tts_backend,
|
||||
tauri_commands::llm_reset_context,
|
||||
tauri_commands::llm_get_last_reply,
|
||||
|
||||
// Voice macros
|
||||
tauri_commands::macros_list,
|
||||
tauri_commands::macros_replay,
|
||||
tauri_commands::macros_delete,
|
||||
tauri_commands::macros_is_recording,
|
||||
tauri_commands::macros_recording_name,
|
||||
tauri_commands::macros_start_recording,
|
||||
tauri_commands::macros_save_recording,
|
||||
tauri_commands::macros_cancel_recording,
|
||||
|
||||
// Scheduler tasks
|
||||
tauri_commands::scheduler_list,
|
||||
tauri_commands::scheduler_remove,
|
||||
tauri_commands::scheduler_clear,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
|
|
|||
|
|
@ -41,4 +41,12 @@ pub use voices::*;
|
|||
|
||||
// LLM/TTS backend introspection + hot-swap
|
||||
mod backends;
|
||||
pub use backends::*;
|
||||
pub use backends::*;
|
||||
|
||||
// Voice macros
|
||||
mod macros;
|
||||
pub use macros::*;
|
||||
|
||||
// Scheduler tasks
|
||||
mod scheduler;
|
||||
pub use scheduler::*;
|
||||
58
crates/jarvis-gui/src/tauri_commands/macros.rs
Normal file
58
crates/jarvis-gui/src/tauri_commands/macros.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//! Tauri commands for the voice-macros system.
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct MacroInfo {
|
||||
pub name: String,
|
||||
pub steps_count: usize,
|
||||
pub steps: Vec<String>,
|
||||
pub created_at: i64,
|
||||
pub last_run: Option<i64>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_list() -> Vec<MacroInfo> {
|
||||
jarvis_core::macros::list().into_iter().map(|m| MacroInfo {
|
||||
name: m.name,
|
||||
steps_count: m.steps.len(),
|
||||
steps: m.steps,
|
||||
created_at: m.created_at,
|
||||
last_run: m.last_run,
|
||||
}).collect()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_replay(name: String) -> Result<usize, String> {
|
||||
jarvis_core::macros::replay(&name)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_delete(name: String) -> bool {
|
||||
jarvis_core::macros::delete(&name)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_is_recording() -> bool {
|
||||
jarvis_core::macros::is_recording()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_recording_name() -> Option<String> {
|
||||
jarvis_core::macros::recording_name()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_start_recording(name: String) -> Result<(), String> {
|
||||
jarvis_core::macros::start_recording(&name)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_save_recording() -> Result<usize, String> {
|
||||
jarvis_core::macros::save_recording()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn macros_cancel_recording() -> bool {
|
||||
jarvis_core::macros::cancel_recording()
|
||||
}
|
||||
59
crates/jarvis-gui/src/tauri_commands/scheduler.rs
Normal file
59
crates/jarvis-gui/src/tauri_commands/scheduler.rs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//! Tauri commands for the proactive scheduler.
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ScheduledTaskInfo {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub schedule_human: String,
|
||||
pub action_kind: String,
|
||||
pub action_text: Option<String>,
|
||||
pub last_fired: Option<i64>,
|
||||
pub enabled: bool,
|
||||
pub created_at: i64,
|
||||
}
|
||||
|
||||
fn schedule_human(s: &jarvis_core::scheduler::Schedule) -> String {
|
||||
use jarvis_core::scheduler::Schedule;
|
||||
match s {
|
||||
Schedule::Daily { hour, minute } => format!("каждый день в {:02}:{:02}", hour, minute),
|
||||
Schedule::Interval { seconds } => {
|
||||
if *seconds % 3600 == 0 { format!("каждые {} ч", seconds / 3600) }
|
||||
else if *seconds % 60 == 0 { format!("каждые {} мин", seconds / 60) }
|
||||
else { format!("каждые {} сек", seconds) }
|
||||
}
|
||||
Schedule::Once { at } => format!("один раз @ {}", at),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn scheduler_list() -> Vec<ScheduledTaskInfo> {
|
||||
use jarvis_core::scheduler::Action;
|
||||
jarvis_core::scheduler::list().into_iter().map(|t| {
|
||||
let (action_kind, action_text) = match &t.action {
|
||||
Action::Speak { text } => ("speak".to_string(), Some(text.clone())),
|
||||
Action::Lua { script_path } => ("lua".to_string(), Some(script_path.clone())),
|
||||
};
|
||||
ScheduledTaskInfo {
|
||||
id: t.id,
|
||||
name: t.name,
|
||||
schedule_human: schedule_human(&t.schedule),
|
||||
action_kind,
|
||||
action_text,
|
||||
last_fired: t.last_fired,
|
||||
enabled: t.enabled,
|
||||
created_at: t.created_at,
|
||||
}
|
||||
}).collect()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn scheduler_remove(id: String) -> bool {
|
||||
jarvis_core::scheduler::remove(&id)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn scheduler_clear() -> usize {
|
||||
jarvis_core::scheduler::clear()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue