pub struct SemanticMemory {
pub token_counter: Arc<TokenCounter>,
pub graph_store: Option<Arc<GraphStore>>,
/* private fields */
}Fields§
§token_counter: Arc<TokenCounter>§graph_store: Option<Arc<GraphStore>>Implementations§
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub async fn store_correction_embedding(
&self,
correction_id: i64,
correction_text: &str,
) -> Result<(), MemoryError>
pub async fn store_correction_embedding( &self, correction_id: i64, correction_text: &str, ) -> Result<(), MemoryError>
Store an embedding for a user correction in the vector store.
Silently skips if no vector store is configured or embeddings are unsupported.
§Errors
Returns an error if embedding generation or vector store write fails.
Sourcepub async fn retrieve_similar_corrections(
&self,
query: &str,
limit: usize,
min_score: f32,
) -> Result<Vec<UserCorrectionRow>, MemoryError>
pub async fn retrieve_similar_corrections( &self, query: &str, limit: usize, min_score: f32, ) -> Result<Vec<UserCorrectionRow>, MemoryError>
Retrieve corrections semantically similar to query.
Returns up to limit corrections scoring above min_score.
Returns an empty vec if no vector store is configured.
§Errors
Returns an error if embedding generation or vector search fails.
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub async fn has_session_summary(
&self,
conversation_id: ConversationId,
) -> Result<bool, MemoryError>
pub async fn has_session_summary( &self, conversation_id: ConversationId, ) -> Result<bool, MemoryError>
Check whether a session summary already exists for the given conversation.
Returns true if at least one session summary is stored in SQLite for this conversation.
Used as the primary guard in the shutdown summary path to handle cases where hard
compaction fired but its Qdrant write failed (the SQLite record is the authoritative source).
§Errors
Returns an error if the database query fails.
Sourcepub async fn store_shutdown_summary(
&self,
conversation_id: ConversationId,
summary_text: &str,
key_facts: &[String],
) -> Result<(), MemoryError>
pub async fn store_shutdown_summary( &self, conversation_id: ConversationId, summary_text: &str, key_facts: &[String], ) -> Result<(), MemoryError>
Store a shutdown session summary: persists to SQLite, embeds into the
zeph_session_summaries Qdrant collection (so cross-session search can find it),
and stores key facts into the key-facts collection.
Unlike the hard-compaction path, first_message_id and last_message_id are None
because the shutdown hook does not track exact message boundaries.
§Errors
Returns an error if the SQLite insert fails. Qdrant errors are logged as warnings
and do not propagate — the SQLite record is the authoritative summary store.
Sourcepub async fn store_session_summary(
&self,
conversation_id: ConversationId,
summary_text: &str,
) -> Result<(), MemoryError>
pub async fn store_session_summary( &self, conversation_id: ConversationId, summary_text: &str, ) -> Result<(), MemoryError>
Store a session summary into the dedicated zeph_session_summaries Qdrant collection.
§Errors
Returns an error if embedding or Qdrant storage fails.
Sourcepub async fn search_session_summaries(
&self,
query: &str,
limit: usize,
exclude_conversation_id: Option<ConversationId>,
) -> Result<Vec<SessionSummaryResult>, MemoryError>
pub async fn search_session_summaries( &self, query: &str, limit: usize, exclude_conversation_id: Option<ConversationId>, ) -> Result<Vec<SessionSummaryResult>, MemoryError>
Search session summaries from other conversations.
§Errors
Returns an error if embedding or Qdrant search fails.
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub fn spawn_graph_extraction(
&self,
content: String,
context_messages: Vec<String>,
config: GraphExtractionConfig,
post_extract_validator: PostExtractValidator,
) -> JoinHandle<()>
pub fn spawn_graph_extraction( &self, content: String, context_messages: Vec<String>, config: GraphExtractionConfig, post_extract_validator: PostExtractValidator, ) -> JoinHandle<()>
Spawn background graph extraction for a message. Fire-and-forget — never blocks.
Extraction runs in a separate tokio task with a timeout. Any error or timeout is logged and the task exits silently; the agent response is never blocked.
The optional post_extract_validator is called after extraction, before upsert.
It is a generic predicate opaque to zeph-memory (design decision D1).
When config.note_linking.enabled is true and an embedding store is available,
link_memory_notes runs after successful extraction inside the same task, bounded
by config.note_linking.timeout_secs.
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub async fn remember(
&self,
conversation_id: ConversationId,
role: &str,
content: &str,
) -> Result<MessageId, MemoryError>
pub async fn remember( &self, conversation_id: ConversationId, role: &str, content: &str, ) -> Result<MessageId, MemoryError>
Save a message to SQLite and optionally embed and store in Qdrant.
Returns the message ID assigned by SQLite.
§Errors
Returns an error if the SQLite save fails. Embedding failures are logged but not
propagated.
Sourcepub async fn remember_with_parts(
&self,
conversation_id: ConversationId,
role: &str,
content: &str,
parts_json: &str,
) -> Result<(MessageId, bool), MemoryError>
pub async fn remember_with_parts( &self, conversation_id: ConversationId, role: &str, content: &str, parts_json: &str, ) -> Result<(MessageId, bool), MemoryError>
Save a message with pre-serialized parts JSON to SQLite and optionally embed in Qdrant.
Returns (message_id, embedding_stored) tuple where embedding_stored is true if
an embedding was successfully generated and stored in Qdrant.
§Errors
Returns an error if the SQLite save fails.
Sourcepub async fn save_only(
&self,
conversation_id: ConversationId,
role: &str,
content: &str,
parts_json: &str,
) -> Result<MessageId, MemoryError>
pub async fn save_only( &self, conversation_id: ConversationId, role: &str, content: &str, parts_json: &str, ) -> Result<MessageId, MemoryError>
Save a message to SQLite without generating an embedding.
Use this when embedding is intentionally skipped (e.g. autosave disabled for assistant).
§Errors
Returns an error if the SQLite save fails.
Sourcepub async fn recall(
&self,
query: &str,
limit: usize,
filter: Option<SearchFilter>,
) -> Result<Vec<RecalledMessage>, MemoryError>
pub async fn recall( &self, query: &str, limit: usize, filter: Option<SearchFilter>, ) -> Result<Vec<RecalledMessage>, MemoryError>
Recall relevant messages using hybrid search (vector + FTS5 keyword).
When Qdrant is available, runs both vector and keyword searches, then merges results using weighted scoring. When Qdrant is unavailable, falls back to FTS5-only keyword search.
§Errors
Returns an error if embedding generation, Qdrant search, or FTS5 query fails.
Sourcepub async fn recall_routed(
&self,
query: &str,
limit: usize,
filter: Option<SearchFilter>,
router: &dyn MemoryRouter,
) -> Result<Vec<RecalledMessage>, MemoryError>
pub async fn recall_routed( &self, query: &str, limit: usize, filter: Option<SearchFilter>, router: &dyn MemoryRouter, ) -> Result<Vec<RecalledMessage>, MemoryError>
Recall messages using query-aware routing.
Delegates to FTS5-only, vector-only, or hybrid search based on the router decision, then runs the shared merge and ranking pipeline.
§Errors
Returns an error if any underlying search or database operation fails.
Sourcepub async fn recall_graph(
&self,
query: &str,
limit: usize,
max_hops: u32,
at_timestamp: Option<&str>,
temporal_decay_rate: f64,
edge_types: &[EdgeType],
) -> Result<Vec<GraphFact>, MemoryError>
pub async fn recall_graph( &self, query: &str, limit: usize, max_hops: u32, at_timestamp: Option<&str>, temporal_decay_rate: f64, edge_types: &[EdgeType], ) -> Result<Vec<GraphFact>, MemoryError>
Retrieve graph facts relevant to query via BFS traversal.
Returns an empty Vec if no graph_store is configured.
§Parameters
at_timestamp: whenSome, only edges valid at thatSQLitedatetime string are returned. WhenNone, only currently active edges are used.temporal_decay_rate: non-negative decay rate (1/day).0.0preserves original ordering.
§Errors
Returns an error if the underlying graph query fails.
Sourcepub async fn recall_graph_activated(
&self,
query: &str,
limit: usize,
params: SpreadingActivationParams,
edge_types: &[EdgeType],
) -> Result<Vec<ActivatedFact>, MemoryError>
pub async fn recall_graph_activated( &self, query: &str, limit: usize, params: SpreadingActivationParams, edge_types: &[EdgeType], ) -> Result<Vec<ActivatedFact>, MemoryError>
Retrieve graph facts via SYNAPSE spreading activation.
Delegates to crate::graph::retrieval::graph_recall_activated.
Used in place of [recall_graph] when spreading_activation.enabled = true.
§Errors
Returns an error if the underlying graph query fails.
Sourcepub async fn has_embedding(
&self,
message_id: MessageId,
) -> Result<bool, MemoryError>
pub async fn has_embedding( &self, message_id: MessageId, ) -> Result<bool, MemoryError>
Check whether an embedding exists for a given message ID.
§Errors
Returns an error if the SQLite query fails.
Sourcepub async fn embed_missing(&self) -> Result<usize, MemoryError>
pub async fn embed_missing(&self) -> Result<usize, MemoryError>
Embed all messages that do not yet have embeddings.
Returns the count of successfully embedded messages.
§Errors
Returns an error if collection initialization or database query fails. Individual embedding failures are logged but do not stop processing.
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub async fn load_summaries(
&self,
conversation_id: ConversationId,
) -> Result<Vec<Summary>, MemoryError>
pub async fn load_summaries( &self, conversation_id: ConversationId, ) -> Result<Vec<Summary>, MemoryError>
Sourcepub async fn summarize(
&self,
conversation_id: ConversationId,
message_count: usize,
) -> Result<Option<i64>, MemoryError>
pub async fn summarize( &self, conversation_id: ConversationId, message_count: usize, ) -> Result<Option<i64>, MemoryError>
Generate a summary of the oldest unsummarized messages.
Returns Ok(None) if there are not enough messages to summarize.
§Errors
Returns an error if LLM call or database operation fails.
Sourcepub async fn search_key_facts(
&self,
query: &str,
limit: usize,
) -> Result<Vec<String>, MemoryError>
pub async fn search_key_facts( &self, query: &str, limit: usize, ) -> Result<Vec<String>, MemoryError>
Search key facts extracted from conversation summaries.
§Errors
Returns an error if embedding or Qdrant search fails.
Sourcepub async fn search_document_collection(
&self,
collection: &str,
query: &str,
limit: usize,
) -> Result<Vec<ScoredVectorPoint>, MemoryError>
pub async fn search_document_collection( &self, collection: &str, query: &str, limit: usize, ) -> Result<Vec<ScoredVectorPoint>, MemoryError>
Search a named document collection by semantic similarity.
Returns up to limit scored vector points whose payloads contain ingested document chunks.
Returns an empty vec when Qdrant is unavailable, the collection does not exist,
or the provider does not support embeddings.
§Errors
Returns an error if embedding generation or Qdrant search fails.
Source§impl SemanticMemory
impl SemanticMemory
Sourcepub async fn new(
sqlite_path: &str,
qdrant_url: &str,
provider: AnyProvider,
embedding_model: &str,
) -> Result<Self, MemoryError>
pub async fn new( sqlite_path: &str, qdrant_url: &str, provider: AnyProvider, embedding_model: &str, ) -> Result<Self, MemoryError>
Create a new SemanticMemory instance with default hybrid search weights (0.7/0.3).
Qdrant connection is best-effort: if unavailable, semantic search is disabled.
For AppBuilder bootstrap, prefer SemanticMemory::with_qdrant_ops to share
a single gRPC channel across all subsystems.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub async fn with_weights(
sqlite_path: &str,
qdrant_url: &str,
provider: AnyProvider,
embedding_model: &str,
vector_weight: f64,
keyword_weight: f64,
) -> Result<Self, MemoryError>
pub async fn with_weights( sqlite_path: &str, qdrant_url: &str, provider: AnyProvider, embedding_model: &str, vector_weight: f64, keyword_weight: f64, ) -> Result<Self, MemoryError>
Create a new SemanticMemory with custom vector/keyword weights for hybrid search.
For AppBuilder bootstrap, prefer SemanticMemory::with_qdrant_ops to share
a single gRPC channel across all subsystems.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub async fn with_weights_and_pool_size(
sqlite_path: &str,
qdrant_url: &str,
provider: AnyProvider,
embedding_model: &str,
vector_weight: f64,
keyword_weight: f64,
pool_size: u32,
) -> Result<Self, MemoryError>
pub async fn with_weights_and_pool_size( sqlite_path: &str, qdrant_url: &str, provider: AnyProvider, embedding_model: &str, vector_weight: f64, keyword_weight: f64, pool_size: u32, ) -> Result<Self, MemoryError>
Create a new SemanticMemory with custom weights and configurable pool size.
For AppBuilder bootstrap, prefer SemanticMemory::with_qdrant_ops to share
a single gRPC channel across all subsystems.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub async fn with_qdrant_ops(
sqlite_path: &str,
ops: QdrantOps,
provider: AnyProvider,
embedding_model: &str,
vector_weight: f64,
keyword_weight: f64,
pool_size: u32,
) -> Result<Self, MemoryError>
pub async fn with_qdrant_ops( sqlite_path: &str, ops: QdrantOps, provider: AnyProvider, embedding_model: &str, vector_weight: f64, keyword_weight: f64, pool_size: u32, ) -> Result<Self, MemoryError>
Create a SemanticMemory from a pre-built QdrantOps instance.
Use this at bootstrap to share one QdrantOps (and thus one gRPC channel)
across all subsystems. The ops is consumed and wrapped inside EmbeddingStore.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub fn with_graph_store(self, store: Arc<GraphStore>) -> Self
pub fn with_graph_store(self, store: Arc<GraphStore>) -> Self
Attach a GraphStore for graph-aware retrieval.
When set, recall_graph traverses the graph starting from entities
matched by the query.
Sourcepub fn community_detection_failures(&self) -> u64
pub fn community_detection_failures(&self) -> u64
Returns the cumulative count of community detection failures since startup.
Sourcepub fn graph_extraction_count(&self) -> u64
pub fn graph_extraction_count(&self) -> u64
Returns the cumulative count of successful graph extractions since startup.
Sourcepub fn graph_extraction_failures(&self) -> u64
pub fn graph_extraction_failures(&self) -> u64
Returns the cumulative count of failed graph extractions since startup.
Sourcepub fn with_ranking_options(
self,
temporal_decay_enabled: bool,
temporal_decay_half_life_days: u32,
mmr_enabled: bool,
mmr_lambda: f32,
) -> Self
pub fn with_ranking_options( self, temporal_decay_enabled: bool, temporal_decay_half_life_days: u32, mmr_enabled: bool, mmr_lambda: f32, ) -> Self
Configure temporal decay and MMR re-ranking options.
Sourcepub fn with_importance_options(self, enabled: bool, weight: f64) -> Self
pub fn with_importance_options(self, enabled: bool, weight: f64) -> Self
Configure write-time importance scoring for memory retrieval.
Sourcepub fn from_parts(
sqlite: SqliteStore,
qdrant: Option<Arc<EmbeddingStore>>,
provider: AnyProvider,
embedding_model: impl Into<String>,
vector_weight: f64,
keyword_weight: f64,
token_counter: Arc<TokenCounter>,
) -> Self
pub fn from_parts( sqlite: SqliteStore, qdrant: Option<Arc<EmbeddingStore>>, provider: AnyProvider, embedding_model: impl Into<String>, vector_weight: f64, keyword_weight: f64, token_counter: Arc<TokenCounter>, ) -> Self
Construct a SemanticMemory from pre-built parts.
Intended for tests that need full control over the backing stores.
Sourcepub async fn with_sqlite_backend(
sqlite_path: &str,
provider: AnyProvider,
embedding_model: &str,
vector_weight: f64,
keyword_weight: f64,
) -> Result<Self, MemoryError>
pub async fn with_sqlite_backend( sqlite_path: &str, provider: AnyProvider, embedding_model: &str, vector_weight: f64, keyword_weight: f64, ) -> Result<Self, MemoryError>
Create a SemanticMemory using the SQLite-embedded vector backend.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub async fn with_sqlite_backend_and_pool_size(
sqlite_path: &str,
provider: AnyProvider,
embedding_model: &str,
vector_weight: f64,
keyword_weight: f64,
pool_size: u32,
) -> Result<Self, MemoryError>
pub async fn with_sqlite_backend_and_pool_size( sqlite_path: &str, provider: AnyProvider, embedding_model: &str, vector_weight: f64, keyword_weight: f64, pool_size: u32, ) -> Result<Self, MemoryError>
Create a SemanticMemory using the SQLite-embedded vector backend with configurable pool size.
§Errors
Returns an error if SQLite cannot be initialized.
Sourcepub fn sqlite(&self) -> &SqliteStore
pub fn sqlite(&self) -> &SqliteStore
Access the underlying SqliteStore for operations that don’t involve semantics.
Sourcepub async fn is_vector_store_connected(&self) -> bool
pub async fn is_vector_store_connected(&self) -> bool
Check if the vector store backend is reachable.
Performs a real health check (Qdrant gRPC ping or SQLite query)
instead of just checking whether the client was created.
Sourcepub fn has_vector_store(&self) -> bool
pub fn has_vector_store(&self) -> bool
Check if a vector store client is configured (may not be connected).
Sourcepub fn embedding_store(&self) -> Option<&Arc<EmbeddingStore>>
pub fn embedding_store(&self) -> Option<&Arc<EmbeddingStore>>
Return a reference to the embedding store, if configured.
Sourcepub async fn message_count(
&self,
conversation_id: ConversationId,
) -> Result<i64, MemoryError>
pub async fn message_count( &self, conversation_id: ConversationId, ) -> Result<i64, MemoryError>
Sourcepub async fn unsummarized_message_count(
&self,
conversation_id: ConversationId,
) -> Result<i64, MemoryError>
pub async fn unsummarized_message_count( &self, conversation_id: ConversationId, ) -> Result<i64, MemoryError>
Auto Trait Implementations§
impl !Freeze for SemanticMemory
impl !RefUnwindSafe for SemanticMemory
impl Send for SemanticMemory
impl Sync for SemanticMemory
impl Unpin for SemanticMemory
impl UnsafeUnpin for SemanticMemory
impl !UnwindSafe for SemanticMemory
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request