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 +31 -0
- package/dist/endeeClient.d.ts +27 -0
- package/dist/endeeClient.js +130 -0
- package/package.json +5 -2
- package/tsconfig.json +16 -0
- package/src/endeeClient.ts +0 -148
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.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "LlamaIndex integration with endee vector database",
|
|
5
|
-
"
|
|
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
|
+
|
package/src/endeeClient.ts
DELETED
|
@@ -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
|
-
}
|