Native node: VRAM-tila TUI:ssa (ollama ps)

- fetch_ps(): hakee /api/ps ja palauttaa ModelVramStatus
- ModelVramStatus: size vs size_vram → 100% GPU / osittainen / CPU
- TUI: uusi "VRAM: ✓ qwen3:32b (20.1 GB) — 100% GPU" -rivi
- Taustapäivitys 30s välein
- Tuore linux-x86_64 binääri
This commit is contained in:
2026-04-13 21:06:27 +03:00
parent 5e44b63b0c
commit e09962940a
4 changed files with 97 additions and 3 deletions

View File

@@ -69,6 +69,10 @@ impl LlmEngine {
self.model.borrow().clone()
}
pub fn ollama_url(&self) -> &str {
&self.ollama_url
}
pub fn set_model(&self, new_model: String) {
*self.model.borrow_mut() = new_model;
}
@@ -91,6 +95,32 @@ impl LlmEngine {
}
}
/// Hakee käynnissä olevan mallin VRAM-tilan (ollama ps)
pub async fn fetch_ps(&self) -> Result<Option<ModelVramStatus>, String> {
let resp = self.client.get(format!("{}/api/ps", self.ollama_url))
.send()
.await
.map_err(|e| format!("Ollama ps: {}", e))?;
if !resp.status().is_success() {
return Err(format!("Ollama ps HTTP {}", resp.status()));
}
let body: serde_json::Value = resp.json().await
.map_err(|e| format!("Ollama ps json: {}", e))?;
let models = body["models"].as_array();
if let Some(arr) = models {
if let Some(m) = arr.first() {
let name = m["name"].as_str().unwrap_or("?").to_string();
let size = m["size"].as_u64().unwrap_or(0);
let size_vram = m["size_vram"].as_u64().unwrap_or(0);
return Ok(Some(ModelVramStatus { name, size, size_vram }));
}
}
Ok(None) // ei ladattua mallia
}
/// Hakee kaikki Ollamaan asennetut mallit
pub async fn fetch_models(&self) -> Result<serde_json::Value, String> {
let resp = self.client.get(format!("{}/api/tags", self.ollama_url))
@@ -184,3 +214,32 @@ pub struct GenerateResult {
pub duration_ms: f64,
pub tokens_per_sec: f64,
}
pub struct ModelVramStatus {
pub name: String,
pub size: u64, // kokonaiskoko (tavuina)
pub size_vram: u64, // VRAM:ssa oleva osuus (tavuina)
}
impl ModelVramStatus {
pub fn fully_in_vram(&self) -> bool {
self.size > 0 && self.size_vram >= self.size
}
pub fn vram_percent(&self) -> f64 {
if self.size == 0 { return 0.0; }
(self.size_vram as f64 / self.size as f64) * 100.0
}
pub fn display(&self) -> String {
let size_gb = self.size as f64 / 1_073_741_824.0;
let vram_gb = self.size_vram as f64 / 1_073_741_824.0;
if self.fully_in_vram() {
format!("{} ({:.1} GB) — 100% GPU", self.name, size_gb)
} else if self.size_vram == 0 {
format!("{} ({:.1} GB) — 100% CPU", self.name, size_gb)
} else {
format!("{} ({:.1}/{:.1} GB VRAM, {:.0}% GPU)", self.name, vram_gb, size_gb, self.vram_percent())
}
}
}