use chat_gpt_lib_rs::client::{ChatGPTError, Message};
use chat_gpt_lib_rs::{ChatGPTClient, ChatInput, Model, Role};
use console::{style, StyledObject};
use dotenvy::dotenv;
use indicatif::{ProgressBar, ProgressStyle};
use std::env;
use std::io::{stdin, stdout, Write};
use std::iter::Skip;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
dotenv().ok();
let api_key = env::var("OPENAI_API_KEY").expect("OPENAI_API_KEY not found in .env");
let use_icons = env::var("USE_ICONS")
.unwrap_or_else(|_| "false".to_string())
.to_lowercase()
.eq("true");
let client = ChatGPTClient::new(&api_key, "https://api.openai.com");
let mut messages = vec![Message {
role: Role::System,
content:
"Be a helpfull pair programmer, who want to show solutions and examples in code blocks"
.to_string(),
}];
let mut args: Skip<env::Args> = env::args().skip(1);
if let Some(first_arg) = args.next() {
let user_message_content = args.fold(first_arg, |acc, arg| acc + " " + &arg);
process_user_input(&client, &mut messages, user_message_content).await?;
}
loop {
let input_prompt: StyledObject<&str> = if use_icons {
style("\u{f0ede} Input: ").green()
} else {
style("Input: ").green()
};
print!("{}", input_prompt);
stdout().flush().unwrap();
let mut user_message_content = String::new();
stdin().read_line(&mut user_message_content).unwrap();
process_user_input(&client, &mut messages, user_message_content).await?;
}
}
async fn process_user_input(
client: &ChatGPTClient,
messages: &mut Vec<Message>,
user_message_content: String,
) -> Result<(), ChatGPTError> {
messages.push(Message {
role: Role::User,
content: user_message_content.trim().to_string(),
});
let input = ChatInput {
model: Model::Gpt_4o,
messages: messages.clone(),
..Default::default()
};
let spinner = ProgressBar::new_spinner();
spinner.set_style(
ProgressStyle::default_spinner()
.tick_chars("⠁⠂⠄⡀⢀⠠⠐⠈ ")
.template("{spinner:.green} Processing...")
.unwrap(),
);
let chat = {
spinner.enable_steady_tick(Duration::from_millis(100));
let result = client.chat(input).await;
spinner.finish_and_clear();
result?
};
let assistant_message = &chat.choices[0].message.content;
let computer_label: StyledObject<&str> = if env::var("USE_ICONS")
.unwrap_or_else(|_| "false".to_string())
.to_lowercase()
.eq("true")
{
style("\u{f12ca} Computer: ").color256(39)
} else {
style("Computer: ").color256(39)
};
let computer_response: StyledObject<String> = style(assistant_message.clone());
println!("{}{}", computer_label, computer_response);
messages.push(Message {
role: Role::Assistant,
content: assistant_message.clone(),
});
Ok(())
}