feat(m2): LLM chat via Ollama — streaming responses with migration context #3

Open
pyr0ball wants to merge 6 commits from feat/m2-llm-chat into feat/m1-system-presence
Showing only changes of commit 9175b7a247 - Show all commits

View file

@ -1,6 +1,6 @@
use crate::config::{MigrationConfig, NotificationLevel, RobinConfig, SourceOs};
use std::sync::Mutex;
use tauri::State;
use tauri::{Emitter, State};
pub struct AppState {
pub config: Mutex<RobinConfig>,
@ -79,3 +79,50 @@ pub fn panel_opened() {
pub fn panel_closed() {
crate::notify::set_panel_open(false);
}
#[tauri::command]
pub async fn chat(
message: String,
state: State<'_, AppState>,
app_handle: tauri::AppHandle,
) -> Result<(), String> {
let (base_url, model, source_os, distro) = {
let cfg = state.config.lock().map_err(|e| e.to_string())?;
let base_url = cfg.ollama.base_url.clone();
let model = cfg.ollama.model.clone();
let (source_os, distro) = match cfg.migration.as_ref() {
Some(m) => {
let os = match m.source_os {
crate::config::SourceOs::Macos => "macOS",
crate::config::SourceOs::Windows => "Windows",
crate::config::SourceOs::Linux => "Linux",
crate::config::SourceOs::Unknown => "an unknown OS",
};
(os.to_string(), m.distro.clone())
}
None => ("an unknown OS".to_string(), "Linux".to_string()),
};
(base_url, model, source_os, distro)
};
let system_prompt = crate::llm::build_system_prompt(&source_os, &distro);
let messages = vec![
crate::llm::ChatMessage {
role: "system".into(),
content: system_prompt,
},
crate::llm::ChatMessage {
role: "user".into(),
content: message,
},
];
tauri::async_runtime::spawn(async move {
if let Err(e) = crate::llm::chat_stream(&base_url, &model, messages, &app_handle).await {
log::error!("chat stream error: {e}");
let _ = app_handle.emit("robin:chat-error", e.to_string());
}
});
Ok(())
}