File size: 2,066 Bytes
3d2a871 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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";
#[derive(Deserialize)]
struct ChatChoice {
message: ChatMessage,
}
#[derive(Deserialize)]
struct ChatMessage {
content: String,
}
#[derive(Deserialize)]
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
))
}
}
}
|