Skip to main content

langchain_rust/schemas/
memory.rs

1use async_trait::async_trait;
2use thiserror::Error;
3
4use super::messages::Message;
5
6/// Errors returned by [`BaseMemory`] implementations (mostly persistent backends).
7#[derive(Error, Debug)]
8pub enum MemoryError {
9    #[error("Memory storage error: {0}")]
10    Storage(String),
11
12    #[error("Memory serialization error: {0}")]
13    Serialization(#[from] serde_json::Error),
14
15    #[error("Memory error: {0}")]
16    Other(String),
17}
18
19#[cfg(feature = "sqlx")]
20impl From<sqlx::Error> for MemoryError {
21    fn from(e: sqlx::Error) -> Self {
22        MemoryError::Storage(e.to_string())
23    }
24}
25
26/// Conversation memory used by chains and agents.
27///
28/// All methods are async and fallible so that memories can be backed by a database
29/// or a remote service (see `SqliteMessageHistory` / `PostgresMessageHistory`).
30#[async_trait]
31pub trait BaseMemory: Send + Sync {
32    async fn messages(&self) -> Result<Vec<Message>, MemoryError>;
33
34    async fn add_user_message(
35        &mut self,
36        message: &(dyn std::fmt::Display + Sync),
37    ) -> Result<(), MemoryError> {
38        self.add_message(Message::new_human_message(message.to_string()))
39            .await
40    }
41
42    async fn add_ai_message(
43        &mut self,
44        message: &(dyn std::fmt::Display + Sync),
45    ) -> Result<(), MemoryError> {
46        self.add_message(Message::new_ai_message(message.to_string()))
47            .await
48    }
49
50    async fn add_message(&mut self, message: Message) -> Result<(), MemoryError>;
51
52    async fn clear(&mut self) -> Result<(), MemoryError>;
53
54    async fn to_string(&self) -> Result<String, MemoryError> {
55        Ok(self
56            .messages()
57            .await?
58            .iter()
59            .map(|msg| format!("{}: {}", msg.message_type.to_string(), msg.content))
60            .collect::<Vec<String>>()
61            .join("\n"))
62    }
63}
64
65impl<M> From<M> for Box<dyn BaseMemory>
66where
67    M: BaseMemory + 'static,
68{
69    fn from(memory: M) -> Self {
70        Box::new(memory)
71    }
72}