pub trait MemoryProvider: Send + Sync {
Show 15 methods
// Required methods
fn name(&self) -> &str;
fn build_messages(
&self,
system_prompt: &str,
new_task: &str,
) -> Vec<MemMessage>;
fn sync_turn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
user: &'life1 str,
assistant: &'life2 str,
metrics: &'life3 TurnMetrics,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
// Provided methods
fn initialize<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn system_prompt_block(&self) -> Option<String> { ... }
fn prefetch<'life0, 'life1, 'async_trait>(
&'life0 self,
_query: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn reset(&mut self) { ... }
fn restore_turns(&mut self, _turns: &[ConversationTurn]) { ... }
fn take_compaction_record(&mut self) -> Option<String> { ... }
fn on_pre_compress<'life0, 'life1, 'async_trait>(
&'life0 self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = String> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn on_session_end<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait { ... }
fn usage(&self) -> Option<(String, usize, usize)> { ... }
fn add_note(&mut self, _fact: &str) -> Result<()> { ... }
fn replace_note(
&mut self,
_old_substring: &str,
_new_text: &str,
) -> Result<()> { ... }
fn remove_note(&mut self, _substring: &str) -> Result<()> { ... }
}Expand description
Contract for all memory backends.
Implement this trait to create a custom memory backend — rolling window, vector store, summarisation engine, or anything else.
Required Methods§
Sourcefn build_messages(&self, system_prompt: &str, new_task: &str) -> Vec<MemMessage>
fn build_messages(&self, system_prompt: &str, new_task: &str) -> Vec<MemMessage>
Build the full message list (including history) to send to the model.
This is where history management lives. Implementations decide:
- How many past turns to include
- Whether to summarise old turns
- Where to inject
prefetchcontext
system_prompt is the fully-assembled system message content.
new_task is the current user turn.
Sourcefn sync_turn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
user: &'life1 str,
assistant: &'life2 str,
metrics: &'life3 TurnMetrics,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
fn sync_turn<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 mut self,
user: &'life1 str,
assistant: &'life2 str,
metrics: &'life3 TurnMetrics,
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Persist a completed turn.
Implementations should queue writes and return immediately so the chat loop never blocks on memory I/O.
Provided Methods§
Sourcefn initialize<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn initialize<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_ctx: &'life1 SessionContext,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
One-time setup at session start (load files, warm caches, etc.). Default: no-op.
Sourcefn system_prompt_block(&self) -> Option<String>
fn system_prompt_block(&self) -> Option<String>
Return a static block for the system prompt.
Called once at session start and frozen — mid-session writes to
memory must NOT change this return value (keeps the KV/prefix cache
valid across all turns). Return None to contribute nothing.
Sourcefn prefetch<'life0, 'life1, 'async_trait>(
&'life0 self,
_query: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn prefetch<'life0, 'life1, 'async_trait>(
&'life0 self,
_query: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Recall relevant context to prepend to the user turn before the API call. Should be fast — use cached results, don’t block. Return empty string to contribute nothing.
Sourcefn reset(&mut self)
fn reset(&mut self)
Clear conversation-local history while preserving provider configuration and system-prompt state. Used when the TUI starts a fresh conversation inside the same running process.
Sourcefn restore_turns(&mut self, _turns: &[ConversationTurn])
fn restore_turns(&mut self, _turns: &[ConversationTurn])
Replace conversation-local history with durable restored turns.
The default is a no-op for providers without conversation-local state.
Providers that include prior user/assistant turns in build_messages
must override this, otherwise /conversation restore will silently
leave their in-memory history unchanged.
Sourcefn take_compaction_record(&mut self) -> Option<String>
fn take_compaction_record(&mut self) -> Option<String>
Take (and clear) the compaction record minted since the last call —
the full marked summary message a compressing provider inserted into
its working set (Step 18.5, #247). The caller persists it as a turn
record (user = the marked message, assistant = empty, token
columns NULL — it is not a backend-measured turn) so a later restore
can rehydrate the same working-set shape via Self::restore_turns.
Default: None — providers that never compress mint nothing.
Sourcefn on_pre_compress<'life0, 'life1, 'async_trait>(
&'life0 self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = String> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_pre_compress<'life0, 'life1, 'async_trait>(
&'life0 self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = String> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called before old messages are discarded (e.g. during compression).
Extract anything worth keeping from messages; return it as a string
to include in the compression summary. Return empty string for nothing.
Sourcefn on_session_end<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_session_end<'life0, 'life1, 'async_trait>(
&'life0 mut self,
_messages: &'life1 [MemMessage],
) -> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Called once when the session ends. Use for final extraction / cleanup.
Sourcefn usage(&self) -> Option<(String, usize, usize)>
fn usage(&self) -> Option<(String, usize, usize)>
Report current usage for display (e.g. /memory command).
Returns (label, current, max) — e.g. ("turns", 12, 20).
Sourcefn add_note(&mut self, _fact: &str) -> Result<()>
fn add_note(&mut self, _fact: &str) -> Result<()>
Add a persistent note.
Providers that persist notes (e.g. NoteStore) override this.
Default: return NotesUnsupported, which MemoryManager::add_note
recognises and skips while looking for a note-capable provider.
Sourcefn replace_note(&mut self, _old_substring: &str, _new_text: &str) -> Result<()>
fn replace_note(&mut self, _old_substring: &str, _new_text: &str) -> Result<()>
Replace the single persisted note containing old_substring with
new_text (Step 19.3 — the save_note tool’s replace action).
Default: NotesUnsupported, same routing contract as add_note.
Sourcefn remove_note(&mut self, _substring: &str) -> Result<()>
fn remove_note(&mut self, _substring: &str) -> Result<()>
Remove the single persisted note containing substring (Step 19.3 —
the save_note tool’s remove action).
Default: NotesUnsupported, same routing contract as add_note.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".