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

+42
View File
@@ -1,6 +1,7 @@
package loki
import (
"encoding/json"
"strings"
"testing"
)
@@ -27,3 +28,44 @@ func TestRecallInterneArchive(t *testing.T) {
}
}
}
// Lot 46 : la façade lit l'archive (un bloc par sa séquence, ou tous les
// blocs lisibles par séquence croissante) ; le reste est chez elle.
func TestRecallInterneLecture(t *testing.T) {
testHome(t)
t.Setenv(internalTokenEnv, jetonTest)
if w := appelOAIInterne(t, "GET", "/internal/v1/recall/blocks", ""); w.Code != 200 || strings.TrimSpace(w.Body.String()) != "[]" {
t.Fatalf("archive vide : %d %s", w.Code, w.Body.String())
}
for _, c := range []string{"premier <bloc>", "second bloc"} {
if _, err := archiveRecallBlock("bash: "+c, "tool", c); err != nil {
t.Fatal(err)
}
}
w := appelOAIInterne(t, "GET", "/internal/v1/recall/block?seq=1", "")
if w.Code != 200 {
t.Fatalf("bloc 1 : %d %s", w.Code, w.Body.String())
}
var blk recallBlock
if err := json.Unmarshal(w.Body.Bytes(), &blk); err != nil || blk.ID != "r1" || blk.Content != "premier <bloc>" || blk.Label != "bash: premier <bloc>" {
t.Fatalf("bloc 1 : %v %+v", err, blk)
}
if w := appelOAIInterne(t, "GET", "/internal/v1/recall/block?seq=9", ""); w.Code != 404 {
t.Fatalf("absent : %d", w.Code)
}
for _, q := range []string{"", "?seq=", "?seq=r1", "?seq=-1"} {
if w := appelOAIInterne(t, "GET", "/internal/v1/recall/block"+q, ""); w.Code != 400 {
t.Fatalf("%q : %d", q, w.Code)
}
}
for _, p := range []string{"/internal/v1/recall/block?seq=1", "/internal/v1/recall/blocks"} {
if w := appelOAIInterne(t, "POST", p, ""); w.Code != 405 {
t.Fatalf("POST %s : %d", p, w.Code)
}
}
w = appelOAIInterne(t, "GET", "/internal/v1/recall/blocks", "")
var all []recallBlock
if err := json.Unmarshal(w.Body.Bytes(), &all); err != nil || len(all) != 2 || all[0].Seq != 1 || all[1].Content != "second bloc" {
t.Fatalf("tous : %v %s", err, w.Body.String())
}
}