use dialoguer::{Select, Input, theme::ColorfulTheme}; use reqwest::Client; pub async fn select_model(ollama_url: &str, client: &Client) -> Result { // 1. Hae tagit let mut models = vec![]; println!(" Haetaan asennettuja malleja osoitteesta {}...", ollama_url); if let Ok(resp) = client.get(&format!("{}/api/tags", ollama_url)).send().await { if resp.status().is_success() { if let Ok(json) = resp.json::().await { if let Some(arr) = json.get("models").and_then(|v| v.as_array()) { for m in arr { if let Some(name) = m.get("name").and_then(|v| v.as_str()) { models.push(name.to_string()); } } } } } } let download_opt = "[➕ Lataa uusi malli internetistä]"; let mut options = vec![download_opt.to_string()]; options.extend(models); // 2. Kysy käyttäjältä Selectillä let theme = ColorfulTheme::default(); let selection = Select::with_theme(&theme) .with_prompt("Valitse Ollama-malli Kipinä-verkkoa varten:") .default(if options.len() > 1 { 1 } else { 0 }) .items(&options) .interact() .map_err(|e| format!("TUI virhe: {}", e))?; let selected = &options[selection]; // 3. Jos käyttäjä haluaa uuden, kysy nimeä if selected == download_opt { let new_model: String = Input::with_theme(&theme) .with_prompt("Syötä ladattavan mallin nimi (esim. llama3 tai qwen2.5-coder:3b)") .interact_text() .map_err(|e| format!("TUI virhe: {}", e))?; let new_model = new_model.trim().to_string(); if new_model.is_empty() { return Err("Mallin nimi ei voi olla tyhjä".to_string()); } println!(" Ladataan malleja taustalla... Tämä voi kestää hetken ({})", new_model); // Odotetaan että pull on valmis let pull_body = serde_json::json!({ "name": &new_model }); let resp = client.post(&format!("{}/api/pull", ollama_url)) .json(&pull_body) .send() .await .map_err(|e| format!("Pull req virhe: {}", e))?; if resp.status().is_success() { println!(" ✓ Malli {} ladattu onnistuneesti!", new_model); return Ok(new_model); } else { return Err(format!("Ollama pull epäonnistui: {}", resp.status())); } } Ok(selected.clone()) }