| use anyhow::Result; | |
| use serde::{Deserialize, Serialize}; | |
| use serde_json::json; | |
| // Ollama OpenAI-compatible endpoint — granite-code:3b running on RTX 3080 | |
| // Ollama is already installed and running: ollama serve | |
| // Model already pulled: ollama pull granite-code:3b | |
| const OLLAMA_URL: &str = "http://localhost:11434/v1/chat/completions"; | |
| struct ChatChoice { | |
| message: ChatMessage, | |
| } | |
| struct ChatMessage { | |
| content: String, | |
| } | |
| struct ChatResponse { | |
| choices: Vec<ChatChoice>, | |
| } | |
| pub async fn complete_code( | |
| client: &reqwest::Client, | |
| prompt: &str, | |
| model: &str, | |
| ) -> Result<String> { | |
| let body = json!({ | |
| "model": model, | |
| "messages": [ | |
| { | |
| "role": "system", | |
| "content": "You are LEGS — a sovereign code executor running on local Granite GPU. Receive architecture specs and produce complete, working, runnable code. No explanations. No prose. Pure code only." | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt | |
| } | |
| ], | |
| "max_tokens": 2048, | |
| "temperature": 0.1 | |
| }); | |
| let resp = client | |
| .post(OLLAMA_URL) | |
| .json(&body) | |
| .timeout(std::time::Duration::from_secs(120)) | |
| .send() | |
| .await; | |
| match resp { | |
| Ok(r) if r.status().is_success() => { | |
| let parsed = r.json::<ChatResponse>().await?; | |
| Ok(parsed.choices | |
| .first() | |
| .map(|c| c.message.content.clone()) | |
| .unwrap_or_else(|| "GRANITE: empty response".to_string())) | |
| } | |
| Ok(r) => { | |
| let status = r.status(); | |
| let text = r.text().await.unwrap_or_default(); | |
| Ok(format!("GRANITE_ERR {}: {}", status, &text[..text.len().min(200)])) | |
| } | |
| Err(e) => { | |
| Ok(format!( | |
| "GRANITE OFFLINE — is Ollama running?\n ollama serve\n ollama list\nError: {}", | |
| e | |
| )) | |
| } | |
| } | |
| } | |