feat: add long-term memory systems with fused retrieval and memory explorer
Phase 5 (ADR-0003). pkg/concepts fixes the epistemic vocabulary (observation, fact, memory, claim, hypothesis, belief, prediction, assumption, inference, opinion), memory kinds and relation names. internal/memory stores episodic, semantic, procedural and autobiographical memories in one mind-scoped table with trust-derived credibility, importance, salience and decaying activation. Retrieval fuses full-text rank (any-term by default), optional pgvector similarity, recency, activation, importance and credibility, and returns the component scores so every recall can be explained. Decay lowers activation and never deletes; retraction and supersession keep rows for provenance. Relationships are constrained to one mind at insert time. Embeddings live in a conditional pgvector table keyed by model so vector spaces are never mixed; without an embedder the system degrades to text and graph retrieval. Attention gates encoding: the attend handler turns admitted observations into episodic memories (operator changes become autobiographical ones) with memory_created events; the retrieve process proposes recalled memories as candidates and admitted recalls are reinforced with memory_retrieved events carrying their scoring components. Memory explorer UI (search with component breakdown, timeline, filters, operator knowledge entry), memory detail with provenance, relationships, citing events and an inaccurate-memory correction; API; noemactl memory commands; decay and embed-missing background jobs.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
// Package embeddings defines the embedding provider interface and helpers for
|
||||
// storing vectors in pgvector. Providers arrive with the LLM layer; None keeps
|
||||
// the system fully functional without them (spec §46).
|
||||
package embeddings
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Embedder turns texts into vectors.
|
||||
type Embedder interface {
|
||||
// Model returns a stable identifier such as "openai/text-embedding-3-small"
|
||||
// so vectors from different models are never compared.
|
||||
Model() string
|
||||
Dims() int
|
||||
Embed(ctx context.Context, texts []string) ([][]float32, error)
|
||||
}
|
||||
|
||||
// ErrUnavailable is returned by None.
|
||||
var ErrUnavailable = errors.New("embeddings unavailable")
|
||||
|
||||
// None is the embedder used when no provider is configured.
|
||||
type None struct{}
|
||||
|
||||
// Model implements Embedder.
|
||||
func (None) Model() string { return "" }
|
||||
|
||||
// Dims implements Embedder.
|
||||
func (None) Dims() int { return 0 }
|
||||
|
||||
// Embed implements Embedder.
|
||||
func (None) Embed(context.Context, []string) ([][]float32, error) { return nil, ErrUnavailable }
|
||||
|
||||
// Format renders a vector in pgvector's text syntax.
|
||||
func Format(v []float32) string {
|
||||
var b strings.Builder
|
||||
b.WriteByte('[')
|
||||
for i, f := range v {
|
||||
if i > 0 {
|
||||
b.WriteByte(',')
|
||||
}
|
||||
b.WriteString(strconv.FormatFloat(float64(f), 'f', -1, 32))
|
||||
}
|
||||
b.WriteByte(']')
|
||||
return b.String()
|
||||
}
|
||||
Reference in New Issue
Block a user