langchain 0.0.197 → 0.0.199
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/agents/index.d.ts +1 -1
- package/dist/chains/conversational_retrieval_chain.cjs +16 -2
- package/dist/chains/conversational_retrieval_chain.d.ts +2 -0
- package/dist/chains/conversational_retrieval_chain.js +16 -2
- package/dist/chat_models/llama_cpp.cjs +45 -0
- package/dist/chat_models/llama_cpp.d.ts +4 -1
- package/dist/chat_models/llama_cpp.js +45 -0
- package/dist/document_loaders/fs/chatgpt.cjs +85 -0
- package/dist/document_loaders/fs/chatgpt.d.ts +8 -0
- package/dist/document_loaders/fs/chatgpt.js +81 -0
- package/dist/document_loaders/fs/pptx.cjs +39 -0
- package/dist/document_loaders/fs/pptx.d.ts +23 -0
- package/dist/document_loaders/fs/pptx.js +35 -0
- package/dist/document_loaders/web/confluence.cjs +31 -7
- package/dist/document_loaders/web/confluence.d.ts +12 -5
- package/dist/document_loaders/web/confluence.js +31 -7
- package/dist/experimental/openai_assistant/index.cjs +32 -0
- package/dist/experimental/openai_assistant/index.d.ts +26 -0
- package/dist/experimental/openai_assistant/index.js +32 -0
- package/dist/experimental/tools/pyinterpreter.cjs +248 -0
- package/dist/experimental/tools/pyinterpreter.d.ts +18 -0
- package/dist/experimental/tools/pyinterpreter.js +244 -0
- package/dist/graphs/neo4j_graph.cjs +49 -14
- package/dist/graphs/neo4j_graph.d.ts +30 -0
- package/dist/graphs/neo4j_graph.js +49 -14
- package/dist/llms/gradient_ai.cjs +98 -0
- package/dist/llms/gradient_ai.d.ts +50 -0
- package/dist/llms/gradient_ai.js +94 -0
- package/dist/llms/hf.cjs +13 -2
- package/dist/llms/hf.d.ts +5 -0
- package/dist/llms/hf.js +13 -2
- package/dist/llms/llama_cpp.cjs +17 -3
- package/dist/llms/llama_cpp.d.ts +4 -1
- package/dist/llms/llama_cpp.js +17 -3
- package/dist/llms/watsonx_ai.cjs +154 -0
- package/dist/llms/watsonx_ai.d.ts +72 -0
- package/dist/llms/watsonx_ai.js +150 -0
- package/dist/load/import_constants.cjs +6 -0
- package/dist/load/import_constants.js +6 -0
- package/dist/load/import_map.cjs +4 -3
- package/dist/load/import_map.d.ts +1 -0
- package/dist/load/import_map.js +1 -0
- package/dist/output_parsers/json.cjs +4 -0
- package/dist/output_parsers/json.js +4 -0
- package/dist/tools/google_places.cjs +81 -0
- package/dist/tools/google_places.d.ts +21 -0
- package/dist/tools/google_places.js +77 -0
- package/dist/vectorstores/clickhouse.cjs +286 -0
- package/dist/vectorstores/clickhouse.d.ts +126 -0
- package/dist/vectorstores/clickhouse.js +259 -0
- package/dist/vectorstores/elasticsearch.cjs +16 -3
- package/dist/vectorstores/elasticsearch.d.ts +6 -2
- package/dist/vectorstores/elasticsearch.js +16 -3
- package/dist/vectorstores/pgvector.cjs +142 -18
- package/dist/vectorstores/pgvector.d.ts +21 -0
- package/dist/vectorstores/pgvector.js +142 -18
- package/dist/vectorstores/prisma.cjs +1 -1
- package/dist/vectorstores/prisma.js +1 -1
- package/dist/vectorstores/weaviate.cjs +45 -2
- package/dist/vectorstores/weaviate.d.ts +27 -1
- package/dist/vectorstores/weaviate.js +45 -2
- package/dist/vectorstores/xata.cjs +3 -2
- package/dist/vectorstores/xata.js +3 -2
- package/document_loaders/fs/chatgpt.cjs +1 -0
- package/document_loaders/fs/chatgpt.d.ts +1 -0
- package/document_loaders/fs/chatgpt.js +1 -0
- package/document_loaders/fs/pptx.cjs +1 -0
- package/document_loaders/fs/pptx.d.ts +1 -0
- package/document_loaders/fs/pptx.js +1 -0
- package/experimental/tools/pyinterpreter.cjs +1 -0
- package/experimental/tools/pyinterpreter.d.ts +1 -0
- package/experimental/tools/pyinterpreter.js +1 -0
- package/llms/gradient_ai.cjs +1 -0
- package/llms/gradient_ai.d.ts +1 -0
- package/llms/gradient_ai.js +1 -0
- package/llms/watsonx_ai.cjs +1 -0
- package/llms/watsonx_ai.d.ts +1 -0
- package/llms/watsonx_ai.js +1 -0
- package/package.json +87 -13
- package/tools/google_places.cjs +1 -0
- package/tools/google_places.d.ts +1 -0
- package/tools/google_places.js +1 -0
- package/vectorstores/clickhouse.cjs +1 -0
- package/vectorstores/clickhouse.d.ts +1 -0
- package/vectorstores/clickhouse.js +1 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import * as uuid from "uuid";
|
|
2
|
+
import { createClient } from "@clickhouse/client";
|
|
3
|
+
import { format } from "mysql2";
|
|
4
|
+
import { VectorStore } from "./base.js";
|
|
5
|
+
import { Document } from "../document.js";
|
|
6
|
+
/**
|
|
7
|
+
* Class for interacting with the ClickHouse database. It extends the
|
|
8
|
+
* VectorStore class and provides methods for adding vectors and
|
|
9
|
+
* documents, searching for similar vectors, and creating instances from
|
|
10
|
+
* texts or documents.
|
|
11
|
+
*/
|
|
12
|
+
export class ClickHouseStore extends VectorStore {
|
|
13
|
+
_vectorstoreType() {
|
|
14
|
+
return "clickhouse";
|
|
15
|
+
}
|
|
16
|
+
constructor(embeddings, args) {
|
|
17
|
+
super(embeddings, args);
|
|
18
|
+
Object.defineProperty(this, "client", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: void 0
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "indexType", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: void 0
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "indexParam", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(this, "indexQueryParams", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(this, "columnMap", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: void 0
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(this, "database", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
configurable: true,
|
|
51
|
+
writable: true,
|
|
52
|
+
value: void 0
|
|
53
|
+
});
|
|
54
|
+
Object.defineProperty(this, "table", {
|
|
55
|
+
enumerable: true,
|
|
56
|
+
configurable: true,
|
|
57
|
+
writable: true,
|
|
58
|
+
value: void 0
|
|
59
|
+
});
|
|
60
|
+
Object.defineProperty(this, "isInitialized", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
configurable: true,
|
|
63
|
+
writable: true,
|
|
64
|
+
value: false
|
|
65
|
+
});
|
|
66
|
+
this.indexType = args.indexType || "annoy";
|
|
67
|
+
this.indexParam = args.indexParam || { L2Distance: 100 };
|
|
68
|
+
this.indexQueryParams = args.indexQueryParams || {};
|
|
69
|
+
this.columnMap = args.columnMap || {
|
|
70
|
+
id: "id",
|
|
71
|
+
document: "document",
|
|
72
|
+
embedding: "embedding",
|
|
73
|
+
metadata: "metadata",
|
|
74
|
+
uuid: "uuid",
|
|
75
|
+
};
|
|
76
|
+
this.database = args.database || "default";
|
|
77
|
+
this.table = args.table || "vector_table";
|
|
78
|
+
this.client = createClient({
|
|
79
|
+
host: `${args.protocol ?? "https://"}${args.host}:${args.port}`,
|
|
80
|
+
username: args.username,
|
|
81
|
+
password: args.password,
|
|
82
|
+
session_id: uuid.v4(),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Method to add vectors to the ClickHouse database.
|
|
87
|
+
* @param vectors The vectors to add.
|
|
88
|
+
* @param documents The documents associated with the vectors.
|
|
89
|
+
* @returns Promise that resolves when the vectors have been added.
|
|
90
|
+
*/
|
|
91
|
+
async addVectors(vectors, documents) {
|
|
92
|
+
if (vectors.length === 0) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!this.isInitialized) {
|
|
96
|
+
await this.initialize(vectors[0].length);
|
|
97
|
+
}
|
|
98
|
+
const queryStr = this.buildInsertQuery(vectors, documents);
|
|
99
|
+
await this.client.exec({ query: queryStr });
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Method to add documents to the ClickHouse database.
|
|
103
|
+
* @param documents The documents to add.
|
|
104
|
+
* @returns Promise that resolves when the documents have been added.
|
|
105
|
+
*/
|
|
106
|
+
async addDocuments(documents) {
|
|
107
|
+
return this.addVectors(await this.embeddings.embedDocuments(documents.map((d) => d.pageContent)), documents);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Method to search for vectors that are similar to a given query vector.
|
|
111
|
+
* @param query The query vector.
|
|
112
|
+
* @param k The number of similar vectors to return.
|
|
113
|
+
* @param filter Optional filter for the search results.
|
|
114
|
+
* @returns Promise that resolves with an array of tuples, each containing a Document and a score.
|
|
115
|
+
*/
|
|
116
|
+
async similaritySearchVectorWithScore(query, k, filter) {
|
|
117
|
+
if (!this.isInitialized) {
|
|
118
|
+
await this.initialize(query.length);
|
|
119
|
+
}
|
|
120
|
+
const queryStr = this.buildSearchQuery(query, k, filter);
|
|
121
|
+
const queryResultSet = await this.client.query({ query: queryStr });
|
|
122
|
+
const queryResult = await queryResultSet.json();
|
|
123
|
+
const result = queryResult.data.map((item) => [
|
|
124
|
+
new Document({ pageContent: item.document, metadata: item.metadata }),
|
|
125
|
+
item.dist,
|
|
126
|
+
]);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Static method to create an instance of ClickHouseStore from texts.
|
|
131
|
+
* @param texts The texts to use.
|
|
132
|
+
* @param metadatas The metadata associated with the texts.
|
|
133
|
+
* @param embeddings The embeddings to use.
|
|
134
|
+
* @param args The arguments for the ClickHouseStore.
|
|
135
|
+
* @returns Promise that resolves with a new instance of ClickHouseStore.
|
|
136
|
+
*/
|
|
137
|
+
static async fromTexts(texts, metadatas, embeddings, args) {
|
|
138
|
+
const docs = [];
|
|
139
|
+
for (let i = 0; i < texts.length; i += 1) {
|
|
140
|
+
const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;
|
|
141
|
+
const newDoc = new Document({
|
|
142
|
+
pageContent: texts[i],
|
|
143
|
+
metadata,
|
|
144
|
+
});
|
|
145
|
+
docs.push(newDoc);
|
|
146
|
+
}
|
|
147
|
+
return ClickHouseStore.fromDocuments(docs, embeddings, args);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Static method to create an instance of ClickHouseStore from documents.
|
|
151
|
+
* @param docs The documents to use.
|
|
152
|
+
* @param embeddings The embeddings to use.
|
|
153
|
+
* @param args The arguments for the ClickHouseStore.
|
|
154
|
+
* @returns Promise that resolves with a new instance of ClickHouseStore.
|
|
155
|
+
*/
|
|
156
|
+
static async fromDocuments(docs, embeddings, args) {
|
|
157
|
+
const instance = new this(embeddings, args);
|
|
158
|
+
await instance.addDocuments(docs);
|
|
159
|
+
return instance;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Static method to create an instance of ClickHouseStore from an existing
|
|
163
|
+
* index.
|
|
164
|
+
* @param embeddings The embeddings to use.
|
|
165
|
+
* @param args The arguments for the ClickHouseStore.
|
|
166
|
+
* @returns Promise that resolves with a new instance of ClickHouseStore.
|
|
167
|
+
*/
|
|
168
|
+
static async fromExistingIndex(embeddings, args) {
|
|
169
|
+
const instance = new this(embeddings, args);
|
|
170
|
+
await instance.initialize();
|
|
171
|
+
return instance;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Method to initialize the ClickHouse database.
|
|
175
|
+
* @param dimension Optional dimension of the vectors.
|
|
176
|
+
* @returns Promise that resolves when the database has been initialized.
|
|
177
|
+
*/
|
|
178
|
+
async initialize(dimension) {
|
|
179
|
+
const dim = dimension ?? (await this.embeddings.embedQuery("test")).length;
|
|
180
|
+
const indexParamStr = this.indexParam
|
|
181
|
+
? Object.entries(this.indexParam)
|
|
182
|
+
.map(([key, value]) => `'${key}', ${value}`)
|
|
183
|
+
.join(", ")
|
|
184
|
+
: "";
|
|
185
|
+
const query = `
|
|
186
|
+
CREATE TABLE IF NOT EXISTS ${this.database}.${this.table}(
|
|
187
|
+
${this.columnMap.id} Nullable(String),
|
|
188
|
+
${this.columnMap.document} Nullable(String),
|
|
189
|
+
${this.columnMap.embedding} Array(Float32),
|
|
190
|
+
${this.columnMap.metadata} JSON,
|
|
191
|
+
${this.columnMap.uuid} UUID DEFAULT generateUUIDv4(),
|
|
192
|
+
CONSTRAINT cons_vec_len CHECK length(${this.columnMap.embedding}) = ${dim},
|
|
193
|
+
INDEX vec_idx ${this.columnMap.embedding} TYPE ${this.indexType}(${indexParamStr}) GRANULARITY 1000
|
|
194
|
+
) ENGINE = MergeTree ORDER BY ${this.columnMap.uuid} SETTINGS index_granularity = 8192;`;
|
|
195
|
+
await this.client.exec({
|
|
196
|
+
query,
|
|
197
|
+
clickhouse_settings: {
|
|
198
|
+
allow_experimental_object_type: 1,
|
|
199
|
+
allow_experimental_annoy_index: 1,
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
this.isInitialized = true;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Method to build an SQL query for inserting vectors and documents into
|
|
206
|
+
* the ClickHouse database.
|
|
207
|
+
* @param vectors The vectors to insert.
|
|
208
|
+
* @param documents The documents to insert.
|
|
209
|
+
* @returns The SQL query string.
|
|
210
|
+
*/
|
|
211
|
+
buildInsertQuery(vectors, documents) {
|
|
212
|
+
const columnsStr = Object.values(Object.fromEntries(Object.entries(this.columnMap).filter(([key]) => key !== this.columnMap.uuid))).join(", ");
|
|
213
|
+
const placeholders = vectors.map(() => "(?, ?, ?, ?)").join(", ");
|
|
214
|
+
const values = [];
|
|
215
|
+
for (let i = 0; i < vectors.length; i += 1) {
|
|
216
|
+
const vector = vectors[i];
|
|
217
|
+
const document = documents[i];
|
|
218
|
+
values.push(uuid.v4(), this.escapeString(document.pageContent), JSON.stringify(vector), JSON.stringify(document.metadata));
|
|
219
|
+
}
|
|
220
|
+
const insertQueryStr = `
|
|
221
|
+
INSERT INTO TABLE ${this.database}.${this.table}(${columnsStr})
|
|
222
|
+
VALUES ${placeholders}
|
|
223
|
+
`;
|
|
224
|
+
const insertQuery = format(insertQueryStr, values);
|
|
225
|
+
return insertQuery;
|
|
226
|
+
}
|
|
227
|
+
escapeString(str) {
|
|
228
|
+
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Method to build an SQL query for searching for similar vectors in the
|
|
232
|
+
* ClickHouse database.
|
|
233
|
+
* @param query The query vector.
|
|
234
|
+
* @param k The number of similar vectors to return.
|
|
235
|
+
* @param filter Optional filter for the search results.
|
|
236
|
+
* @returns The SQL query string.
|
|
237
|
+
*/
|
|
238
|
+
buildSearchQuery(query, k, filter) {
|
|
239
|
+
const order = "ASC";
|
|
240
|
+
const whereStr = filter ? `PREWHERE ${filter.whereStr}` : "";
|
|
241
|
+
const placeholders = query.map(() => "?").join(", ");
|
|
242
|
+
const settingStrings = [];
|
|
243
|
+
if (this.indexQueryParams) {
|
|
244
|
+
for (const [key, value] of Object.entries(this.indexQueryParams)) {
|
|
245
|
+
settingStrings.push(`SETTING ${key}=${value}`);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
const searchQueryStr = `
|
|
249
|
+
SELECT ${this.columnMap.document} AS document, ${this.columnMap.metadata} AS metadata, dist
|
|
250
|
+
FROM ${this.database}.${this.table}
|
|
251
|
+
${whereStr}
|
|
252
|
+
ORDER BY L2Distance(${this.columnMap.embedding}, [${placeholders}]) AS dist ${order}
|
|
253
|
+
LIMIT ${k} ${settingStrings.join(" ")}
|
|
254
|
+
`;
|
|
255
|
+
// Format the query with actual values
|
|
256
|
+
const searchQuery = format(searchQueryStr, query);
|
|
257
|
+
return searchQuery;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -258,12 +258,25 @@ class ElasticVectorSearch extends base_js_1.VectorStore {
|
|
|
258
258
|
return;
|
|
259
259
|
await this.client.indices.create(request);
|
|
260
260
|
}
|
|
261
|
-
buildMetadataTerms(filter
|
|
261
|
+
buildMetadataTerms(filter
|
|
262
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
263
|
+
) {
|
|
262
264
|
if (filter == null)
|
|
263
265
|
return [];
|
|
264
266
|
const result = [];
|
|
265
|
-
|
|
266
|
-
|
|
267
|
+
const filters = Array.isArray(filter)
|
|
268
|
+
? filter
|
|
269
|
+
: Object.entries(filter).map(([key, value]) => ({
|
|
270
|
+
operator: "term",
|
|
271
|
+
field: key,
|
|
272
|
+
value,
|
|
273
|
+
}));
|
|
274
|
+
for (const condition of filters) {
|
|
275
|
+
result.push({
|
|
276
|
+
[condition.operator]: {
|
|
277
|
+
[`metadata.${condition.field}`]: condition.value,
|
|
278
|
+
},
|
|
279
|
+
});
|
|
267
280
|
}
|
|
268
281
|
return result;
|
|
269
282
|
}
|
|
@@ -33,7 +33,11 @@ export interface ElasticClientArgs {
|
|
|
33
33
|
/**
|
|
34
34
|
* Type representing a filter object in Elasticsearch.
|
|
35
35
|
*/
|
|
36
|
-
type ElasticFilter = object
|
|
36
|
+
type ElasticFilter = object | {
|
|
37
|
+
field: string;
|
|
38
|
+
operator: string;
|
|
39
|
+
value: any;
|
|
40
|
+
}[];
|
|
37
41
|
/**
|
|
38
42
|
* Class for interacting with an Elasticsearch database. It extends the
|
|
39
43
|
* VectorStore base class and provides methods for adding documents and
|
|
@@ -83,7 +87,7 @@ export declare class ElasticVectorSearch extends VectorStore {
|
|
|
83
87
|
* @param filter Optional filter to apply to the search.
|
|
84
88
|
* @returns A promise that resolves with an array of tuples, where each tuple contains a Document and its similarity score.
|
|
85
89
|
*/
|
|
86
|
-
similaritySearchVectorWithScore(query: number[], k: number, filter?: ElasticFilter
|
|
90
|
+
similaritySearchVectorWithScore(query: number[], k: number, filter?: ElasticFilter): Promise<[Document, number][]>;
|
|
87
91
|
/**
|
|
88
92
|
* Method to delete documents from the Elasticsearch database.
|
|
89
93
|
* @param params Object containing the IDs of the documents to delete.
|
|
@@ -232,12 +232,25 @@ export class ElasticVectorSearch extends VectorStore {
|
|
|
232
232
|
return;
|
|
233
233
|
await this.client.indices.create(request);
|
|
234
234
|
}
|
|
235
|
-
buildMetadataTerms(filter
|
|
235
|
+
buildMetadataTerms(filter
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
237
|
+
) {
|
|
236
238
|
if (filter == null)
|
|
237
239
|
return [];
|
|
238
240
|
const result = [];
|
|
239
|
-
|
|
240
|
-
|
|
241
|
+
const filters = Array.isArray(filter)
|
|
242
|
+
? filter
|
|
243
|
+
: Object.entries(filter).map(([key, value]) => ({
|
|
244
|
+
operator: "term",
|
|
245
|
+
field: key,
|
|
246
|
+
value,
|
|
247
|
+
}));
|
|
248
|
+
for (const condition of filters) {
|
|
249
|
+
result.push({
|
|
250
|
+
[condition.operator]: {
|
|
251
|
+
[`metadata.${condition.field}`]: condition.value,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
241
254
|
}
|
|
242
255
|
return result;
|
|
243
256
|
}
|
|
@@ -26,6 +26,24 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
26
26
|
writable: true,
|
|
27
27
|
value: void 0
|
|
28
28
|
});
|
|
29
|
+
Object.defineProperty(this, "collectionTableName", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "collectionName", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: "langchain"
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "collectionMetadata", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
29
47
|
Object.defineProperty(this, "idColumnName", {
|
|
30
48
|
enumerable: true,
|
|
31
49
|
configurable: true,
|
|
@@ -81,6 +99,9 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
81
99
|
value: 500
|
|
82
100
|
});
|
|
83
101
|
this.tableName = config.tableName;
|
|
102
|
+
this.collectionTableName = config.collectionTableName;
|
|
103
|
+
this.collectionName = config.collectionName ?? "langchain";
|
|
104
|
+
this.collectionMetadata = config.collectionMetadata ?? null;
|
|
84
105
|
this.filter = config.filter;
|
|
85
106
|
this.vectorColumnName = config.columns?.vectorColumnName ?? "embedding";
|
|
86
107
|
this.contentColumnName = config.columns?.contentColumnName ?? "text";
|
|
@@ -106,6 +127,9 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
106
127
|
const postgresqlVectorStore = new PGVectorStore(embeddings, config);
|
|
107
128
|
await postgresqlVectorStore._initializeClient();
|
|
108
129
|
await postgresqlVectorStore.ensureTableInDatabase();
|
|
130
|
+
if (postgresqlVectorStore.collectionTableName) {
|
|
131
|
+
await postgresqlVectorStore.ensureCollectionTableInDatabase();
|
|
132
|
+
}
|
|
109
133
|
return postgresqlVectorStore;
|
|
110
134
|
}
|
|
111
135
|
async _initializeClient() {
|
|
@@ -122,15 +146,56 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
122
146
|
const texts = documents.map(({ pageContent }) => pageContent);
|
|
123
147
|
return this.addVectors(await this.embeddings.embedDocuments(texts), documents);
|
|
124
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Inserts a row for the collectionName provided at initialization if it does not
|
|
151
|
+
* exist and returns the collectionId.
|
|
152
|
+
*
|
|
153
|
+
* @returns The collectionId for the given collectionName.
|
|
154
|
+
*/
|
|
155
|
+
async getOrCreateCollection() {
|
|
156
|
+
const queryString = `
|
|
157
|
+
SELECT uuid from ${this.collectionTableName}
|
|
158
|
+
WHERE name = $1;
|
|
159
|
+
`;
|
|
160
|
+
const queryResult = await this.pool.query(queryString, [
|
|
161
|
+
this.collectionName,
|
|
162
|
+
]);
|
|
163
|
+
let collectionId = queryResult.rows[0]?.uuid;
|
|
164
|
+
if (!collectionId) {
|
|
165
|
+
const insertString = `
|
|
166
|
+
INSERT INTO ${this.collectionTableName}(
|
|
167
|
+
uuid,
|
|
168
|
+
name,
|
|
169
|
+
cmetadata
|
|
170
|
+
)
|
|
171
|
+
VALUES (
|
|
172
|
+
uuid_generate_v4(),
|
|
173
|
+
$1,
|
|
174
|
+
$2
|
|
175
|
+
)
|
|
176
|
+
RETURNING uuid;
|
|
177
|
+
`;
|
|
178
|
+
const insertResult = await this.pool.query(insertString, [
|
|
179
|
+
this.collectionName,
|
|
180
|
+
this.collectionMetadata,
|
|
181
|
+
]);
|
|
182
|
+
collectionId = insertResult.rows[0]?.uuid;
|
|
183
|
+
}
|
|
184
|
+
return collectionId;
|
|
185
|
+
}
|
|
125
186
|
/**
|
|
126
187
|
* Generates the SQL placeholders for a specific row at the provided index.
|
|
127
188
|
*
|
|
128
189
|
* @param index - The index of the row for which placeholders need to be generated.
|
|
190
|
+
* @param numOfColumns - The number of columns we are inserting data into.
|
|
129
191
|
* @returns The SQL placeholders for the row values.
|
|
130
192
|
*/
|
|
131
|
-
generatePlaceholderForRowAt(index) {
|
|
132
|
-
const
|
|
133
|
-
|
|
193
|
+
generatePlaceholderForRowAt(index, numOfColumns) {
|
|
194
|
+
const placeholders = [];
|
|
195
|
+
for (let i = 0; i < numOfColumns; i += 1) {
|
|
196
|
+
placeholders.push(`$${index * numOfColumns + i + 1}`);
|
|
197
|
+
}
|
|
198
|
+
return `(${placeholders.join(", ")})`;
|
|
134
199
|
}
|
|
135
200
|
/**
|
|
136
201
|
* Constructs the SQL query for inserting rows into the specified table.
|
|
@@ -139,15 +204,25 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
139
204
|
* @param chunkIndex - The starting index for generating query placeholders based on chunk positioning.
|
|
140
205
|
* @returns The complete SQL INSERT INTO query string.
|
|
141
206
|
*/
|
|
142
|
-
buildInsertQuery(rows) {
|
|
207
|
+
async buildInsertQuery(rows) {
|
|
208
|
+
let collectionId;
|
|
209
|
+
if (this.collectionTableName) {
|
|
210
|
+
collectionId = await this.getOrCreateCollection();
|
|
211
|
+
}
|
|
212
|
+
const columns = [
|
|
213
|
+
this.contentColumnName,
|
|
214
|
+
this.vectorColumnName,
|
|
215
|
+
this.metadataColumnName,
|
|
216
|
+
];
|
|
217
|
+
if (collectionId) {
|
|
218
|
+
columns.push("collection_id");
|
|
219
|
+
}
|
|
143
220
|
const valuesPlaceholders = rows
|
|
144
|
-
.map((_, j) => this.generatePlaceholderForRowAt(j))
|
|
221
|
+
.map((_, j) => this.generatePlaceholderForRowAt(j, columns.length))
|
|
145
222
|
.join(", ");
|
|
146
223
|
const text = `
|
|
147
224
|
INSERT INTO ${this.tableName}(
|
|
148
|
-
${
|
|
149
|
-
${this.vectorColumnName},
|
|
150
|
-
${this.metadataColumnName}
|
|
225
|
+
${columns}
|
|
151
226
|
)
|
|
152
227
|
VALUES ${valuesPlaceholders}
|
|
153
228
|
`;
|
|
@@ -162,17 +237,24 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
162
237
|
* @returns Promise that resolves when the vectors have been added.
|
|
163
238
|
*/
|
|
164
239
|
async addVectors(vectors, documents) {
|
|
165
|
-
const rows =
|
|
240
|
+
const rows = [];
|
|
241
|
+
let collectionId;
|
|
242
|
+
if (this.collectionTableName) {
|
|
243
|
+
collectionId = await this.getOrCreateCollection();
|
|
244
|
+
}
|
|
245
|
+
for (let i = 0; i < vectors.length; i += 1) {
|
|
246
|
+
const values = [];
|
|
247
|
+
const embedding = vectors[i];
|
|
166
248
|
const embeddingString = `[${embedding.join(",")}]`;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
249
|
+
values.push(documents[i].pageContent, embeddingString, documents[i].metadata);
|
|
250
|
+
if (collectionId) {
|
|
251
|
+
values.push(collectionId);
|
|
252
|
+
}
|
|
253
|
+
rows.push(values);
|
|
254
|
+
}
|
|
173
255
|
for (let i = 0; i < rows.length; i += this.chunkSize) {
|
|
174
256
|
const chunk = rows.slice(i, i + this.chunkSize);
|
|
175
|
-
const insertQuery = this.buildInsertQuery(chunk);
|
|
257
|
+
const insertQuery = await this.buildInsertQuery(chunk);
|
|
176
258
|
const flatValues = chunk.flat();
|
|
177
259
|
try {
|
|
178
260
|
await this.pool.query(insertQuery, flatValues);
|
|
@@ -196,13 +278,23 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
196
278
|
async similaritySearchVectorWithScore(query, k, filter) {
|
|
197
279
|
const embeddingString = `[${query.join(",")}]`;
|
|
198
280
|
const _filter = filter ?? "{}";
|
|
281
|
+
let collectionId;
|
|
282
|
+
if (this.collectionTableName) {
|
|
283
|
+
collectionId = await this.getOrCreateCollection();
|
|
284
|
+
}
|
|
285
|
+
const parameters = [embeddingString, _filter, k];
|
|
286
|
+
if (collectionId) {
|
|
287
|
+
parameters.push(collectionId);
|
|
288
|
+
}
|
|
199
289
|
const queryString = `
|
|
200
290
|
SELECT *, ${this.vectorColumnName} <=> $1 as "_distance"
|
|
201
291
|
FROM ${this.tableName}
|
|
202
292
|
WHERE ${this.metadataColumnName}::jsonb @> $2
|
|
293
|
+
${collectionId ? "AND collection_id = $4" : ""}
|
|
203
294
|
ORDER BY "_distance" ASC
|
|
204
|
-
LIMIT $3
|
|
205
|
-
|
|
295
|
+
LIMIT $3;
|
|
296
|
+
`;
|
|
297
|
+
const documents = (await this.pool.query(queryString, parameters)).rows;
|
|
206
298
|
const results = [];
|
|
207
299
|
for (const doc of documents) {
|
|
208
300
|
if (doc._distance != null && doc[this.contentColumnName] != null) {
|
|
@@ -233,6 +325,38 @@ class PGVectorStore extends base_js_1.VectorStore {
|
|
|
233
325
|
);
|
|
234
326
|
`);
|
|
235
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Method to ensure the existence of the collection table in the database.
|
|
330
|
+
* It creates the table if it does not already exist.
|
|
331
|
+
*
|
|
332
|
+
* @returns Promise that resolves when the collection table has been ensured.
|
|
333
|
+
*/
|
|
334
|
+
async ensureCollectionTableInDatabase() {
|
|
335
|
+
try {
|
|
336
|
+
await this.pool.query(`
|
|
337
|
+
CREATE TABLE IF NOT EXISTS ${this.collectionTableName} (
|
|
338
|
+
uuid uuid NOT NULL DEFAULT uuid_generate_v4() PRIMARY KEY,
|
|
339
|
+
name character varying,
|
|
340
|
+
cmetadata jsonb
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
ALTER TABLE ${this.tableName}
|
|
344
|
+
ADD COLUMN collection_id uuid;
|
|
345
|
+
|
|
346
|
+
ALTER TABLE ${this.tableName}
|
|
347
|
+
ADD CONSTRAINT ${this.tableName}_collection_id_fkey
|
|
348
|
+
FOREIGN KEY (collection_id)
|
|
349
|
+
REFERENCES ${this.collectionTableName}(uuid)
|
|
350
|
+
ON DELETE CASCADE;
|
|
351
|
+
`);
|
|
352
|
+
}
|
|
353
|
+
catch (e) {
|
|
354
|
+
if (!e.message.includes("already exists")) {
|
|
355
|
+
console.error(e);
|
|
356
|
+
throw new Error(`Error adding column: ${e.message}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
236
360
|
/**
|
|
237
361
|
* Static method to create a new `PGVectorStore` instance from an
|
|
238
362
|
* array of texts and their metadata. It converts the texts into
|
|
@@ -11,6 +11,9 @@ type Metadata = Record<string, unknown>;
|
|
|
11
11
|
export interface PGVectorStoreArgs {
|
|
12
12
|
postgresConnectionOptions: PoolConfig;
|
|
13
13
|
tableName: string;
|
|
14
|
+
collectionTableName?: string;
|
|
15
|
+
collectionName?: string;
|
|
16
|
+
collectionMetadata?: Metadata | null;
|
|
14
17
|
columns?: {
|
|
15
18
|
idColumnName?: string;
|
|
16
19
|
vectorColumnName?: string;
|
|
@@ -35,6 +38,9 @@ export interface PGVectorStoreArgs {
|
|
|
35
38
|
export declare class PGVectorStore extends VectorStore {
|
|
36
39
|
FilterType: Metadata;
|
|
37
40
|
tableName: string;
|
|
41
|
+
collectionTableName?: string;
|
|
42
|
+
collectionName: string;
|
|
43
|
+
collectionMetadata: Metadata | null;
|
|
38
44
|
idColumnName: string;
|
|
39
45
|
vectorColumnName: string;
|
|
40
46
|
contentColumnName: string;
|
|
@@ -65,10 +71,18 @@ export declare class PGVectorStore extends VectorStore {
|
|
|
65
71
|
* @returns Promise that resolves when the documents have been added.
|
|
66
72
|
*/
|
|
67
73
|
addDocuments(documents: Document[]): Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Inserts a row for the collectionName provided at initialization if it does not
|
|
76
|
+
* exist and returns the collectionId.
|
|
77
|
+
*
|
|
78
|
+
* @returns The collectionId for the given collectionName.
|
|
79
|
+
*/
|
|
80
|
+
getOrCreateCollection(): Promise<string>;
|
|
68
81
|
/**
|
|
69
82
|
* Generates the SQL placeholders for a specific row at the provided index.
|
|
70
83
|
*
|
|
71
84
|
* @param index - The index of the row for which placeholders need to be generated.
|
|
85
|
+
* @param numOfColumns - The number of columns we are inserting data into.
|
|
72
86
|
* @returns The SQL placeholders for the row values.
|
|
73
87
|
*/
|
|
74
88
|
private generatePlaceholderForRowAt;
|
|
@@ -107,6 +121,13 @@ export declare class PGVectorStore extends VectorStore {
|
|
|
107
121
|
* @returns Promise that resolves when the table has been ensured.
|
|
108
122
|
*/
|
|
109
123
|
ensureTableInDatabase(): Promise<void>;
|
|
124
|
+
/**
|
|
125
|
+
* Method to ensure the existence of the collection table in the database.
|
|
126
|
+
* It creates the table if it does not already exist.
|
|
127
|
+
*
|
|
128
|
+
* @returns Promise that resolves when the collection table has been ensured.
|
|
129
|
+
*/
|
|
130
|
+
ensureCollectionTableInDatabase(): Promise<void>;
|
|
110
131
|
/**
|
|
111
132
|
* Static method to create a new `PGVectorStore` instance from an
|
|
112
133
|
* array of texts and their metadata. It converts the texts into
|