@deepagents/retrieval 4.3.0 → 6.0.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.
@@ -1,11 +1,25 @@
1
- import { EmbeddingModel } from 'fastembed';
2
1
  import type { Embedder } from '../stores/store.js';
3
- type StandardModel = EmbeddingModel.AllMiniLML6V2 | EmbeddingModel.BGEBaseEN | EmbeddingModel.BGEBaseENV15 | EmbeddingModel.BGESmallEN | EmbeddingModel.BGESmallENV15 | EmbeddingModel.BGESmallZH | EmbeddingModel.MLE5Large;
2
+ /**
3
+ * Stable model identifiers retained from the former `fastembed` adapter.
4
+ */
5
+ export declare enum EmbeddingModel {
6
+ AllMiniLML6V2 = "fast-all-MiniLM-L6-v2",
7
+ BGEBaseEN = "fast-bge-base-en",
8
+ BGEBaseENV15 = "fast-bge-base-en-v1.5",
9
+ BGESmallEN = "fast-bge-small-en",
10
+ BGESmallENV15 = "fast-bge-small-en-v1.5",
11
+ BGESmallZH = "fast-bge-small-zh-v1.5",
12
+ MLE5Large = "fast-multilingual-e5-large"
13
+ }
4
14
  export interface FastEmbedOptions {
5
- model?: StandardModel;
15
+ model?: EmbeddingModel;
6
16
  batchSize?: number;
7
17
  cacheDir?: string;
8
18
  }
19
+ /**
20
+ * Local feature extraction backed by Transformers.js. The historical function
21
+ * and model identifiers remain stable while avoiding FastEmbed's archived tar
22
+ * extraction dependency.
23
+ */
9
24
  export declare function fastembed(options?: FastEmbedOptions): Embedder;
10
- export {};
11
25
  //# sourceMappingURL=fastembed.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fastembed.d.ts","sourceRoot":"","sources":["../../../src/lib/embedders/fastembed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,WAAW,CAAC;AAE1D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,KAAK,aAAa,GACd,cAAc,CAAC,aAAa,GAC5B,cAAc,CAAC,SAAS,GACxB,cAAc,CAAC,YAAY,GAC3B,cAAc,CAAC,UAAU,GACzB,cAAc,CAAC,aAAa,GAC5B,cAAc,CAAC,UAAU,GACzB,cAAc,CAAC,SAAS,CAAC;AAE7B,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,QAAQ,CAoClE"}
