package embeddings import ( "context" "errors" "github.com/missionworkforce/missionmatch/internal/platform/config" "github.com/missionworkforce/missionmatch/internal/platform/inference" ) // megamindEmbedder is the Embedder backed by the stateless MEGAMIND inference plane. It is the // production path for cleared CUI data: the embedding model runs out of process on the Apple Silicon // cluster (Metal), and this adapter reaches it through the typed inference client (timeouts, retries, // circuit breaker). It L2 normalizes the returned vectors so cosine distance over the pgvector column is // meaningful, matching the contract every other provider here follows. type megamindEmbedder struct { client *inference.Client dim int } // newMegamind builds the MEGAMIND backed Embedder from the embeddings config. func newMegamind(cfg config.Embeddings) (Embedder, error) { if cfg.MegamindURL == "" { return nil, errors.New("embeddings: MM_MEGAMIND_URL required for the megamind provider") } model := cfg.Model if model == "" { model = "all-minilm" } c, err := inference.New(inference.Config{ BaseURL: cfg.MegamindURL, EmbedModel: model, Dimension: cfg.Dimension, }) if err != nil { return nil, err } return &megamindEmbedder{client: c, dim: cfg.Dimension}, nil } func (m *megamindEmbedder) Dimension() int { return m.dim } func (m *megamindEmbedder) Embed(ctx context.Context, text string) ([]float32, error) { out, err := m.EmbedBatch(ctx, []string{text}) if err != nil { return nil, err } return out[0], nil } func (m *megamindEmbedder) EmbedBatch(ctx context.Context, texts []string) ([][]float32, error) { res, err := m.client.Embed(ctx, texts) if err != nil { return nil, err } for i := range res.Embeddings { normalize(res.Embeddings[i]) } return res.Embeddings, nil }