b25377b6ca
Task 7 inserted note embeddings into the memory Store but nothing read them
back, and facts weren't indexed at all. Complete the read side:
- Facts are now embedded and inserted into memStore on capture (best-effort,
never fails the fact write) — the notes table can't answer fact questions
("когда я пил воду?"), so memStore is their only recall path.
- Insert meta now carries text/ts/type so a Search hit is self-describing.
- IntentQuery consults memStore.Search after notes-RAG misses and before the
general-knowledge phraser fallback (bestRecall, unit-tested). Strictly
additive: it only runs once the notes path has already given up, so it can't
regress existing recall. Note hits here overlap notes-RAG by design; the
payoff is fact recall and a real read seam for a future persistent backend.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
26 lines
866 B
Go
26 lines
866 B
Go
package main
|
|
|
|
import "github.com/kami/maven/internal/memory"
|
|
|
|
// bestRecall is the read side of the long-term memory store: the top hit's
|
|
// stored text when it clears the confidence gate. This recalls across BOTH
|
|
// notes and facts (facts aren't in the notes table, so this is the only path
|
|
// that can answer "when did I last …?" from a captured fact). A note hit here
|
|
// is redundant with the notes-RAG path — by design; the two indexes can diverge
|
|
// once the backend is swapped for a persistent/external store. ok=false when
|
|
// there's no hit above the threshold or the hit carries no text.
|
|
func bestRecall(results []memory.Result, min float64) (string, bool) {
|
|
if len(results) == 0 {
|
|
return "", false
|
|
}
|
|
top := results[0]
|
|
if top.Score < min {
|
|
return "", false
|
|
}
|
|
text := top.Meta["text"]
|
|
if text == "" {
|
|
return "", false
|
|
}
|
|
return text, true
|
|
}
|