ceylon_next/memory/
mod.rs

1//! Memory system for storing and retrieving agent conversation history.
2//!
3//! This module provides types and traits for implementing memory storage,
4//! allowing agents to maintain context across multiple conversations.
5//!
6//! # Available Backends
7//!
8//! - [`InMemoryStore`] - Fast, volatile storage for development and testing
9//! - [`SqliteStore`] - Persistent storage using SQLite database
10//! - [`FileStore`] - File-based storage with JSON or MessagePack formats
11//!
12//! # Vector Memory & Semantic Search
13//!
14//! The [`vector`] module provides semantic search capabilities using vector embeddings:
15//!
16//! - **Local Vector Store** - In-memory vector storage with cosine similarity search
17//! - **Embedding Providers** - OpenAI, Ollama, Hugging Face, and custom embedding models
18//! - **Caching Layer** - Efficient embedding caching to reduce API costs
19//! - **Semantic Search** - Find similar memories based on meaning, not just keywords
20//!
21//! Enable vector memory features in `Cargo.toml`:
22//! ```toml
23//! [dependencies]
24//! ceylon = { version = "*", features = ["vector-openai"] }       # For OpenAI embeddings
25//! ceylon = { version = "*", features = ["vector-ollama"] }       # For Ollama embeddings
26//! ceylon = { version = "*", features = ["vector-huggingface"] }  # For Hugging Face embeddings
27//! ceylon = { version = "*", features = ["full-vector"] }         # For all vector features
28//! ```
29//!
30//! See the [`vector`] module documentation for detailed examples.
31//!
32//! # Migration Utilities
33//!
34//! - [`migrate_memory`] - Migrate data between different backends
35//! - [`export_to_json`] / [`import_from_json`] - JSON backup/restore
36//! - [`export_to_msgpack`] / [`import_from_msgpack`] - MessagePack backup/restore
37
38use crate::llm::types::Message;
39use async_trait::async_trait;
40use serde::{Deserialize, Serialize};
41
42// ============================================
43// Core Types
44// ============================================
45
46/// A stored conversation between an agent and user.
47///
48/// Each memory entry represents a complete task execution, including
49/// all messages exchanged between the user and agent.
50///
51/// # Examples
52///
53/// ```rust
54/// use ceylon_next::memory::MemoryEntry;
55/// use ceylon_next::llm::types::Message;
56///
57/// let messages = vec![
58///     Message {
59///         role: "user".to_string(),
60///         content: "Hello!".to_string(),
61///     },
62///     Message {
63///         role: "assistant".to_string(),
64///         content: "Hi there!".to_string(),
65///     },
66/// ];
67///
68/// let entry = MemoryEntry::new(
69///     "agent-123".to_string(),
70///     "task-456".to_string(),
71///     messages,
72/// );
73/// ```
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct MemoryEntry {
76    /// Unique identifier for this memory entry
77    pub id: String,
78    /// ID of the agent that created this memory
79    pub agent_id: String,
80    /// ID of the task this memory is associated with
81    pub task_id: String,
82    /// The conversation messages
83    pub messages: Vec<Message>,
84    /// Unix timestamp when this memory was created
85    pub created_at: u64,
86}
87
88impl MemoryEntry {
89    /// Creates a new memory entry.
90    ///
91    /// # Arguments
92    ///
93    /// * `agent_id` - The ID of the agent that created this memory
94    /// * `task_id` - The ID of the task this memory is associated with
95    /// * `messages` - The conversation messages to store
96    pub fn new(agent_id: String, task_id: String, messages: Vec<Message>) -> Self {
97        Self {
98            id: uuid::Uuid::new_v4().to_string(),
99            agent_id,
100            task_id,
101            messages,
102            created_at: Self::current_timestamp(),
103        }
104    }
105
106    fn current_timestamp() -> u64 {
107        std::time::SystemTime::now()
108            .duration_since(std::time::UNIX_EPOCH)
109            .unwrap()
110            .as_secs()
111    }
112}
113
114// ============================================
115// Memory Trait
116// ============================================
117
118/// Trait for implementing memory storage backends.
119///
120/// The `Memory` trait defines the interface for storing and retrieving
121/// agent conversation history. Implementations can use different storage
122/// backends like in-memory, SQLite, file-based, etc.
123///
124/// # Examples
125///
126/// ```rust,no_run
127/// use ceylon_next::memory::{Memory, MemoryEntry, InMemoryStore};
128/// use std::sync::Arc;
129///
130/// #[tokio::main]
131/// async fn main() {
132///     let memory: Arc<dyn Memory> = Arc::new(InMemoryStore::new());
133///
134///     // Store a conversation
135///     // let entry = MemoryEntry::new(...);
136///     // memory.store(entry).await.unwrap();
137/// }
138/// ```
139#[async_trait]
140pub trait Memory: Send + Sync {
141    /// Stores a conversation in memory.
142    async fn store(&self, entry: MemoryEntry) -> Result<String, String>;
143
144    /// Retrieves a specific conversation by ID.
145    async fn get(&self, id: &str) -> Result<Option<MemoryEntry>, String>;
146
147    /// Retrieves all conversations for an agent.
148    async fn get_agent_history(&self, agent_id: &str) -> Result<Vec<MemoryEntry>, String>;
149
150    /// Retrieves the most recent N conversations for an agent.
151    async fn get_recent(&self, agent_id: &str, limit: usize) -> Result<Vec<MemoryEntry>, String>;
152
153    /// Searches conversations for a query string.
154    async fn search(&self, agent_id: &str, query: &str) -> Result<Vec<MemoryEntry>, String>;
155
156    /// Clears all memory for an agent.
157    async fn clear_agent_memory(&self, agent_id: &str) -> Result<(), String>;
158}
159
160// ============================================
161// Module Declarations
162// ============================================
163
164mod in_memory;
165mod sqlite;
166mod file_store;
167mod migration;
168
169#[cfg(feature = "vector")]
170pub mod vector;
171
172pub mod advanced;
173
174#[cfg(test)]
175mod tests;
176
177// ============================================
178// Public Exports
179// ============================================
180
181pub use in_memory::InMemoryStore;
182pub use sqlite::SqliteStore;
183pub use file_store::{FileStore, StorageFormat};
184pub use migration::{
185    migrate_memory,
186    export_to_json,
187    import_from_json,
188    export_to_msgpack,
189    import_from_msgpack,
190};