use std::sync::Arc;
use async_trait::async_trait;
use synaptic_core::{MemoryStore, Message, Store, SynapticError};
pub struct ChatMessageHistory {
store: Arc<dyn Store>,
}
impl ChatMessageHistory {
pub fn new(store: Arc<dyn Store>) -> Self {
Self { store }
}
pub async fn get_summary(&self, session_id: &str) -> Result<Option<String>, SynapticError> {
let item = self.store.get(&["memory", session_id], "summary").await?;
Ok(item.and_then(|i| i.value.as_str().map(String::from)))
}
pub async fn set_summary(&self, session_id: &str, summary: &str) -> Result<(), SynapticError> {
self.store
.put(
&["memory", session_id],
"summary",
serde_json::Value::String(summary.to_string()),
)
.await
}
pub fn store(&self) -> &Arc<dyn Store> {
&self.store
}
}
#[async_trait]
impl MemoryStore for ChatMessageHistory {
async fn append(&self, session_id: &str, message: Message) -> Result<(), SynapticError> {
let mut messages = self.load(session_id).await?;
messages.push(message);
let value = serde_json::to_value(&messages)
.map_err(|e| SynapticError::Memory(format!("failed to serialize messages: {e}")))?;
self.store
.put(&["memory", session_id], "messages", value)
.await
}
async fn load(&self, session_id: &str) -> Result<Vec<Message>, SynapticError> {
let item = self.store.get(&["memory", session_id], "messages").await?;
match item {
Some(item) => {
let messages: Vec<Message> = serde_json::from_value(item.value).map_err(|e| {
SynapticError::Memory(format!("failed to deserialize messages: {e}"))
})?;
Ok(messages)
}
None => Ok(Vec::new()),
}
}
async fn clear(&self, session_id: &str) -> Result<(), SynapticError> {
self.store
.delete(&["memory", session_id], "messages")
.await?;
self.store
.delete(&["memory", session_id], "summary")
.await?;
Ok(())
}
}