use uuid::Uuid;
use chrono::Utc;
use haki_llm::Message;
use haki_config::Config;
#[derive(Debug, Clone)]
pub struct Session {
pub id: String,
pub created_at: String,
pub model: String,
pub history: Vec<Message>,
pub config: Config,
}
impl Session {
pub fn new(config: Config) -> Self {
Self {
id: Uuid::new_v4().to_string(),
created_at: Utc::now().to_rfc3339(),
model: config.model.clone(),
history: Vec::new(),
config,
}
}
pub fn push(&mut self, msg: Message) {
self.history.push(msg);
}
pub fn history(&self) -> &[Message] {
&self.history
}
pub fn last_assistant_message(&self) -> Option<&str> {
self.history
.iter()
.rev()
.find(|m| m.role == haki_llm::Role::Assistant)
.map(|m| m.content.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
use haki_llm::Message;
fn test_config() -> Config {
Config::default()
}
#[test]
fn session_has_unique_id() {
let s1 = Session::new(test_config());
let s2 = Session::new(test_config());
assert_ne!(s1.id, s2.id);
}
#[test]
fn push_and_history() {
let mut s = Session::new(test_config());
s.push(Message::user("hello"));
s.push(Message::assistant("hi"));
assert_eq!(s.history().len(), 2);
}
#[test]
fn last_assistant_message() {
let mut s = Session::new(test_config());
s.push(Message::user("ping"));
s.push(Message::assistant("pong"));
assert_eq!(s.last_assistant_message(), Some("pong"));
}
#[test]
fn last_assistant_message_none_when_empty() {
let s = Session::new(test_config());
assert!(s.last_assistant_message().is_none());
}
}