langchain 0.0.179 → 0.0.181

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.
Files changed (65) hide show
  1. package/chat_models/bedrock/web.cjs +1 -0
  2. package/chat_models/bedrock/web.d.ts +1 -0
  3. package/chat_models/bedrock/web.js +1 -0
  4. package/chat_models/bedrock.cjs +1 -1
  5. package/chat_models/bedrock.d.ts +1 -1
  6. package/chat_models/bedrock.js +1 -1
  7. package/dist/cache/base.cjs +2 -5
  8. package/dist/cache/base.js +2 -2
  9. package/dist/chains/combine_documents/reduce.cjs +3 -1
  10. package/dist/chains/combine_documents/reduce.js +3 -1
  11. package/dist/chat_models/baiduwenxin.cjs +16 -2
  12. package/dist/chat_models/baiduwenxin.js +16 -2
  13. package/dist/chat_models/bedrock/index.cjs +24 -0
  14. package/dist/chat_models/bedrock/index.d.ts +12 -0
  15. package/dist/chat_models/bedrock/index.js +18 -0
  16. package/dist/chat_models/{bedrock.cjs → bedrock/web.cjs} +44 -15
  17. package/dist/chat_models/{bedrock.d.ts → bedrock/web.d.ts} +14 -5
  18. package/dist/chat_models/{bedrock.js → bedrock/web.js} +42 -13
  19. package/dist/embeddings/cache_backed.cjs +2 -5
  20. package/dist/embeddings/cache_backed.js +2 -2
  21. package/dist/embeddings/voyage.cjs +120 -0
  22. package/dist/embeddings/voyage.d.ts +66 -0
  23. package/dist/embeddings/voyage.js +116 -0
  24. package/dist/llms/bedrock/index.cjs +17 -0
  25. package/dist/llms/bedrock/index.d.ts +7 -0
  26. package/dist/llms/bedrock/index.js +13 -0
  27. package/dist/llms/{bedrock.cjs → bedrock/web.cjs} +46 -12
  28. package/dist/llms/{bedrock.d.ts → bedrock/web.d.ts} +17 -4
  29. package/dist/llms/{bedrock.js → bedrock/web.js} +46 -12
  30. package/dist/load/import_constants.cjs +3 -0
  31. package/dist/load/import_constants.js +3 -0
  32. package/dist/load/import_map.cjs +3 -2
  33. package/dist/load/import_map.d.ts +1 -0
  34. package/dist/load/import_map.js +1 -0
  35. package/dist/stores/message/cassandra.cjs +135 -0
  36. package/dist/stores/message/cassandra.d.ts +44 -0
  37. package/dist/stores/message/cassandra.js +131 -0
  38. package/dist/util/bedrock.cjs +13 -1
  39. package/dist/util/bedrock.d.ts +5 -2
  40. package/dist/util/bedrock.js +13 -1
  41. package/dist/util/js-sha1/hash.cjs +358 -0
  42. package/dist/util/js-sha1/hash.d.ts +1 -0
  43. package/dist/util/js-sha1/hash.js +355 -0
  44. package/dist/util/stream.cjs +4 -1
  45. package/dist/util/stream.d.ts +4 -1
  46. package/dist/util/stream.js +4 -1
  47. package/dist/vectorstores/cassandra.cjs +197 -47
  48. package/dist/vectorstores/cassandra.d.ts +47 -4
  49. package/dist/vectorstores/cassandra.js +197 -47
  50. package/embeddings/voyage.cjs +1 -0
  51. package/embeddings/voyage.d.ts +1 -0
  52. package/embeddings/voyage.js +1 -0
  53. package/llms/bedrock/web.cjs +1 -0
  54. package/llms/bedrock/web.d.ts +1 -0
  55. package/llms/bedrock/web.js +1 -0
  56. package/llms/bedrock.cjs +1 -1
  57. package/llms/bedrock.d.ts +1 -1
  58. package/llms/bedrock.js +1 -1
  59. package/package.json +34 -4
  60. package/stores/message/cassandra.cjs +1 -0
  61. package/stores/message/cassandra.d.ts +1 -0
  62. package/stores/message/cassandra.js +1 -0
  63. package/dist/schema/runnable/remote.cjs +0 -225
  64. package/dist/schema/runnable/remote.d.ts +0 -28
  65. package/dist/schema/runnable/remote.js +0 -221
@@ -17,19 +17,19 @@ class CassandraStore extends base_js_1.VectorStore {
17
17
  return "cassandra";
18
18
  }
19
19
  constructor(embeddings, args) {
20
- const argsWithDefaults = {
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
- this.asyncCaller = new async_caller_js_1.AsyncCaller(argsWithDefaults ?? {});
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
- this.dimensions = argsWithDefaults.dimensions;
90
- this.keyspace = argsWithDefaults.keyspace;
91
- this.table = argsWithDefaults.table;
92
- this.primaryKey = argsWithDefaults.primaryKey;
93
- this.metadataColumns = argsWithDefaults.metadataColumns;
94
- this.indices = argsWithDefaults.indices;
95
- this.batchSize = argsWithDefaults.batchSize;
96
- if (this.batchSize < 1) {
97
- console.warn("batchSize must be greater than or equal to 1, defaulting to 1");
98
- this.batchSize = 1;
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
- const queryStr = this.buildSearchQuery(query, k, filter);
136
- const queryResultSet = await this.client.execute(queryStr);
137
- return queryResultSet?.rows.map((row, index) => {
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 = Object.assign(row, {});
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
- index,
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
- await this.client.execute(`CREATE TABLE IF NOT EXISTS ${this.keyspace}.${this.table} (
198
- ${this.primaryKey.name} ${this.primaryKey.type} PRIMARY KEY,
199
- text TEXT,
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
- ? this.metadataColumns.map((col) => `${col.name} ${col.type},`)
251
+ ? ", " +
252
+ this.metadataColumns
253
+ .map((col) => `${col.name} ${col.type}`)
254
+ .join(", ")
202
255
  : ""}
203
- vector VECTOR<FLOAT, ${this.dimensions}>
204
- );`);
205
- await this.client
206
- .execute(`CREATE CUSTOM INDEX IF NOT EXISTS idx_vector_${this.table}
207
- ON ${this.keyspace}.${this.table}(vector) USING 'StorageAttachedIndex';`);
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
- await this.client
210
- .execute(`CREATE CUSTOM INDEX IF NOT EXISTS idx_${this.table}_${name}
211
- ON ${this.keyspace}.${this.table} ${value} USING 'StorageAttachedIndex';`);
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
- buildWhereClause(filter) {
216
- const whereClause = Object.entries(filter)
217
- .map(([key, value]) => `${key} = '${value}'`)
218
- .join(" AND ");
219
- return `WHERE ${whereClause}`;
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 filter
374
+ * @param filters
227
375
  * @returns The CQL query string.
228
376
  */
229
- buildSearchQuery(query, k = 1, filter = undefined) {
230
- const whereClause = filter ? this.buildWhereClause(filter) : "";
231
- return `SELECT * FROM ${this.keyspace}.${this.table} ${whereClause} ORDER BY vector ANN OF [${query}] LIMIT ${k}`;
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: Record<string, any>;
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?: this["FilterType"]): Promise<[Document, number][]>;
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 filter
143
+ * @param filters
101
144
  * @returns The CQL query string.
102
145
  */
103
146
  private buildSearchQuery;