f3fa6b353a
Revert voided the fact row and left the vector, so recall kept serving the voided fact's utterance and the documented repair reported success on a box that stayed broken. There was no way to repair a poisoned box at all. DeletePrefix covers every vector for the key, earlier rows included: their values are superseded, and a superseded value has no business claiming a turn. It is best-effort — the audit trail is already committed, and a fact that is voided but still recallable beats a void that failed.
65 lines
1.9 KiB
Go
65 lines
1.9 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Stage 3 of #470: reverting a fact reported success and left the vector that
|
|
// was answering questions, so the documented repair did not repair.
|
|
func TestVoidLatestFactDropsMemoryVectors(t *testing.T) {
|
|
ctx := context.Background()
|
|
s := newTestStore(t)
|
|
now := time.Now()
|
|
mem := s.VectorMemory()
|
|
|
|
if _, err := s.WriteFact(ctx, now, KindSelf, "go_version", `"1.20"`, "tap:voice", 1.0, sql.NullInt64{}); err != nil {
|
|
t.Fatalf("WriteFact: %v", err)
|
|
}
|
|
// The id shape actionFact writes: fact:<key>:<unix>.
|
|
if err := mem.Insert(ctx, "fact:go_version:1", []float32{1, 0, 0}, map[string]string{
|
|
"type": "fact", "text": "какая последняя версия языка Go?",
|
|
}); err != nil {
|
|
t.Fatalf("Insert: %v", err)
|
|
}
|
|
// A vector for another key must survive the void.
|
|
if err := mem.Insert(ctx, "fact:water:1", []float32{0, 1, 0}, map[string]string{
|
|
"type": "fact", "text": "запиши что я пил воду",
|
|
}); err != nil {
|
|
t.Fatalf("Insert: %v", err)
|
|
}
|
|
|
|
if _, _, err := s.VoidLatestFact(ctx, "go_version", "feedback", now.Add(time.Minute)); err != nil {
|
|
t.Fatalf("VoidLatestFact: %v", err)
|
|
}
|
|
|
|
got, err := mem.ByPrefix(ctx, "fact:")
|
|
if err != nil {
|
|
t.Fatalf("ByPrefix: %v", err)
|
|
}
|
|
if len(got) != 1 || got[0].ID != "fact:water:1" {
|
|
t.Fatalf("after the void the index holds %+v; want only fact:water:1", got)
|
|
}
|
|
}
|
|
|
|
func TestDeletePrefixDoesNotWidenOnWildcards(t *testing.T) {
|
|
ctx := context.Background()
|
|
s := newTestStore(t)
|
|
mem := s.VectorMemory()
|
|
|
|
for _, id := range []string{"fact:a_b:1", "fact:axb:1"} {
|
|
if err := mem.Insert(ctx, id, []float32{1, 0}, map[string]string{"type": "fact"}); err != nil {
|
|
t.Fatalf("Insert %q: %v", id, err)
|
|
}
|
|
}
|
|
n, err := mem.DeletePrefix(ctx, "fact:a_b:")
|
|
if err != nil {
|
|
t.Fatalf("DeletePrefix: %v", err)
|
|
}
|
|
if n != 1 {
|
|
t.Fatalf("deleted %d rows; the _ in the key must not match x", n)
|
|
}
|
|
}
|