Compare commits

..

No commits in common. "85bc4265cf0639c11cc354f574775e4b81942b7c" and "bab5cdaf2e03d155105d79abb5b54998bd29187c" have entirely different histories.

4 changed files with 9 additions and 82 deletions

View File

@ -5,7 +5,7 @@ use std::process::exit;
use reqwest::{header::{HeaderMap, HeaderValue}, Client}; use reqwest::{header::{HeaderMap, HeaderValue}, Client};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{config::Config, history::HistoryObject, session::Session}; use crate::{config::Config, session::Session};
use crate::{WARN, RED, RESET}; use crate::{WARN, RED, RESET};
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
@ -14,15 +14,6 @@ pub struct ChatMessagePayload {
pub content: String, pub content: String,
} }
impl ChatMessagePayload {
pub fn empty(role: String) -> Self {
Self {
role,
content: String::new()
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChatPayload { pub struct ChatPayload {
pub model: String, pub model: String,
@ -123,8 +114,6 @@ pub async fn get_res<'a>(cli: &Client, query: String, vqd: String, config: &Conf
}; };
let payload = serde_json::to_string(&payload).unwrap(); let payload = serde_json::to_string(&payload).unwrap();
println!("{}", init_msg.display_as_history());
let req = cli.post("https://duckduckgo.com/duckchat/v1/chat") let req = cli.post("https://duckduckgo.com/duckchat/v1/chat")
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0") .header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:124.0) Gecko/20100101 Firefox/124.0")
@ -146,7 +135,6 @@ pub async fn get_res<'a>(cli: &Client, query: String, vqd: String, config: &Conf
} }
let mut error = None; let mut error = None;
println!("{}", ChatMessagePayload::empty("assistant".into()).display_as_history());
while let Some(chunk) = res.chunk().await.unwrap() { while let Some(chunk) = res.chunk().await.unwrap() {
if let Ok(obj) = serde_json::from_slice::<ErrChatChunk>(&chunk) { if let Ok(obj) = serde_json::from_slice::<ErrChatChunk>(&chunk) {
@ -167,10 +155,9 @@ pub async fn get_res<'a>(cli: &Client, query: String, vqd: String, config: &Conf
} }
} }
} }
println!("\n");
if let Some(err) = error { if let Some(err) = error {
eprintln!("Error while writing to session: {err:#?}"); eprintln!("Error while writing to session: {err:#?}");
eprintln!("Session may be broken."); eprintln!("Session may be broken.");
} }
println!("\n");
} }

View File

@ -1,27 +0,0 @@
use crate::api::ChatMessagePayload;
use crate::{RESET, GREEN, GRAY, BLUE};
pub trait HistoryObject {
fn display_as_history(&self) -> String;
}
impl HistoryObject for ChatMessagePayload {
fn display_as_history(&self) -> String {
let user = &self.role;
let msg = &self.content;
let role_color = {
if user == "user" { GREEN }
else if user == "assistant" { BLUE }
else { GRAY }
};
let short_user = {
if user == "user" { "you" }
else if user == "assistant" { "ai" }
else { user }
}.to_string();
format!("{role_color}{short_user}{RESET}\t: {msg}{RESET}")
}
}

View File

@ -12,7 +12,6 @@ use crate::api::{get_res, get_vqd, simulate_browser_reqs};
mod config; mod config;
mod api; mod api;
mod session; mod session;
mod history;
pub const GREEN: &str = "\x1b[1;32m"; pub const GREEN: &str = "\x1b[1;32m";
pub const RED: &str = "\x1b[1;31m"; pub const RED: &str = "\x1b[1;31m";
@ -43,13 +42,6 @@ async fn main() {
let args = Args::parse(); let args = Args::parse();
let query = args.query.join(" ").trim().to_string(); let query = args.query.join(" ").trim().to_string();
{
let session = Session::create_or_restore("");
if session.is_restored() {
session.print_history();
}
}
if query.len() == 0 { if query.len() == 0 {
exit(0); exit(0);
} }
@ -65,6 +57,8 @@ async fn main() {
config.check_tos(); config.check_tos();
println!("{GREEN}Contacting DuckDuckGo chat AI...{RESET}");
let cli = Client::new(); let cli = Client::new();
simulate_browser_reqs(&cli).await.unwrap(); simulate_browser_reqs(&cli).await.unwrap();
@ -73,6 +67,8 @@ async fn main() {
None => get_vqd(&cli).await.unwrap() None => get_vqd(&cli).await.unwrap()
}; };
println!("{vqd:?}");
get_res(&cli, query, vqd, &config).await; get_res(&cli, query, vqd, &config).await;
} }

View File

@ -7,18 +7,13 @@ use chrono::{DateTime, Local};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::api::{ChatChunk, ChatMessagePayload}; use crate::api::{ChatChunk, ChatMessagePayload};
use crate::{GRAY, RESET};
use crate::history::HistoryObject;
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Session { pub struct Session {
session_id: String, session_id: String,
ttl: DateTime<Local>, ttl: DateTime<Local>,
messages: Vec<ChatMessagePayload>, messages: Vec<ChatMessagePayload>,
vqd: String, vqd: String
#[serde(skip)]
restored: bool
} }
impl Session { impl Session {
@ -73,7 +68,6 @@ impl Session {
match inner(Self::path_for_id(id)) { match inner(Self::path_for_id(id)) {
Ok(mut session) => { Ok(mut session) => {
session.restored = true;
if session.is_expired() { if session.is_expired() {
session.destroy().expect("Couldn't destroy expired session"); session.destroy().expect("Couldn't destroy expired session");
None None
@ -100,16 +94,11 @@ impl Session {
session_id: id.into(), session_id: id.into(),
ttl: Self::get_ttl(), ttl: Self::get_ttl(),
messages: vec![], messages: vec![],
vqd: vqd.into(), vqd: vqd.into()
restored: false
} }
} }
fn save(&self) -> Result<(), Box<dyn std::error::Error>> { fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
if self.messages.len() == 0 {
return Ok(());
}
fs::write(self.path(), serde_json::to_string_pretty(self)?)?; fs::write(self.path(), serde_json::to_string_pretty(self)?)?;
Ok(()) Ok(())
} }
@ -118,24 +107,6 @@ impl Session {
self.ttl < Local::now() self.ttl < Local::now()
} }
pub fn is_restored(&self) -> bool {
self.restored
}
pub fn print_history(&self) {
println!("{GRAY}* start restored conversation *{RESET}");
println!();
for message in self.messages.iter() {
println!("{}", message.display_as_history());
if message.role == "assistant" {
println!("\n");
}
}
println!("{GRAY}* end restored conversation *{RESET}");
}
pub fn destroy(&self) -> Result<(), Box<dyn std::error::Error>> { pub fn destroy(&self) -> Result<(), Box<dyn std::error::Error>> {
Ok(fs::remove_file(self.path())?) Ok(fs::remove_file(self.path())?)
} }
@ -143,7 +114,7 @@ impl Session {
pub fn create_or_restore<T: Into<String>>(vqd: T) -> Self { pub fn create_or_restore<T: Into<String>>(vqd: T) -> Self {
let session_id: String = Self::terminal_session_id(); let session_id: String = Self::terminal_session_id();
match Self::restore_with_id(&session_id) { match Self::restore_with_id(&session_id) {
Some(session) => { session }, Some(session) => session,
None => { None => {
let session = Self::new(&session_id, vqd); let session = Self::new(&session_id, vqd);
session.save().expect("Couldn't save new session"); session.save().expect("Couldn't save new session");