Skip to main content

MemoryStore

Trait MemoryStore 

Source
pub trait MemoryStore: Send + Sync {
Show 27 methods // Required methods fn close_current_conversation<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, project: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn get_memory_stats<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(i64, i64, i64, i64), MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn db_size<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<u64, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn get_total_usage<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<UsageSummary, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn get_history<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, limit: i64, ) -> Pin<Box<dyn Future<Output = Result<Vec<HistoryRow>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn search_messages<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, query: &'life1 str, exclude_conversation_id: &'life2 str, sender_id: &'life3 str, limit: i64, since: Option<SystemTime>, ) -> Pin<Box<dyn Future<Output = Result<Vec<MessageRow>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn get_message_by_id<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<MessageRow>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn store_fact<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, value: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait; fn get_fact<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<Option<String>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn get_facts<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String)>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn soft_delete_fact<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn soft_delete_facts<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<u64, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn list_soft_deleted_facts<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, String)>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn save_observation<'life0, 'async_trait>( &'life0 self, entry: SaveEntry, ) -> Pin<Box<dyn Future<Output = Result<Observation, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn get_observation_by_id<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Observation>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn search_observations<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, sender_id: &'life2 str, limit: i64, since: Option<SystemTime>, kind: Option<ObservationType>, ) -> Pin<Box<dyn Future<Output = Result<Vec<Observation>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn soft_delete_observation<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn list_soft_deleted_observations<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<Observation>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn create_task<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'life7, 'life8, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, reply_target: &'life3 str, description: &'life4 str, due_at: &'life5 str, repeat: Option<&'life6 str>, task_type: &'life7 str, project: &'life8 str, ) -> Pin<Box<dyn Future<Output = Result<String, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait, 'life6: 'async_trait, 'life7: 'async_trait, 'life8: 'async_trait; fn get_tasks_for_sender<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, String, Option<String>, String, String)>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait; fn complete_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, repeat: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn fail_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, error: &'life2 str, max_retries: u32, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn cancel_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id_prefix: &'life1 str, sender_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait; fn get_due_tasks<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<DueTask>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn claim_due_tasks<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<DueTask>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait; fn record_task_run<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, task_id: &'life1 str, started_at: &'life2 str, status: &'life3 str, result: Option<&'life4 str>, error: Option<&'life5 str>, tokens_used: Option<u64>, ) -> Pin<Box<dyn Future<Output = Result<String, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait; fn list_task_runs<'life0, 'life1, 'async_trait>( &'life0 self, task_id_prefix: &'life1 str, limit: u32, ) -> Pin<Box<dyn Future<Output = Result<Vec<TaskRunRecord>, MemoryError>> + Send + 'async_trait>> where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait;
}
Expand description

Public trait surface over Store.

Returned from kernex-runtime::Runtime::store_handle() as Arc<dyn MemoryStore>. Consumers should prefer this trait over the concrete Store type so future schema changes do not ripple into call sites.

Required Methods§

Source

fn close_current_conversation<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, project: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Mark the active conversation for (channel, sender_id, project) as closed. Returns true if a row transitioned from active to closed.

Source

fn get_memory_stats<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<(i64, i64, i64, i64), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Aggregate counters: (conversation_count, message_count, observation_count, fact_count).

Breaking change (kernex-memory 0.8.0): prior versions returned a 3-tuple (conversation, message, fact). The observation count joins the tuple at position 2; consumers must destructure four elements after the bump. Soft-deleted observations and facts are excluded; conversations and messages have no soft-delete column today and are counted whole.

Source

fn db_size<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<u64, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

On-disk byte size of the SQLite database file.

Source

fn get_total_usage<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<UsageSummary, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Aggregate token usage across all sessions.

Source

fn get_history<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, limit: i64, ) -> Pin<Box<dyn Future<Output = Result<Vec<HistoryRow>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Recent closed-conversation summaries for a given channel + sender, newest first, capped at limit.

Source

fn search_messages<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, query: &'life1 str, exclude_conversation_id: &'life2 str, sender_id: &'life3 str, limit: i64, since: Option<SystemTime>, ) -> Pin<Box<dyn Future<Output = Result<Vec<MessageRow>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

FTS5 full-text search over user messages, excluding the live conversation. When since is Some, only rows with timestamp >= since are returned and limit applies after the recency filter.

Source

fn get_message_by_id<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<MessageRow>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetch a single message row by its UUID. Returns None when the id is missing.

Source

fn store_fact<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, value: &'life3 str, ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait,

Upsert a fact for (sender_id, key). If the row was previously soft-deleted, this clears deleted_at so the value is visible again to default-filtered reads.

Source

fn get_fact<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<Option<String>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Read a single active fact by (sender_id, key). Returns None if the row is soft-deleted, missing, or never existed.

Source

fn get_facts<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String)>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Active (not soft-deleted) facts for sender_id.

Source

