Skip to main content

nano_agent/context/
chat_history.rs

1use genai::chat::{ChatMessage, ChatRole, MessageContent};
2use serde::Serialize;
3
4/// Error when building chat history from high-level helpers.
5#[derive(Debug, thiserror::Error)]
6pub enum ChatHistoryError {
7    #[error("unknown chat role {0:?} (use \"user\", \"assistant\", or \"system\")")]
8    UnknownRole(String),
9    #[error("serialization failed: {0}")]
10    Serialize(#[from] serde_json::Error),
11}
12
13/// Chat history for the agent.
14pub struct ChatHistory {
15    messages: Vec<ChatMessage>,
16}
17
18impl ChatHistory {
19    /// Create a new chat history.
20    pub fn new() -> Self {
21        Self { messages: vec![] }
22    }
23
24    /// Add a message to the chat history.
25    pub fn add_message(&mut self, role: ChatRole, message: MessageContent) {
26        self.messages.push(ChatMessage {
27            role,
28            content: message,
29            options: None,
30        });
31    }
32
33    /// Serializes `payload` to JSON and stores it as one text turn for `role`.
34    pub fn add_message_schema(
35        &mut self,
36        role: &str,
37        payload: &impl Serialize,
38    ) -> Result<(), ChatHistoryError> {
39        let role = match role.to_ascii_lowercase().as_str() {
40            "user" => ChatRole::User,
41            "assistant" => ChatRole::Assistant,
42            "system" => ChatRole::System,
43            other => return Err(ChatHistoryError::UnknownRole(other.to_string())),
44        };
45        let json = serde_json::to_string(payload)?;
46        self.add_message(role, MessageContent::from_text(json));
47        Ok(())
48    }
49
50    /// Get the chat history as the LLM API request format.
51    pub fn get_history(&self) -> &[ChatMessage] {
52        &self.messages
53    }
54}
55
56impl Default for ChatHistory {
57    fn default() -> Self {
58        Self::new()
59    }
60}