// {{ display_name }} MCP server — generated by mcpify. Do not hand-edit.
//
// Single source of truth for embedding computation. scripts/populate-embeddings.ts
// (indexing time) and tools/search-tool.ts (live query time) both import
// `embed()` from here, so the two are structurally guaranteed to share the
// same model and vector space — see the plan's embeddings decision.

import { pipeline } from '@xenova/transformers';

const MODEL_ID = 'Xenova/all-mpnet-base-v2';

type Extractor = (text: string, options: { pooling: string; normalize: boolean }) => Promise<{ data: Float32Array }>;

let extractor: Extractor | undefined;

async function getExtractor(): Promise<Extractor> {
  extractor ??= (await pipeline('feature-extraction', MODEL_ID)) as unknown as Extractor;
  return extractor;
}

/** Computes a 768-dim embedding vector for `text`, mean-pooled and normalized. */
export async function embed(text: string): Promise<number[]> {
  const model = await getExtractor();
  const output = await model(text, { pooling: 'mean', normalize: true });
  return Array.from(output.data);
}
