pub mod file_backend;
pub mod long_term;
pub mod project;
pub mod session;
pub mod system;
pub mod working;
pub use file_backend::{FileBackend, JsonFileBackend, StorageContainer};
pub use long_term::LongTermMemory;
pub use project::ProjectMemory;
pub use session::SessionMemory;
pub use system::UnifiedMemorySystem;
pub use working::WorkingMemory;
use crate::types::{Layer3Result, MemoryEntry, MemoryQuery, MemoryTier};
use async_trait::async_trait;
use std::collections::HashMap;
#[async_trait]
pub trait MemoryStore: Send + Sync {
fn tier(&self) -> MemoryTier;
async fn store(&self, entry: MemoryEntry) -> Layer3Result<String>;
async fn get(&self, id: &str) -> Layer3Result<Option<MemoryEntry>>;
async fn delete(&self, id: &str) -> Layer3Result<bool>;
async fn query(&self, query: &MemoryQuery) -> Layer3Result<Vec<MemoryEntry>>;
async fn list(&self, limit: Option<usize>) -> Layer3Result<Vec<MemoryEntry>>;
async fn clear(&self) -> Layer3Result<usize>;
async fn count(&self) -> Layer3Result<usize>;
}
#[async_trait]
pub trait MemorySystem: Send + Sync {
async fn store(&self, tier: MemoryTier, content: String) -> Layer3Result<String>;
async fn get(&self, tier: MemoryTier, id: &str) -> Layer3Result<Option<MemoryEntry>>;
async fn query_all(&self, query: &MemoryQuery) -> Layer3Result<Vec<MemoryEntry>>;
async fn query(&self, tier: MemoryTier, query: &MemoryQuery) -> Layer3Result<Vec<MemoryEntry>>;
async fn delete(&self, tier: MemoryTier, id: &str) -> Layer3Result<bool>;
async fn clear(&self, tier: MemoryTier) -> Layer3Result<usize>;
async fn stats(&self) -> Layer3Result<HashMap<MemoryTier, usize>>;
}
pub trait ImportanceScorer: Send + Sync {
fn score(&self, entry: &MemoryEntry) -> f32;
}
pub trait DecayPolicy: Send + Sync {
fn decay(&self, entry: &MemoryEntry, current_time: chrono::DateTime<chrono::Utc>) -> f32;
fn should_evict(&self, entry: &MemoryEntry) -> bool;
}
pub struct TimeBasedDecay {
decay_rate: f32,
min_threshold: f32,
}
impl TimeBasedDecay {
pub fn new(decay_rate: f32, min_threshold: f32) -> Self {
Self {
decay_rate,
min_threshold,
}
}
}
impl Default for TimeBasedDecay {
fn default() -> Self {
Self {
decay_rate: 0.1,
min_threshold: 0.1,
}
}
}
impl DecayPolicy for TimeBasedDecay {
fn decay(&self, entry: &MemoryEntry, current_time: chrono::DateTime<chrono::Utc>) -> f32 {
let days_since_access = (current_time - entry.last_accessed).num_days() as f32;
let decayed = entry.importance * (1.0 - self.decay_rate * days_since_access);
decayed.max(0.0)
}
fn should_evict(&self, entry: &MemoryEntry) -> bool {
entry.importance < self.min_threshold
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_decay_policy_default() {
let decay = TimeBasedDecay::default();
assert_eq!(decay.decay_rate, 0.1);
assert_eq!(decay.min_threshold, 0.1);
}
}