pub struct PostgresMemoryProvider { /* private fields */ }Expand description
PostgreSQL-backed MemoryProvider using pgvector + tsvector retrieval.
Implementations§
Source§impl PostgresMemoryProvider
impl PostgresMemoryProvider
Sourcepub async fn connect(
database_url: &str,
embedder: Arc<dyn Embedder>,
) -> Result<Self, PostgresMemoryError>
pub async fn connect( database_url: &str, embedder: Arc<dyn Embedder>, ) -> Result<Self, PostgresMemoryError>
Connect to PostgreSQL, run migrations, and return a ready provider.
The embedder must declare dimension [EMBEDDING_DIM] (384) to match the
schema. Use cel_memory::MockEmbedder in 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 PostgresMemoryProvider
impl MemoryProvider for PostgresMemoryProvider
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 PostgresMemoryProvider
impl !UnwindSafe for PostgresMemoryProvider
impl Freeze for PostgresMemoryProvider
impl Send for PostgresMemoryProvider
impl Sync for PostgresMemoryProvider
impl Unpin for PostgresMemoryProvider
impl UnsafeUnpin for PostgresMemoryProvider
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
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>
Converts
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>
Converts
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 more