Lot 46 : outils recall et recall_search exécutés par la façade

Les deux outils qui rappellent un bloc archivé par la compaction ne passent
plus par /tool/exec du Go : src/recall.rs porte toolRecall et
toolRecallSearch (id tolérant comme recallIDToSeq, mots-clés en minuscules
rune par rune comme strings.ToLower, score libellé double et plus récent
d'abord, limites, extraits et textes du Go). L'archive reste au Go, seul à
tenir la séquence de la base, qui la sert à la façade
(GET /internal/v1/recall/block?seq=N et /internal/v1/recall/blocks, blocs
chiffrés sous une mémoire verrouillée exclus) ; ses propres outils passent
par les mêmes lectures. Go injoignable : l'appel passe par lui.

Parité : journal de 41 appels sur une archive de 35 blocs tiré du Go
(parity_recall_test.go → tests/parity_recall/recall.json), rejoué par
tests/recall.rs ; un tour de la façade qui rappelle et cherche
(tests/lot6.rs) ; TestRecallInterneLecture côté Go.

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 06:54:35 +00:00
1 parent db1f20c0a4
commit 92e9adee7d
15 files changed
+1416 -25

No files matched your search

@@ -0,0 +1,97 @@
# Lot 46 — Outils recall et recall_search dans la façade
## Contexte
La compaction résume les vieux tours d'une discussion. Avant de résumer un
gros bloc (un code, une page, un diff), elle l'archive verbatim sous un id
court (`r7`) que le résumé cite. L'agent a deux outils pour le retrouver :
- `recall(id)` rend le bloc exact ;
- `recall_search(query)` retrouve un bloc et son id par mots-clés, même
sorti du résumé courant.
La façade compacte elle-même et archive par le Go
(`/internal/v1/recall/archive`, lot 6) : l'id vient de la séquence de la
base, que seul le Go tient. Les deux outils passaient encore par
`/internal/v1/tool/exec`.
## Le lot
`src/recall.rs` porte `toolRecall` et `toolRecallSearch`
(`chat_recall.go`) :
- **l'id tolérant** (`recallIDToSeq`) :
- espaces, un préfixe `r` puis un préfixe `R`, espaces encore ;
- des chiffres seulement : ni signe, ni dépassement de 64 bits ;
- un id mal formé ne lit pas l'archive ;
- **les mots-clés** (`recallTokens`) :
- mise en minuscules rune par rune, comme `strings.ToLower` (`İ`
donne `i`, `Σ` donne `σ`) ;
- coupés sur tout ce qui n'est ni `a`–`z`, ni `0`–`9`, ni `à`–`ÿ` ;
- deux runes au moins ;
- **le score** :
- un point par terme présent dans le contenu, deux dans le libellé ;
- à égalité, le plus récent d'abord ;
- 5 résultats par défaut, 20 au plus, limite tronquée comme
`int(float64)` ;
- **les textes**, mêmes que le Go :
- id ou requête manquants ;
- bloc introuvable (id cité par `%q`) ;
- bloc rappelé verbatim ;
- liste des résultats avec un extrait d'une ligne de 160 runes ;
- aucun résultat.
L'archive reste au Go, qui la sert à la façade :
- `GET /internal/v1/recall/block?seq=N` : le bloc (200), ou 404 s'il est
absent ou chiffré sous une mémoire verrouillée ;
- `GET /internal/v1/recall/blocks` : tous les blocs lisibles, par séquence
croissante.
`recallGet` et `recallSearch` du Go passent par les mêmes lectures
(`recallGetSeq`, `recallAll`).
`GoTurnHost::exec_tool` exécute les deux outils avant le repli sur le Go.
Si le Go ne répond pas, l'appel passe par lui.
## Parité
`internal/loki/parity_recall_test.go` archive 35 blocs variés :
- accents et casse Unicode ;
- balises et entités ;
- bloc vide ;
- premières lignes longues ;
- vingt-cinq blocs semblables.
Il tire ensuite du Go un journal de 41 appels
(`tests/parity_recall/recall.json`), avec les blocs tels que l'archive les
sert :
- `recall` :
- id absent, non texte, blanc ;
- variantes de préfixe et d'espaces ;
- zéros de tête ;
- mal formé, négatif, signe plus, zéro, absent, démesuré ;
- guillemets dans l'id ;
- `recall_search` :
- requête absente, non texte, blanche ;
- mots trop courts ;
- casse, accents, `İ`, grec hors des mots ;
- souligné coupé ;
- extraits bornés ;
- limites : une, tronquée, négative, par défaut, au plus, en texte
ignorée ;
- aucun résultat ;
- ponctuation.
`tests/recall.rs` le rejoue : le faux Go sert les mêmes blocs. Il vérifie
aussi le repli quand le Go ne répond pas.
D'autres tests complètent :
- `tests/lot6.rs` (`recall_par_la_facade`) : un tour de la façade rappelle
et cherche sans passer par `/tool/exec` ;
- `TestRecallInterneLecture` : les deux lectures du Go (absent, seq
illisible, méthode refusée, ordre) ;
- tests unitaires : ids, mots-clés, score, extraits, textes.