use crate::provider::{ChatMessage, MessageRole};
use serde::{Deserialize, Serialize};
use std::collections::VecDeque;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct AgentContext {
pub system_prompt: Arc<str>,
pub messages: VecDeque<ChatMessage>,
pub max_messages: usize,
pub token_count: usize,
pub max_tokens: usize,
}
impl AgentContext {
pub fn new(system_prompt: Arc<str>, max_messages: usize, max_tokens: usize) -> Self {
Self {
system_prompt,
messages: VecDeque::new(),
max_messages,
token_count: 0,
max_tokens,
}
}
pub fn add_user_message(&mut self, content: impl Into<String>) {
let msg = ChatMessage::user(content);
self.token_count += estimate_tokens(&msg.content);
self.messages.push_back(msg);
self.trim_if_needed();
}
pub fn add_assistant_message(&mut self, content: impl Into<String>) {
let msg = ChatMessage::assistant(content);
self.token_count += estimate_tokens(&msg.content);
self.messages.push_back(msg);
self.trim_if_needed();
}
pub fn get_messages(&self) -> Vec<ChatMessage> {
let mut msgs = vec![ChatMessage::system(self.system_prompt.as_ref())];
msgs.extend(self.messages.iter().cloned());
msgs
}
fn trim_if_needed(&mut self) {
while self.messages.len() > self.max_messages || self.token_count > self.max_tokens {
if let Some(msg) = self.messages.pop_front() {
self.token_count = self
.token_count
.saturating_sub(estimate_tokens(&msg.content));
} else {
break;
}
}
}
pub fn clear(&mut self) {
self.messages.clear();
self.token_count = 0;
}
pub fn message_count(&self) -> usize {
self.messages.len()
}
}
fn estimate_tokens(text: &str) -> usize {
text.len() / 4
}
impl Default for AgentContext {
fn default() -> Self {
Self::new(Arc::from("You are a helpful assistant."), 100, 4000)
}
}