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};