@mastra/fastembed 1.3.4 → 1.3.5-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import fsp from "fs/promises";
2
2
  import os from "os";
3
3
  import path from "path";
4
- import { AddedToken, Tokenizer } from "@anush008/tokenizers";
5
4
  import fs from "fs";
6
5
  import { Readable } from "stream";
7
6
  import { pipeline } from "stream/promises";
8
- import * as ort from "onnxruntime-node";
7
+ import { AddedToken, Tokenizer } from "@anush008/tokenizers";
9
8
  import { downloadFile } from "@huggingface/hub";
9
+ import * as ort from "onnxruntime-node";
10
10
  //#region ../../../../../setup-pnpm/node_modules/.bin/store/v11/links/@/zod/4.6.7/4c9f15c99caaca8b83ba8ab68f247a75121c86fb7e498876ed36daccd0f3d3ce/node_modules/zod/v4/core/util.js
11
11
  function getEnumValues(entries) {
12
12
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
@@ -18387,12 +18387,19 @@ function normalize(v) {
18387
18387
  const epsilon = 1e-12;
18388
18388
  return v.map((val) => val / Math.max(norm, epsilon));
18389
18389
  }
18390
- function getEmbeddings(data, dimensions) {
18391
- const [x, _y, z] = dimensions;
18392
- return new Array(x).fill(void 0).map((_, index) => {
18393
- const startIndex = index * _y * z;
18394
- const endIndex = startIndex + z;
18395
- return data.slice(startIndex, endIndex);
18390
+ function getEmbeddings(data, dimensions, masks) {
18391
+ const [batchSize, sequenceLength, hiddenSize] = dimensions;
18392
+ return Array.from({ length: batchSize }, (_, batchIndex) => {
18393
+ const start = batchIndex * sequenceLength * hiddenSize;
18394
+ if (!masks) return data.slice(start, start + hiddenSize);
18395
+ const embedding = new Array(hiddenSize).fill(0);
18396
+ let tokenCount = 0;
18397
+ for (let tokenIndex = 0; tokenIndex < sequenceLength; tokenIndex++) {
18398
+ if (masks[batchIndex][tokenIndex] === 0n) continue;
18399
+ tokenCount++;
18400
+ for (let dimension = 0; dimension < hiddenSize; dimension++) embedding[dimension] = embedding[dimension] + data[start + tokenIndex * hiddenSize + dimension];
18401
+ }
18402
+ return embedding.map((value) => value / Math.max(tokenCount, 1));
18396
18403
  });
18397
18404
  }
18398
18405
  var Embedding = class {};
@@ -18544,7 +18551,7 @@ var FlagEmbedding = class FlagEmbedding extends Embedding {
18544
18551
  };
18545
18552
  if (this.model === "fast-multilingual-e5-large") delete inputs.token_type_ids;
18546
18553
  const lastHiddenState = (await this.session.run(inputs)).last_hidden_state;
18547
- yield getEmbeddings(lastHiddenState.data, lastHiddenState.dims).map(normalize);
18554
+ yield getEmbeddings(lastHiddenState.data, lastHiddenState.dims, this.model === "fast-all-MiniLM-L6-v2" || this.model === "fast-multilingual-e5-large" ? maskArray : void 0).map(normalize);
18548
18555
  }
18549
18556
  }
18550
18557
  passageEmbed(texts, batchSize = 256) {
@@ -18622,26 +18629,40 @@ var SparseTextEmbedding = class SparseTextEmbedding extends SparseEmbedding {
18622
18629
  if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { mode: 493 });
18623
18630
  const modelDir = path.join(cacheDir.toString(), model.replace("/", "_"));
18624
18631
  if (fs.existsSync(modelDir)) return modelDir;
18625
- fs.mkdirSync(modelDir, { mode: 493 });
18626
- for (const fileName of [
18632
+ const filesToDownload = [
18627
18633
  "onnx/model.onnx",
18628
18634
  "tokenizer.json",
18629
18635
  "tokenizer_config.json",
18630
18636
  "config.json",
18631
18637
  "special_tokens_map.json"
18632
- ]) {
18633
- const outputPath = path.join(modelDir, fileName);
18634
- const outputDir = path.dirname(outputPath);
18635
- if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir, {
18638
+ ];
18639
+ const tmpDir = fs.mkdtempSync(`${modelDir}.tmp-`);
18640
+ try {
18641
+ for (const fileName of filesToDownload) {
18642
+ const outputPath = path.join(tmpDir, fileName);
18643
+ fs.mkdirSync(path.dirname(outputPath), {
18644
+ recursive: true,
18645
+ mode: 493
18646
+ });
18647
+ const downloaded = await downloadFile({
18648
+ repo: model,
18649
+ path: fileName
18650
+ });
18651
+ if (!downloaded) throw new Error(`Model file not found in ${model}: ${fileName}`);
18652
+ await pipeline(Readable.fromWeb(downloaded.stream()), fs.createWriteStream(outputPath));
18653
+ }
18654
+ try {
18655
+ fs.renameSync(tmpDir, modelDir);
18656
+ } catch (error) {
18657
+ const code = error.code;
18658
+ if ((code === "EEXIST" || code === "ENOTEMPTY") && fs.existsSync(modelDir)) return modelDir;
18659
+ throw error;
18660
+ }
18661
+ } finally {
18662
+ fs.rmSync(tmpDir, {
18636
18663
  recursive: true,
18637
- mode: 493
18638
- });
18639
- const downloaded = await downloadFile({
18640
- repo: model,
18641
- path: fileName
18664
+ force: true
18642
18665
  });
18643
- if (!downloaded) throw new Error(`Model file not found in ${model}: ${fileName}`);
18644
- await pipeline(Readable.fromWeb(downloaded.stream()), fs.createWriteStream(outputPath));
18645
18666
  }
18646
18667
  return modelDir;
18647
18668
  }