Lot 40 : outils mémoire de l'agent exécutés par la façade

Quand la façade tient la mémoire (LOKI_MEM=rust), les outils mem_search,
mem_read, mem_add, mem_edit et tracker de ses tours s'exécutent chez elle
(src/memory/tools.rs, port de chat_memory.go et de l'outil de tracker.go) :
mêmes résultats et diffs, mêmes lectures et écritures que les routes de la
mémoire (scellées selon le chiffrement, .bak, index tenu par le code, seed
au nom du projet). Recherche classée par couverture puis pertinence,
extrait coupé à l'octet comme le Go ; trackers vus niveau par niveau.

ChatShared porte la même mémoire que les routes ; tracker_add prend l'heure
en paramètre (tracker_add_at). Côté Go, l'heure des trackers passe par
trackerNow, que le journal fixe.

Parité : journal de 57 appels tiré du Go (parity_mem_tools_test.go →
tests/parity_mem/outils.json : résultats, diffs, fichiers de la mémoire et
trackers), rejoué par tests/memory.rs ; un tour de la façade qui crée une
page (tests/lot6.rs).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016tcGfJWefW5kUGoC2wL8cv
This commit is contained in:
Claude committed 2026-10-16 04:29:53 +00:00
1 parent 35886da9b1
commit 90d6dd4a9a
14 files changed
+3578 -14

No files matched your search

+17 -1
View File
@@ -43,6 +43,8 @@ use crate::gojson::{self, Kind};
use crate::proxy::Body;
use crate::store::{BK_CONFIG, BK_STATE, CryptError, Store};
pub mod tools;
/// Index du projet, tenu par le code.
pub const MEM_INDEX_FILE: &str = "MEMORY.md";
/// Magic des contenus chiffrés (`memPageMagic`).
@@ -1021,6 +1023,20 @@ impl Memory {
name: &str,
when: &str,
text: &str,
) -> Result<String, String> {
self.tracker_add_at(store, proj, name, when, text, now_ms())
.await
}
/// [`Self::tracker_add`], « maintenant » donné (`when` vide).
async fn tracker_add_at(
&self,
store: &Store,
proj: &str,
name: &str,
when: &str,
text: &str,
now: i64,
) -> Result<String, String> {
let name = go_trim(name).to_string();
if name.is_empty() {
@@ -1029,7 +1045,7 @@ impl Memory {
if go_trim(text).is_empty() {
return Err("contenu vide".into());
}
let (ts, date_only) = parse_when(when, now_ms(), self.tz)?;
let (ts, date_only) = parse_when(when, now, self.tz)?;
let mut slug = slugify_ident(&name);
if slug.is_empty() {
slug = "tracker".into();