cargo_ai/
openai_api_client.rs1use reqwest::ClientBuilder; use serde::{Deserialize, Serialize}; use std::time::Duration; #[derive(Serialize, Debug)]
7pub struct Request {
8 pub model: String, pub messages: Vec<Message>, pub temperature: f64, pub response_format: serde_json::Value,
12}
13
14#[derive(Serialize, Deserialize, Debug)]
15pub struct Message {
16 pub role: String, pub content: String, }
19
20#[derive(Deserialize, Debug)]
21#[allow(dead_code)] pub struct Response {
23 pub id: String, pub object: String, pub created: u64, pub model: String, pub choices: Vec<Choice>, pub usage: Usage, }
30
31#[derive(Deserialize, Debug)]
32#[allow(dead_code)] pub struct Choice {
34 pub message: Message, pub finish_reason: Option<String>, pub index: usize, }
38
39#[derive(Serialize, Deserialize, Debug)]
40pub struct Usage {
41 pub prompt_tokens: u32, pub completion_tokens: u32, pub total_tokens: u32, }
45
46pub async fn send_request(
47 url: &String,
48 model: &String,
49 prompt: &String,
50 timeout_in_sec: u64,
51 token: &String,
52 response_format: serde_json::Value,
53) -> Result<String, Box<dyn std::error::Error>> {
54 let client = ClientBuilder::new()
55 .timeout(Duration::from_secs(timeout_in_sec))
56 .build()?; let temperature = if model.starts_with("gpt-5") {
59 1.0
60 } else {
61 crate::DEFAULT_TEMPERATURE
62 };
63
64 let role = String::from("user");
65
66 let message = Message {
67 role,
68 content: prompt.clone(),
69 };
70
71 let messages = vec![message];
72
73 let request = Request {
76 model: model.clone(),
77 messages,
78 temperature,
79 response_format: response_format.clone(),
80 };
81
82 let http_resp = client
86 .post(url)
87 .header("Authorization", format!("Bearer {}", token))
88 .header("Content-Type", "application/json")
89 .json(&request)
90 .send()
91 .await?;
92
93 let body_bytes = http_resp.bytes().await?;
95 let response: Response = match serde_json::from_slice(&body_bytes) {
99 Ok(resp) => resp,
100 Err(e) => {
101 let raw = String::from_utf8_lossy(&body_bytes);
102 return Err(format!("Failed to parse JSON: {}\nRaw response:\n{}", e, raw).into());
103 }
104 };
105
106 let response_content = response
107 .choices
108 .get(0)
109 .ok_or("No ChatGPT Response Index 0 Choice.")?
110 .message
111 .content
112 .clone();
113
114 Ok(response_content)
115}