pub struct AgentScopedMemory { /* private fields */ }Expand description
A Memory impl that scopes every read and write to a bound agent’s
UUID + a resolved cross-agent allowlist.
Construct via AgentScopedMemory::new at agent-loop entry. The
runtime holds one per agent. Non-generic over the inner backend
(holds Arc<dyn Memory>) so the per-agent factory can hand back a
single concrete type regardless of the agent’s chosen backend kind.
Implementations§
Source§impl AgentScopedMemory
impl AgentScopedMemory
Sourcepub fn new(
inner: Arc<dyn Memory>,
agent_id: impl Into<String>,
allowed_sibling_agent_ids: impl IntoIterator<Item = String>,
) -> AgentScopedMemory
pub fn new( inner: Arc<dyn Memory>, agent_id: impl Into<String>, allowed_sibling_agent_ids: impl IntoIterator<Item = String>, ) -> AgentScopedMemory
Build a new agent-scoped wrapper around inner.
agent_id is the bound agent’s UUID (looked up from the
agents table by alias at construction time in the runtime
factory). allowed_sibling_agent_ids is the resolved
read_memory_from allowlist; the bound agent_id is added
automatically to the in-memory allowed_agent_ids set so
callers do not need to remember to include themselves.
Trait Implementations§
Source§impl Attributable for AgentScopedMemory
impl Attributable for AgentScopedMemory
Source§impl Memory for AgentScopedMemory
impl Memory for AgentScopedMemory
Source§fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
fn health_check<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = bool> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
Health check
Source§fn store<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
AgentScopedMemory: 'async_trait,
fn store<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
AgentScopedMemory: 'async_trait,
Store a memory entry, optionally scoped to a session
Source§fn store_with_metadata<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
namespace: Option<&'life4 str>,
importance: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
AgentScopedMemory: 'async_trait,
fn store_with_metadata<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
namespace: Option<&'life4 str>,
importance: Option<f64>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
AgentScopedMemory: 'async_trait,
Store a memory entry with namespace and importance. Read more
Source§fn store_with_agent<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
namespace: Option<&'life4 str>,
importance: Option<f64>,
agent_id: Option<&'life5 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
AgentScopedMemory: 'async_trait,
fn store_with_agent<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
key: &'life1 str,
content: &'life2 str,
category: MemoryCategory,
session_id: Option<&'life3 str>,
namespace: Option<&'life4 str>,
importance: Option<f64>,
agent_id: Option<&'life5 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
AgentScopedMemory: 'async_trait,
Store a memory entry attributed to an explicit agent UUID.
Every backend must implement this explicitly so the agent_id
is never silently dropped at storage time. Backends with
native agent_id columns (SqliteMemory, PostgresMemory,
LucidMemory) persist the attribution in SQL; MarkdownMemory
attributes via the per-agent directory path; QdrantMemory
persists in the vector payload; NoneMemory is a no-op stub.
AgentScopedMemory is the canonical caller.Source§fn recall<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
query: &'life1 str,
limit: usize,
session_id: Option<&'life2 str>,
since: Option<&'life3 str>,
until: Option<&'life4 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
AgentScopedMemory: 'async_trait,
fn recall<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
&'life0 self,
query: &'life1 str,
limit: usize,
session_id: Option<&'life2 str>,
since: Option<&'life3 str>,
until: Option<&'life4 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
AgentScopedMemory: 'async_trait,
Recall memories matching a query (keyword search), optionally scoped to a session
and time range. Empty, whitespace-only, and bare “” queries return recent/time-only
entries. Non-bare wildcard terms such as “wild” remain keyword queries.
Time bounds use RFC 3339 / ISO 8601 format
(e.g. “2025-03-01T00:00:00Z”); inclusive (created_at >= since, created_at <= until).
Source§fn recall_for_agents<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'async_trait>(
&'life0 self,
caller_allowed: &'life1 [&'life2 str],
query: &'life3 str,
limit: usize,
session_id: Option<&'life4 str>,
since: Option<&'life5 str>,
until: Option<&'life6 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
'life6: 'async_trait,
AgentScopedMemory: 'async_trait,
fn recall_for_agents<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'async_trait>(
&'life0 self,
caller_allowed: &'life1 [&'life2 str],
query: &'life3 str,
limit: usize,
session_id: Option<&'life4 str>,
since: Option<&'life5 str>,
until: Option<&'life6 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
'life6: 'async_trait,
AgentScopedMemory: 'async_trait,
Recall memory entries scoped to a specific set of agent UUIDs.
When
allowed_agent_ids is non-empty, the backend filters its
result set to rows whose agent_id matches one of the listed
UUIDs (or is NULL, for legacy rows written before the agent_id
column existed). Every backend must implement this explicitly
so the allowlist is never silently dropped at read time. Read moreSource§fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn get<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Get a specific memory by key. Read more
Source§fn get_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
fn get_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<Option<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
Get the memory row matching
(key, agent_id). Siblings of the same
key under other agents are invisible. Read moreSource§fn list<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
category: Option<&'life1 MemoryCategory>,
session_id: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
fn list<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
category: Option<&'life1 MemoryCategory>,
session_id: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
List all memory keys, optionally filtered by category and/or session
Source§fn forget<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn forget<'life0, 'life1, 'async_trait>(
&'life0 self,
key: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Remove a memory by key. Deletes every row matching
key, regardless
of agent attribution. Agent-scoped callers (the AgentScopedMemory
wrapper) use forget_for_agent instead.Source§fn forget_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
fn forget_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
key: &'life1 str,
agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
Remove the row matching
(key, agent_id). Siblings of the same key
under other agents are untouched. Returns true if a row was
removed. Required: no safe default exists for backends or wrappers
that can hold more than one row per key — the unscoped forget
would destroy sibling rows.Source§fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
fn count<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
Count total memories
Source§fn purge_namespace<'life0, 'life1, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn purge_namespace<'life0, 'life1, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Remove all memories whose
namespace field equals the given value.
Returns the number of deleted entries.
Default: returns unsupported error. Backends that support bulk deletion override this.Source§fn purge_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn purge_session<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Remove all memories in a session.
Returns the number of deleted entries.
Default: returns unsupported error. Backends that support bulk deletion override this.
Source§fn reindex<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
fn reindex<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
AgentScopedMemory: 'async_trait,
Rebuild backend indexes: FTS tables and any missing embedding vectors. Read more
Source§fn store_procedural<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
messages: &'life1 [ProceduralMessage],
session_id: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
fn store_procedural<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
messages: &'life1 [ProceduralMessage],
session_id: Option<&'life2 str>,
) -> Pin<Box<dyn Future<Output = Result<(), Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
AgentScopedMemory: 'async_trait,
Store a conversation trace as procedural memory. Read more
Source§fn recall_namespaced<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
query: &'life2 str,
limit: usize,
session_id: Option<&'life3 str>,
since: Option<&'life4 str>,
until: Option<&'life5 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
AgentScopedMemory: 'async_trait,
fn recall_namespaced<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'async_trait>(
&'life0 self,
namespace: &'life1 str,
query: &'life2 str,
limit: usize,
session_id: Option<&'life3 str>,
since: Option<&'life4 str>,
until: Option<&'life5 str>,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
'life4: 'async_trait,
'life5: 'async_trait,
AgentScopedMemory: 'async_trait,
Recall memories scoped to a specific namespace. Read more
Source§fn export<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ExportFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn export<'life0, 'life1, 'async_trait>(
&'life0 self,
filter: &'life1 ExportFilter,
) -> Pin<Box<dyn Future<Output = Result<Vec<MemoryEntry>, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Bulk-export memories matching the given filter criteria. Read more
Source§fn ensure_agent_uuid<'life0, 'life1, 'async_trait>(
&'life0 self,
alias: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
fn ensure_agent_uuid<'life0, 'life1, 'async_trait>(
&'life0 self,
alias: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<String, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
AgentScopedMemory: 'async_trait,
Look up (or create) the identifier the backend uses to refer
to the agent named by
alias. Read moreSource§fn purge_session_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
_agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn purge_session_for_agent<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session_id: &'life1 str,
_agent_id: &'life2 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Remove all memories in a session for one agent.
Returns the number of deleted entries.
Default: returns unsupported error. Backends with per-agent storage
override this; agent-scoped wrappers use it instead of composing a
session list with key-only deletes.
Source§fn purge_agent<'life0, 'life1, 'async_trait>(
&'life0 self,
_agent_alias: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
fn purge_agent<'life0, 'life1, 'async_trait>(
&'life0 self,
_agent_alias: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<usize, Error>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
Self: 'async_trait,
Remove every memory row attributed to the given agent alias.
Returns the number of deleted entries. Called when an agent alias is
removed from
[agents.<alias>] so the database doesn’t accumulate
rows for retired aliases.
Default: returns unsupported error. Backends with per-agent storage
(sqlite, postgres) override this; backends without (markdown, none)
keep the default and the caller logs a warning.Auto Trait Implementations§
impl Freeze for AgentScopedMemory
impl !RefUnwindSafe for AgentScopedMemory
impl Send for AgentScopedMemory
impl Sync for AgentScopedMemory
impl Unpin for AgentScopedMemory
impl UnsafeUnpin for AgentScopedMemory
impl !UnwindSafe for AgentScopedMemory
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
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§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