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" } // THE BEARER IS PASSED THROUGH, and its absence was a single point of failure hiding in an omitted field. // // The gateway requires a bearer on every route except the health check. This constructor accepted an // APIKey on the config and never handed it to the client, so the megamind embedding provider could not // authenticate AT ALL. It appeared to work only because MM_MEGAMIND_URL points at port 8090, which is a // fifteen line node reverse proxy belonging to another project that injects the credential and forwards to // the real gateway. Every embedding in this platform therefore depended on that proxy process being alive, // and if it stopped there was no way to recover from inside this codebase, because no code path could // supply a token. // // Found by Gate A, and the failure shape is worth remembering: the unauthenticated call returned 401, the // error was swallowed upstream, and the test reported SIMILARITY 0. It read as "the embedder has no // semantics" when the real cause was "the request was refused". A transport failure wearing the costume of // a bad model score is the most misleading result in this whole build. c, err := inference.New(inference.Config{ BaseURL: cfg.MegamindURL, EmbedModel: model, Dimension: cfg.Dimension, Token: cfg.APIKey, }) 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 }