use crate::traits::MemoryMeta;
use crate::traits::ScoredResult;
pub trait ConsolidationStrategy: Send + Sync {
fn consolidate(
&self,
new: &MemoryMeta,
existing: &[ScoredResult],
) -> Vec<ConsolidationAction>;
}
#[derive(Debug, Clone, PartialEq)]
pub enum ConsolidationAction {
Add,
Update {
target_id: i64,
},
Delete {
target_id: i64,
},
Noop,
#[cfg(feature = "graph-memory")]
Relate {
target_id: i64,
relation: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
struct AlwaysAdd;
impl ConsolidationStrategy for AlwaysAdd {
fn consolidate(&self, _new: &MemoryMeta, _existing: &[ScoredResult]) -> Vec<ConsolidationAction> {
vec![ConsolidationAction::Add]
}
}
struct AlwaysNoop;
impl ConsolidationStrategy for AlwaysNoop {
fn consolidate(&self, _new: &MemoryMeta, _existing: &[ScoredResult]) -> Vec<ConsolidationAction> {
vec![ConsolidationAction::Noop]
}
}
#[test]
fn trait_object_works() {
let strategy: Box<dyn ConsolidationStrategy> = Box::new(AlwaysAdd);
let meta = MemoryMeta {
id: None,
searchable_text: "test".into(),
memory_type: crate::traits::MemoryType::Semantic,
importance: 5,
category: None,
created_at: chrono::Utc::now(),
metadata: Default::default(),
};
let actions = strategy.consolidate(&meta, &[]);
assert_eq!(actions, vec![ConsolidationAction::Add]);
}
#[test]
fn noop_action() {
let strategy: Box<dyn ConsolidationStrategy> = Box::new(AlwaysNoop);
let meta = MemoryMeta {
id: None,
searchable_text: "test".into(),
memory_type: crate::traits::MemoryType::Semantic,
importance: 5,
category: None,
created_at: chrono::Utc::now(),
metadata: Default::default(),
};
let actions = strategy.consolidate(&meta, &[]);
assert_eq!(actions, vec![ConsolidationAction::Noop]);
}
}