pub struct Memory { /* private fields */ }Expand description
Mémoire d’un agent : moteur de stockage (vecteur natif) + embedder,
scellés par un AgentId. Le chiffrement est obligatoire (ADR-007).
Implementations§
Source§impl Memory
impl Memory
Sourcepub async fn export_jsonl(&self) -> Result<String>
pub async fn export_jsonl(&self) -> Result<String>
Exporte tout ce qui appartient à cet agent — souvenirs (y compris invalidés/expirés : c’est un backup, la validité est préservée), entités et relations du graphe — en JSONL versionné.
Les embeddings sont volontairement exclus (re-calculables) : le fichier est portable entre machines et entre modèles d’embedding.
§Errors
Propage les erreurs de stockage/sérialisation.
Sourcepub async fn import_jsonl(&self, jsonl: &str) -> Result<ImportReport>
pub async fn import_jsonl(&self, jsonl: &str) -> Result<ImportReport>
Importe un export JSONL dans cette mémoire (l’agent cible est celui
de la façade, quel que soit l’agent_id d’origine de l’export).
Les souvenirs sont ré-embeddés par l’embedder courant (une passe
embed_batch par lots de 128), puis tout est inséré dans une seule
transaction : l’import aboutit entièrement ou pas du tout.
Idempotent : les lignes dont l’identifiant existe déjà sont comptées
en *_skipped et laissées intactes.
§Errors
MemoryError::Porting si l’en-tête manque/diverge ou si une ligne est
malformée ; MemoryError::UnknownLayer si une couche est inconnue ;
propage les erreurs d’embedding/stockage.
Source§impl Memory
impl Memory
Sourcepub fn new(store: Store, embedder: Box<dyn Embedder>, agent: AgentId) -> Self
pub fn new(store: Store, embedder: Box<dyn Embedder>, agent: AgentId) -> Self
Assemble une mémoire à partir des primitives du core déjà construites, sans migrer le schéma (à utiliser quand le schéma est déjà en place).
Sourcepub async fn open(
store: Store,
embedder: Box<dyn Embedder>,
agent: AgentId,
) -> Result<Self>
pub async fn open( store: Store, embedder: Box<dyn Embedder>, agent: AgentId, ) -> Result<Self>
Ouvre une mémoire : vérifie le chiffrement, applique le schéma
(memory + index vecteur natif), puis renvoie la façade scellée par agent.
Le chiffrement est obligatoire pour les stores sur fichier (ADR-007) :
un store :memory: est éphémère, la règle ne s’y applique pas.
§Errors
crate::MemoryError::EncryptionRequired si le store est sur fichier et non chiffré.
crate::MemoryError::Core si la migration échoue.
Examples found in repository?
52async fn main() -> Result<(), Box<dyn std::error::Error>> {
53 let store = Store::open_in_memory().await?;
54 let agent = AgentId::new("consolidation-demo").expect("non-empty id");
55 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
56
57 // Store a raw episode (what happened).
58 memory
59 .remember(
60 "Alice attended a conference in Paris, the capital of France.",
61 MemoryLayer::Episodic,
62 )
63 .await?;
64
65 // Consolidate: extract facts + populate graph via FakeLlm.
66 let report = consolidate(&memory, &FakeLlm).await?;
67 println!(
68 "Consolidation: {} episode(s) seen, {} fact(s) added, {} entity(ies) upserted, {} relation(s).",
69 report.episodes_seen, report.facts_added, report.entities_upserted, report.relations_upserted,
70 );
71
72 // The extracted fact should now be searchable in semantic layer.
73 let facts = memory
74 .recall_by_layer("What is the capital of France?", MemoryLayer::Semantic, 5)
75 .await?;
76 println!("\nSemantic facts after consolidation ({}):", facts.len());
77 for f in &facts {
78 println!(" • {}", f.text);
79 }
80
81 Ok(())
82}More examples
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44 let store = Store::open_in_memory().await?;
45 let agent = AgentId::new("temporal-demo").expect("non-empty id");
46 let memory = Memory::open(store, Box::new(DemoEmbedder), agent).await?;
47
48 let old_id = memory
49 .remember("The user is on the Free billing plan.", MemoryLayer::Semantic)
50 .await?;
51
52 println!("Initially remembered: Free plan ({old_id})");
53
54 memory.invalidate(&old_id).await?;
55 let new_id = memory
56 .remember("The user is on the Pro billing plan.", MemoryLayer::Semantic)
57 .await?;
58
59 println!("Invalidated old fact and remembered: Pro plan ({new_id})");
60
61 let hits = memory.recall_hybrid("current billing plan", 5).await?;
62 println!("\nRecall for `current billing plan`:");
63 for hit in &hits {
64 println!(" [{layer}] {text}", layer = hit.layer.table(), text = hit.text);
65 }
66
67 assert!(
68 hits.iter().any(|r| r.text.contains("Pro billing plan")),
69 "the current fact should be recalled"
70 );
71 assert!(
72 hits.iter().all(|r| !r.text.contains("Free billing plan")),
73 "the invalidated fact should not be recalled"
74 );
75
76 Ok(())
77}29async fn main() -> Result<(), Box<dyn std::error::Error>> {
30 let store = Store::open_in_memory().await?;
31 let agent = AgentId::new("demo-agent").expect("non-empty id");
32 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
33
34 memory
35 .remember("The Eiffel Tower is in Paris.", MemoryLayer::Semantic)
36 .await?;
37 memory
38 .remember("Paris is the capital of France.", MemoryLayer::Semantic)
39 .await?;
40 memory.remember("Bonjour!", MemoryLayer::ShortTerm).await?;
41
42 println!("=== recall (top 2) ===");
43 let results = memory.recall("What city is the Eiffel Tower in?", 2).await?;
44 for r in &results {
45 println!(
46 " [{layer}] {score:.3} {text}",
47 layer = r.layer.table(),
48 score = r.score,
49 text = r.text
50 );
51 }
52
53 let first_id = results[0].id.clone();
54 memory.invalidate(&first_id).await?;
55 println!("\nInvalidated id={first_id}");
56
57 let after = memory.recall("Eiffel Tower", 5).await?;
58 println!("Recall after invalidation: {} result(s)", after.len());
59
60 let stats = memory.stats().await?;
61 println!(
62 "\nStats: {} semantic, {} short-term (valid).",
63 stats.semantic, stats.short_term
64 );
65
66 Ok(())
67}Sourcepub fn watch(
&self,
agent_id: &str,
layer: Option<MemoryLayer>,
) -> MemorySubscription
pub fn watch( &self, agent_id: &str, layer: Option<MemoryLayer>, ) -> MemorySubscription
S’abonne au flux d’événements mémoire de cet agent (et d’une couche
donnée, si layer est fourni). L’abonnement renvoyé n’expose jamais le
canal brut : l’isolation par agent/couche est appliquée côté serveur dans
MemorySubscription::recv, jamais déléguée à l’appelant.
agent_id est capturé tel quel : un appelant qui passe l’identifiant
d’un autre agent ne reçoit que les événements de cet autre agent — il ne
peut pas remonter au-delà de ce que Memory émet, et chaque Memory
n’émet que pour son propre agent. La sécurité multi-tenant repose sur
l’isolation SQL en amont (ADR-006) ; ce filtre la prolonge au flux.
Sourcepub fn graph(&self) -> Graph
pub fn graph(&self) -> Graph
Façade graphe sur le même moteur, scellée par le même agent.
Permet aux consommateurs externes (MCP, REST, bindings) de traverser le
graphe entités/relations (recall_graph) sans accéder au moteur, tout
en conservant l’isolation par agent au niveau SQL (ADR-006).
Sourcepub async fn remember(&self, text: &str, layer: MemoryLayer) -> Result<String>
pub async fn remember(&self, text: &str, layer: MemoryLayer) -> Result<String>
Mémorise un texte dans une couche, valide dès maintenant et sans expiration. Renvoie l’identifiant (UUID v4) du souvenir créé.
§Errors
Propage les erreurs d’embedding/stockage.
Examples found in repository?
52async fn main() -> Result<(), Box<dyn std::error::Error>> {
53 let store = Store::open_in_memory().await?;
54 let agent = AgentId::new("consolidation-demo").expect("non-empty id");
55 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
56
57 // Store a raw episode (what happened).
58 memory
59 .remember(
60 "Alice attended a conference in Paris, the capital of France.",
61 MemoryLayer::Episodic,
62 )
63 .await?;
64
65 // Consolidate: extract facts + populate graph via FakeLlm.
66 let report = consolidate(&memory, &FakeLlm).await?;
67 println!(
68 "Consolidation: {} episode(s) seen, {} fact(s) added, {} entity(ies) upserted, {} relation(s).",
69 report.episodes_seen, report.facts_added, report.entities_upserted, report.relations_upserted,
70 );
71
72 // The extracted fact should now be searchable in semantic layer.
73 let facts = memory
74 .recall_by_layer("What is the capital of France?", MemoryLayer::Semantic, 5)
75 .await?;
76 println!("\nSemantic facts after consolidation ({}):", facts.len());
77 for f in &facts {
78 println!(" • {}", f.text);
79 }
80
81 Ok(())
82}More examples
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44 let store = Store::open_in_memory().await?;
45 let agent = AgentId::new("temporal-demo").expect("non-empty id");
46 let memory = Memory::open(store, Box::new(DemoEmbedder), agent).await?;
47
48 let old_id = memory
49 .remember("The user is on the Free billing plan.", MemoryLayer::Semantic)
50 .await?;
51
52 println!("Initially remembered: Free plan ({old_id})");
53
54 memory.invalidate(&old_id).await?;
55 let new_id = memory
56 .remember("The user is on the Pro billing plan.", MemoryLayer::Semantic)
57 .await?;
58
59 println!("Invalidated old fact and remembered: Pro plan ({new_id})");
60
61 let hits = memory.recall_hybrid("current billing plan", 5).await?;
62 println!("\nRecall for `current billing plan`:");
63 for hit in &hits {
64 println!(" [{layer}] {text}", layer = hit.layer.table(), text = hit.text);
65 }
66
67 assert!(
68 hits.iter().any(|r| r.text.contains("Pro billing plan")),
69 "the current fact should be recalled"
70 );
71 assert!(
72 hits.iter().all(|r| !r.text.contains("Free billing plan")),
73 "the invalidated fact should not be recalled"
74 );
75
76 Ok(())
77}29async fn main() -> Result<(), Box<dyn std::error::Error>> {
30 let store = Store::open_in_memory().await?;
31 let agent = AgentId::new("demo-agent").expect("non-empty id");
32 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
33
34 memory
35 .remember("The Eiffel Tower is in Paris.", MemoryLayer::Semantic)
36 .await?;
37 memory
38 .remember("Paris is the capital of France.", MemoryLayer::Semantic)
39 .await?;
40 memory.remember("Bonjour!", MemoryLayer::ShortTerm).await?;
41
42 println!("=== recall (top 2) ===");
43 let results = memory.recall("What city is the Eiffel Tower in?", 2).await?;
44 for r in &results {
45 println!(
46 " [{layer}] {score:.3} {text}",
47 layer = r.layer.table(),
48 score = r.score,
49 text = r.text
50 );
51 }
52
53 let first_id = results[0].id.clone();
54 memory.invalidate(&first_id).await?;
55 println!("\nInvalidated id={first_id}");
56
57 let after = memory.recall("Eiffel Tower", 5).await?;
58 println!("Recall after invalidation: {} result(s)", after.len());
59
60 let stats = memory.stats().await?;
61 println!(
62 "\nStats: {} semantic, {} short-term (valid).",
63 stats.semantic, stats.short_term
64 );
65
66 Ok(())
67}Sourcepub async fn remember_with(
&self,
text: &str,
layer: MemoryLayer,
validity: Validity,
) -> Result<String>
pub async fn remember_with( &self, text: &str, layer: MemoryLayer, validity: Validity, ) -> Result<String>
Mémorise un texte avec une fenêtre de validité explicite. Renvoie l’identifiant (UUID v4) du souvenir créé — les consommateurs (MCP, REST, bindings) le retournent à l’appelant pour invalidation/effacement ultérieurs.
L’insertion memory + miroir FTS est atomique (Store::begin_write) :
jamais de souvenir visible par vecteur mais invisible en BM25, ou l’inverse.
§Errors
MemoryError::TextTooLong si text dépasse MAX_TEXT_LEN.
Propage aussi les erreurs d’embedding/stockage.
Sourcepub async fn remember_batch(
&self,
texts: &[String],
layer: MemoryLayer,
) -> Result<Vec<String>>
pub async fn remember_batch( &self, texts: &[String], layer: MemoryLayer, ) -> Result<Vec<String>>
Mémorise un lot de textes dans une couche, valides dès maintenant et sans expiration. Renvoie les identifiants créés, dans l’ordre des textes.
§Errors
Propage les erreurs d’embedding/stockage.
Sourcepub async fn remember_batch_with(
&self,
texts: &[String],
layer: MemoryLayer,
validity: Validity,
) -> Result<Vec<String>>
pub async fn remember_batch_with( &self, texts: &[String], layer: MemoryLayer, validity: Validity, ) -> Result<Vec<String>>
Mémorise un lot avec une fenêtre de validité explicite : une passe
d’embedding (Embedder::embed_batch) et une transaction — le lot
devient visible d’un coup, ou pas du tout. C’est le chemin de
l’ingestion initiale (import d’historique, seed de connaissances).
§Errors
MemoryError::TextTooLong si un texte du lot dépasse MAX_TEXT_LEN
(fail-fast : le premier texte trop long stoppe le lot, rien n’est inséré
puisque la validation précède l’embedding/la transaction).
Propage aussi les erreurs d’embedding/stockage.
Sourcepub async fn recall(&self, query: &str, k: usize) -> Result<Vec<Record>>
pub async fn recall(&self, query: &str, k: usize) -> Result<Vec<Record>>
Recall temporel : pertinent ET valide, borné à cet agent.
L’isolation (agent_id) et le filtre temporel sont appliqués par le
moteur de stockage (MemoryStore::recall_vector) — Memory ne
connaît plus le SQL, seulement le vecteur de requête et l’agent.
§Errors
Propage les erreurs d’embedding/recherche.
Examples found in repository?
29async fn main() -> Result<(), Box<dyn std::error::Error>> {
30 let store = Store::open_in_memory().await?;
31 let agent = AgentId::new("demo-agent").expect("non-empty id");
32 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
33
34 memory
35 .remember("The Eiffel Tower is in Paris.", MemoryLayer::Semantic)
36 .await?;
37 memory
38 .remember("Paris is the capital of France.", MemoryLayer::Semantic)
39 .await?;
40 memory.remember("Bonjour!", MemoryLayer::ShortTerm).await?;
41
42 println!("=== recall (top 2) ===");
43 let results = memory.recall("What city is the Eiffel Tower in?", 2).await?;
44 for r in &results {
45 println!(
46 " [{layer}] {score:.3} {text}",
47 layer = r.layer.table(),
48 score = r.score,
49 text = r.text
50 );
51 }
52
53 let first_id = results[0].id.clone();
54 memory.invalidate(&first_id).await?;
55 println!("\nInvalidated id={first_id}");
56
57 let after = memory.recall("Eiffel Tower", 5).await?;
58 println!("Recall after invalidation: {} result(s)", after.len());
59
60 let stats = memory.stats().await?;
61 println!(
62 "\nStats: {} semantic, {} short-term (valid).",
63 stats.semantic, stats.short_term
64 );
65
66 Ok(())
67}Sourcepub async fn recall_with_metric(
&self,
query: &str,
k: usize,
metric: Metric,
) -> Result<Vec<Record>>
pub async fn recall_with_metric( &self, query: &str, k: usize, metric: Metric, ) -> Result<Vec<Record>>
Recall sémantique temporel avec métrique explicite (Metric).
Metric::Cosine emprunte le chemin natif ; Metric::Euclidean et
Metric::Hamming sur-échantillonnent les candidats cosinus puis sont
re-classées en Rust (ADR-012). Met à jour last_access sur les résultats.
§Errors
Propage les erreurs d’embedding/recherche.
Sourcepub async fn recall_hybrid(&self, query: &str, k: usize) -> Result<Vec<Record>>
pub async fn recall_hybrid(&self, query: &str, k: usize) -> Result<Vec<Record>>
Recall hybride (ADR-014) : fusionne le classement vectoriel et le
classement BM25 (full-text natif libSQL) par Reciprocal Rank Fusion
(rrf_fuse). Un terme exact que l’embedding rate (sigle, identifiant
rare, nom propre) remonte par BM25 ; une reformulation que les mots-clés
ratent remonte par le vecteur. Borné à l’agent et à la validité.
Met à jour last_access sur les résultats.
Le score du Record retourné porte le score RRF fusionné, pas la
similarité cosinus.
§Errors
Propage les erreurs d’embedding/recherche/stockage.
Examples found in repository?
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44 let store = Store::open_in_memory().await?;
45 let agent = AgentId::new("temporal-demo").expect("non-empty id");
46 let memory = Memory::open(store, Box::new(DemoEmbedder), agent).await?;
47
48 let old_id = memory
49 .remember("The user is on the Free billing plan.", MemoryLayer::Semantic)
50 .await?;
51
52 println!("Initially remembered: Free plan ({old_id})");
53
54 memory.invalidate(&old_id).await?;
55 let new_id = memory
56 .remember("The user is on the Pro billing plan.", MemoryLayer::Semantic)
57 .await?;
58
59 println!("Invalidated old fact and remembered: Pro plan ({new_id})");
60
61 let hits = memory.recall_hybrid("current billing plan", 5).await?;
62 println!("\nRecall for `current billing plan`:");
63 for hit in &hits {
64 println!(" [{layer}] {text}", layer = hit.layer.table(), text = hit.text);
65 }
66
67 assert!(
68 hits.iter().any(|r| r.text.contains("Pro billing plan")),
69 "the current fact should be recalled"
70 );
71 assert!(
72 hits.iter().all(|r| !r.text.contains("Free billing plan")),
73 "the invalidated fact should not be recalled"
74 );
75
76 Ok(())
77}Sourcepub async fn recall_by_layer(
&self,
query: &str,
layer: MemoryLayer,
k: usize,
) -> Result<Vec<Record>>
pub async fn recall_by_layer( &self, query: &str, layer: MemoryLayer, k: usize, ) -> Result<Vec<Record>>
Recall filtré sur une couche unique. Met à jour last_access sur chaque
souvenir retourné (l’oubli adaptatif en dépend).
§Errors
Propage les erreurs d’embedding/recherche.
Examples found in repository?
52async fn main() -> Result<(), Box<dyn std::error::Error>> {
53 let store = Store::open_in_memory().await?;
54 let agent = AgentId::new("consolidation-demo").expect("non-empty id");
55 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
56
57 // Store a raw episode (what happened).
58 memory
59 .remember(
60 "Alice attended a conference in Paris, the capital of France.",
61 MemoryLayer::Episodic,
62 )
63 .await?;
64
65 // Consolidate: extract facts + populate graph via FakeLlm.
66 let report = consolidate(&memory, &FakeLlm).await?;
67 println!(
68 "Consolidation: {} episode(s) seen, {} fact(s) added, {} entity(ies) upserted, {} relation(s).",
69 report.episodes_seen, report.facts_added, report.entities_upserted, report.relations_upserted,
70 );
71
72 // The extracted fact should now be searchable in semantic layer.
73 let facts = memory
74 .recall_by_layer("What is the capital of France?", MemoryLayer::Semantic, 5)
75 .await?;
76 println!("\nSemantic facts after consolidation ({}):", facts.len());
77 for f in &facts {
78 println!(" • {}", f.text);
79 }
80
81 Ok(())
82}Sourcepub async fn invalidate(&self, id: &str) -> Result<()>
pub async fn invalidate(&self, id: &str) -> Result<()>
Invalide un souvenir en fixant valid_until = now(). Il n’apparaît plus
dans les recalls futurs mais reste physiquement en base.
§Errors
Propage les erreurs de stockage.
Examples found in repository?
43async fn main() -> Result<(), Box<dyn std::error::Error>> {
44 let store = Store::open_in_memory().await?;
45 let agent = AgentId::new("temporal-demo").expect("non-empty id");
46 let memory = Memory::open(store, Box::new(DemoEmbedder), agent).await?;
47
48 let old_id = memory
49 .remember("The user is on the Free billing plan.", MemoryLayer::Semantic)
50 .await?;
51
52 println!("Initially remembered: Free plan ({old_id})");
53
54 memory.invalidate(&old_id).await?;
55 let new_id = memory
56 .remember("The user is on the Pro billing plan.", MemoryLayer::Semantic)
57 .await?;
58
59 println!("Invalidated old fact and remembered: Pro plan ({new_id})");
60
61 let hits = memory.recall_hybrid("current billing plan", 5).await?;
62 println!("\nRecall for `current billing plan`:");
63 for hit in &hits {
64 println!(" [{layer}] {text}", layer = hit.layer.table(), text = hit.text);
65 }
66
67 assert!(
68 hits.iter().any(|r| r.text.contains("Pro billing plan")),
69 "the current fact should be recalled"
70 );
71 assert!(
72 hits.iter().all(|r| !r.text.contains("Free billing plan")),
73 "the invalidated fact should not be recalled"
74 );
75
76 Ok(())
77}More examples
29async fn main() -> Result<(), Box<dyn std::error::Error>> {
30 let store = Store::open_in_memory().await?;
31 let agent = AgentId::new("demo-agent").expect("non-empty id");
32 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
33
34 memory
35 .remember("The Eiffel Tower is in Paris.", MemoryLayer::Semantic)
36 .await?;
37 memory
38 .remember("Paris is the capital of France.", MemoryLayer::Semantic)
39 .await?;
40 memory.remember("Bonjour!", MemoryLayer::ShortTerm).await?;
41
42 println!("=== recall (top 2) ===");
43 let results = memory.recall("What city is the Eiffel Tower in?", 2).await?;
44 for r in &results {
45 println!(
46 " [{layer}] {score:.3} {text}",
47 layer = r.layer.table(),
48 score = r.score,
49 text = r.text
50 );
51 }
52
53 let first_id = results[0].id.clone();
54 memory.invalidate(&first_id).await?;
55 println!("\nInvalidated id={first_id}");
56
57 let after = memory.recall("Eiffel Tower", 5).await?;
58 println!("Recall after invalidation: {} result(s)", after.len());
59
60 let stats = memory.stats().await?;
61 println!(
62 "\nStats: {} semantic, {} short-term (valid).",
63 stats.semantic, stats.short_term
64 );
65
66 Ok(())
67}Sourcepub async fn forget(&self, id: &str) -> Result<()>
pub async fn forget(&self, id: &str) -> Result<()>
Suppression physique d’un souvenir (RGPD, droit à l’effacement).
Atomique : la ligne memory et son miroir FTS disparaissent ensemble.
§Errors
Propage les erreurs de stockage.
Sourcepub async fn purge_agent(&self) -> Result<()>
pub async fn purge_agent(&self) -> Result<()>
Purge toutes les données de cet agent : souvenirs (memory), entités
(entity) et relations (edge). Irréversible (RGPD, droit à l’oubli).
Idempotent : ne renvoie pas d’erreur si l’agent n’a aucune donnée.
Atomique : pas de purge partielle possible (tout ou rien).
§Errors
Propage les erreurs de stockage.
Sourcepub async fn stats(&self) -> Result<AgentStats>
pub async fn stats(&self) -> Result<AgentStats>
Statistiques des souvenirs valides de cet agent, par couche.
§Errors
Propage les erreurs de stockage.
Examples found in repository?
29async fn main() -> Result<(), Box<dyn std::error::Error>> {
30 let store = Store::open_in_memory().await?;
31 let agent = AgentId::new("demo-agent").expect("non-empty id");
32 let memory = Memory::open(store, Box::new(FakeEmbedder), agent).await?;
33
34 memory
35 .remember("The Eiffel Tower is in Paris.", MemoryLayer::Semantic)
36 .await?;
37 memory
38 .remember("Paris is the capital of France.", MemoryLayer::Semantic)
39 .await?;
40 memory.remember("Bonjour!", MemoryLayer::ShortTerm).await?;
41
42 println!("=== recall (top 2) ===");
43 let results = memory.recall("What city is the Eiffel Tower in?", 2).await?;
44 for r in &results {
45 println!(
46 " [{layer}] {score:.3} {text}",
47 layer = r.layer.table(),
48 score = r.score,
49 text = r.text
50 );
51 }
52
53 let first_id = results[0].id.clone();
54 memory.invalidate(&first_id).await?;
55 println!("\nInvalidated id={first_id}");
56
57 let after = memory.recall("Eiffel Tower", 5).await?;
58 println!("Recall after invalidation: {} result(s)", after.len());
59
60 let stats = memory.stats().await?;
61 println!(
62 "\nStats: {} semantic, {} short-term (valid).",
63 stats.semantic, stats.short_term
64 );
65
66 Ok(())
67}Auto Trait Implementations§
impl !RefUnwindSafe for Memory
impl !UnwindSafe for Memory
impl Freeze for Memory
impl Send for Memory
impl Sync for Memory
impl Unpin for Memory
impl UnsafeUnpin for Memory
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
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>
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>
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