feat(memory): lucid memory integration with optional backends (#285)

This commit is contained in:
Chummy 2026-02-17 00:31:50 +08:00 committed by GitHub
parent 04bf94443f
commit 53844f7207
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 1089 additions and 137 deletions

74
src/memory/none.rs Normal file
View file

@ -0,0 +1,74 @@
use super::traits::{Memory, MemoryCategory, MemoryEntry};
use async_trait::async_trait;
/// Explicit no-op memory backend.
///
/// This backend is used when `memory.backend = "none"` to disable persistence
/// while keeping the runtime wiring stable.
#[derive(Debug, Default, Clone, Copy)]
pub struct NoneMemory;
impl NoneMemory {
pub fn new() -> Self {
Self
}
}
#[async_trait]
impl Memory for NoneMemory {
fn name(&self) -> &str {
"none"
}
async fn store(
&self,
_key: &str,
_content: &str,
_category: MemoryCategory,
) -> anyhow::Result<()> {
Ok(())
}
async fn recall(&self, _query: &str, _limit: usize) -> anyhow::Result<Vec<MemoryEntry>> {
Ok(Vec::new())
}
async fn get(&self, _key: &str) -> anyhow::Result<Option<MemoryEntry>> {
Ok(None)
}
async fn list(&self, _category: Option<&MemoryCategory>) -> anyhow::Result<Vec<MemoryEntry>> {
Ok(Vec::new())
}
async fn forget(&self, _key: &str) -> anyhow::Result<bool> {
Ok(false)
}
async fn count(&self) -> anyhow::Result<usize> {
Ok(0)
}
async fn health_check(&self) -> bool {
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn none_memory_is_noop() {
let memory = NoneMemory::new();
memory.store("k", "v", MemoryCategory::Core).await.unwrap();
assert!(memory.get("k").await.unwrap().is_none());
assert!(memory.recall("k", 10).await.unwrap().is_empty());
assert!(memory.list(None).await.unwrap().is_empty());
assert!(!memory.forget("k").await.unwrap());
assert_eq!(memory.count().await.unwrap(), 0);
assert!(memory.health_check().await);
}
}