@flowrag/provider-local 0.0.1 → 1.4.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/README.md CHANGED
@@ -36,13 +36,6 @@ const embeddings = await embedder.embedBatch(['Hello', 'World']);
36
36
  - `Xenova/all-MiniLM-L6-v2` (384 dims) - Compact
37
37
  - `Xenova/all-mpnet-base-v2` (768 dims) - Good balance
38
38
 
39
- ## Environment Variables
40
-
41
- ```bash
42
- FLOWRAG_EMBEDDING_MODEL=Xenova/e5-small-v2
43
- FLOWRAG_EMBEDDING_DTYPE=q8
44
- ```
45
-
46
39
  ## License
47
40
 
48
41
  MIT
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Embedder } from "@flowrag/core";
1
+ import { Embedder, RerankDocument, RerankResult, Reranker } from "@flowrag/core";
2
2
 
3
3
  //#region src/embedder.d.ts
4
4
  interface LocalEmbedderOptions {
@@ -12,12 +12,36 @@ declare class LocalEmbedder implements Embedder {
12
12
  private readonly dtype;
13
13
  private readonly device;
14
14
  private pipeline;
15
- constructor(options?: LocalEmbedderOptions);
15
+ constructor({
16
+ model,
17
+ dtype,
18
+ device
19
+ }?: LocalEmbedderOptions);
16
20
  private getModelDimensions;
17
21
  embed(text: string): Promise<number[]>;
18
22
  embedBatch(texts: string[]): Promise<number[][]>;
19
23
  private getPipeline;
20
24
  }
21
25
  //#endregion
22
- export { LocalEmbedder, type LocalEmbedderOptions };
26
+ //#region src/reranker.d.ts
27
+ interface LocalRerankerOptions {
28
+ model?: string;
29
+ dtype?: "fp32" | "q8" | "q4";
30
+ device?: "auto" | "cpu" | "gpu";
31
+ }
32
+ declare class LocalReranker implements Reranker {
33
+ readonly modelName: string;
34
+ private readonly dtype;
35
+ private readonly device;
36
+ private pipeline;
37
+ constructor({
38
+ model,
39
+ dtype,
40
+ device
41
+ }?: LocalRerankerOptions);
42
+ rerank(query: string, documents: RerankDocument[], limit?: number): Promise<RerankResult[]>;
43
+ private getPipeline;
44
+ }
45
+ //#endregion
46
+ export { LocalEmbedder, type LocalEmbedderOptions, LocalReranker, type LocalRerankerOptions };
23
47
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -5,10 +5,10 @@ var LocalEmbedder = class {
5
5
  dtype;
6
6
  device;
7
7
  pipeline = null;
8
- constructor(options = {}) {
9
- this.modelName = options.model || "Xenova/e5-small-v2";
10
- this.dtype = options.dtype || "q8";
11
- this.device = options.device || "auto";
8
+ constructor({ model = "Xenova/e5-small-v2", dtype = "q8", device = "auto" } = {}) {
9
+ this.modelName = model;
10
+ this.dtype = dtype;
11
+ this.device = device;
12
12
  this.dimensions = this.getModelDimensions(this.modelName);
13
13
  }
14
14
  getModelDimensions(modelName) {
@@ -49,5 +49,42 @@ var LocalEmbedder = class {
49
49
  };
50
50
 
51
51
  //#endregion
52
- export { LocalEmbedder };
52
+ //#region src/reranker.ts
53
+ var LocalReranker = class {
54
+ modelName;
55
+ dtype;
56
+ device;
57
+ pipeline = null;
58
+ constructor({ model = "Xenova/ms-marco-MiniLM-L-6-v2", dtype = "q8", device = "auto" } = {}) {
59
+ this.modelName = model;
60
+ this.dtype = dtype;
61
+ this.device = device;
62
+ }
63
+ async rerank(query, documents, limit) {
64
+ if (documents.length === 0) return [];
65
+ const scores = await (await this.getPipeline())(documents.map((d) => ({
66
+ text: query,
67
+ text_pair: d.content
68
+ })), { topk: 1 });
69
+ const ranked = documents.map((d, i) => ({
70
+ id: d.id,
71
+ score: scores[i][0].score,
72
+ index: i
73
+ })).sort((a, b) => b.score - a.score);
74
+ return limit ? ranked.slice(0, limit) : ranked;
75
+ }
76
+ async getPipeline() {
77
+ if (!this.pipeline) {
78
+ const { pipeline } = await import("@huggingface/transformers");
79
+ this.pipeline = await pipeline("text-classification", this.modelName, {
80
+ dtype: this.dtype,
81
+ device: this.device
82
+ });
83
+ }
84
+ return this.pipeline;
85
+ }
86
+ };
87
+
88
+ //#endregion
89
+ export { LocalEmbedder, LocalReranker };
53
90
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/embedder.ts"],"sourcesContent":["import type { Embedder } from '@flowrag/core';\n\nexport interface LocalEmbedderOptions {\n model?: string;\n dtype?: 'fp32' | 'q8' | 'q4';\n device?: 'auto' | 'cpu' | 'gpu';\n}\n\nexport class LocalEmbedder implements Embedder {\n readonly modelName: string;\n readonly dimensions: number;\n private readonly dtype: string;\n private readonly device: string;\n private pipeline: unknown = null;\n\n constructor(options: LocalEmbedderOptions = {}) {\n this.modelName = options.model || 'Xenova/e5-small-v2';\n this.dtype = options.dtype || 'q8';\n this.device = options.device || 'auto';\n\n // Set dimensions based on model\n this.dimensions = this.getModelDimensions(this.modelName);\n }\n\n private getModelDimensions(modelName: string): number {\n // Common embedding model dimensions\n const dimensionMap: Record<string, number> = {\n 'Xenova/e5-small-v2': 384,\n 'Xenova/e5-base-v2': 768,\n 'Xenova/e5-large-v2': 1024,\n 'Xenova/all-MiniLM-L6-v2': 384,\n 'Xenova/all-MiniLM-L12-v2': 384,\n 'Xenova/all-mpnet-base-v2': 768,\n };\n\n return dimensionMap[modelName] || 384; // Default to 384\n }\n\n async embed(text: string): Promise<number[]> {\n const pipeline = (await this.getPipeline()) as (\n text: string,\n options: { pooling: string; normalize: boolean },\n ) => Promise<{ data: ArrayLike<number> }>;\n const result = await pipeline(text, { pooling: 'mean', normalize: true });\n return Array.from(result.data);\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n\n const pipeline = (await this.getPipeline()) as (\n text: string,\n options: { pooling: string; normalize: boolean },\n ) => Promise<{ data: ArrayLike<number> }>;\n const results = await Promise.all(\n texts.map((text) => pipeline(text, { pooling: 'mean', normalize: true })),\n );\n return results.map((result) => Array.from(result.data));\n }\n\n private async getPipeline(): Promise<unknown> {\n if (!this.pipeline) {\n const { pipeline } = await import('@huggingface/transformers');\n this.pipeline = await pipeline('feature-extraction', this.modelName, {\n dtype: this.dtype as 'fp32' | 'q8' | 'q4',\n device: this.device as 'auto' | 'cpu' | 'gpu',\n });\n }\n return this.pipeline;\n }\n}\n"],"mappings":";AAQA,IAAa,gBAAb,MAA+C;CAC7C,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAQ,WAAoB;CAE5B,YAAY,UAAgC,EAAE,EAAE;AAC9C,OAAK,YAAY,QAAQ,SAAS;AAClC,OAAK,QAAQ,QAAQ,SAAS;AAC9B,OAAK,SAAS,QAAQ,UAAU;AAGhC,OAAK,aAAa,KAAK,mBAAmB,KAAK,UAAU;;CAG3D,AAAQ,mBAAmB,WAA2B;AAWpD,SAT6C;GAC3C,sBAAsB;GACtB,qBAAqB;GACrB,sBAAsB;GACtB,2BAA2B;GAC3B,4BAA4B;GAC5B,4BAA4B;GAC7B,CAEmB,cAAc;;CAGpC,MAAM,MAAM,MAAiC;EAK3C,MAAM,SAAS,OAJG,MAAM,KAAK,aAAa,EAIZ,MAAM;GAAE,SAAS;GAAQ,WAAW;GAAM,CAAC;AACzE,SAAO,MAAM,KAAK,OAAO,KAAK;;CAGhC,MAAM,WAAW,OAAsC;AACrD,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE;EAEjC,MAAM,WAAY,MAAM,KAAK,aAAa;AAO1C,UAHgB,MAAM,QAAQ,IAC5B,MAAM,KAAK,SAAS,SAAS,MAAM;GAAE,SAAS;GAAQ,WAAW;GAAM,CAAC,CAAC,CAC1E,EACc,KAAK,WAAW,MAAM,KAAK,OAAO,KAAK,CAAC;;CAGzD,MAAc,cAAgC;AAC5C,MAAI,CAAC,KAAK,UAAU;GAClB,MAAM,EAAE,aAAa,MAAM,OAAO;AAClC,QAAK,WAAW,MAAM,SAAS,sBAAsB,KAAK,WAAW;IACnE,OAAO,KAAK;IACZ,QAAQ,KAAK;IACd,CAAC;;AAEJ,SAAO,KAAK"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/embedder.ts","../src/reranker.ts"],"sourcesContent":["import type { Embedder } from '@flowrag/core';\n\nexport interface LocalEmbedderOptions {\n model?: string;\n dtype?: 'fp32' | 'q8' | 'q4';\n device?: 'auto' | 'cpu' | 'gpu';\n}\n\nexport class LocalEmbedder implements Embedder {\n readonly modelName: string;\n readonly dimensions: number;\n private readonly dtype: string;\n private readonly device: string;\n private pipeline: unknown = null;\n\n constructor({\n model = 'Xenova/e5-small-v2',\n dtype = 'q8',\n device = 'auto',\n }: LocalEmbedderOptions = {}) {\n this.modelName = model;\n this.dtype = dtype;\n this.device = device;\n\n // Set dimensions based on model\n this.dimensions = this.getModelDimensions(this.modelName);\n }\n\n private getModelDimensions(modelName: string): number {\n // Common embedding model dimensions\n const dimensionMap: Record<string, number> = {\n 'Xenova/e5-small-v2': 384,\n 'Xenova/e5-base-v2': 768,\n 'Xenova/e5-large-v2': 1024,\n 'Xenova/all-MiniLM-L6-v2': 384,\n 'Xenova/all-MiniLM-L12-v2': 384,\n 'Xenova/all-mpnet-base-v2': 768,\n };\n\n return dimensionMap[modelName] || 384; // Default to 384\n }\n\n async embed(text: string): Promise<number[]> {\n const pipeline = (await this.getPipeline()) as (\n text: string,\n options: { pooling: string; normalize: boolean },\n ) => Promise<{ data: ArrayLike<number> }>;\n const result = await pipeline(text, { pooling: 'mean', normalize: true });\n return Array.from(result.data);\n }\n\n async embedBatch(texts: string[]): Promise<number[][]> {\n if (texts.length === 0) return [];\n\n const pipeline = (await this.getPipeline()) as (\n text: string,\n options: { pooling: string; normalize: boolean },\n ) => Promise<{ data: ArrayLike<number> }>;\n const results = await Promise.all(\n texts.map((text) => pipeline(text, { pooling: 'mean', normalize: true })),\n );\n return results.map((result) => Array.from(result.data));\n }\n\n private async getPipeline(): Promise<unknown> {\n if (!this.pipeline) {\n const { pipeline } = await import('@huggingface/transformers');\n this.pipeline = await pipeline('feature-extraction', this.modelName, {\n dtype: this.dtype as 'fp32' | 'q8' | 'q4',\n device: this.device as 'auto' | 'cpu' | 'gpu',\n });\n }\n return this.pipeline;\n }\n}\n","import type { RerankDocument, Reranker, RerankResult } from '@flowrag/core';\n\nexport interface LocalRerankerOptions {\n model?: string;\n dtype?: 'fp32' | 'q8' | 'q4';\n device?: 'auto' | 'cpu' | 'gpu';\n}\n\nexport class LocalReranker implements Reranker {\n readonly modelName: string;\n private readonly dtype: string;\n private readonly device: string;\n private pipeline: unknown = null;\n\n constructor({\n model = 'Xenova/ms-marco-MiniLM-L-6-v2',\n dtype = 'q8',\n device = 'auto',\n }: LocalRerankerOptions = {}) {\n this.modelName = model;\n this.dtype = dtype;\n this.device = device;\n }\n\n async rerank(\n query: string,\n documents: RerankDocument[],\n limit?: number,\n ): Promise<RerankResult[]> {\n if (documents.length === 0) return [];\n\n const classifier = (await this.getPipeline()) as (\n inputs: { text: string; text_pair: string }[],\n options: { topk: number },\n ) => Promise<{ label: string; score: number }[][]>;\n\n const inputs = documents.map((d) => ({ text: query, text_pair: d.content }));\n const scores = await classifier(inputs, { topk: 1 });\n\n const ranked = documents\n .map((d, i) => ({ id: d.id, score: scores[i][0].score, index: i }))\n .sort((a, b) => b.score - a.score);\n\n return limit ? ranked.slice(0, limit) : ranked;\n }\n\n private async getPipeline(): Promise<unknown> {\n if (!this.pipeline) {\n const { pipeline } = await import('@huggingface/transformers');\n this.pipeline = await pipeline('text-classification', this.modelName, {\n dtype: this.dtype as 'fp32' | 'q8' | 'q4',\n device: this.device as 'auto' | 'cpu' | 'gpu',\n });\n }\n return this.pipeline;\n }\n}\n"],"mappings":";AAQA,IAAa,gBAAb,MAA+C;CAC7C,AAAS;CACT,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAQ,WAAoB;CAE5B,YAAY,EACV,QAAQ,sBACR,QAAQ,MACR,SAAS,WACe,EAAE,EAAE;AAC5B,OAAK,YAAY;AACjB,OAAK,QAAQ;AACb,OAAK,SAAS;AAGd,OAAK,aAAa,KAAK,mBAAmB,KAAK,UAAU;;CAG3D,AAAQ,mBAAmB,WAA2B;AAWpD,SAT6C;GAC3C,sBAAsB;GACtB,qBAAqB;GACrB,sBAAsB;GACtB,2BAA2B;GAC3B,4BAA4B;GAC5B,4BAA4B;GAC7B,CAEmB,cAAc;;CAGpC,MAAM,MAAM,MAAiC;EAK3C,MAAM,SAAS,OAJG,MAAM,KAAK,aAAa,EAIZ,MAAM;GAAE,SAAS;GAAQ,WAAW;GAAM,CAAC;AACzE,SAAO,MAAM,KAAK,OAAO,KAAK;;CAGhC,MAAM,WAAW,OAAsC;AACrD,MAAI,MAAM,WAAW,EAAG,QAAO,EAAE;EAEjC,MAAM,WAAY,MAAM,KAAK,aAAa;AAO1C,UAHgB,MAAM,QAAQ,IAC5B,MAAM,KAAK,SAAS,SAAS,MAAM;GAAE,SAAS;GAAQ,WAAW;GAAM,CAAC,CAAC,CAC1E,EACc,KAAK,WAAW,MAAM,KAAK,OAAO,KAAK,CAAC;;CAGzD,MAAc,cAAgC;AAC5C,MAAI,CAAC,KAAK,UAAU;GAClB,MAAM,EAAE,aAAa,MAAM,OAAO;AAClC,QAAK,WAAW,MAAM,SAAS,sBAAsB,KAAK,WAAW;IACnE,OAAO,KAAK;IACZ,QAAQ,KAAK;IACd,CAAC;;AAEJ,SAAO,KAAK;;;;;;AChEhB,IAAa,gBAAb,MAA+C;CAC7C,AAAS;CACT,AAAiB;CACjB,AAAiB;CACjB,AAAQ,WAAoB;CAE5B,YAAY,EACV,QAAQ,iCACR,QAAQ,MACR,SAAS,WACe,EAAE,EAAE;AAC5B,OAAK,YAAY;AACjB,OAAK,QAAQ;AACb,OAAK,SAAS;;CAGhB,MAAM,OACJ,OACA,WACA,OACyB;AACzB,MAAI,UAAU,WAAW,EAAG,QAAO,EAAE;EAQrC,MAAM,SAAS,OANK,MAAM,KAAK,aAAa,EAK7B,UAAU,KAAK,OAAO;GAAE,MAAM;GAAO,WAAW,EAAE;GAAS,EAAE,EACpC,EAAE,MAAM,GAAG,CAAC;EAEpD,MAAM,SAAS,UACZ,KAAK,GAAG,OAAO;GAAE,IAAI,EAAE;GAAI,OAAO,OAAO,GAAG,GAAG;GAAO,OAAO;GAAG,EAAE,CAClE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;AAEpC,SAAO,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;;CAG1C,MAAc,cAAgC;AAC5C,MAAI,CAAC,KAAK,UAAU;GAClB,MAAM,EAAE,aAAa,MAAM,OAAO;AAClC,QAAK,WAAW,MAAM,SAAS,uBAAuB,KAAK,WAAW;IACpE,OAAO,KAAK;IACZ,QAAQ,KAAK;IACd,CAAC;;AAEJ,SAAO,KAAK"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowrag/provider-local",
3
- "version": "0.0.1",
3
+ "version": "1.4.0",
4
4
  "description": "Local AI provider for FlowRAG - ONNX embeddings and future local extraction",
5
5
  "keywords": [
6
6
  "flowrag",
@@ -16,7 +16,7 @@
16
16
  "bugs": "https://github.com/Zweer/FlowRAG/issues",
17
17
  "repository": {
18
18
  "type": "git",
19
- "url": "https://github.com/Zweer/FlowRAG.git",
19
+ "url": "git+https://github.com/Zweer/FlowRAG.git",
20
20
  "directory": "packages/provider-local"
21
21
  },
22
22
  "license": "MIT",
@@ -29,21 +29,19 @@
29
29
  ".": "./dist/index.mjs",
30
30
  "./package.json": "./package.json"
31
31
  },
32
- "main": "./dist/index.mjs",
33
- "module": "./dist/index.mjs",
34
32
  "types": "./dist/index.d.mts",
35
33
  "files": [
36
34
  "dist"
37
35
  ],
38
36
  "dependencies": {
39
- "@flowrag/core": "1.0.2",
40
- "@huggingface/transformers": "^3.8.1"
37
+ "@flowrag/core": "^1.4.0",
38
+ "@huggingface/transformers": "3.1.0"
41
39
  },
42
40
  "engines": {
43
41
  "node": ">=20.3"
44
42
  },
45
43
  "publishConfig": {
46
44
  "access": "public",
47
- "provenance": false
45
+ "provenance": true
48
46
  }
49
47
  }