From 5304adcf644a1b8626add37effcf685decfd3dde Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 08:22:49 +0000 Subject: [PATCH] Extract AI provider logic into helper functions to reduce nesting in register_ai Co-authored-by: Tcode-Motion <188012755+Tcode-Motion@users.noreply.github.com> --- stdlib/src/ai.rs | 228 +++++++++++++++++++++++++++++++---------------- 1 file changed, 149 insertions(+), 79 deletions(-) diff --git a/stdlib/src/ai.rs b/stdlib/src/ai.rs index 6bb8d55c..8004d09d 100644 --- a/stdlib/src/ai.rs +++ b/stdlib/src/ai.rs @@ -26,7 +26,10 @@ impl StdlibRegistry { // Check environment capability for retrieving API keys if !ctx.config.capabilities.contains(&Capability::Environment) { return Err(RuntimeError::new( - RuntimeErrorKind::InvalidOperation("Security policy violation: Environment capability is denied".to_string()), + RuntimeErrorKind::InvalidOperation( + "Security policy violation: Environment capability is denied" + .to_string(), + ), None, None, )); @@ -35,93 +38,27 @@ impl StdlibRegistry { // Also requires Network capability to make HTTP requests if !ctx.config.capabilities.contains(&Capability::Network) { return Err(RuntimeError::new( - RuntimeErrorKind::InvalidOperation("Security policy violation: Network capability is denied".to_string()), + RuntimeErrorKind::InvalidOperation( + "Security policy violation: Network capability is denied" + .to_string(), + ), None, None, )); } match provider.as_str() { - "openai" => { - let key = std::env::var("OPENAI_API_KEY").unwrap_or_default(); - if key.is_empty() { - return Ok(RuntimeValue::Str(format!("[Mock OpenAI Response] Prompt: {}", prompt))); - } - - // Real HTTP call to OpenAI Chat Completion - let body = serde_json::json!({ - "model": "gpt-4o-mini", - "messages": [{"role": "user", "content": prompt}] - }); - - let resp = ureq::post("https://api.openai.com/v1/chat/completions") - .set("Authorization", &format!("Bearer {}", key)) - .set("Content-Type", "application/json") - .send_json(body) - .map_err(|e| RuntimeError::new(RuntimeErrorKind::InvalidOperation(format!("OpenAI request failed: {}", e)), None, None))?; - - let json: serde_json::Value = resp.into_json() - .map_err(|e| RuntimeError::new(RuntimeErrorKind::InvalidOperation(format!("Failed to parse OpenAI JSON response: {}", e)), None, None))?; - - let content = json["choices"][0]["message"]["content"].as_str() - .ok_or_else(|| RuntimeError::new(RuntimeErrorKind::InvalidOperation("OpenAI response content empty".to_string()), None, None))?; - - Ok(RuntimeValue::Str(content.to_string())) - } - "gemini" => { - let key = std::env::var("GEMINI_API_KEY").unwrap_or_default(); - if key.is_empty() { - return Ok(RuntimeValue::Str(format!("[Mock Gemini Response] Prompt: {}", prompt))); - } - - // Real HTTP call to Gemini API - let url = format!("https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={}", key); - let body = serde_json::json!({ - "contents": [{ - "parts": [{"text": prompt}] - }] - }); - - let resp = ureq::post(&url) - .set("Content-Type", "application/json") - .send_json(body) - .map_err(|e| RuntimeError::new(RuntimeErrorKind::InvalidOperation(format!("Gemini request failed: {}", e)), None, None))?; - - let json: serde_json::Value = resp.into_json() - .map_err(|e| RuntimeError::new(RuntimeErrorKind::InvalidOperation(format!("Failed to parse Gemini JSON response: {}", e)), None, None))?; - - let content = json["candidates"][0]["content"]["parts"][0]["text"].as_str() - .ok_or_else(|| RuntimeError::new(RuntimeErrorKind::InvalidOperation("Gemini response content empty".to_string()), None, None))?; - - Ok(RuntimeValue::Str(content.to_string())) - } - "local" => { - // Mock local Llama.cpp inference endpoint check (e.g. running on localhost:8080) - let local_url = "http://127.0.0.1:8080/completion"; - let body = serde_json::json!({ - "prompt": prompt, - "n_predict": 128 - }); - - match ureq::post(local_url).set("Content-Type", "application/json").send_json(body) { - Ok(resp) => { - if let Ok(json) = resp.into_json::() { - if let Some(content) = json["content"].as_str() { - return Ok(RuntimeValue::Str(content.to_string())); - } - } - Ok(RuntimeValue::Str("[Mock Local LLM Response] (local server responded with invalid content)".to_string())) - } - Err(_) => { - Ok(RuntimeValue::Str(format!("[Mock Local LLM Response] Prompt: {}", prompt))) - } - } - } + "openai" => generate_openai(&prompt), + "gemini" => generate_gemini(&prompt), + "local" => generate_local(&prompt), _ => Err(RuntimeError::new( - RuntimeErrorKind::InvalidOperation(format!("Unknown AI provider: {}", provider)), + RuntimeErrorKind::InvalidOperation(format!( + "Unknown AI provider: {}", + provider + )), None, None, - )) + )), } }, }), @@ -138,3 +75,136 @@ impl StdlibRegistry { ); } } + +fn generate_openai(prompt: &str) -> Result { + let key = std::env::var("OPENAI_API_KEY").unwrap_or_default(); + if key.is_empty() { + return Ok(RuntimeValue::Str(format!( + "[Mock OpenAI Response] Prompt: {}", + prompt + ))); + } + + // Real HTTP call to OpenAI Chat Completion + let body = serde_json::json!({ + "model": "gpt-4o-mini", + "messages": [{"role": "user", "content": prompt}] + }); + + let resp = ureq::post("https://api.openai.com/v1/chat/completions") + .set("Authorization", &format!("Bearer {}", key)) + .set("Content-Type", "application/json") + .send_json(body) + .map_err(|e| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation(format!("OpenAI request failed: {}", e)), + None, + None, + ) + })?; + + let json: serde_json::Value = resp.into_json().map_err(|e| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation(format!( + "Failed to parse OpenAI JSON response: {}", + e + )), + None, + None, + ) + })?; + + let content = json["choices"][0]["message"]["content"] + .as_str() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation("OpenAI response content empty".to_string()), + None, + None, + ) + })?; + + Ok(RuntimeValue::Str(content.to_string())) +} + +fn generate_gemini(prompt: &str) -> Result { + let key = std::env::var("GEMINI_API_KEY").unwrap_or_default(); + if key.is_empty() { + return Ok(RuntimeValue::Str(format!( + "[Mock Gemini Response] Prompt: {}", + prompt + ))); + } + + // Real HTTP call to Gemini API + let url = format!("https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key={}", key); + let body = serde_json::json!({ + "contents": [{ + "parts": [{"text": prompt}] + }] + }); + + let resp = ureq::post(&url) + .set("Content-Type", "application/json") + .send_json(body) + .map_err(|e| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation(format!("Gemini request failed: {}", e)), + None, + None, + ) + })?; + + let json: serde_json::Value = resp.into_json().map_err(|e| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation(format!( + "Failed to parse Gemini JSON response: {}", + e + )), + None, + None, + ) + })?; + + let content = json["candidates"][0]["content"]["parts"][0]["text"] + .as_str() + .ok_or_else(|| { + RuntimeError::new( + RuntimeErrorKind::InvalidOperation("Gemini response content empty".to_string()), + None, + None, + ) + })?; + + Ok(RuntimeValue::Str(content.to_string())) +} + +fn generate_local(prompt: &str) -> Result { + // Mock local Llama.cpp inference endpoint check (e.g. running on localhost:8080) + let local_url = "http://127.0.0.1:8080/completion"; + let body = serde_json::json!({ + "prompt": prompt, + "n_predict": 128 + }); + + match ureq::post(local_url) + .set("Content-Type", "application/json") + .send_json(body) + { + Ok(resp) => { + if let Ok(json) = resp.into_json::() { + if let Some(content) = json["content"].as_str() { + return Ok(RuntimeValue::Str(content.to_string())); + } + } + Ok(RuntimeValue::Str( + "[Mock Local LLM Response] (local server responded with invalid content)" + .to_string(), + )) + } + Err(_) => Ok(RuntimeValue::Str(format!( + "[Mock Local LLM Response] Prompt: {}", + prompt + ))), + } +}