pub trait SemanticMemoryBackend:
Send
+ Sync
+ 'static {
// Required methods
fn namespace(&self) -> &Namespace;
fn dimension(&self) -> usize;
fn search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn search_filtered<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
filter: &'life3 VectorFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn search_with_rerank_dyn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
candidates: usize,
reranker: &'life3 dyn Reranker,
) -> Pin<Box<dyn Future<Output = Result<Vec<RerankedDocument>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn add<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn add_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
documents: Vec<Document>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn update<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn count<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn list<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
limit: usize,
offset: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
}Expand description
Object-safe consumer trait — tier 3 of the semantic-memory
layering documented at the module level. Consumers (tools,
orchestration code, recipes) take
Arc<dyn SemanticMemoryBackend> to operate on a namespace-scoped
embed-and-search surface without parameterising over the
concrete embedder / vector-store types.
Operators do not implement this trait directly. Implement
crate::VectorStore (and optionally crate::Embedder),
then wrap in SemanticMemory::new — the
impl SemanticMemoryBackend for SemanticMemory<E, V> blanket
produces the trait-object view automatically.
The trait mirrors the full SemanticMemory surface (search,
add, delete, update, add_batch, search_filtered, plus a
rerank-aware variant via &dyn Reranker) so consumers do not
need to downcast to the concrete generic type to access mutating
or rerank operations.
Required Methods§
Sourcefn namespace(&self) -> &Namespace
fn namespace(&self) -> &Namespace
Borrow the bound Namespace. Tools and orchestration code
that route queries by tenant or scope read this to validate
the backend is wired to the expected slice without downcasting
to the concrete generic type.
Sourcefn dimension(&self) -> usize
fn dimension(&self) -> usize
Vector dimension the backend embeds and indexes at. Lets schedulers verify a query embedder matches before issuing a search, and lets dashboards report index width per tenant.
Sourcefn search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn search<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Embed query and return the top top_k matches.
Sourcefn search_filtered<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
filter: &'life3 VectorFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn search_filtered<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
filter: &'life3 VectorFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Embed query, fetch candidates, push down filter if the
backend supports it; otherwise the underlying VectorStore
returns Error::Config.
Sourcefn search_with_rerank_dyn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
candidates: usize,
reranker: &'life3 dyn Reranker,
) -> Pin<Box<dyn Future<Output = Result<Vec<RerankedDocument>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn search_with_rerank_dyn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
query: &'life2 str,
top_k: usize,
candidates: usize,
reranker: &'life3 dyn Reranker,
) -> Pin<Box<dyn Future<Output = Result<Vec<RerankedDocument>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Two-stage retrieval: over-fetch candidates then rerank
down to top_k. The reranker is supplied as a trait object
so the backend trait stays object-safe (the concrete
SemanticMemory::search_with_rerank also accepts
monomorphic R: Reranker for users who prefer static
dispatch). Returns RerankedDocuments so callers can
inspect the reranker’s score alongside the retrieval score.
Sourcefn add<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn add<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Embed document.content and add the document to the index.
Sourcefn add_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
documents: Vec<Document>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn add_batch<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
documents: Vec<Document>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Add many documents at once. Default implementations defer to the embedder’s batch path then to the vector store’s batch path so backends that support either can amortise round-trips.
Sourcefn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn delete<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Delete a previously-indexed document by its backend id.
Sourcefn update<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn update<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
doc_id: &'life2 str,
document: Document,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Replace an existing document’s vector and metadata atomically when the backend supports it; otherwise non-atomic via delete + add.
Sourcefn count<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn count<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
) -> Pin<Box<dyn Future<Output = Result<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Count documents in the bound namespace, optionally narrowed
by a metadata filter. Pass-through to
VectorStore::count — backends without count support
surface Error::Config.
Sourcefn list<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
limit: usize,
offset: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn list<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
ctx: &'life1 ExecutionContext,
filter: Option<&'life2 VectorFilter>,
limit: usize,
offset: usize,
) -> Pin<Box<dyn Future<Output = Result<Vec<Document>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Enumerate documents in the bound namespace. Pass-through to
VectorStore::list — backends without enumeration
support surface Error::Config.