feat(memory): hybrid vector search via embedder

- repository: optional pgvector embedding column (migration with
  CREATE EXTENSION guarded by main), SearchByVector cosine search,
  vector-enabled insert path
- service: SetEmbedder — memories are embedded on Add; Search merges
  vector hits with n-gram keyword matches (vector first, deduped)
- embedder was already implemented (OpenAI-compatible API + n-gram FNV
  fallback) but never instantiated; main now wires it from
  EMBEDDING_API_URL/EMBEDDING_MODEL config
This commit is contained in:
Aska committed 2026-08-20 20:57:13 +08:00
1 parent 8190007865
commit 8495a4b055
4 files changed
+119 -8

No files matched your search

+10
View File
@@ -133,6 +133,16 @@ func main() {
if database != nil {
memRepo := memory.NewRepository(database)
memSvc = memory.NewService(memRepo)
// Embedding: real API when configured, n-gram FNV fallback otherwise
emb := memory.NewEmbedder(cfg.EmbeddingAPIURL, cfg.EmbeddingAPIKey, cfg.EmbeddingModel)
if err := db.RunMigration(context.Background(), database, "memories-vector", db.SplitSQL(memory.VectorMigrationSQL(emb.Dims()))); err != nil {
logger.Infof("[memory] pgvector unavailable, keyword-only search: %v", err)
} else {
memRepo.EnableVector()
memSvc.SetEmbedder(emb)
logger.Infof("[memory] hybrid search enabled (vector dims=%d, api=%v)", emb.Dims(), emb.IsAvailable())
}
logger.Infof("[memory] connected")
} else {
logger.Infof("[memory] disabled (no database)")