MemoryService

Trait MemoryService 

Source
pub trait MemoryService: Send + Sync {
Show 20 methods // Required methods fn store_document<'life0, 'life1, 'async_trait>( &'life0 self, document: &'life1 Document, ) -> Pin<Box<dyn Future<Output = MemoryResult<Uuid>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn store_documents<'life0, 'life1, 'async_trait>( &'life0 self, documents: &'life1 [Document], ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Uuid>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_document<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<Option<Document>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn delete_document<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_documents<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Uuid>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn search<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn search_with_config<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, config: &'life2 ContextConfig, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn search_by_vector<'life0, 'life1, 'async_trait>( &'life0 self, embedding: &'life1 [f32], top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn search_by_keywords<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_context<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<ContextWindow>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn get_context_with_config<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, config: &'life2 ContextConfig, ) -> Pin<Box<dyn Future<Output = MemoryResult<ContextWindow>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn get_document_chunks<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Chunk>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn embed<'life0, 'life1, 'async_trait>( &'life0 self, text: &'life1 str, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<f32>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn embed_batch<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, texts: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Vec<f32>>>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn build_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn rebuild_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn check_index_health<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<IndexStats>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryStats>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn is_healthy<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<bool>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn clear_all<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait;
}
Expand description

Main trait for memory service operations

This trait defines the interface that reasonkit-core uses to interact with reasonkit-mem. Implementations handle:

  • Document storage and retrieval
  • Vector embeddings and similarity search
  • Hybrid search (dense + sparse)
  • Context assembly for reasoning

§Thread Safety

All implementations MUST be:

  • Send + Sync for safe cross-thread sharing
  • Internally synchronized (e.g., using Arc<RwLock<T>>)
  • Panic-safe (errors should propagate, not panic)

Required Methods§

Source

fn store_document<'life0, 'life1, 'async_trait>( &'life0 self, document: &'life1 Document, ) -> Pin<Box<dyn Future<Output = MemoryResult<Uuid>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Store a document in memory

This operation:

  1. Validates the document structure
  2. Stores metadata in the document store
  3. Chunks the content (if not already chunked)
  4. Prepares chunks for embedding
§Arguments
  • document - The document to store
§Returns
  • Ok(Uuid) - The document ID if successful
  • Err(MemoryError) - If storage fails
§Example
let doc_id = memory.store_document(document).await?;
println!("Stored document: {}", doc_id);
Source

fn store_documents<'life0, 'life1, 'async_trait>( &'life0 self, documents: &'life1 [Document], ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Uuid>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Store multiple documents (batch operation)

Stores documents in parallel where possible for efficiency.

§Arguments
  • documents - Slice of documents to store
§Returns
  • Ok(Vec<Uuid>) - IDs of stored documents
  • Err(MemoryError) - If any document fails to store
Source

fn get_document<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<Option<Document>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Retrieve a document by ID

§Arguments
  • doc_id - The document UUID
§Returns
  • Ok(Some(Document)) - The document if found
  • Ok(None) - If document doesn’t exist
  • Err(MemoryError) - If retrieval fails
Source

fn delete_document<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Delete a document by ID

This removes:

  • Document metadata
  • All associated chunks
  • Embeddings for those chunks
  • Index entries
§Arguments
  • doc_id - The document UUID
§Returns
  • Ok(()) - If successful (no error if document doesn’t exist)
  • Err(MemoryError) - If deletion fails
Source

fn list_documents<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Uuid>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

List all document IDs in memory

§Returns
  • Ok(Vec<Uuid>) - All document IDs
  • Err(MemoryError) - If listing fails
Source

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

Search documents using hybrid search

Performs a combined search across:

  • Dense vector search (semantic similarity)
  • Sparse BM25 search (keyword matching)
  • Reciprocal Rank Fusion for combining results
  • Optional cross-encoder reranking
§Arguments
  • query - The search query text
  • top_k - Number of results to return
§Returns
  • Ok(Vec<SearchResult>) - Ranked search results
  • Err(MemoryError) - If search fails
§Example
let results = memory.search("machine learning optimization", 10).await?;
for result in results {
    println!("Score: {}, Document: {}", result.score, result.document_id);
}
Source

fn search_with_config<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, config: &'life2 ContextConfig, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Search with advanced configuration

§Arguments
  • query - The search query
  • config - Retrieval configuration
§Returns
  • Ok(Vec<SearchResult>) - Ranked results
  • Err(MemoryError) - If search fails
Source