fn soft_delete_fact<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Soft-delete a single fact by setting its deleted_at timestamp. Returns true if a row transitioned from active to deleted; false if the row was already deleted, missing, or never existed.

Source

fn soft_delete_facts<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, sender_id: &'life1 str, key: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<u64, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Soft-delete multiple facts. With Some(key), soft-deletes that specific key. With None, soft-deletes every active fact for the sender. Returns the count of rows that transitioned from active to deleted.

Source

fn list_soft_deleted_facts<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, String)>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read soft-deleted facts (debug / recovery helper). Returns (key, value, deleted_at) rows for sender_id.

Source

fn save_observation<'life0, 'async_trait>( &'life0 self, entry: SaveEntry, ) -> Pin<Box<dyn Future<Output = Result<Observation, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Persist a typed observation and return the saved row. Generates a fresh UUIDv4 id; sets created_at == updated_at == now. The DB enforces length(title) > 0 and the seven-value type CHECK constraint; violations surface as MemoryError::Sqlite.

Source

fn get_observation_by_id<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Observation>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Fetch an active observation by id. Returns None when the id is missing OR the row is soft-deleted (CC-9 invariant). Mirrors the get_message_by_id shape introduced in 0.7.0.

Source

fn search_observations<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, query: &'life1 str, sender_id: &'life2 str, limit: i64, since: Option<SystemTime>, kind: Option<ObservationType>, ) -> Pin<Box<dyn Future<Output = Result<Vec<Observation>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

FTS5 search across observation title + structured fields. Optional since filters by created_at >=; optional kind narrows to a single type. Soft-deleted rows never appear.

Source

fn soft_delete_observation<'life0, 'life1, 'async_trait>( &'life0 self, id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Soft-delete an observation by id. Returns Ok(true) on transition from active to deleted; Ok(false) when the row was already deleted, missing, or never existed (matches the soft_delete_fact contract).

Source

fn list_soft_deleted_observations<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<Observation>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Read soft-deleted observations for a sender. Recovery helper; surfaced on the trait so future tooling can offer an “undelete” command without dropping back to the inherent Store.

Source

fn create_task<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'life7, 'life8, 'async_trait>( &'life0 self, channel: &'life1 str, sender_id: &'life2 str, reply_target: &'life3 str, description: &'life4 str, due_at: &'life5 str, repeat: Option<&'life6 str>, task_type: &'life7 str, project: &'life8 str, ) -> Pin<Box<dyn Future<Output = Result<String, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait, 'life6: 'async_trait, 'life7: 'async_trait, 'life8: 'async_trait,

Insert a new scheduled task. Returns the new task id.

Source

fn get_tasks_for_sender<'life0, 'life1, 'async_trait>( &'life0 self, sender_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Vec<(String, String, String, Option<String>, String, String)>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Pending tasks for sender_id as raw (id, description, due_at, repeat, task_type, project) rows, ordered by due_at ascending.

Source

fn complete_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, repeat: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Result<(), MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Mark a task as completed. With Some("daily") / Some("weekly") / etc., reschedules the next occurrence; with None or Some("once"), the task transitions to a terminal status.

Source

fn fail_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id: &'life1 str, error: &'life2 str, max_retries: u32, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Record a task failure. Increments retry counter; transitions to a terminal failed status when retries exhaust. Returns true if the task transitioned to a terminal state.

Source

fn cancel_task<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, id_prefix: &'life1 str, sender_id: &'life2 str, ) -> Pin<Box<dyn Future<Output = Result<bool, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Cancel a pending task whose id starts with id_prefix, scoped to sender_id. Returns true if a row was cancelled.

Source

fn get_due_tasks<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<DueTask>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

All pending tasks whose due_at is in the past.

Source

fn claim_due_tasks<'life0, 'async_trait>( &'life0 self, ) -> Pin<Box<dyn Future<Output = Result<Vec<DueTask>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Atomically claim every due task (status ‘pending’ -> ‘claimed’ in a single statement) and return the claimed rows. When several pollers share a store, each due task is handed to exactly one of them; a claim abandoned by a dead claimer becomes reclaimable after a timeout. The claim is released by complete_task (recurring tasks return to ‘pending’ at the next due time) or fail_task (retries return to ‘pending’).

Source

fn record_task_run<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>( &'life0 self, task_id: &'life1 str, started_at: &'life2 str, status: &'life3 str, result: Option<&'life4 str>, error: Option<&'life5 str>, tokens_used: Option<u64>, ) -> Pin<Box<dyn Future<Output = Result<String, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait,

Record one execution of a scheduled task. status must be "completed" or "failed". Returns the new run id.

Source

fn list_task_runs<'life0, 'life1, 'async_trait>( &'life0 self, task_id_prefix: &'life1 str, limit: u32, ) -> Pin<Box<dyn Future<Output = Result<Vec<TaskRunRecord>, MemoryError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Recorded runs for tasks whose id starts with task_id_prefix, newest first, capped at limit.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§