A3S Memory
Custom Backend
Implement MemoryStore to use any storage system — SQLite, Redis, vector DB
Custom Backend
Implement the MemoryStore trait to use any storage system. The search() method is the only one where backends meaningfully differ — FileMemoryStore uses substring matching, a vector store would use semantic similarity.
MemoryStore trait
use a3s_memory::{MemoryItem, MemoryStore};
use async_trait::async_trait;
struct MyStore { /* ... */ }
#[async_trait]
impl MemoryStore for MyStore {
async fn store(&self, item: MemoryItem) -> anyhow::Result<()> { todo!() }
async fn retrieve(&self, id: &str) -> anyhow::Result<Option<MemoryItem>> { todo!() }
async fn search(&self, query: &str, limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
async fn search_by_tags(&self, tags: &[String], limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
async fn get_recent(&self, limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
async fn get_important(&self, threshold: f32, limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
async fn delete(&self, id: &str) -> anyhow::Result<()> { todo!() }
async fn clear(&self) -> anyhow::Result<()> { todo!() }
async fn count(&self) -> anyhow::Result<usize> { todo!() }
}Method reference
Prop
Type
Vector store example
use a3s_memory::{MemoryItem, MemoryStore};
use async_trait::async_trait;
struct VectorStore {
client: MyVectorDbClient,
}
#[async_trait]
impl MemoryStore for VectorStore {
async fn store(&self, item: MemoryItem) -> anyhow::Result<()> {
let embedding = self.client.embed(&item.content).await?;
self.client.upsert(&item.id, embedding, &item).await?;
Ok(())
}
async fn search(&self, query: &str, limit: usize) -> anyhow::Result<Vec<MemoryItem>> {
let embedding = self.client.embed(query).await?;
let results = self.client.ann_search(embedding, limit).await?;
Ok(results)
}
// remaining methods: standard CRUD against your DB
# async fn retrieve(&self, id: &str) -> anyhow::Result<Option<MemoryItem>> { todo!() }
# async fn search_by_tags(&self, tags: &[String], limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
# async fn get_recent(&self, limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
# async fn get_important(&self, threshold: f32, limit: usize) -> anyhow::Result<Vec<MemoryItem>> { todo!() }
# async fn delete(&self, id: &str) -> anyhow::Result<()> { todo!() }
# async fn clear(&self) -> anyhow::Result<()> { todo!() }
# async fn count(&self) -> anyhow::Result<usize> { todo!() }
}Use with A3S Code
The A3S Code v2.1.0 Node SDK supports FileMemoryStore and
MemorySessionStore. Passing an arbitrary Rust MemoryStore implementation
into an A3S Code session is outside this page's scope.
Use this page for standalone a3s-memory backend design. Add an A3S Code
custom-memory adapter only after testing that adapter in your application.
Use standalone
use std::sync::Arc;
use a3s_memory::MemoryStore;
let store: Arc<dyn MemoryStore> = Arc::new(VectorStore::new());
store.store(MemoryItem::new("some fact")).await?;
let results = store.search("fact", 5).await?;MemoryStore is object-safe — Arc<dyn MemoryStore> works without any additional bounds.