fn search_by_vector<'life0, 'life1, 'async_trait>( &'life0 self, embedding: &'life1 [f32], top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Vector similarity search

Searches using only dense embeddings (fast, semantic). Use when you already have embeddings or want pure semantic search.

§Arguments
  • embedding - Query vector
  • top_k - Number of results
§Returns
  • Ok(Vec<SearchResult>) - Top K similar chunks
  • Err(MemoryError) - If search fails
Source

fn search_by_keywords<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<SearchResult>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Keyword search (BM25)

Searches using only sparse BM25 indexing (fast, keyword-based). Use when you want keyword matching or have specific terms.

§Arguments
  • query - The search query
  • top_k - Number of results
§Returns
  • Ok(Vec<SearchResult>) - Ranked results by BM25 score
  • Err(MemoryError) - If search fails
Source

fn get_context<'life0, 'life1, 'async_trait>( &'life0 self, query: &'life1 str, top_k: usize, ) -> Pin<Box<dyn Future<Output = MemoryResult<ContextWindow>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get context window for reasoning

This is the primary method for assembling context for LLM reasoning. It returns a structured context window with:

  • Ranked, relevant chunks
  • Associated documents
  • Quality metrics
  • Token count estimate
§Arguments
  • query - The reasoning query/prompt
  • top_k - Number of chunks to include
§Returns
  • Ok(ContextWindow) - Assembled context
  • Err(MemoryError) - If context assembly fails
§Example
let context = memory.get_context("How does RAG improve reasoning?", 5).await?;
println!("Context: {} chunks, {} tokens",
    context.chunks.len(),
    context.token_count);

// Use context in prompt
let prompt = format!("Context:\n{}\n\nQuestion: ...",
    context.chunks.iter()
        .map(|c| &c.text)
        .collect::<Vec<_>>()
        .join("\n---\n"));
Source

fn get_context_with_config<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, config: &'life2 ContextConfig, ) -> Pin<Box<dyn Future<Output = MemoryResult<ContextWindow>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Get context with advanced configuration

§Arguments
  • query - The reasoning query
  • config - Context retrieval configuration
§Returns
  • Ok(ContextWindow) - Assembled context
  • Err(MemoryError) - If context assembly fails
Source

fn get_document_chunks<'life0, 'life1, 'async_trait>( &'life0 self, doc_id: &'life1 Uuid, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Chunk>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Get chunks by document ID

§Arguments
  • doc_id - The document UUID
§Returns
  • Ok(Vec<Chunk>) - All chunks in the document
  • Err(MemoryError) - If operation fails
Source

fn embed<'life0, 'life1, 'async_trait>( &'life0 self, text: &'life1 str, ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<f32>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Embed text and get vector representation

Uses the configured embedding model to convert text to vectors. Results are cached where possible.

§Arguments
  • text - Text to embed
§Returns
  • Ok(Vec<f32>) - The embedding vector
  • Err(MemoryError) - If embedding fails
Source

fn embed_batch<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, texts: &'life1 [&'life2 str], ) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<Vec<f32>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Embed multiple texts (batch operation)

§Arguments
  • texts - Slice of texts to embed
§Returns
  • Ok(Vec<Vec<f32>>) - Embeddings (same order as input)
  • Err(MemoryError) - If any embedding fails
Source

fn build_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Build or update indexes

Triggers indexing for documents that haven’t been indexed yet. Safe to call multiple times (idempotent for already-indexed docs).

§Returns
  • Ok(()) - If indexing succeeds
  • Err(MemoryError) - If indexing fails
Source

fn rebuild_indexes<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Rebuild all indexes from scratch

Use when you suspect corruption or want to optimize. This is slower but ensures consistency.

§Returns
  • Ok(()) - If rebuild succeeds
  • Err(MemoryError) - If rebuild fails
Source

fn check_index_health<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<IndexStats>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Check index health and statistics

§Returns
  • Ok(IndexStats) - Index statistics
  • Err(MemoryError) - If health check fails
Source

fn stats<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryStats>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Get current memory service statistics

§Returns
  • Ok(MemoryStats) - Current statistics
  • Err(MemoryError) - If stats retrieval fails
Source

fn is_healthy<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<bool>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Check if memory service is healthy

§Returns
  • Ok(true) - Service is operational
  • Ok(false) - Service has issues
  • Err(MemoryError) - If health check fails
Source

fn clear_all<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Clear all data (for testing)

WARNING: This is destructive and irreversible in most implementations. Only use for testing.

§Returns
  • Ok(()) - If clear succeeds
  • Err(MemoryError) - If clear fails

Implementors§