Merge branch 'fix/g09' into fix/integrated
This commit is contained in:
@@ -64,11 +64,17 @@ func (m *MemoryStore) Insert(ctx context.Context, id string, vec []float32, meta
|
||||
|
||||
// Search returns the topK nearest rows by cosine similarity. A full scan; see
|
||||
// the type doc for why that's fine at this scale.
|
||||
//
|
||||
// Rows under memory.NonRecallPrefix are excluded in SQL. They are speaker
|
||||
// voiceprints sharing this table, and note recall must not rank them; see that
|
||||
// constant for why the previous arrangement only appeared to do this.
|
||||
func (m *MemoryStore) Search(ctx context.Context, vec []float32, topK int) ([]memory.Result, error) {
|
||||
if topK <= 0 {
|
||||
topK = 10
|
||||
}
|
||||
rows, err := m.db.QueryContext(ctx, `SELECT id, vec, meta FROM memory_vectors`)
|
||||
rows, err := m.db.QueryContext(ctx,
|
||||
`SELECT id, vec, meta FROM memory_vectors WHERE id NOT LIKE ? ESCAPE '\'`,
|
||||
escapeLike(memory.NonRecallPrefix)+"%")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("memory: scan: %w", err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package store
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/kami/maven/internal/memory"
|
||||
)
|
||||
|
||||
func newMemTestStore(t *testing.T) *Store {
|
||||
@@ -101,3 +104,38 @@ func TestMemoryStorePersistsAcrossReopen(t *testing.T) {
|
||||
t.Fatalf("memory did not survive reopen: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
// A voiceprint sharing the vector table must never rank as a note hit. The
|
||||
// dimensions match here on purpose: what used to hide these rows was cosine
|
||||
// returning 0 on a width mismatch, which is a property of two model choices and
|
||||
// not of the store.
|
||||
func TestMemoryStoreSearchSkipsVoiceprints(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
m := newMemTestStore(t).VectorMemory()
|
||||
|
||||
if err := m.Insert(ctx, "note:1", []float32{0, 1, 0}, map[string]string{"text": "заметка"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := m.Insert(ctx, memory.NonRecallPrefix+"kami", []float32{1, 0, 0}, map[string]string{"name": "Ками"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got, err := m.Search(ctx, []float32{1, 0, 0}, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("Search: %v", err)
|
||||
}
|
||||
for _, r := range got {
|
||||
if strings.HasPrefix(r.ID, memory.NonRecallPrefix) {
|
||||
t.Fatalf("recall returned a voiceprint: %+v", r)
|
||||
}
|
||||
}
|
||||
if len(got) != 1 || got[0].ID != "note:1" {
|
||||
t.Fatalf("Search = %+v, want just the note", got)
|
||||
}
|
||||
|
||||
// The row is still there for the speaker code that owns it.
|
||||
recs, err := m.ByPrefix(ctx, memory.NonRecallPrefix)
|
||||
if err != nil || len(recs) != 1 {
|
||||
t.Fatalf("ByPrefix = %+v, %v; want the voiceprint", recs, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user