1use std::path::Path;
2use std::str::FromStr;
3use ureq::{Agent, AgentBuilder};
4use chrono::Local;
5use reqwest::header::AUTHORIZATION;
6use reqwest::{
7 header::{HeaderMap, HeaderValue},
8 Url,
9};
10
11use crate::converse::Conversation;
12use crate::types::{ChatMessage, CompletionRequest, CompletionResponse, Role, ServerResponse};
13
14#[derive(Debug, Clone)]
16pub struct ChatGPT {
17 client: ureq::Agent,
18 token: String,
19}
20
21impl ChatGPT {
22 pub fn new<S: Into<String>>(api_key: S) -> crate::Result<Self> {
24 let api_key = api_key.into();
25 let token = format!("Bearer {api_key}");
26 let client = AgentBuilder::new().build();
27 Ok(Self { client, token})
28 }
29
30 pub fn new_conversation(&self) -> Conversation {
34 self.new_conversation_directed(format!("You are ChatGPT, an AI model developed by OpenAI. Answer as concisely as possible. Today is: {0}", Local::now().format("%d/%m/%Y %H:%M")))
35 }
36
37 pub fn new_conversation_directed<S: Into<String>>(&self, direction_message: S) -> Conversation {
41 Conversation::new(self.clone(), direction_message.into())
42 }
43
44 pub fn send_history(
49 &self,
50 history: &Vec<ChatMessage>,
51 ) -> String {
52 let response = self
53 .client
54 .post("https://api.openai.com/v1/chat/completions")
55 .set("Authorization", &self.token)
56 .send_json(ureq::json!({
57 "model": "gpt-3.5-turbo",
58 "rust": true,
59 "messages": history
60 }))
61 .unwrap()
62 .into_string();
63 response.unwrap_or_default()
64 }
65
66 pub fn send_message<S: Into<String>>(
68 &self,
69 message: S,
70 ) -> Result<CompletionResponse, ureq::Error> {
71 let response: CompletionResponse = self
72 .client
73 .post("https://api.openai.com/v1/chat/completions")
74 .set("Authorization", &self.token)
75 .send_json(ureq::json!({
76 "model": "gpt-3.5-turbo",
77 "messages": &vec![ChatMessage {
78 role: Role::User,
79 content: message.into(),
80 }],
81 }))
82 .unwrap()
83 .into_json()?;
84 Ok(response)
85 }
86}