{"version":3,"file":"pooling.mjs","names":[],"sources":["../../../../src/batteries/embeddings/transformers_js/pooling.ts"],"sourcesContent":["/**\n * Deterministic, battery-owned pooling + L2-normalization for the transformers.js embeddings battery.\n *\n * @module @nhtio/adk/batteries/embeddings/transformers_js/pooling\n *\n * @remarks\n * Used when `poolingOwner: 'battery'`. The pipeline is asked for raw `pooling:'none'` token states —\n * a `[batch, seq, hidden]` tensor — and this module pools them into one vector per input in pure JS,\n * identically across Node and the browser. That removes the per-runtime post-processing variance that\n * widens the node↔browser cosine gap; only the irreducible ONNX-Runtime kernel floor remains.\n *\n * Pooling strategies mirror the transformers.js feature-extraction options:\n * - `mean` — attention-unaware mean over the sequence axis (matches the pipeline's `'mean'`, which\n *   also means over all positions for a single ungrouped sequence).\n * - `cls` / `first_token` — the first token's hidden state.\n * - `eos` / `last_token` — the last token's hidden state.\n * - `none` — no pooling (caller already has the vector); returned unchanged per row.\n */\n\n/** A 3-D `[batch, seq, hidden]` nested array (raw token states from `pooling:'none'`). */\nexport type TokenStates3D = number[][][]\n/** A 2-D `[batch, hidden]` nested array (already-pooled vectors). */\nexport type Pooled2D = number[][]\n\n/**\n * Mean-pool a `[seq, hidden]` matrix into a `[hidden]` vector.\n *\n * @param rows - The per-token hidden-state rows.\n */\nconst meanPool = (rows: number[][]): number[] => {\n  const seq = rows.length\n  if (seq === 0) return []\n  const hidden = rows[0].length\n  const out = new Array<number>(hidden).fill(0)\n  for (const row of rows) {\n    for (let h = 0; h < hidden; h++) out[h] += row[h]\n  }\n  for (let h = 0; h < hidden; h++) out[h] /= seq\n  return out\n}\n\n/**\n * L2-normalize a vector in place-safe fashion (returns a new array). A zero vector is returned\n * unchanged (no divide-by-zero).\n *\n * @param vec - The vector to normalize.\n */\nexport const l2Normalize = (vec: number[]): number[] => {\n  let sumSq = 0\n  for (const v of vec) sumSq += v * v\n  const norm = Math.sqrt(sumSq)\n  if (norm === 0) return vec.slice()\n  return vec.map((v) => v / norm)\n}\n\n/**\n * Pool a single `[seq, hidden]` matrix into one `[hidden]` vector per the strategy.\n *\n * @param rows - The per-token hidden-state rows for one input.\n * @param pooling - The pooling strategy.\n */\nconst poolOne = (rows: number[][], pooling: string): number[] => {\n  switch (pooling) {\n    case 'cls':\n    case 'first_token':\n      return (rows[0] ?? []).slice()\n    case 'eos':\n    case 'last_token':\n      return (rows[rows.length - 1] ?? []).slice()\n    case 'none':\n      // No pooling requested but we have token states — fall back to mean so a vector still results.\n      return meanPool(rows)\n    case 'mean':\n    default:\n      return meanPool(rows)\n  }\n}\n\n/**\n * Pool raw `[batch, seq, hidden]` token states into `[batch, hidden]` vectors and optionally\n * L2-normalize — the deterministic battery-owned path (`poolingOwner: 'battery'`).\n *\n * @param tokenStates - The `[batch, seq, hidden]` raw states from `pooling:'none'`.\n * @param pooling - The pooling strategy (`'mean'` default).\n * @param normalize - Whether to L2-normalize each pooled vector (default `true`).\n * @returns One pooled (and optionally normalized) vector per batch row.\n */\nexport const poolAndNormalize = (\n  tokenStates: TokenStates3D,\n  pooling: string,\n  normalize: boolean\n): Pooled2D =>\n  tokenStates.map((rows) => {\n    const pooled = poolOne(rows, pooling)\n    return normalize ? l2Normalize(pooled) : pooled\n  })\n\n/** Default {@link poolAndNormalize}. */\nexport const defaultPoolAndNormalize = poolAndNormalize\n"],"mappings":";;;;;;AA6BA,IAAM,YAAY,SAA+B;CAC/C,MAAM,MAAM,KAAK;CACjB,IAAI,QAAQ,GAAG,OAAO,CAAC;CACvB,MAAM,SAAS,KAAK,GAAG;CACvB,MAAM,MAAM,IAAI,MAAc,MAAM,EAAE,KAAK,CAAC;CAC5C,KAAK,MAAM,OAAO,MAChB,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,IAAI,MAAM,IAAI;CAEjD,KAAK,IAAI,IAAI,GAAG,IAAI,QAAQ,KAAK,IAAI,MAAM;CAC3C,OAAO;AACT;;;;;;;AAQA,IAAa,eAAe,QAA4B;CACtD,IAAI,QAAQ;CACZ,KAAK,MAAM,KAAK,KAAK,SAAS,IAAI;CAClC,MAAM,OAAO,KAAK,KAAK,KAAK;CAC5B,IAAI,SAAS,GAAG,OAAO,IAAI,MAAM;CACjC,OAAO,IAAI,KAAK,MAAM,IAAI,IAAI;AAChC;;;;;;;AAQA,IAAM,WAAW,MAAkB,YAA8B;CAC/D,QAAQ,SAAR;EACE,KAAK;EACL,KAAK,eACH,QAAQ,KAAK,MAAM,CAAC,GAAG,MAAM;EAC/B,KAAK;EACL,KAAK,cACH,QAAQ,KAAK,KAAK,SAAS,MAAM,CAAC,GAAG,MAAM;EAC7C,KAAK,QAEH,OAAO,SAAS,IAAI;EAEtB,SACE,OAAO,SAAS,IAAI;CACxB;AACF;;;;;;;;;;AAWA,IAAa,oBACX,aACA,SACA,cAEA,YAAY,KAAK,SAAS;CACxB,MAAM,SAAS,QAAQ,MAAM,OAAO;CACpC,OAAO,YAAY,YAAY,MAAM,IAAI;AAC3C,CAAC;;AAGH,IAAa,0BAA0B"}