use crate::{api, config::*, models::*, utils};
use reqwest::Client;
use std::fs::File;
use std::io::Write;
pub struct Gemini {
client: Client,
env_vars: EnvVars,
access_token: String,
}
#[async_trait::async_trait]
pub trait Think {
async fn new() -> Result<Self, Box<dyn std::error::Error>>
where
Self: Sized;
async fn think(&self, prompt: &str) -> Result<String, Box<dyn std::error::Error>>;
}
#[async_trait::async_trait]
impl Think for Gemini {
async fn new() -> Result<Self, Box<dyn std::error::Error>> {
let env_vars = load_env_vars()?;
let access_token = get_access_token().await?;
let client = Client::new();
Ok(Self {
client,
env_vars,
access_token,
})
}
async fn think(&self, prompt: &str) -> Result<String, Box<dyn std::error::Error>> {
let mut request = utils::create_request();
request.contents[0].parts[0].text = prompt.to_string();
let request_json_content = serde_json::to_string_pretty(&request)?;
let mut file = File::create("request.json")?;
file.write_all(request_json_content.as_bytes())?;
let api_url = build_api_url(&self.env_vars);
let response = api::make_api_request(
&self.client,
&api_url,
&self.access_token,
&request_json_content,
)
.await?;
if response.status().is_success() {
let response_body = response.text().await?;
let responses: Vec<StreamResponse> = serde_json::from_str(&response_body)?;
let final_text = api::process_response_chunks(responses);
api::parse_final_response(&final_text)
} else {
let error_text = response.text().await?;
Err(format!("Error Response: {}", error_text).into())
}
}
}