1
+ {"version":3,"file":"fastembed.d.ts","sourceRoot":"","sources":["../../../src/lib/embedders/fastembed.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD;;GAEG;AACH,oBAAY,cAAc;IACxB,aAAa,0BAA0B;IACvC,SAAS,qBAAqB;IAC9B,YAAY,0BAA0B;IACtC,UAAU,sBAAsB;IAChC,aAAa,2BAA2B;IACxC,UAAU,2BAA2B;IACrC,SAAS,+BAA+B;CACzC;AAYD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,QAAQ,CA4ClE"}
@@ -1,35 +1,64 @@
1
- import { EmbeddingModel, FlagEmbedding } from "fastembed";
1
+ import { tensorToEmbeddings } from "./huggingface.js";
2
+ var EmbeddingModel = /* @__PURE__ */ ((EmbeddingModel2) => {
3
+ EmbeddingModel2["AllMiniLML6V2"] = "fast-all-MiniLM-L6-v2";
4
+ EmbeddingModel2["BGEBaseEN"] = "fast-bge-base-en";
5
+ EmbeddingModel2["BGEBaseENV15"] = "fast-bge-base-en-v1.5";
6
+ EmbeddingModel2["BGESmallEN"] = "fast-bge-small-en";
7
+ EmbeddingModel2["BGESmallENV15"] = "fast-bge-small-en-v1.5";
8
+ EmbeddingModel2["BGESmallZH"] = "fast-bge-small-zh-v1.5";
9
+ EmbeddingModel2["MLE5Large"] = "fast-multilingual-e5-large";
10
+ return EmbeddingModel2;
11
+ })(EmbeddingModel || {});
12
+ const transformerModels = {
13
+ ["fast-all-MiniLM-L6-v2" /* AllMiniLML6V2 */]: "Xenova/all-MiniLM-L6-v2",
14
+ ["fast-bge-base-en" /* BGEBaseEN */]: "Xenova/bge-base-en",
15
+ ["fast-bge-base-en-v1.5" /* BGEBaseENV15 */]: "Xenova/bge-base-en-v1.5",
16
+ ["fast-bge-small-en" /* BGESmallEN */]: "Xenova/bge-small-en",
17
+ ["fast-bge-small-en-v1.5" /* BGESmallENV15 */]: "Xenova/bge-small-en-v1.5",
18
+ ["fast-bge-small-zh-v1.5" /* BGESmallZH */]: "Xenova/bge-small-zh-v1.5",
19
+ ["fast-multilingual-e5-large" /* MLE5Large */]: "Xenova/multilingual-e5-large"
20
+ };
2
21
  function fastembed(options = {}) {
3
22
  const {
4
- model: modelId = EmbeddingModel.BGESmallENV15,
5
- batchSize,
23
+ model: modelId = "fast-bge-small-en-v1.5" /* BGESmallENV15 */,
24
+ batchSize = 256,
6
25
  cacheDir
7
26
  } = options;
27
+ if (!Number.isInteger(batchSize) || batchSize <= 0) {
28
+ throw new RangeError("batchSize must be a positive integer");
29
+ }
8
30
  let modelPromise = null;
9
31
  const getModel = () => {
10
32
  if (!modelPromise) {
11
- modelPromise = FlagEmbedding.init({
12
- model: modelId,
13
- cacheDir
14
- });
33
+ modelPromise = import("@huggingface/transformers").then(
34
+ ({ pipeline }) => pipeline("feature-extraction", transformerModels[modelId], {
35
+ cache_dir: cacheDir
36
+ })
37
+ );
15
38
  }
16
39
  return modelPromise;
17
40
  };
18
41
  return async (documents) => {
42
+ if (documents.length === 0) {
43
+ return { embeddings: [], dimensions: 0 };
44
+ }
19
45
  const model = await getModel();
20
- const batches = model.embed(documents, batchSize);
21
46
  const embeddings = [];
22
47
  let dimensions = 0;
23
- for await (const batch of batches) {
24
- for (const vec of batch) {
25
- if (dimensions === 0) dimensions = vec.length;
26
- embeddings.push(vec);
27
- }
48
+ for (let start = 0; start < documents.length; start += batchSize) {
49
+ const tensor = await model(documents.slice(start, start + batchSize), {
50
+ pooling: "mean",
51
+ normalize: true
52
+ });
53
+ const batch = tensorToEmbeddings(tensor);
54
+ dimensions ||= batch.dimensions;
55
+ embeddings.push(...batch.embeddings);
28
56
  }
29
57
  return { embeddings, dimensions };
30
58
  };
31
59
  }
32
60
  export {
61
+ EmbeddingModel,
33
62
  fastembed
34
63
  };
35
64
  //# sourceMappingURL=fastembed.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/embedders/fastembed.ts"],
4
- "sourcesContent": ["import { EmbeddingModel, FlagEmbedding } from 'fastembed';\n\nimport type { Embedder } from '../stores/store.js';\n\ntype StandardModel =\n | EmbeddingModel.AllMiniLML6V2\n | EmbeddingModel.BGEBaseEN\n | EmbeddingModel.BGEBaseENV15\n | EmbeddingModel.BGESmallEN\n | EmbeddingModel.BGESmallENV15\n | EmbeddingModel.BGESmallZH\n | EmbeddingModel.MLE5Large;\n\nexport interface FastEmbedOptions {\n model?: StandardModel;\n batchSize?: number;\n cacheDir?: string;\n}\n\nexport function fastembed(options: FastEmbedOptions = {}): Embedder {\n const {\n model: modelId = EmbeddingModel.BGESmallENV15,\n batchSize,\n cacheDir,\n } = options;\n\n let modelPromise: Promise<\n Awaited<ReturnType<typeof FlagEmbedding.init>>\n > | null = null;\n const getModel = () => {\n if (!modelPromise) {\n modelPromise = FlagEmbedding.init({\n model: modelId,\n cacheDir,\n });\n }\n return modelPromise;\n };\n\n return async (documents: string[]) => {\n const model = await getModel();\n const batches = model.embed(documents, batchSize);\n\n const embeddings: number[][] = [];\n let dimensions = 0;\n\n for await (const batch of batches) {\n for (const vec of batch) {\n if (dimensions === 0) dimensions = vec.length;\n embeddings.push(vec);\n }\n }\n\n return { embeddings, dimensions };\n };\n}\n"],
5
- "mappings": "AAAA,SAAS,gBAAgB,qBAAqB;AAmBvC,SAAS,UAAU,UAA4B,CAAC,GAAa;AAClE,QAAM;AAAA,IACJ,OAAO,UAAU,eAAe;AAAA,IAChC;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,MAAI,eAEO;AACX,QAAM,WAAW,MAAM;AACrB,QAAI,CAAC,cAAc;AACjB,qBAAe,cAAc,KAAK;AAAA,QAChC,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,cAAwB;AACpC,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,UAAU,MAAM,MAAM,WAAW,SAAS;AAEhD,UAAM,aAAyB,CAAC;AAChC,QAAI,aAAa;AAEjB,qBAAiB,SAAS,SAAS;AACjC,iBAAW,OAAO,OAAO;AACvB,YAAI,eAAe,EAAG,cAAa,IAAI;AACvC,mBAAW,KAAK,GAAG;AAAA,MACrB;AAAA,IACF;AAEA,WAAO,EAAE,YAAY,WAAW;AAAA,EAClC;AACF;",
6
- "names": []
4
+ "sourcesContent": ["import type { FeatureExtractionPipeline } from '@huggingface/transformers';\n\nimport type { Embedder } from '../stores/store.js';\nimport { tensorToEmbeddings } from './huggingface.js';\n\n/**\n * Stable model identifiers retained from the former `fastembed` adapter.\n */\nexport enum EmbeddingModel {\n AllMiniLML6V2 = 'fast-all-MiniLM-L6-v2',\n BGEBaseEN = 'fast-bge-base-en',\n BGEBaseENV15 = 'fast-bge-base-en-v1.5',\n BGESmallEN = 'fast-bge-small-en',\n BGESmallENV15 = 'fast-bge-small-en-v1.5',\n BGESmallZH = 'fast-bge-small-zh-v1.5',\n MLE5Large = 'fast-multilingual-e5-large',\n}\n\nconst transformerModels: Record<EmbeddingModel, string> = {\n [EmbeddingModel.AllMiniLML6V2]: 'Xenova/all-MiniLM-L6-v2',\n [EmbeddingModel.BGEBaseEN]: 'Xenova/bge-base-en',\n [EmbeddingModel.BGEBaseENV15]: 'Xenova/bge-base-en-v1.5',\n [EmbeddingModel.BGESmallEN]: 'Xenova/bge-small-en',\n [EmbeddingModel.BGESmallENV15]: 'Xenova/bge-small-en-v1.5',\n [EmbeddingModel.BGESmallZH]: 'Xenova/bge-small-zh-v1.5',\n [EmbeddingModel.MLE5Large]: 'Xenova/multilingual-e5-large',\n};\n\nexport interface FastEmbedOptions {\n model?: EmbeddingModel;\n batchSize?: number;\n cacheDir?: string;\n}\n\n/**\n * Local feature extraction backed by Transformers.js. The historical function\n * and model identifiers remain stable while avoiding FastEmbed's archived tar\n * extraction dependency.\n */\nexport function fastembed(options: FastEmbedOptions = {}): Embedder {\n const {\n model: modelId = EmbeddingModel.BGESmallENV15,\n batchSize = 256,\n cacheDir,\n } = options;\n\n if (!Number.isInteger(batchSize) || batchSize <= 0) {\n throw new RangeError('batchSize must be a positive integer');\n }\n\n let modelPromise: Promise<FeatureExtractionPipeline> | null = null;\n const getModel = () => {\n if (!modelPromise) {\n modelPromise = import('@huggingface/transformers').then(({ pipeline }) =>\n pipeline('feature-extraction', transformerModels[modelId], {\n cache_dir: cacheDir,\n }),\n );\n }\n return modelPromise;\n };\n\n return async (documents: string[]) => {\n if (documents.length === 0) {\n return { embeddings: [], dimensions: 0 };\n }\n\n const model = await getModel();\n const embeddings: Float32Array[] = [];\n let dimensions = 0;\n\n for (let start = 0; start < documents.length; start += batchSize) {\n const tensor = await model(documents.slice(start, start + batchSize), {\n pooling: 'mean',\n normalize: true,\n });\n const batch = tensorToEmbeddings(tensor);\n dimensions ||= batch.dimensions;\n embeddings.push(...batch.embeddings);\n }\n\n return { embeddings, dimensions };\n };\n}\n"],
5
+ "mappings": "AAGA,SAAS,0BAA0B;AAK5B,IAAK,iBAAL,kBAAKA,oBAAL;AACL,EAAAA,gBAAA,mBAAgB;AAChB,EAAAA,gBAAA,eAAY;AACZ,EAAAA,gBAAA,kBAAe;AACf,EAAAA,gBAAA,gBAAa;AACb,EAAAA,gBAAA,mBAAgB;AAChB,EAAAA,gBAAA,gBAAa;AACb,EAAAA,gBAAA,eAAY;AAPF,SAAAA;AAAA,GAAA;AAUZ,MAAM,oBAAoD;AAAA,EACxD,CAAC,2CAA4B,GAAG;AAAA,EAChC,CAAC,kCAAwB,GAAG;AAAA,EAC5B,CAAC,0CAA2B,GAAG;AAAA,EAC/B,CAAC,oCAAyB,GAAG;AAAA,EAC7B,CAAC,4CAA4B,GAAG;AAAA,EAChC,CAAC,yCAAyB,GAAG;AAAA,EAC7B,CAAC,4CAAwB,GAAG;AAC9B;AAaO,SAAS,UAAU,UAA4B,CAAC,GAAa;AAClE,QAAM;AAAA,IACJ,OAAO,UAAU;AAAA,IACjB,YAAY;AAAA,IACZ;AAAA,EACF,IAAI;AAEJ,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,aAAa,GAAG;AAClD,UAAM,IAAI,WAAW,sCAAsC;AAAA,EAC7D;AAEA,MAAI,eAA0D;AAC9D,QAAM,WAAW,MAAM;AACrB,QAAI,CAAC,cAAc;AACjB,qBAAe,OAAO,2BAA2B,EAAE;AAAA,QAAK,CAAC,EAAE,SAAS,MAClE,SAAS,sBAAsB,kBAAkB,OAAO,GAAG;AAAA,UACzD,WAAW;AAAA,QACb,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO,OAAO,cAAwB;AACpC,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,EAAE,YAAY,CAAC,GAAG,YAAY,EAAE;AAAA,IACzC;AAEA,UAAM,QAAQ,MAAM,SAAS;AAC7B,UAAM,aAA6B,CAAC;AACpC,QAAI,aAAa;AAEjB,aAAS,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,WAAW;AAChE,YAAM,SAAS,MAAM,MAAM,UAAU,MAAM,OAAO,QAAQ,SAAS,GAAG;AAAA,QACpE,SAAS;AAAA,QACT,WAAW;AAAA,MACb,CAAC;AACD,YAAM,QAAQ,mBAAmB,MAAM;AACvC,qBAAe,MAAM;AACrB,iBAAW,KAAK,GAAG,MAAM,UAAU;AAAA,IACrC;AAEA,WAAO,EAAE,YAAY,WAAW;AAAA,EAClC;AACF;",
6
+ "names": ["EmbeddingModel"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MarkdownTextSplitter,
3
3
  RecursiveCharacterTextSplitter
4
- } from "langchain/text_splitter";
4
+ } from "@langchain/textsplitters";
5
5
  import { cid } from "./stores/cid.js";
6
6
  async function ingest(config, callback) {
7
7
  const splitter = config.splitter ?? split;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/ingest.ts"],
4
- "sourcesContent": ["import {\n MarkdownTextSplitter,\n RecursiveCharacterTextSplitter,\n} from 'langchain/text_splitter';\n\nimport type { Connector } from './connectors/connector.js';\nimport type { Splitter } from './pipeline.js';\nimport { cid } from './stores/cid.js';\nimport type { Embedder, Store } from './stores/store.js';\n\nexport interface IngestionConfig {\n connector: Connector;\n store: Store;\n splitter?: Splitter;\n embedder: Embedder;\n}\n\nexport async function ingest(\n config: IngestionConfig,\n callback?: (it: string) => void,\n) {\n const splitter = config.splitter ?? split;\n const embedder = config.embedder;\n const corpuses = config.connector.sources();\n\n for await (const it of corpuses) {\n callback?.(it.id);\n const content = await it.content();\n if (!content.trim()) {\n // skip empty files\n continue;\n }\n await config.store.index(config.connector.sourceId, {\n id: it.id,\n cid: cid(content),\n metadata: it.metadata,\n chunker: async function* () {\n // Embed in small batches to control memory usage\n const values = await splitter(it.id, content);\n const batchSize = 40;\n for (let i = 0; i < values.length; i += batchSize) {\n const batch = values.slice(i, i + batchSize);\n const { embeddings } = await embedder(batch);\n for (let j = 0; j < embeddings.length; j++) {\n yield {\n content: batch[j],\n embedding: embeddings[j],\n };\n }\n }\n },\n });\n }\n}\n\nfunction split(id: string, content: string) {\n const splitter = new MarkdownTextSplitter();\n return splitter.splitText(content);\n}\n\nexport type ChunkPosition = {\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n};\n\nexport type SplitChunkWithPosition = {\n content: string;\n position: ChunkPosition | null;\n index: number;\n};\n\nfunction normalizeNewlines(value: string) {\n return value.replace(/\\r\\n/g, '\\n');\n}\n\nfunction computePositions(\n originalContent: string,\n chunks: string[],\n): Array<ChunkPosition | null> {\n if (!chunks.length) {\n return [];\n }\n\n const normalizedContent = normalizeNewlines(originalContent);\n const positions: Array<ChunkPosition | null> = [];\n let searchOffset = 0;\n\n for (const chunk of chunks) {\n const normalizedChunk = normalizeNewlines(chunk);\n const trimmedChunk = normalizedChunk.trim();\n\n const seek = (needle: string, fromIndex: number) =>\n needle ? normalizedContent.indexOf(needle, fromIndex) : -1;\n\n let matchIndex = seek(normalizedChunk, searchOffset);\n let matchValue = normalizedChunk;\n\n if (matchIndex === -1 && trimmedChunk) {\n matchIndex = seek(trimmedChunk, searchOffset);\n matchValue = trimmedChunk;\n }\n\n if (matchIndex === -1) {\n matchIndex = seek(normalizedChunk, 0);\n matchValue = normalizedChunk;\n }\n\n if (matchIndex === -1 && trimmedChunk) {\n matchIndex = seek(trimmedChunk, 0);\n matchValue = trimmedChunk;\n }\n\n if (matchIndex === -1) {\n positions.push(null);\n continue;\n }\n\n const before = normalizedContent.slice(0, matchIndex);\n const beforeLines = before.split('\\n');\n const startLine = beforeLines.length;\n const startColumn = beforeLines[beforeLines.length - 1].length + 1;\n\n const lines = matchValue.split('\\n');\n const endLine = startLine + lines.length - 1;\n const endColumn =\n lines.length === 1\n ? startColumn + lines[0].length\n : lines[lines.length - 1].length + 1;\n\n positions.push({ startLine, startColumn, endLine, endColumn });\n searchOffset = matchIndex + matchValue.length;\n }\n\n return positions;\n}\n\nfunction buildChunksWithPositions(\n originalContent: string,\n chunks: string[],\n): SplitChunkWithPosition[] {\n const positions = computePositions(originalContent, chunks);\n return chunks.map((content, index) => ({\n content,\n index,\n position: positions[index] ?? null,\n }));\n}\n\nexport async function splitTypeScriptWithPositions(\n id: string,\n content: string,\n): Promise<SplitChunkWithPosition[]> {\n const splitter = RecursiveCharacterTextSplitter.fromLanguage('js', {\n chunkSize: 512,\n chunkOverlap: 100,\n });\n const docs = await splitter.createDocuments([content]);\n const chunks = docs.map((d) => d.pageContent);\n return buildChunksWithPositions(content, chunks);\n}\n\nexport async function splitTypeScript(id: string, content: string) {\n const chunks = await splitTypeScriptWithPositions(id, content);\n return chunks.map((chunk) => chunk.content);\n}\n"],
4
+ "sourcesContent": ["import {\n MarkdownTextSplitter,\n RecursiveCharacterTextSplitter,\n} from '@langchain/textsplitters';\n\nimport type { Connector } from './connectors/connector.js';\nimport type { Splitter } from './pipeline.js';\nimport { cid } from './stores/cid.js';\nimport type { Embedder, Store } from './stores/store.js';\n\nexport interface IngestionConfig {\n connector: Connector;\n store: Store;\n splitter?: Splitter;\n embedder: Embedder;\n}\n\nexport async function ingest(\n config: IngestionConfig,\n callback?: (it: string) => void,\n) {\n const splitter = config.splitter ?? split;\n const embedder = config.embedder;\n const corpuses = config.connector.sources();\n\n for await (const it of corpuses) {\n callback?.(it.id);\n const content = await it.content();\n if (!content.trim()) {\n // skip empty files\n continue;\n }\n await config.store.index(config.connector.sourceId, {\n id: it.id,\n cid: cid(content),\n metadata: it.metadata,\n chunker: async function* () {\n // Embed in small batches to control memory usage\n const values = await splitter(it.id, content);\n const batchSize = 40;\n for (let i = 0; i < values.length; i += batchSize) {\n const batch = values.slice(i, i + batchSize);\n const { embeddings } = await embedder(batch);\n for (let j = 0; j < embeddings.length; j++) {\n yield {\n content: batch[j],\n embedding: embeddings[j],\n };\n }\n }\n },\n });\n }\n}\n\nfunction split(id: string, content: string) {\n const splitter = new MarkdownTextSplitter();\n return splitter.splitText(content);\n}\n\nexport type ChunkPosition = {\n startLine: number;\n startColumn: number;\n endLine: number;\n endColumn: number;\n};\n\nexport type SplitChunkWithPosition = {\n content: string;\n position: ChunkPosition | null;\n index: number;\n};\n\nfunction normalizeNewlines(value: string) {\n return value.replace(/\\r\\n/g, '\\n');\n}\n\nfunction computePositions(\n originalContent: string,\n chunks: string[],\n): Array<ChunkPosition | null> {\n if (!chunks.length) {\n return [];\n }\n\n const normalizedContent = normalizeNewlines(originalContent);\n const positions: Array<ChunkPosition | null> = [];\n let searchOffset = 0;\n\n for (const chunk of chunks) {\n const normalizedChunk = normalizeNewlines(chunk);\n const trimmedChunk = normalizedChunk.trim();\n\n const seek = (needle: string, fromIndex: number) =>\n needle ? normalizedContent.indexOf(needle, fromIndex) : -1;\n\n let matchIndex = seek(normalizedChunk, searchOffset);\n let matchValue = normalizedChunk;\n\n if (matchIndex === -1 && trimmedChunk) {\n matchIndex = seek(trimmedChunk, searchOffset);\n matchValue = trimmedChunk;\n }\n\n if (matchIndex === -1) {\n matchIndex = seek(normalizedChunk, 0);\n matchValue = normalizedChunk;\n }\n\n if (matchIndex === -1 && trimmedChunk) {\n matchIndex = seek(trimmedChunk, 0);\n matchValue = trimmedChunk;\n }\n\n if (matchIndex === -1) {\n positions.push(null);\n continue;\n }\n\n const before = normalizedContent.slice(0, matchIndex);\n const beforeLines = before.split('\\n');\n const startLine = beforeLines.length;\n const startColumn = beforeLines[beforeLines.length - 1].length + 1;\n\n const lines = matchValue.split('\\n');\n const endLine = startLine + lines.length - 1;\n const endColumn =\n lines.length === 1\n ? startColumn + lines[0].length\n : lines[lines.length - 1].length + 1;\n\n positions.push({ startLine, startColumn, endLine, endColumn });\n searchOffset = matchIndex + matchValue.length;\n }\n\n return positions;\n}\n\nfunction buildChunksWithPositions(\n originalContent: string,\n chunks: string[],\n): SplitChunkWithPosition[] {\n const positions = computePositions(originalContent, chunks);\n return chunks.map((content, index) => ({\n content,\n index,\n position: positions[index] ?? null,\n }));\n}\n\nexport async function splitTypeScriptWithPositions(\n id: string,\n content: string,\n): Promise<SplitChunkWithPosition[]> {\n const splitter = RecursiveCharacterTextSplitter.fromLanguage('js', {\n chunkSize: 512,\n chunkOverlap: 100,\n });\n const docs = await splitter.createDocuments([content]);\n const chunks = docs.map((d) => d.pageContent);\n return buildChunksWithPositions(content, chunks);\n}\n\nexport async function splitTypeScript(id: string, content: string) {\n const chunks = await splitTypeScriptWithPositions(id, content);\n return chunks.map((chunk) => chunk.content);\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepagents/retrieval",
3
- "version": "4.3.0",
3
+ "version": "6.0.0",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,6 +31,7 @@
31
31
  },
32
32
  "files": [
33
33
  "dist",
34
+ "!dist/spec/**",
34
35
  "!**/*.tsbuildinfo",
35
36
  "!**/*.test.*"
36
37
  ],
@@ -38,20 +39,20 @@
38
39
  "access": "public"
39
40
  },
40
41
  "dependencies": {
41
- "execa": "^9.6.0",
42
- "@linear/sdk": "^63.0.0",
42
+ "@langchain/textsplitters": "^1.0.1",
43
+ "execa": "^10.0.0",
44
+ "@linear/sdk": "^88.2.0",
43
45
  "fast-glob": "^3.3.3",
44
- "ignore": "^7.0.5",
45
- "unpdf": "^1.3.2",
46
+ "ignore": "^7.0.6",
47
+ "unpdf": "^1.6.2",
46
48
  "@mozilla/readability": "^0.6.0",
47
49
  "rss-parser": "^3.13.0",
48
- "jsdom": "^27.0.0",
49
- "fastembed": "^2.1.0",
50
- "@huggingface/transformers": "^3.7.5",
51
- "langchain": "^0.3.35",
52
- "ai": "^6.0.218",
50
+ "jsdom": "^29.1.1",
51
+ "@huggingface/transformers": "^4.2.0",
52
+ "langchain": "^1.5.3",
53
+ "ai": "^7.0.30",
53
54
  "sqlite-vec": "^0.1.9",
54
- "dedent": "1.7.0",
55
- "lodash-es": "^4.17.21"
55
+ "dedent": "1.7.2",
56
+ "lodash-es": "^4.18.1"
56
57
  }
57
58
  }