use molo::{ChatRequest, Memory, Message, Provider, WindowMemory};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenvy::dotenv().ok();
let base_url =
std::env::var("MOLO_BASE_URL").unwrap_or_else(|_| "https://api.openai.com/v1".to_string());
let api_key = std::env::var("MOLO_API_KEY").unwrap_or_default();
let model = std::env::var("MOLO_MODEL").unwrap_or_else(|_| "gpt-4o-mini".to_string());
let max_tokens: usize = std::env::var("MOLO_MAX_TOKENS")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(200);
let provider = molo::provider::OpenAiProvider::new(base_url, api_key, model);
let mut memory = WindowMemory::new(max_tokens);
let mut recorded = 0usize;
let mut input = String::new();
loop {
input.clear();
println!("user:");
let read = std::io::stdin().read_line(&mut input)?;
if read == 0 {
break; }
let input = input.trim();
if input.is_empty() {
continue;
}
if input == "exit" || input == "quit" {
break;
}
memory.record(Message::user(input)).await?;
recorded += 1;
let context = memory.context().await?;
if context.len() < recorded {
println!(
" [context trimmed: {recorded} recorded → {} returned; the earliest conversation was dropped]",
context.len()
);
} else {
println!(" [context {} messages, within budget]", context.len());
}
let response = provider
.chat(ChatRequest {
messages: context,
tools: vec![],
..Default::default()
})
.await?;
let reply = match response.message {
Message::Assistant { content, .. } => content,
_ => unreachable!("reply must be an Assistant message in tool-free chat"),
};
println!("assistant: {reply}");
memory.record(Message::assistant(reply)).await?;
recorded += 1;
}
Ok(())
}