SemanticFallback

Trait SemanticFallback 

Source
pub trait SemanticFallback: Send + Sync {
    // Required method
    fn search<'life0, 'life1, 'async_trait>(
        &'life0 self,
        query: &'life1 str,
        limit: usize,
    ) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryId>, MemoryError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided method
    fn reconcile<'life0, 'life1, 'async_trait>(
        &'life0 self,
        _active: &'life1 [(MemoryId, String)],
        _revision: u64,
    ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

An optional paraphrase-tolerant backend.

Reached only when lexical search finds too little — an indirect question, a pronoun-heavy reference, or a fact the user is describing rather than naming.

Required Methods§

Source

fn search<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, limit: usize, ) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryId>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Return record ids in descending relevance.

Provided Methods§

Source

fn reconcile<'life0, 'life1, 'async_trait>( &'life0 self, _active: &'life1 [(MemoryId, String)], _revision: u64, ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Bring the backend in line with the active corpus.

Called after the canonical index is recompiled — that is, after a session seals and reconciliation has decided what is true. active is the entire desired state: every active record paired with the text it should be findable by, from embedding_text.

Passing the whole set rather than a diff is deliberate. A diff has to be right, and the cost of getting it wrong is a vector store that quietly disagrees with the corpus — which is the failure this method exists to prevent, reintroduced by the fix for it. A backend given the full set can reconcile idempotently and embed only what it does not already hold.

Default is a no-op, so an existing implementation keeps compiling and keeps its current behaviour: an index that never learns about corrections. That is the safe failure — semantic_ranking resolves every returned id against the canonical index and drops what is no longer retrievable, so a stale backend loses facts rather than serving wrong ones — but it is still a failure, and it lands hardest on corrected facts, which are the ones a user has shown they care about.

§revision orders concurrent callers

One engine hands the same backend to every session it opens, so two sessions sealing at the same moment both call this — each with a corpus snapshot taken before it started. Because active is a whole desired state rather than a diff, the call that finishes last wins, and if that is the one that started first it silently removes every record the other added, vectors and all.

Serialising the calls does not fix that: the loser’s snapshot is stale whenever it is applied, not only when it interleaves. So callers pass the canonical index revision the snapshot was taken from — monotonic per engine — and an implementation must ignore a revision it has already passed. Pass 0 if there is nothing meaningful to order by; that disables the check rather than breaking it.

Implementors§