kpn load: Ollama-mallin vaihto lennossa (0.5b → 32b)

- Hub: uusi POST /api/v1/model endpoint, broadcastaa change_model
- Native node: kuuntelee change_model, kutsuu Ollaman pull + vaihtaa mallin
- Frontend: kpn load näyttää 5 mallia, numero vaihtaa Ollaman mallin
- Selain-WASM pysyy 0.5B:nä (kpn load 1)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 07:05:57 +03:00
parent 54a5af96c7
commit 34ef19472a
4 changed files with 95 additions and 19 deletions

View File

@@ -1,8 +1,9 @@
use std::time::Instant;
use std::cell::RefCell;
pub struct LlmEngine {
ollama_url: String,
model: String,
model: RefCell<String>,
client: reqwest::Client,
}
@@ -18,24 +19,29 @@ impl LlmEngine {
.build()
.map_err(|e| format!("HTTP client: {}", e))?;
Ok(LlmEngine { ollama_url, model, client })
Ok(LlmEngine { ollama_url, model: RefCell::new(model), client })
}
pub fn model_name(&self) -> &str {
&self.model
pub fn model_name(&self) -> String {
self.model.borrow().clone()
}
pub fn set_model(&self, new_model: String) {
*self.model.borrow_mut() = new_model;
}
/// Varmistaa että malli on ladattu Ollamaan (ollama pull)
pub async fn ensure_model(&self) -> Result<(), String> {
tracing::info!("Tarkistetaan malli {}...", self.model);
let model = self.model.borrow().clone();
tracing::info!("Tarkistetaan malli {}...", model);
let resp = self.client.post(format!("{}/api/pull", self.ollama_url))
.json(&serde_json::json!({ "name": self.model, "stream": false }))
.json(&serde_json::json!({ "name": model, "stream": false }))
.send()
.await
.map_err(|e| format!("Ollama pull: {}", e))?;
if resp.status().is_success() {
tracing::info!("Malli {} valmis", self.model);
tracing::info!("Malli {} valmis", model);
Ok(())
} else {
Err(format!("Ollama pull epäonnistui: {}", resp.status()))
@@ -44,11 +50,12 @@ impl LlmEngine {
pub async fn generate(&self, prompt: &str, max_tokens: usize) -> Result<GenerateResult, String> {
let system = "You are a coding assistant. Respond with ONLY code. No explanations, no markdown, no comments unless asked.";
let model = self.model.borrow().clone();
let start = Instant::now();
let resp = self.client.post(format!("{}/api/generate", self.ollama_url))
.json(&serde_json::json!({
"model": self.model,
"model": model,
"prompt": prompt,
"system": system,
"stream": false,