pub struct DuckdbMemoryProvider { /* private fields */ }Expand description
DuckDB-backed MemoryProvider using array_cosine_distance + ILIKE retrieval.
Implementations§
Source§impl DuckdbMemoryProvider
impl DuckdbMemoryProvider
Sourcepub async fn open(
path: impl AsRef<Path>,
embedder: Arc<dyn Embedder>,
) -> Result<Self, DuckdbMemoryError>
pub async fn open( path: impl AsRef<Path>, embedder: Arc<dyn Embedder>, ) -> Result<Self, DuckdbMemoryError>
Open or create a DuckDB database file, run migrations, and return a provider.
Sourcepub async fn open_in_memory(
embedder: Arc<dyn Embedder>,
) -> Result<Self, DuckdbMemoryError>
pub async fn open_in_memory( embedder: Arc<dyn Embedder>, ) -> Result<Self, DuckdbMemoryError>
Open an in-memory DuckDB database for tests.
Sourcepub fn with_write_hook(self, hook: Arc<dyn MemoryWriteHook>) -> Self
pub fn with_write_hook(self, hook: Arc<dyn MemoryWriteHook>) -> Self
Attach a write hook consulted before every persist.
Sourcepub fn with_summarizer(self, summarizer: Arc<dyn Summarizer>) -> Self
pub fn with_summarizer(self, summarizer: Arc<dyn Summarizer>) -> Self
Attach a summarizer for session summaries and rollups (Phase 3).
Trait Implementations§
Source§impl MemoryProvider for DuckdbMemoryProvider
impl MemoryProvider for DuckdbMemoryProvider
Source§fn retrieve<'life0, 'async_trait>(
&'life0 self,
query: MemoryQuery,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn retrieve<'life0, 'async_trait>(
&'life0 self,
query: MemoryQuery,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Hybrid retrieval over the memory store. The provider applies the
query’s profile, scope, and filters and returns up to
query.k
chunks in descending relevance order.Source§fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
chunk_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<Option<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
chunk_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<Option<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch a chunk by ID.
Source§fn get_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<Option<MemorySession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<Option<MemorySession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Fetch a session by ID.
Source§fn list_sessions<'life0, 'async_trait>(
&'life0 self,
filter: SessionFilter,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemorySession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_sessions<'life0, 'async_trait>(
&'life0 self,
filter: SessionFilter,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemorySession>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
List sessions matching the filter, most-recent-first.
Source§fn write<'life0, 'async_trait>(
&'life0 self,
new_chunk: NewMemoryChunk,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn write<'life0, 'async_trait>(
&'life0 self,
new_chunk: NewMemoryChunk,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Persist a single new chunk. The provider assigns
id, created_at,
tier, and embedding-model metadata.Source§fn write_batch<'life0, 'async_trait>(
&'life0 self,
chunks: Vec<NewMemoryChunk>,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn write_batch<'life0, 'async_trait>(
&'life0 self,
chunks: Vec<NewMemoryChunk>,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Persist many chunks in one call. The provider may batch embeddings;
the v1 stub processes them one at a time.
Source§fn open_session<'life0, 'async_trait>(
&'life0 self,
init: NewMemorySession,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemorySession>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn open_session<'life0, 'async_trait>(
&'life0 self,
init: NewMemorySession,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemorySession>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Open a new session. Returns the session record.
Source§fn close_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
outcome: SessionOutcome,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn close_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
outcome: SessionOutcome,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Close an open session. Triggers session summarization where supported.
Source§fn rename_session<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
title: &'life2 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn rename_session<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
title: &'life2 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Rename a session’s display title. Returns
Err(NotFound) if the session
does not exist. The v1 BasicMemoryProvider implements this in-memory;
SqliteMemoryProvider updates the memory_sessions.title column.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,
fn stats<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryStats>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Summary statistics for the dashboard / doctor check.
Source§fn summarize_session<'life0, 'life1, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn summarize_session<'life0, 'life1, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Produce a
JobSummary chunk synthesizing the named session. Inserted
into the store; returned to the caller. v1 stub returns
crate::MemoryError::NotImplemented.Source§fn rollup_day<'life0, 'async_trait>(
&'life0 self,
_date: NaiveDate,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn rollup_day<'life0, 'async_trait>(
&'life0 self,
_date: NaiveDate,
) -> Pin<Box<dyn Future<Output = MemoryResult<Vec<MemoryChunk>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Produce one or more
Rollup chunks for the named day. v1 stub returns
crate::MemoryError::NotImplemented. Read moreSource§fn rollup_rule_week<'life0, 'life1, 'async_trait>(
&'life0 self,
_rule_id: &'life1 str,
_week_start: NaiveDate,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn rollup_rule_week<'life0, 'life1, 'async_trait>(
&'life0 self,
_rule_id: &'life1 str,
_week_start: NaiveDate,
) -> Pin<Box<dyn Future<Output = MemoryResult<MemoryChunk>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Produce a
Rollup chunk for the named rule across the named week.
v1 stub returns crate::MemoryError::NotImplemented. Read moreSource§fn run_aging_sweep<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = MemoryResult<AgingReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn run_aging_sweep<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = MemoryResult<AgingReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Run the aging sweeper: tier transitions, retention-horizon deletes,
importance-based eviction. Idempotent.
Source§fn re_embed_all<'life0, 'life1, 'async_trait>(
&'life0 self,
_target_model: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<ReEmbedReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn re_embed_all<'life0, 'life1, 'async_trait>(
&'life0 self,
_target_model: &'life1 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<ReEmbedReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Re-embed every chunk against the target model. Long-running. Resumable.
v1 stub returns
crate::MemoryError::NotImplemented.Source§fn export<'life0, 'async_trait>(
&'life0 self,
_filter: ExportFilter,
) -> Pin<Box<dyn Future<Output = MemoryResult<ExportBundle>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn export<'life0, 'async_trait>(
&'life0 self,
_filter: ExportFilter,
) -> Pin<Box<dyn Future<Output = MemoryResult<ExportBundle>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Export memory matching the filter as a self-contained bundle.
Source§fn pin<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_pinned: bool,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn pin<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_pinned: bool,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Set or clear the pin flag on a chunk.
Source§fn update_importance<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_importance: f32,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_importance<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_importance: f32,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Set the importance score on a chunk. Out-of-range values are clamped
to
[0.0, 1.0]. The v1 stub no-ops (importance is not scored).Source§fn supersede<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_old_id: &'life1 str,
_new_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn supersede<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_old_id: &'life1 str,
_new_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Mark
old_id as superseded by new_id. Both chunks are retained;
retrieval surfaces the superseder. The v1 stub no-ops.Source§fn record_access<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_retrieved_by: &'life2 str,
_used: bool,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn record_access<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_retrieved_by: &'life2 str,
_used: bool,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Record that a chunk was returned by a retrieval call.
used=true
signals the consumer cited or acted on it (drives importance bumps
in the full impl).Source§fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_reason: EvictionReason,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
_chunk_id: &'life1 str,
_reason: EvictionReason,
) -> Pin<Box<dyn Future<Output = MemoryResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Hard-delete a single chunk, logging the reason.
Source§fn delete_matching<'life0, 'async_trait>(
&'life0 self,
_predicate: MemoryPredicate,
_reason: EvictionReason,
) -> Pin<Box<dyn Future<Output = MemoryResult<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_matching<'life0, 'async_trait>(
&'life0 self,
_predicate: MemoryPredicate,
_reason: EvictionReason,
) -> Pin<Box<dyn Future<Output = MemoryResult<usize>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Hard-delete all chunks matching the predicate. Returns the count. Read more
Source§fn purge_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = MemoryResult<PurgeReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn purge_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = MemoryResult<PurgeReport>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Hard-delete every chunk, session, access-log row, and eviction-log
row. The “forget everything” flow.
Source§fn rollup_day_forced<'life0, 'async_trait>(
&'life0 self,
date: NaiveDate,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryChunk>, MemoryError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
fn rollup_day_forced<'life0, 'async_trait>(
&'life0 self,
date: NaiveDate,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryChunk>, MemoryError>> + Send + 'async_trait>>where
'life0: 'async_trait,
Self: 'async_trait,
Force-produce one or more
Rollup chunks for the named day even
if a prior rollup exists. Default impl delegates to
Self::rollup_day for backward compatibility; the SQLite
provider overrides to actually honour the force flag.Source§fn rollup_rule_week_forced<'life0, 'life1, 'async_trait>(
&'life0 self,
rule_id: &'life1 str,
week_start: NaiveDate,
) -> Pin<Box<dyn Future<Output = Result<MemoryChunk, MemoryError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn rollup_rule_week_forced<'life0, 'life1, 'async_trait>(
&'life0 self,
rule_id: &'life1 str,
week_start: NaiveDate,
) -> Pin<Box<dyn Future<Output = Result<MemoryChunk, MemoryError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Force-produce a
Rollup chunk for the named rule + week even if
a prior rollup exists. Default impl delegates to
Self::rollup_rule_week for backward compatibility; the SQLite
provider overrides to honour the force flag.Auto Trait Implementations§
impl !RefUnwindSafe for DuckdbMemoryProvider
impl !UnwindSafe for DuckdbMemoryProvider
impl Freeze for DuckdbMemoryProvider
impl Send for DuckdbMemoryProvider
impl Sync for DuckdbMemoryProvider
impl Unpin for DuckdbMemoryProvider
impl UnsafeUnpin for DuckdbMemoryProvider
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
Mutably borrows from an owned value. Read more