endee-llamaindex 1.0.0 → 1.0.1

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
@@ -112,6 +112,37 @@ const queryEngine = index.asQueryEngine();
112
112
  const response = await queryEngine.query({
113
113
  query: "Summarize the key points",
114
114
  });
115
+
116
+ console.log(response.toString());
117
+ ```
118
+
119
+ ### Filtering in Queries
120
+
121
+ `EndeeVectorStore` supports **metadata filtering** during queries via LlamaIndex's `MetadataFilters`.
122
+ Currently, **only the `==` (equals) and `in` operators** are supported.
123
+
124
+ ```typescript
125
+ import { MetadataFilters, MetadataFilter } from "llamaindex";
126
+
127
+ const vectorStore = new EndeeVectorStore({
128
+ indexName: "knowledge-base",
129
+ apiToken: process.env.ENDEE_API_TOKEN,
130
+ });
131
+
132
+ const index = await VectorStoreIndex.fromVectorStore(vectorStore);
133
+
134
+ const filter : MetadataFilter[] = [{key: "type", value: "sports", operator: "=="}];
135
+
136
+ const queryEngine = index.asQueryEngine({
137
+ preFilters: {filters: filter}
138
+ });
139
+
140
+ const response = await queryEngine.query({
141
+ query: "Explain the main concepts",
142
+ filters,
143
+ });
144
+
145
+ console.log(response.toString());
115
146
  ```
116
147
 
117
148
  ### Deleting Documents
@@ -0,0 +1,27 @@
1
+ import { BaseNode, BaseVectorStore, Metadata, VectorStoreBaseParams, VectorStoreQuery, VectorStoreQueryResult } from "llamaindex";
2
+ type EndeeParams = {
3
+ indexName: string;
4
+ authToken: string;
5
+ chunkSize?: number;
6
+ } & VectorStoreBaseParams;
7
+ export declare class EndeeVectorStore extends BaseVectorStore {
8
+ storesText: boolean;
9
+ private authToken;
10
+ private indexName;
11
+ private chunkSize;
12
+ private db;
13
+ constructor(params: EndeeParams);
14
+ private getDB;
15
+ client(): any;
16
+ index(): Promise<any>;
17
+ add(embeddingResults: BaseNode<Metadata>[]): Promise<string[]>;
18
+ protected saveChunk(idx: any, chunk: any): Promise<boolean>;
19
+ nodeToRecord(node: BaseNode<Metadata>): {
20
+ id: string;
21
+ vector: number[];
22
+ meta: Metadata;
23
+ };
24
+ query(query: VectorStoreQuery, _options?: object): Promise<VectorStoreQueryResult>;
25
+ delete(refDocId: string, deleteKwargs?: object): Promise<void>;
26
+ }
27
+ export {};
@@ -0,0 +1,130 @@
1
+ import { Endee } from "endee";
2
+ import { BaseVectorStore, metadataDictToNode, nodeToMetadata, } from "llamaindex";
3
+ export class EndeeVectorStore extends BaseVectorStore {
4
+ constructor(params) {
5
+ super(params);
6
+ this.storesText = true;
7
+ this.authToken = params.authToken;
8
+ this.indexName = params.indexName;
9
+ this.chunkSize = params.chunkSize ?? 100;
10
+ this.db = new Endee(params.authToken);
11
+ }
12
+ getDB() {
13
+ if (!this.db) {
14
+ this.db = new Endee(this.authToken);
15
+ }
16
+ return this.db;
17
+ }
18
+ client() {
19
+ return this.getDB();
20
+ }
21
+ async index() {
22
+ const db = this.getDB();
23
+ const index = await db.getIndex(this.indexName);
24
+ return index;
25
+ }
26
+ async add(embeddingResults) {
27
+ if (embeddingResults.length == 0) {
28
+ return [];
29
+ }
30
+ const idx = await this.index();
31
+ const nodes = embeddingResults.map((node) => {
32
+ const nodeRecord = this.nodeToRecord(node);
33
+ if (nodeRecord.meta.ref_doc_id) {
34
+ // adding refDoc id as prefix to the chunk to find them using refDoc id
35
+ nodeRecord.id = `${nodeRecord.meta.ref_doc_id}_chunk_${nodeRecord.id}`;
36
+ }
37
+ return nodeRecord;
38
+ });
39
+ for (let i = 0; i < nodes.length; i += this.chunkSize) {
40
+ const chunk = nodes.slice(i, i + this.chunkSize);
41
+ const chunkData = chunk.map((node) => {
42
+ const nodeContent = JSON.parse(node.meta._node_content);
43
+ return {
44
+ id: node.id,
45
+ vector: node.vector,
46
+ meta: { text: nodeContent.text },
47
+ filter: nodeContent.relationships.SOURCE.metadata,
48
+ };
49
+ });
50
+ const result = await this.saveChunk(idx, chunkData);
51
+ if (!result) {
52
+ throw new Error("Failed to save chunk");
53
+ }
54
+ }
55
+ return [];
56
+ }
57
+ async saveChunk(idx, chunk) {
58
+ try {
59
+ await idx.upsert(chunk);
60
+ return true;
61
+ }
62
+ catch (err) {
63
+ const msg = `${err}`;
64
+ return false;
65
+ }
66
+ }
67
+ nodeToRecord(node) {
68
+ const id = node.id_.length ? node.id_ : null;
69
+ return {
70
+ id: id,
71
+ vector: node.getEmbedding(),
72
+ meta: nodeToMetadata(node),
73
+ };
74
+ }
75
+ async query(query, _options) {
76
+ const filter = query.filters;
77
+ const defaultOptions = {
78
+ vector: query.queryEmbedding,
79
+ topK: query.similarityTopK,
80
+ includeVectors: true,
81
+ };
82
+ if (filter) {
83
+ const filterArray = filter.filters.map((f) => {
84
+ if (f.operator == "==") {
85
+ const obj = {
86
+ [f.key]: { $eq: f.value },
87
+ };
88
+ return obj;
89
+ }
90
+ else if (f.operator == "in") {
91
+ const obj = {
92
+ [f.key]: { $in: f.value },
93
+ };
94
+ return obj;
95
+ }
96
+ });
97
+ defaultOptions.filter = filterArray;
98
+ }
99
+ const idx = await this.index();
100
+ const results = await idx.query(defaultOptions);
101
+ const idList = results.map((row) => row.id);
102
+ if (idList.length == 0) {
103
+ return { nodes: [], similarities: [], ids: [] };
104
+ }
105
+ const nodes = results.map((row) => {
106
+ const node = metadataDictToNode(row.meta ?? {}, {
107
+ fallback: {
108
+ id: row.id,
109
+ text: row._node_content,
110
+ metadata: row.meta,
111
+ embedding: row.vector,
112
+ },
113
+ });
114
+ return node;
115
+ });
116
+ return {
117
+ nodes: nodes,
118
+ similarities: results.map((row) => row.similarity || 999),
119
+ ids: results.map((row) => row.id),
120
+ };
121
+ }
122
+ async delete(refDocId, deleteKwargs) {
123
+ const [idx, index] = await Promise.all([
124
+ this.index(),
125
+ //to get the information about the index
126
+ this.db?.describeIndex(this.indexName),
127
+ ]);
128
+ await idx.deleteVector(refDocId);
129
+ }
130
+ }
package/package.json CHANGED
@@ -1,9 +1,12 @@
1
1
  {
2
2
  "name": "endee-llamaindex",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "LlamaIndex integration with endee vector database",
5
- "main": "index.js",
5
+ "type": "module",
6
+ "main": "dist/endeeClient.js",
7
+ "types": "dist/endeeClient.d.ts",
6
8
  "scripts": {
9
+ "build": "tsc",
7
10
  "test": "echo \"Error: no test specified\" && exit 1"
8
11
  },
9
12
  "keywords": [],
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "Node16",
5
+ "moduleResolution": "node16",
6
+ "declaration": true,
7
+ "outDir": "dist",
8
+ "rootDir": "src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": ["src/**/*"]
14
+ }
15
+
16
+
@@ -1,148 +0,0 @@
1
- import { Endee } from "endee";
2
- import {
3
- BaseNode,
4
- BaseVectorStore,
5
- Metadata,
6
- metadataDictToNode,
7
- nodeToMetadata,
8
- VectorStoreBaseParams,
9
- VectorStoreQuery,
10
- VectorStoreQueryResult,
11
- } from "llamaindex";
12
-
13
- type EndeeParams = {
14
- indexName: string;
15
- apiToken: string;
16
- chunkSize: number;
17
- } & VectorStoreBaseParams;
18
-
19
- export class EndeeVectorStore extends BaseVectorStore {
20
- storesText: boolean = true;
21
- private apiToken: string;
22
- private indexName: string;
23
- private chunkSize: number;
24
- private db: any;
25
-
26
- constructor(params: EndeeParams) {
27
- super(params);
28
- this.apiToken = params.apiToken;
29
- this.indexName = params.indexName;
30
- this.chunkSize = params.chunkSize;
31
- this.db = new Endee(params.apiToken);
32
- }
33
-
34
- private getDB() {
35
- if (!this.db) {
36
- this.db = new Endee(this.apiToken);
37
- }
38
- return this.db;
39
- }
40
-
41
- client() {
42
- return this.getDB();
43
- }
44
-
45
- async index() {
46
- const db = this.getDB();
47
- const index = await db.getIndex(this.indexName);
48
- return index;
49
- }
50
-
51
- async add(embeddingResults: BaseNode<Metadata>[]): Promise<string[]> {
52
- if (embeddingResults.length == 0) {
53
- return [];
54
- }
55
-
56
- const idx: any = await this.index();
57
- const nodes = embeddingResults.map((node) => {
58
- const nodeRecord = this.nodeToRecord(node);
59
-
60
- if (nodeRecord.meta.ref_doc_id) {
61
- // adding refDoc id as prefix to the chunk to find them using refDoc id
62
- nodeRecord.id = `${nodeRecord.meta.ref_doc_id}_chunk_${nodeRecord.id}`;
63
- }
64
- return nodeRecord;
65
- });
66
-
67
- for (let i = 0; i < nodes.length; i += this.chunkSize) {
68
- const chunk = nodes.slice(i, i + this.chunkSize);
69
- const result = await this.saveChunk(idx, chunk);
70
- if (!result) {
71
- throw new Error("Failed to save chunk");
72
- }
73
- }
74
- return [];
75
- }
76
-
77
- protected async saveChunk(idx: any, chunk: any) {
78
- try {
79
- await idx.upsert(chunk);
80
- return true;
81
- } catch (err) {
82
- const msg = `${err}`;
83
- console.log(msg, err);
84
- return false;
85
- }
86
- }
87
-
88
- nodeToRecord(node: BaseNode<Metadata>) {
89
- const id = node.id_.length ? node.id_ : null;
90
- return {
91
- id: id!,
92
- vector: node.getEmbedding(),
93
- meta: nodeToMetadata(node),
94
- };
95
- }
96
-
97
- async query(
98
- query: VectorStoreQuery,
99
- _options?: object
100
- ): Promise<VectorStoreQueryResult> {
101
- const filter = "";
102
- const defaultOptions: any = {
103
- vector: query.queryEmbedding!,
104
- topK: query.similarityTopK,
105
- includeVectors: true,
106
- };
107
-
108
- if (filter) {
109
- defaultOptions.filter = filter;
110
- }
111
-
112
- const idx = await this.index();
113
- const results = await idx.query(defaultOptions);
114
-
115
- const idList = results.map((row: any) => row.id);
116
- if (idList.length == 0) {
117
- return { nodes: [], similarities: [], ids: [] };
118
- }
119
-
120
- const nodes = results.map((row: any) => {
121
- const node = metadataDictToNode(row.meta ?? {}, {
122
- fallback: {
123
- id: row.id,
124
- text: row._node_content,
125
- metadata: row.meta,
126
- embedding: row.vector,
127
- },
128
- });
129
- return node;
130
- });
131
-
132
- return {
133
- nodes: nodes,
134
- similarities: results.map((row: any) => row.similarity || 999),
135
- ids: results.map((row: any) => row.id),
136
- };
137
- }
138
-
139
- async delete(refDocId: string, deleteKwargs?: object): Promise<void> {
140
- const [idx, index] = await Promise.all([
141
- this.index(),
142
- //to get the information about the index
143
- this.db?.describeIndex(this.indexName),
144
- ]);
145
-
146
- await idx.deleteVector(refDocId);
147
- }
148
- }