feat(embeddings): add embedding model support and related changes

* Introduced EmbeddingModel method in Client and Provider interfaces
* Updated InsertThought and SearchThoughts methods to handle embedding models
* Created embeddings table and updated match_thoughts function for model filtering
* Removed embedding column from thoughts table
* Adjusted permissions for new embeddings table
This commit is contained in:
Hein
2026-03-25 16:25:41 +02:00
parent c8ca272b03
commit cebef3a07c
19 changed files with 259 additions and 88 deletions

View File

@@ -3,7 +3,6 @@ package store
import (
"context"
"fmt"
"regexp"
"time"
"github.com/jackc/pgx/v5"
@@ -68,7 +67,7 @@ func (db *DB) Ready(ctx context.Context) error {
return db.Ping(readyCtx)
}
func (db *DB) VerifyRequirements(ctx context.Context, dimensions int) error {
func (db *DB) VerifyRequirements(ctx context.Context) error {
var hasVector bool
if err := db.pool.QueryRow(ctx, `select exists(select 1 from pg_extension where extname = 'vector')`).Scan(&hasVector); err != nil {
return fmt.Errorf("verify vector extension: %w", err)
@@ -85,33 +84,12 @@ func (db *DB) VerifyRequirements(ctx context.Context, dimensions int) error {
return fmt.Errorf("match_thoughts function is missing")
}
var embeddingType string
err := db.pool.QueryRow(ctx, `
select format_type(a.atttypid, a.atttypmod)
from pg_attribute a
join pg_class c on c.oid = a.attrelid
join pg_namespace n on n.oid = c.relnamespace
where n.nspname = 'public'
and c.relname = 'thoughts'
and a.attname = 'embedding'
and not a.attisdropped
`).Scan(&embeddingType)
if err != nil {
return fmt.Errorf("verify thoughts.embedding type: %w", err)
var hasEmbeddings bool
if err := db.pool.QueryRow(ctx, `select exists(select 1 from pg_tables where schemaname = 'public' and tablename = 'embeddings')`).Scan(&hasEmbeddings); err != nil {
return fmt.Errorf("verify embeddings table: %w", err)
}
re := regexp.MustCompile(`vector\((\d+)\)`)
matches := re.FindStringSubmatch(embeddingType)
if len(matches) != 2 {
return fmt.Errorf("unexpected embedding type %q", embeddingType)
}
var actualDimensions int
if _, err := fmt.Sscanf(matches[1], "%d", &actualDimensions); err != nil {
return fmt.Errorf("parse embedding dimensions from %q: %w", embeddingType, err)
}
if actualDimensions != dimensions {
return fmt.Errorf("embedding dimension mismatch: config=%d db=%d", dimensions, actualDimensions)
if !hasEmbeddings {
return fmt.Errorf("embeddings table is missing — run migrations")
}
return nil