langchain 0.0.179 → 0.0.180
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/chat_models/bedrock/web.cjs +1 -0
- package/chat_models/bedrock/web.d.ts +1 -0
- package/chat_models/bedrock/web.js +1 -0
- package/chat_models/bedrock.cjs +1 -1
- package/chat_models/bedrock.d.ts +1 -1
- package/chat_models/bedrock.js +1 -1
- package/dist/chains/combine_documents/reduce.cjs +3 -1
- package/dist/chains/combine_documents/reduce.js +3 -1
- package/dist/chat_models/baiduwenxin.cjs +16 -2
- package/dist/chat_models/baiduwenxin.js +16 -2
- package/dist/chat_models/bedrock/index.cjs +24 -0
- package/dist/chat_models/bedrock/index.d.ts +12 -0
- package/dist/chat_models/bedrock/index.js +18 -0
- package/dist/chat_models/{bedrock.cjs → bedrock/web.cjs} +44 -15
- package/dist/chat_models/{bedrock.d.ts → bedrock/web.d.ts} +14 -5
- package/dist/chat_models/{bedrock.js → bedrock/web.js} +42 -13
- package/dist/llms/bedrock/index.cjs +17 -0
- package/dist/llms/bedrock/index.d.ts +7 -0
- package/dist/llms/bedrock/index.js +13 -0
- package/dist/llms/{bedrock.cjs → bedrock/web.cjs} +46 -12
- package/dist/llms/{bedrock.d.ts → bedrock/web.d.ts} +17 -4
- package/dist/llms/{bedrock.js → bedrock/web.js} +46 -12
- package/dist/load/import_constants.cjs +3 -0
- package/dist/load/import_constants.js +3 -0
- package/dist/stores/message/cassandra.cjs +135 -0
- package/dist/stores/message/cassandra.d.ts +44 -0
- package/dist/stores/message/cassandra.js +131 -0
- package/dist/util/bedrock.cjs +13 -1
- package/dist/util/bedrock.d.ts +5 -2
- package/dist/util/bedrock.js +13 -1
- package/dist/vectorstores/cassandra.cjs +197 -47
- package/dist/vectorstores/cassandra.d.ts +47 -4
- package/dist/vectorstores/cassandra.js +197 -47
- package/llms/bedrock/web.cjs +1 -0
- package/llms/bedrock/web.d.ts +1 -0
- package/llms/bedrock/web.js +1 -0
- package/llms/bedrock.cjs +1 -1
- package/llms/bedrock.d.ts +1 -1
- package/llms/bedrock.js +1 -1
- package/package.json +25 -1
- package/stores/message/cassandra.cjs +1 -0
- package/stores/message/cassandra.d.ts +1 -0
- package/stores/message/cassandra.js +1 -0
- package/dist/schema/runnable/remote.cjs +0 -225
- package/dist/schema/runnable/remote.d.ts +0 -28
- package/dist/schema/runnable/remote.js +0 -221
package/dist/util/bedrock.cjs
CHANGED
|
@@ -11,7 +11,7 @@ class BedrockLLMInputOutputAdapter {
|
|
|
11
11
|
/** Adapter class to prepare the inputs from Langchain to a format
|
|
12
12
|
that LLM model expects. Also, provides a helper function to extract
|
|
13
13
|
the generated text from the model response. */
|
|
14
|
-
static prepareInput(provider, prompt, maxTokens = 50, temperature = 0, stopSequences = undefined, modelKwargs = {}) {
|
|
14
|
+
static prepareInput(provider, prompt, maxTokens = 50, temperature = 0, stopSequences = undefined, modelKwargs = {}, bedrockMethod = "invoke") {
|
|
15
15
|
const inputBody = {};
|
|
16
16
|
if (provider === "anthropic") {
|
|
17
17
|
inputBody.prompt = prompt;
|
|
@@ -32,6 +32,15 @@ class BedrockLLMInputOutputAdapter {
|
|
|
32
32
|
temperature,
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
+
else if (provider === "cohere") {
|
|
36
|
+
inputBody.prompt = prompt;
|
|
37
|
+
inputBody.max_tokens = maxTokens;
|
|
38
|
+
inputBody.temperature = temperature;
|
|
39
|
+
inputBody.stop_sequences = stopSequences;
|
|
40
|
+
if (bedrockMethod === "invoke-with-response-stream") {
|
|
41
|
+
inputBody.stream = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
return { ...inputBody, ...modelKwargs };
|
|
36
45
|
}
|
|
37
46
|
/**
|
|
@@ -48,6 +57,9 @@ class BedrockLLMInputOutputAdapter {
|
|
|
48
57
|
else if (provider === "ai21") {
|
|
49
58
|
return responseBody?.completions?.[0]?.data?.text ?? "";
|
|
50
59
|
}
|
|
60
|
+
else if (provider === "cohere") {
|
|
61
|
+
return responseBody?.generations?.[0]?.text ?? responseBody?.text ?? "";
|
|
62
|
+
}
|
|
51
63
|
// I haven't been able to get a response with more than one result in it.
|
|
52
64
|
return responseBody.results?.[0]?.outputText;
|
|
53
65
|
}
|
package/dist/util/bedrock.d.ts
CHANGED
|
@@ -29,7 +29,10 @@ export interface BaseBedrockInput {
|
|
|
29
29
|
endpointUrl?: string;
|
|
30
30
|
/** Override the default endpoint hostname. */
|
|
31
31
|
endpointHost?: string;
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Optional additional stop sequences to pass to the model. Currently only supported for Anthropic and AI21.
|
|
34
|
+
* @deprecated Use .bind({ "stop": [...] }) instead
|
|
35
|
+
* */
|
|
33
36
|
stopSequences?: string[];
|
|
34
37
|
/** Additional kwargs to pass to the model. */
|
|
35
38
|
modelKwargs?: Record<string, unknown>;
|
|
@@ -49,7 +52,7 @@ export declare class BedrockLLMInputOutputAdapter {
|
|
|
49
52
|
/** Adapter class to prepare the inputs from Langchain to a format
|
|
50
53
|
that LLM model expects. Also, provides a helper function to extract
|
|
51
54
|
the generated text from the model response. */
|
|
52
|
-
static prepareInput(provider: string, prompt: string, maxTokens?: number, temperature?: number, stopSequences?: string[] | undefined, modelKwargs?: Record<string, unknown
|
|
55
|
+
static prepareInput(provider: string, prompt: string, maxTokens?: number, temperature?: number, stopSequences?: string[] | undefined, modelKwargs?: Record<string, unknown>, bedrockMethod?: "invoke" | "invoke-with-response-stream"): Dict;
|
|
53
56
|
/**
|
|
54
57
|
* Extracts the generated text from the service response.
|
|
55
58
|
* @param provider The provider name.
|
package/dist/util/bedrock.js
CHANGED
|
@@ -8,7 +8,7 @@ export class BedrockLLMInputOutputAdapter {
|
|
|
8
8
|
/** Adapter class to prepare the inputs from Langchain to a format
|
|
9
9
|
that LLM model expects. Also, provides a helper function to extract
|
|
10
10
|
the generated text from the model response. */
|
|
11
|
-
static prepareInput(provider, prompt, maxTokens = 50, temperature = 0, stopSequences = undefined, modelKwargs = {}) {
|
|
11
|
+
static prepareInput(provider, prompt, maxTokens = 50, temperature = 0, stopSequences = undefined, modelKwargs = {}, bedrockMethod = "invoke") {
|
|
12
12
|
const inputBody = {};
|
|
13
13
|
if (provider === "anthropic") {
|
|
14
14
|
inputBody.prompt = prompt;
|
|
@@ -29,6 +29,15 @@ export class BedrockLLMInputOutputAdapter {
|
|
|
29
29
|
temperature,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
else if (provider === "cohere") {
|
|
33
|
+
inputBody.prompt = prompt;
|
|
34
|
+
inputBody.max_tokens = maxTokens;
|
|
35
|
+
inputBody.temperature = temperature;
|
|
36
|
+
inputBody.stop_sequences = stopSequences;
|
|
37
|
+
if (bedrockMethod === "invoke-with-response-stream") {
|
|
38
|
+
inputBody.stream = true;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
32
41
|
return { ...inputBody, ...modelKwargs };
|
|
33
42
|
}
|
|
34
43
|
/**
|
|
@@ -45,6 +54,9 @@ export class BedrockLLMInputOutputAdapter {
|
|
|
45
54
|
else if (provider === "ai21") {
|
|
46
55
|
return responseBody?.completions?.[0]?.data?.text ?? "";
|
|
47
56
|
}
|
|
57
|
+
else if (provider === "cohere") {
|
|
58
|
+
return responseBody?.generations?.[0]?.text ?? responseBody?.text ?? "";
|
|
59
|
+
}
|
|
48
60
|
// I haven't been able to get a response with more than one result in it.
|
|
49
61
|
return responseBody.results?.[0]?.outputText;
|
|
50
62
|
}
|
|
@@ -17,19 +17,19 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
17
17
|
return "cassandra";
|
|
18
18
|
}
|
|
19
19
|
constructor(embeddings, args) {
|
|
20
|
-
|
|
21
|
-
indices: [],
|
|
22
|
-
maxConcurrency: 25,
|
|
23
|
-
batchSize: 1,
|
|
24
|
-
...args,
|
|
25
|
-
};
|
|
26
|
-
super(embeddings, argsWithDefaults);
|
|
20
|
+
super(embeddings, args);
|
|
27
21
|
Object.defineProperty(this, "client", {
|
|
28
22
|
enumerable: true,
|
|
29
23
|
configurable: true,
|
|
30
24
|
writable: true,
|
|
31
25
|
value: void 0
|
|
32
26
|
});
|
|
27
|
+
Object.defineProperty(this, "vectorType", {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
configurable: true,
|
|
30
|
+
writable: true,
|
|
31
|
+
value: void 0
|
|
32
|
+
});
|
|
33
33
|
Object.defineProperty(this, "dimensions", {
|
|
34
34
|
enumerable: true,
|
|
35
35
|
configurable: true,
|
|
@@ -54,6 +54,18 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
54
54
|
writable: true,
|
|
55
55
|
value: void 0
|
|
56
56
|
});
|
|
57
|
+
Object.defineProperty(this, "withClause", {
|
|
58
|
+
enumerable: true,
|
|
59
|
+
configurable: true,
|
|
60
|
+
writable: true,
|
|
61
|
+
value: void 0
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(this, "selectColumns", {
|
|
64
|
+
enumerable: true,
|
|
65
|
+
configurable: true,
|
|
66
|
+
writable: true,
|
|
67
|
+
value: void 0
|
|
68
|
+
});
|
|
57
69
|
Object.defineProperty(this, "table", {
|
|
58
70
|
enumerable: true,
|
|
59
71
|
configurable: true,
|
|
@@ -84,19 +96,27 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
84
96
|
writable: true,
|
|
85
97
|
value: void 0
|
|
86
98
|
});
|
|
87
|
-
|
|
99
|
+
const { indices = [], maxConcurrency = 25, withClause = "", batchSize = 1, vectorType = "cosine", dimensions, keyspace, table, primaryKey, metadataColumns, } = args;
|
|
100
|
+
const argsWithDefaults = {
|
|
101
|
+
...args,
|
|
102
|
+
indices,
|
|
103
|
+
maxConcurrency,
|
|
104
|
+
withClause,
|
|
105
|
+
batchSize,
|
|
106
|
+
vectorType,
|
|
107
|
+
};
|
|
108
|
+
this.asyncCaller = new async_caller_js_1.AsyncCaller(argsWithDefaults);
|
|
88
109
|
this.client = new cassandra_driver_1.Client(argsWithDefaults);
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
110
|
+
// Assign properties
|
|
111
|
+
this.vectorType = vectorType;
|
|
112
|
+
this.dimensions = dimensions;
|
|
113
|
+
this.keyspace = keyspace;
|
|
114
|
+
this.table = table;
|
|
115
|
+
this.primaryKey = Array.isArray(primaryKey) ? primaryKey : [primaryKey];
|
|
116
|
+
this.metadataColumns = metadataColumns;
|
|
117
|
+
this.withClause = withClause.trim().replace(/^with\s*/i, "");
|
|
118
|
+
this.indices = indices;
|
|
119
|
+
this.batchSize = batchSize >= 1 ? batchSize : 1;
|
|
100
120
|
}
|
|
101
121
|
/**
|
|
102
122
|
* Method to save vectors to the Cassandra database.
|
|
@@ -132,16 +152,45 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
132
152
|
if (!this.isInitialized) {
|
|
133
153
|
await this.initialize();
|
|
134
154
|
}
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
|
|
155
|
+
// Ensure we have an array of Filter from the public interface
|
|
156
|
+
const filters = this.asFilters(filter);
|
|
157
|
+
const queryStr = this.buildSearchQuery(filters);
|
|
158
|
+
// Search query will be of format:
|
|
159
|
+
// SELECT ..., text, similarity_x(?) AS similarity_score
|
|
160
|
+
// FROM ...
|
|
161
|
+
// <WHERE ...>
|
|
162
|
+
// ORDER BY vector ANN OF ?
|
|
163
|
+
// LIMIT ?
|
|
164
|
+
// If any filter values are specified, they will be in the WHERE clause as
|
|
165
|
+
// filter.name filter.operator ?
|
|
166
|
+
// queryParams is a list of bind variables sent with the prepared statement
|
|
167
|
+
const queryParams = [];
|
|
168
|
+
const vectorAsFloat32Array = new Float32Array(query);
|
|
169
|
+
queryParams.push(vectorAsFloat32Array);
|
|
170
|
+
if (filters) {
|
|
171
|
+
const values = filters.map(({ value }) => value);
|
|
172
|
+
queryParams.push(...values);
|
|
173
|
+
}
|
|
174
|
+
queryParams.push(vectorAsFloat32Array);
|
|
175
|
+
queryParams.push(k);
|
|
176
|
+
const queryResultSet = await this.client.execute(queryStr, queryParams, {
|
|
177
|
+
prepare: true,
|
|
178
|
+
});
|
|
179
|
+
return queryResultSet?.rows.map((row) => {
|
|
138
180
|
const textContent = row.text;
|
|
139
|
-
const sanitizedRow =
|
|
140
|
-
delete sanitizedRow.vector;
|
|
181
|
+
const sanitizedRow = { ...row };
|
|
141
182
|
delete sanitizedRow.text;
|
|
183
|
+
delete sanitizedRow.similarity_score;
|
|
184
|
+
// A null value in Cassandra evaluates to a deleted column
|
|
185
|
+
// as this is treated as a tombstone record for the cell.
|
|
186
|
+
Object.keys(sanitizedRow).forEach((key) => {
|
|
187
|
+
if (sanitizedRow[key] === null) {
|
|
188
|
+
delete sanitizedRow[key];
|
|
189
|
+
}
|
|
190
|
+
});
|
|
142
191
|
return [
|
|
143
192
|
new document_js_1.Document({ pageContent: textContent, metadata: sanitizedRow }),
|
|
144
|
-
|
|
193
|
+
row.similarity_score,
|
|
145
194
|
];
|
|
146
195
|
});
|
|
147
196
|
}
|
|
@@ -194,41 +243,142 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
194
243
|
* @returns Promise that resolves when the database has been initialized.
|
|
195
244
|
*/
|
|
196
245
|
async initialize() {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
246
|
+
let cql = "";
|
|
247
|
+
cql = `CREATE TABLE IF NOT EXISTS ${this.keyspace}.${this.table} (
|
|
248
|
+
${this.primaryKey.map((col) => `${col.name} ${col.type}`).join(", ")}
|
|
249
|
+
, text TEXT
|
|
200
250
|
${this.metadataColumns.length > 0
|
|
201
|
-
?
|
|
251
|
+
? ", " +
|
|
252
|
+
this.metadataColumns
|
|
253
|
+
.map((col) => `${col.name} ${col.type}`)
|
|
254
|
+
.join(", ")
|
|
202
255
|
: ""}
|
|
203
|
-
vector VECTOR<FLOAT, ${this.dimensions}>
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
256
|
+
, vector VECTOR<FLOAT, ${this.dimensions}>
|
|
257
|
+
, ${this.buildPrimaryKey(this.primaryKey)}
|
|
258
|
+
) ${this.withClause ? `WITH ${this.withClause}` : ""};`;
|
|
259
|
+
await this.client.execute(cql);
|
|
260
|
+
this.selectColumns = `${this.primaryKey
|
|
261
|
+
.map((col) => `${col.name}`)
|
|
262
|
+
.join(", ")}
|
|
263
|
+
${this.metadataColumns.length > 0
|
|
264
|
+
? ", " +
|
|
265
|
+
this.metadataColumns
|
|
266
|
+
.map((col) => `${col.name}`)
|
|
267
|
+
.join(", ")
|
|
268
|
+
: ""}`;
|
|
269
|
+
cql = `CREATE CUSTOM INDEX IF NOT EXISTS idx_vector_${this.table}
|
|
270
|
+
ON ${this.keyspace}.${this.table}(vector) USING 'StorageAttachedIndex' WITH OPTIONS = {'similarity_function': '${this.vectorType.toUpperCase()}'};`;
|
|
271
|
+
await this.client.execute(cql);
|
|
208
272
|
for await (const { name, value } of this.indices) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
273
|
+
cql = `CREATE CUSTOM INDEX IF NOT EXISTS idx_${this.table}_${name}
|
|
274
|
+
ON ${this.keyspace}.${this.table} ${value} USING 'StorageAttachedIndex';`;
|
|
275
|
+
await this.client.execute(cql);
|
|
212
276
|
}
|
|
213
277
|
this.isInitialized = true;
|
|
214
278
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
279
|
+
/**
|
|
280
|
+
* Method to build the PRIMARY KEY clause for CREATE TABLE.
|
|
281
|
+
* @param columns: list of Column to include in the key
|
|
282
|
+
* @returns The clause, including PRIMARY KEY
|
|
283
|
+
*/
|
|
284
|
+
buildPrimaryKey(columns) {
|
|
285
|
+
// Partition columns may be specified with optional attribute col.partition
|
|
286
|
+
const partitionColumns = columns
|
|
287
|
+
.filter((col) => col.partition)
|
|
288
|
+
.map((col) => col.name)
|
|
289
|
+
.join(", ");
|
|
290
|
+
// All columns not part of the partition key are clustering columns
|
|
291
|
+
const clusteringColumns = columns
|
|
292
|
+
.filter((col) => !col.partition)
|
|
293
|
+
.map((col) => col.name)
|
|
294
|
+
.join(", ");
|
|
295
|
+
let primaryKey = "";
|
|
296
|
+
// If partition columns are specified, they are included in a () wrapper
|
|
297
|
+
// If not, the clustering columns are used, and the first clustering column
|
|
298
|
+
// is the partition key per normal Cassandra behaviour.
|
|
299
|
+
if (partitionColumns) {
|
|
300
|
+
primaryKey = `PRIMARY KEY ((${partitionColumns}), ${clusteringColumns})`;
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
primaryKey = `PRIMARY KEY (${clusteringColumns})`;
|
|
304
|
+
}
|
|
305
|
+
return primaryKey;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Type guard to check if an object is a Filter.
|
|
309
|
+
* @param obj: the object to check
|
|
310
|
+
* @returns boolean indicating if the object is a Filter
|
|
311
|
+
*/
|
|
312
|
+
isFilter(obj) {
|
|
313
|
+
return (typeof obj === "object" && obj !== null && "name" in obj && "value" in obj);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Helper to convert Record<string,unknown> to a Filter[]
|
|
317
|
+
* @param record: a key-value Record collection
|
|
318
|
+
* @returns Record as a Filter[]
|
|
319
|
+
*/
|
|
320
|
+
convertToFilters(record) {
|
|
321
|
+
return Object.entries(record).map(([name, value]) => ({
|
|
322
|
+
name,
|
|
323
|
+
value,
|
|
324
|
+
operator: "=",
|
|
325
|
+
}));
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Input santisation method for filters, as FilterType is not required to be
|
|
329
|
+
* Filter[], but we want to use Filter[] internally.
|
|
330
|
+
* @param record: the proposed filter
|
|
331
|
+
* @returns A Filter[], which may be empty
|
|
332
|
+
*/
|
|
333
|
+
asFilters(record) {
|
|
334
|
+
if (!record) {
|
|
335
|
+
return [];
|
|
336
|
+
}
|
|
337
|
+
// If record is already an array
|
|
338
|
+
if (Array.isArray(record)) {
|
|
339
|
+
return record.flatMap((item) => {
|
|
340
|
+
// Check if item is a Filter before passing it to convertToFilters
|
|
341
|
+
if (this.isFilter(item)) {
|
|
342
|
+
return [item];
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
// Here item is treated as Record<string, unknown>
|
|
346
|
+
return this.convertToFilters(item);
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
// If record is a single Filter object, return it in an array
|
|
351
|
+
if (this.isFilter(record)) {
|
|
352
|
+
return [record];
|
|
353
|
+
}
|
|
354
|
+
// If record is a Record<string, unknown>, convert it to an array of Filter
|
|
355
|
+
return this.convertToFilters(record);
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Method to build the WHERE clause of a CQL query, using bind variable ?
|
|
359
|
+
* @param filters list of filters to include in the WHERE clause
|
|
360
|
+
* @returns The WHERE clause
|
|
361
|
+
*/
|
|
362
|
+
buildWhereClause(filters) {
|
|
363
|
+
if (!filters || filters.length === 0) {
|
|
364
|
+
return "";
|
|
365
|
+
}
|
|
366
|
+
const whereConditions = filters.map(({ name, operator = "=" }) => `${name} ${operator} ?`);
|
|
367
|
+
return `WHERE ${whereConditions.join(" AND ")}`;
|
|
220
368
|
}
|
|
221
369
|
/**
|
|
222
370
|
* Method to build an CQL query for searching for similar vectors in the
|
|
223
371
|
* Cassandra database.
|
|
224
372
|
* @param query The query vector.
|
|
225
373
|
* @param k The number of similar vectors to return.
|
|
226
|
-
* @param
|
|
374
|
+
* @param filters
|
|
227
375
|
* @returns The CQL query string.
|
|
228
376
|
*/
|
|
229
|
-
buildSearchQuery(
|
|
230
|
-
const whereClause =
|
|
231
|
-
|
|
377
|
+
buildSearchQuery(filters) {
|
|
378
|
+
const whereClause = filters ? this.buildWhereClause(filters) : "";
|
|
379
|
+
const cqlQuery = `SELECT ${this.selectColumns}, text, similarity_${this.vectorType}(vector, ?) AS similarity_score
|
|
380
|
+
FROM ${this.keyspace}.${this.table} ${whereClause} ORDER BY vector ANN OF ? LIMIT ?`;
|
|
381
|
+
return cqlQuery;
|
|
232
382
|
}
|
|
233
383
|
/**
|
|
234
384
|
* Method for inserting vectors and documents into the Cassandra database in a batch.
|
|
@@ -256,7 +406,7 @@ class CassandraStore extends base_js_1.VectorStore {
|
|
|
256
406
|
const metadataInsert = metadataColNames.length > 0 ? ", " + metadataColNames.join(", ") : "";
|
|
257
407
|
// Construct the query string and parameters
|
|
258
408
|
const query = {
|
|
259
|
-
query: `INSERT INTO ${this.keyspace}.${this.table} (vector, text${metadataInsert})
|
|
409
|
+
query: `INSERT INTO ${this.keyspace}.${this.table} (vector, text${metadataInsert})
|
|
260
410
|
VALUES (?, ?${", ?".repeat(metadataColNames.length)})`,
|
|
261
411
|
params: [preparedVector, document.pageContent, ...metadataVals],
|
|
262
412
|
};
|
|
@@ -6,17 +6,27 @@ import { Document } from "../document.js";
|
|
|
6
6
|
export interface Column {
|
|
7
7
|
type: string;
|
|
8
8
|
name: string;
|
|
9
|
+
partition?: boolean;
|
|
9
10
|
}
|
|
10
11
|
export interface Index {
|
|
11
12
|
name: string;
|
|
12
13
|
value: string;
|
|
13
14
|
}
|
|
15
|
+
export interface Filter {
|
|
16
|
+
name: string;
|
|
17
|
+
value: unknown;
|
|
18
|
+
operator?: string;
|
|
19
|
+
}
|
|
20
|
+
export type WhereClause = Filter[] | Filter | Record<string, unknown>;
|
|
21
|
+
export type SupportedVectorTypes = "cosine" | "dot_product" | "euclidean";
|
|
14
22
|
export interface CassandraLibArgs extends DseClientOptions, AsyncCallerParams {
|
|
15
23
|
table: string;
|
|
16
24
|
keyspace: string;
|
|
25
|
+
vectorType?: SupportedVectorTypes;
|
|
17
26
|
dimensions: number;
|
|
18
|
-
primaryKey: Column;
|
|
27
|
+
primaryKey: Column | Column[];
|
|
19
28
|
metadataColumns: Column[];
|
|
29
|
+
withClause?: string;
|
|
20
30
|
indices?: Index[];
|
|
21
31
|
batchSize?: number;
|
|
22
32
|
}
|
|
@@ -27,12 +37,15 @@ export interface CassandraLibArgs extends DseClientOptions, AsyncCallerParams {
|
|
|
27
37
|
* texts or documents.
|
|
28
38
|
*/
|
|
29
39
|
export declare class CassandraStore extends VectorStore {
|
|
30
|
-
FilterType:
|
|
40
|
+
FilterType: WhereClause;
|
|
31
41
|
private client;
|
|
42
|
+
private readonly vectorType;
|
|
32
43
|
private readonly dimensions;
|
|
33
44
|
private readonly keyspace;
|
|
34
45
|
private primaryKey;
|
|
35
46
|
private metadataColumns;
|
|
47
|
+
private withClause;
|
|
48
|
+
private selectColumns;
|
|
36
49
|
private readonly table;
|
|
37
50
|
private indices;
|
|
38
51
|
private isInitialized;
|
|
@@ -60,7 +73,7 @@ export declare class CassandraStore extends VectorStore {
|
|
|
60
73
|
* @param filter
|
|
61
74
|
* @returns Promise that resolves with an array of tuples, each containing a Document and a score.
|
|
62
75
|
*/
|
|
63
|
-
similaritySearchVectorWithScore(query: number[], k: number, filter?:
|
|
76
|
+
similaritySearchVectorWithScore(query: number[], k: number, filter?: WhereClause): Promise<[Document, number][]>;
|
|
64
77
|
/**
|
|
65
78
|
* Static method to create an instance of CassandraStore from texts.
|
|
66
79
|
* @param texts The texts to use.
|
|
@@ -91,13 +104,43 @@ export declare class CassandraStore extends VectorStore {
|
|
|
91
104
|
* @returns Promise that resolves when the database has been initialized.
|
|
92
105
|
*/
|
|
93
106
|
private initialize;
|
|
107
|
+
/**
|
|
108
|
+
* Method to build the PRIMARY KEY clause for CREATE TABLE.
|
|
109
|
+
* @param columns: list of Column to include in the key
|
|
110
|
+
* @returns The clause, including PRIMARY KEY
|
|
111
|
+
*/
|
|
112
|
+
private buildPrimaryKey;
|
|
113
|
+
/**
|
|
114
|
+
* Type guard to check if an object is a Filter.
|
|
115
|
+
* @param obj: the object to check
|
|
116
|
+
* @returns boolean indicating if the object is a Filter
|
|
117
|
+
*/
|
|
118
|
+
private isFilter;
|
|
119
|
+
/**
|
|
120
|
+
* Helper to convert Record<string,unknown> to a Filter[]
|
|
121
|
+
* @param record: a key-value Record collection
|
|
122
|
+
* @returns Record as a Filter[]
|
|
123
|
+
*/
|
|
124
|
+
private convertToFilters;
|
|
125
|
+
/**
|
|
126
|
+
* Input santisation method for filters, as FilterType is not required to be
|
|
127
|
+
* Filter[], but we want to use Filter[] internally.
|
|
128
|
+
* @param record: the proposed filter
|
|
129
|
+
* @returns A Filter[], which may be empty
|
|
130
|
+
*/
|
|
131
|
+
private asFilters;
|
|
132
|
+
/**
|
|
133
|
+
* Method to build the WHERE clause of a CQL query, using bind variable ?
|
|
134
|
+
* @param filters list of filters to include in the WHERE clause
|
|
135
|
+
* @returns The WHERE clause
|
|
136
|
+
*/
|
|
94
137
|
private buildWhereClause;
|
|
95
138
|
/**
|
|
96
139
|
* Method to build an CQL query for searching for similar vectors in the
|
|
97
140
|
* Cassandra database.
|
|
98
141
|
* @param query The query vector.
|
|
99
142
|
* @param k The number of similar vectors to return.
|
|
100
|
-
* @param
|
|
143
|
+
* @param filters
|
|
101
144
|
* @returns The CQL query string.
|
|
102
145
|
*/
|
|
103
146
|
private buildSearchQuery;
|