@mastra/couchbase 1.1.0 → 1.1.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/dist/index.cjs CHANGED
@@ -1,488 +1,381 @@
1
- 'use strict';
2
-
3
- var error = require('@mastra/core/error');
4
- var storage = require('@mastra/core/storage');
5
- var vector = require('@mastra/core/vector');
6
- var couchbase = require('couchbase');
7
-
8
- // src/vector/index.ts
9
- var DISTANCE_MAPPING = {
10
- cosine: "cosine",
11
- euclidean: "l2_norm",
12
- dotproduct: "dot_product"
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let _mastra_core_error = require("@mastra/core/error");
3
+ let _mastra_core_storage = require("@mastra/core/storage");
4
+ let _mastra_core_vector = require("@mastra/core/vector");
5
+ let couchbase = require("couchbase");
6
+ //#region src/vector/index.ts
7
+ const DISTANCE_MAPPING = {
8
+ cosine: "cosine",
9
+ euclidean: "l2_norm",
10
+ dotproduct: "dot_product"
13
11
  };
14
- var CouchbaseVector = class extends vector.MastraVector {
15
- clusterPromise;
16
- cluster;
17
- bucketName;
18
- collectionName;
19
- scopeName;
20
- collection;
21
- bucket;
22
- scope;
23
- vector_dimension;
24
- constructor({
25
- id,
26
- connectionString,
27
- username,
28
- password,
29
- bucketName,
30
- scopeName,
31
- collectionName
32
- }) {
33
- super({ id });
34
- try {
35
- this.clusterPromise = couchbase.connect(connectionString, {
36
- username,
37
- password,
38
- configProfile: "wanDevelopment"
39
- });
40
- this.cluster = null;
41
- this.bucketName = bucketName;
42
- this.collectionName = collectionName;
43
- this.scopeName = scopeName;
44
- this.collection = null;
45
- this.bucket = null;
46
- this.scope = null;
47
- this.vector_dimension = null;
48
- } catch (error$1) {
49
- throw new error.MastraError(
50
- {
51
- id: storage.createVectorErrorId("COUCHBASE", "INITIALIZE", "FAILED"),
52
- domain: error.ErrorDomain.STORAGE,
53
- category: error.ErrorCategory.THIRD_PARTY,
54
- details: {
55
- connectionString,
56
- username,
57
- bucketName,
58
- scopeName,
59
- collectionName
60
- }
61
- },
62
- error$1
63
- );
64
- }
65
- }
66
- async getCollection() {
67
- if (!this.cluster) {
68
- this.cluster = await this.clusterPromise;
69
- }
70
- if (!this.collection) {
71
- this.bucket = this.cluster.bucket(this.bucketName);
72
- this.scope = this.bucket.scope(this.scopeName);
73
- this.collection = this.scope.collection(this.collectionName);
74
- }
75
- return this.collection;
76
- }
77
- async createIndex({ indexName, dimension, metric = "dotproduct" }) {
78
- try {
79
- await this.getCollection();
80
- if (!Number.isInteger(dimension) || dimension <= 0) {
81
- throw new Error("Dimension must be a positive integer");
82
- }
83
- await this.scope.searchIndexes().upsertIndex({
84
- name: indexName,
85
- sourceName: this.bucketName,
86
- type: "fulltext-index",
87
- params: {
88
- doc_config: {
89
- docid_prefix_delim: "",
90
- docid_regexp: "",
91
- mode: "scope.collection.type_field",
92
- type_field: "type"
93
- },
94
- mapping: {
95
- default_analyzer: "standard",
96
- default_datetime_parser: "dateTimeOptional",
97
- default_field: "_all",
98
- default_mapping: {
99
- dynamic: true,
100
- enabled: false
101
- },
102
- default_type: "_default",
103
- docvalues_dynamic: true,
104
- // [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
105
- index_dynamic: true,
106
- store_dynamic: true,
107
- // [Doc](https://docs.couchbase.com/server/current/search/search-index-params.html#params) mentions this attribute is required for vector search to return the indexed field
108
- type_field: "_type",
109
- types: {
110
- [`${this.scopeName}.${this.collectionName}`]: {
111
- dynamic: true,
112
- enabled: true,
113
- properties: {
114
- embedding: {
115
- enabled: true,
116
- fields: [
117
- {
118
- dims: dimension,
119
- index: true,
120
- name: "embedding",
121
- similarity: DISTANCE_MAPPING[metric],
122
- type: "vector",
123
- vector_index_optimized_for: "recall",
124
- store: true,
125
- // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
126
- docvalues: true,
127
- // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
128
- include_term_vectors: true
129
- // CHANGED due to https://docs.couchbase.com/server/current/search/search-index-params.html#fields
130
- }
131
- ]
132
- },
133
- content: {
134
- enabled: true,
135
- fields: [
136
- {
137
- index: true,
138
- name: "content",
139
- store: true,
140
- type: "text"
141
- }
142
- ]
143
- }
144
- }
145
- }
146
- }
147
- },
148
- store: {
149
- indexType: "scorch",
150
- segmentVersion: 16
151
- }
152
- },
153
- sourceUuid: "",
154
- sourceParams: {},
155
- sourceType: "gocbcore",
156
- planParams: {
157
- maxPartitionsPerPIndex: 64,
158
- indexPartitions: 16,
159
- numReplicas: 0
160
- }
161
- });
162
- this.vector_dimension = dimension;
163
- } catch (error$1) {
164
- const message = error$1?.message || error$1?.toString();
165
- if (message && message.toLowerCase().includes("index exists")) {
166
- await this.validateExistingIndex(indexName, dimension, metric);
167
- return;
168
- }
169
- throw new error.MastraError(
170
- {
171
- id: storage.createVectorErrorId("COUCHBASE", "CREATE_INDEX", "FAILED"),
172
- domain: error.ErrorDomain.STORAGE,
173
- category: error.ErrorCategory.THIRD_PARTY,
174
- details: {
175
- indexName,
176
- dimension,
177
- metric
178
- }
179
- },
180
- error$1
181
- );
182
- }
183
- }
184
- async upsert({ vectors, metadata, ids }) {
185
- try {
186
- await this.getCollection();
187
- if (!vectors || vectors.length === 0) {
188
- throw new Error("No vectors provided");
189
- }
190
- if (this.vector_dimension) {
191
- for (const vector of vectors) {
192
- if (!vector || this.vector_dimension !== vector.length) {
193
- throw new Error("Vector dimension mismatch");
194
- }
195
- }
196
- }
197
- const pointIds = ids || vectors.map(() => crypto.randomUUID());
198
- const records = vectors.map((vector, i) => {
199
- const metadataObj = metadata?.[i] || {};
200
- const record = {
201
- embedding: vector,
202
- metadata: metadataObj
203
- };
204
- if (metadataObj.text) {
205
- record.content = metadataObj.text;
206
- }
207
- return record;
208
- });
209
- const allPromises = [];
210
- for (let i = 0; i < records.length; i++) {
211
- allPromises.push(this.collection.upsert(pointIds[i], records[i]));
212
- }
213
- await Promise.all(allPromises);
214
- return pointIds;
215
- } catch (error$1) {
216
- throw new error.MastraError(
217
- {
218
- id: storage.createVectorErrorId("COUCHBASE", "UPSERT", "FAILED"),
219
- domain: error.ErrorDomain.STORAGE,
220
- category: error.ErrorCategory.THIRD_PARTY
221
- },
222
- error$1
223
- );
224
- }
225
- }
226
- async query({ indexName, queryVector, topK = 10, includeVector = false }) {
227
- if (!queryVector) {
228
- throw new error.MastraError({
229
- id: storage.createVectorErrorId("COUCHBASE", "QUERY", "MISSING_VECTOR"),
230
- text: "queryVector is required for Couchbase queries. Metadata-only queries are not supported by this vector store.",
231
- domain: error.ErrorDomain.STORAGE,
232
- category: error.ErrorCategory.USER,
233
- details: { indexName }
234
- });
235
- }
236
- try {
237
- await this.getCollection();
238
- const index_stats = await this.describeIndex({ indexName });
239
- if (queryVector.length !== index_stats.dimension) {
240
- throw new Error(
241
- `Query vector dimension mismatch. Expected ${index_stats.dimension}, got ${queryVector.length}`
242
- );
243
- }
244
- let request = couchbase.SearchRequest.create(
245
- couchbase.VectorSearch.fromVectorQuery(couchbase.VectorQuery.create("embedding", queryVector).numCandidates(topK))
246
- );
247
- const results = await this.scope.search(indexName, request, {
248
- fields: ["*"]
249
- });
250
- if (includeVector) {
251
- throw new Error("Including vectors in search results is not yet supported by the Couchbase vector store");
252
- }
253
- const output = [];
254
- for (const match of results.rows) {
255
- const cleanedMetadata = {};
256
- const fields = match.fields || {};
257
- for (const key in fields) {
258
- if (Object.prototype.hasOwnProperty.call(fields, key)) {
259
- const newKey = key.startsWith("metadata.") ? key.substring("metadata.".length) : key;
260
- cleanedMetadata[newKey] = fields[key];
261
- }
262
- }
263
- output.push({
264
- id: match.id,
265
- score: match.score || 0,
266
- metadata: cleanedMetadata
267
- // Use the cleaned metadata object
268
- });
269
- }
270
- return output;
271
- } catch (error$1) {
272
- throw new error.MastraError(
273
- {
274
- id: storage.createVectorErrorId("COUCHBASE", "QUERY", "FAILED"),
275
- domain: error.ErrorDomain.STORAGE,
276
- category: error.ErrorCategory.THIRD_PARTY,
277
- details: {
278
- indexName,
279
- topK
280
- }
281
- },
282
- error$1
283
- );
284
- }
285
- }
286
- async listIndexes() {
287
- try {
288
- await this.getCollection();
289
- const indexes = await this.scope.searchIndexes().getAllIndexes();
290
- return indexes?.map((index) => index.name) || [];
291
- } catch (error$1) {
292
- throw new error.MastraError(
293
- {
294
- id: storage.createVectorErrorId("COUCHBASE", "LIST_INDEXES", "FAILED"),
295
- domain: error.ErrorDomain.STORAGE,
296
- category: error.ErrorCategory.THIRD_PARTY
297
- },
298
- error$1
299
- );
300
- }
301
- }
302
- /**
303
- * Retrieves statistics about a vector index.
304
- *
305
- * @param {string} indexName - The name of the index to describe
306
- * @returns A promise that resolves to the index statistics including dimension, count and metric
307
- */
308
- async describeIndex({ indexName }) {
309
- try {
310
- await this.getCollection();
311
- if (!(await this.listIndexes()).includes(indexName)) {
312
- throw new Error(`Index ${indexName} does not exist`);
313
- }
314
- const index = await this.scope.searchIndexes().getIndex(indexName);
315
- const dimensions = index.params.mapping?.types?.[`${this.scopeName}.${this.collectionName}`]?.properties?.embedding?.fields?.[0]?.dims;
316
- const count = -1;
317
- const metric = index.params.mapping?.types?.[`${this.scopeName}.${this.collectionName}`]?.properties?.embedding?.fields?.[0]?.similarity;
318
- return {
319
- dimension: dimensions,
320
- count,
321
- metric: Object.keys(DISTANCE_MAPPING).find(
322
- (key) => DISTANCE_MAPPING[key] === metric
323
- )
324
- };
325
- } catch (error$1) {
326
- throw new error.MastraError(
327
- {
328
- id: storage.createVectorErrorId("COUCHBASE", "DESCRIBE_INDEX", "FAILED"),
329
- domain: error.ErrorDomain.STORAGE,
330
- category: error.ErrorCategory.THIRD_PARTY,
331
- details: {
332
- indexName
333
- }
334
- },
335
- error$1
336
- );
337
- }
338
- }
339
- async deleteIndex({ indexName }) {
340
- try {
341
- await this.getCollection();
342
- if (!(await this.listIndexes()).includes(indexName)) {
343
- throw new Error(`Index ${indexName} does not exist`);
344
- }
345
- await this.scope.searchIndexes().dropIndex(indexName);
346
- this.vector_dimension = null;
347
- } catch (error$1) {
348
- if (error$1 instanceof error.MastraError) {
349
- throw error$1;
350
- }
351
- throw new error.MastraError(
352
- {
353
- id: storage.createVectorErrorId("COUCHBASE", "DELETE_INDEX", "FAILED"),
354
- domain: error.ErrorDomain.STORAGE,
355
- category: error.ErrorCategory.THIRD_PARTY,
356
- details: {
357
- indexName
358
- }
359
- },
360
- error$1
361
- );
362
- }
363
- }
364
- /**
365
- * Updates a vector by its ID with the provided vector and/or metadata.
366
- * @param indexName - The name of the index containing the vector.
367
- * @param id - The ID of the vector to update.
368
- * @param update - An object containing the vector and/or metadata to update.
369
- * @param update.vector - An optional array of numbers representing the new vector.
370
- * @param update.metadata - An optional record containing the new metadata.
371
- * @returns A promise that resolves when the update is complete.
372
- * @throws Will throw an error if no updates are provided or if the update operation fails.
373
- */
374
- async updateVector({ id, update }) {
375
- if (!id) {
376
- throw new error.MastraError({
377
- id: storage.createVectorErrorId("COUCHBASE", "UPDATE_VECTOR", "INVALID_ARGS"),
378
- domain: error.ErrorDomain.STORAGE,
379
- category: error.ErrorCategory.USER,
380
- text: "id is required for Couchbase updateVector",
381
- details: {}
382
- });
383
- }
384
- try {
385
- if (!update.vector && !update.metadata) {
386
- throw new Error("No updates provided");
387
- }
388
- if (update.vector && this.vector_dimension && update.vector.length !== this.vector_dimension) {
389
- throw new Error("Vector dimension mismatch");
390
- }
391
- const collection = await this.getCollection();
392
- try {
393
- await collection.get(id);
394
- } catch (err) {
395
- if (err.code === 13 || err.message?.includes("document not found")) {
396
- throw new Error(`Vector with id ${id} does not exist`);
397
- }
398
- throw err;
399
- }
400
- const specs = [];
401
- if (update.vector) specs.push(couchbase.MutateInSpec.replace("embedding", update.vector));
402
- if (update.metadata) specs.push(couchbase.MutateInSpec.replace("metadata", update.metadata));
403
- await collection.mutateIn(id, specs);
404
- } catch (error$1) {
405
- throw new error.MastraError(
406
- {
407
- id: storage.createVectorErrorId("COUCHBASE", "UPDATE_VECTOR", "FAILED"),
408
- domain: error.ErrorDomain.STORAGE,
409
- category: error.ErrorCategory.THIRD_PARTY,
410
- details: {
411
- ...id && { id },
412
- hasVectorUpdate: !!update.vector,
413
- hasMetadataUpdate: !!update.metadata
414
- }
415
- },
416
- error$1
417
- );
418
- }
419
- }
420
- /**
421
- * Deletes a vector by its ID.
422
- * @param indexName - The name of the index containing the vector.
423
- * @param id - The ID of the vector to delete.
424
- * @returns A promise that resolves when the deletion is complete.
425
- * @throws Will throw an error if the deletion operation fails.
426
- */
427
- async deleteVector({ id }) {
428
- try {
429
- const collection = await this.getCollection();
430
- try {
431
- await collection.get(id);
432
- } catch (err) {
433
- if (err.code === 13 || err.message?.includes("document not found")) {
434
- throw new Error(`Vector with id ${id} does not exist`);
435
- }
436
- throw err;
437
- }
438
- await collection.remove(id);
439
- } catch (error$1) {
440
- throw new error.MastraError(
441
- {
442
- id: storage.createVectorErrorId("COUCHBASE", "DELETE_VECTOR", "FAILED"),
443
- domain: error.ErrorDomain.STORAGE,
444
- category: error.ErrorCategory.THIRD_PARTY,
445
- details: {
446
- ...id && { id }
447
- }
448
- },
449
- error$1
450
- );
451
- }
452
- }
453
- async deleteVectors({ indexName, filter, ids }) {
454
- throw new error.MastraError({
455
- id: storage.createVectorErrorId("COUCHBASE", "DELETE_VECTORS", "NOT_SUPPORTED"),
456
- text: "deleteVectors is not yet implemented for Couchbase vector store",
457
- domain: error.ErrorDomain.STORAGE,
458
- category: error.ErrorCategory.SYSTEM,
459
- details: {
460
- indexName,
461
- ...filter && { filter: JSON.stringify(filter) },
462
- ...ids && { idsCount: ids.length }
463
- }
464
- });
465
- }
466
- async disconnect() {
467
- try {
468
- if (!this.cluster) {
469
- return;
470
- }
471
- await this.cluster.close();
472
- } catch (error$1) {
473
- throw new error.MastraError(
474
- {
475
- id: storage.createVectorErrorId("COUCHBASE", "DISCONNECT", "FAILED"),
476
- domain: error.ErrorDomain.STORAGE,
477
- category: error.ErrorCategory.THIRD_PARTY
478
- },
479
- error$1
480
- );
481
- }
482
- }
12
+ var CouchbaseVector = class extends _mastra_core_vector.MastraVector {
13
+ clusterPromise;
14
+ cluster;
15
+ bucketName;
16
+ collectionName;
17
+ scopeName;
18
+ collection;
19
+ bucket;
20
+ scope;
21
+ vector_dimension;
22
+ constructor({ id, connectionString, username, password, bucketName, scopeName, collectionName }) {
23
+ super({ id });
24
+ try {
25
+ this.clusterPromise = (0, couchbase.connect)(connectionString, {
26
+ username,
27
+ password,
28
+ configProfile: "wanDevelopment"
29
+ });
30
+ this.cluster = null;
31
+ this.bucketName = bucketName;
32
+ this.collectionName = collectionName;
33
+ this.scopeName = scopeName;
34
+ this.collection = null;
35
+ this.bucket = null;
36
+ this.scope = null;
37
+ this.vector_dimension = null;
38
+ } catch (error) {
39
+ throw new _mastra_core_error.MastraError({
40
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "INITIALIZE", "FAILED"),
41
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
42
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
43
+ details: {
44
+ connectionString,
45
+ username,
46
+ bucketName,
47
+ scopeName,
48
+ collectionName
49
+ }
50
+ }, error);
51
+ }
52
+ }
53
+ async getCollection() {
54
+ if (!this.cluster) this.cluster = await this.clusterPromise;
55
+ if (!this.collection) {
56
+ this.bucket = this.cluster.bucket(this.bucketName);
57
+ this.scope = this.bucket.scope(this.scopeName);
58
+ this.collection = this.scope.collection(this.collectionName);
59
+ }
60
+ return this.collection;
61
+ }
62
+ async createIndex({ indexName, dimension, metric = "dotproduct" }) {
63
+ try {
64
+ await this.getCollection();
65
+ if (!Number.isInteger(dimension) || dimension <= 0) throw new Error("Dimension must be a positive integer");
66
+ await this.scope.searchIndexes().upsertIndex({
67
+ name: indexName,
68
+ sourceName: this.bucketName,
69
+ type: "fulltext-index",
70
+ params: {
71
+ doc_config: {
72
+ docid_prefix_delim: "",
73
+ docid_regexp: "",
74
+ mode: "scope.collection.type_field",
75
+ type_field: "type"
76
+ },
77
+ mapping: {
78
+ default_analyzer: "standard",
79
+ default_datetime_parser: "dateTimeOptional",
80
+ default_field: "_all",
81
+ default_mapping: {
82
+ dynamic: true,
83
+ enabled: false
84
+ },
85
+ default_type: "_default",
86
+ docvalues_dynamic: true,
87
+ index_dynamic: true,
88
+ store_dynamic: true,
89
+ type_field: "_type",
90
+ types: { [`${this.scopeName}.${this.collectionName}`]: {
91
+ dynamic: true,
92
+ enabled: true,
93
+ properties: {
94
+ embedding: {
95
+ enabled: true,
96
+ fields: [{
97
+ dims: dimension,
98
+ index: true,
99
+ name: "embedding",
100
+ similarity: DISTANCE_MAPPING[metric],
101
+ type: "vector",
102
+ vector_index_optimized_for: "recall",
103
+ store: true,
104
+ docvalues: true,
105
+ include_term_vectors: true
106
+ }]
107
+ },
108
+ content: {
109
+ enabled: true,
110
+ fields: [{
111
+ index: true,
112
+ name: "content",
113
+ store: true,
114
+ type: "text"
115
+ }]
116
+ }
117
+ }
118
+ } }
119
+ },
120
+ store: {
121
+ indexType: "scorch",
122
+ segmentVersion: 16
123
+ }
124
+ },
125
+ sourceUuid: "",
126
+ sourceParams: {},
127
+ sourceType: "gocbcore",
128
+ planParams: {
129
+ maxPartitionsPerPIndex: 64,
130
+ indexPartitions: 16,
131
+ numReplicas: 0
132
+ }
133
+ });
134
+ this.vector_dimension = dimension;
135
+ } catch (error) {
136
+ const message = error?.message || error?.toString();
137
+ if (message && message.toLowerCase().includes("index exists")) {
138
+ await this.validateExistingIndex(indexName, dimension, metric);
139
+ return;
140
+ }
141
+ throw new _mastra_core_error.MastraError({
142
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "CREATE_INDEX", "FAILED"),
143
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
144
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
145
+ details: {
146
+ indexName,
147
+ dimension,
148
+ metric
149
+ }
150
+ }, error);
151
+ }
152
+ }
153
+ async upsert({ vectors, metadata, ids }) {
154
+ try {
155
+ await this.getCollection();
156
+ if (!vectors || vectors.length === 0) throw new Error("No vectors provided");
157
+ if (this.vector_dimension) {
158
+ for (const vector of vectors) if (!vector || this.vector_dimension !== vector.length) throw new Error("Vector dimension mismatch");
159
+ }
160
+ const pointIds = ids || vectors.map(() => crypto.randomUUID());
161
+ const records = vectors.map((vector, i) => {
162
+ const metadataObj = metadata?.[i] || {};
163
+ const record = {
164
+ embedding: vector,
165
+ metadata: metadataObj
166
+ };
167
+ if (metadataObj.text) record.content = metadataObj.text;
168
+ return record;
169
+ });
170
+ const allPromises = [];
171
+ for (let i = 0; i < records.length; i++) allPromises.push(this.collection.upsert(pointIds[i], records[i]));
172
+ await Promise.all(allPromises);
173
+ return pointIds;
174
+ } catch (error) {
175
+ throw new _mastra_core_error.MastraError({
176
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "UPSERT", "FAILED"),
177
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
178
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
179
+ }, error);
180
+ }
181
+ }
182
+ async query({ indexName, queryVector, topK = 10, includeVector = false }) {
183
+ if (!queryVector) throw new _mastra_core_error.MastraError({
184
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "QUERY", "MISSING_VECTOR"),
185
+ text: "queryVector is required for Couchbase queries. Metadata-only queries are not supported by this vector store.",
186
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
187
+ category: _mastra_core_error.ErrorCategory.USER,
188
+ details: { indexName }
189
+ });
190
+ try {
191
+ await this.getCollection();
192
+ const index_stats = await this.describeIndex({ indexName });
193
+ if (queryVector.length !== index_stats.dimension) throw new Error(`Query vector dimension mismatch. Expected ${index_stats.dimension}, got ${queryVector.length}`);
194
+ let request = couchbase.SearchRequest.create(couchbase.VectorSearch.fromVectorQuery(couchbase.VectorQuery.create("embedding", queryVector).numCandidates(topK)));
195
+ const results = await this.scope.search(indexName, request, { fields: ["*"] });
196
+ if (includeVector) throw new Error("Including vectors in search results is not yet supported by the Couchbase vector store");
197
+ const output = [];
198
+ for (const match of results.rows) {
199
+ const cleanedMetadata = {};
200
+ const fields = match.fields || {};
201
+ for (const key in fields) if (Object.prototype.hasOwnProperty.call(fields, key)) {
202
+ const newKey = key.startsWith("metadata.") ? key.substring(9) : key;
203
+ cleanedMetadata[newKey] = fields[key];
204
+ }
205
+ output.push({
206
+ id: match.id,
207
+ score: match.score || 0,
208
+ metadata: cleanedMetadata
209
+ });
210
+ }
211
+ return output;
212
+ } catch (error) {
213
+ throw new _mastra_core_error.MastraError({
214
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "QUERY", "FAILED"),
215
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
216
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
217
+ details: {
218
+ indexName,
219
+ topK
220
+ }
221
+ }, error);
222
+ }
223
+ }
224
+ async listIndexes() {
225
+ try {
226
+ await this.getCollection();
227
+ return (await this.scope.searchIndexes().getAllIndexes())?.map((index) => index.name) || [];
228
+ } catch (error) {
229
+ throw new _mastra_core_error.MastraError({
230
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "LIST_INDEXES", "FAILED"),
231
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
232
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
233
+ }, error);
234
+ }
235
+ }
236
+ /**
237
+ * Retrieves statistics about a vector index.
238
+ *
239
+ * @param {string} indexName - The name of the index to describe
240
+ * @returns A promise that resolves to the index statistics including dimension, count and metric
241
+ */
242
+ async describeIndex({ indexName }) {
243
+ try {
244
+ await this.getCollection();
245
+ if (!(await this.listIndexes()).includes(indexName)) throw new Error(`Index ${indexName} does not exist`);
246
+ const index = await this.scope.searchIndexes().getIndex(indexName);
247
+ const dimensions = index.params.mapping?.types?.[`${this.scopeName}.${this.collectionName}`]?.properties?.embedding?.fields?.[0]?.dims;
248
+ const count = -1;
249
+ const metric = index.params.mapping?.types?.[`${this.scopeName}.${this.collectionName}`]?.properties?.embedding?.fields?.[0]?.similarity;
250
+ return {
251
+ dimension: dimensions,
252
+ count,
253
+ metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === metric)
254
+ };
255
+ } catch (error) {
256
+ throw new _mastra_core_error.MastraError({
257
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "DESCRIBE_INDEX", "FAILED"),
258
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
259
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
260
+ details: { indexName }
261
+ }, error);
262
+ }
263
+ }
264
+ async deleteIndex({ indexName }) {
265
+ try {
266
+ await this.getCollection();
267
+ if (!(await this.listIndexes()).includes(indexName)) throw new Error(`Index ${indexName} does not exist`);
268
+ await this.scope.searchIndexes().dropIndex(indexName);
269
+ this.vector_dimension = null;
270
+ } catch (error) {
271
+ if (error instanceof _mastra_core_error.MastraError) throw error;
272
+ throw new _mastra_core_error.MastraError({
273
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "DELETE_INDEX", "FAILED"),
274
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
275
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
276
+ details: { indexName }
277
+ }, error);
278
+ }
279
+ }
280
+ /**
281
+ * Updates a vector by its ID with the provided vector and/or metadata.
282
+ * @param indexName - The name of the index containing the vector.
283
+ * @param id - The ID of the vector to update.
284
+ * @param update - An object containing the vector and/or metadata to update.
285
+ * @param update.vector - An optional array of numbers representing the new vector.
286
+ * @param update.metadata - An optional record containing the new metadata.
287
+ * @returns A promise that resolves when the update is complete.
288
+ * @throws Will throw an error if no updates are provided or if the update operation fails.
289
+ */
290
+ async updateVector({ id, update }) {
291
+ if (!id) throw new _mastra_core_error.MastraError({
292
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "UPDATE_VECTOR", "INVALID_ARGS"),
293
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
294
+ category: _mastra_core_error.ErrorCategory.USER,
295
+ text: "id is required for Couchbase updateVector",
296
+ details: {}
297
+ });
298
+ try {
299
+ if (!update.vector && !update.metadata) throw new Error("No updates provided");
300
+ if (update.vector && this.vector_dimension && update.vector.length !== this.vector_dimension) throw new Error("Vector dimension mismatch");
301
+ const collection = await this.getCollection();
302
+ try {
303
+ await collection.get(id);
304
+ } catch (err) {
305
+ if (err.code === 13 || err.message?.includes("document not found")) throw new Error(`Vector with id ${id} does not exist`);
306
+ throw err;
307
+ }
308
+ const specs = [];
309
+ if (update.vector) specs.push(couchbase.MutateInSpec.replace("embedding", update.vector));
310
+ if (update.metadata) specs.push(couchbase.MutateInSpec.replace("metadata", update.metadata));
311
+ await collection.mutateIn(id, specs);
312
+ } catch (error) {
313
+ throw new _mastra_core_error.MastraError({
314
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "UPDATE_VECTOR", "FAILED"),
315
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
316
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
317
+ details: {
318
+ ...id && { id },
319
+ hasVectorUpdate: !!update.vector,
320
+ hasMetadataUpdate: !!update.metadata
321
+ }
322
+ }, error);
323
+ }
324
+ }
325
+ /**
326
+ * Deletes a vector by its ID.
327
+ * @param indexName - The name of the index containing the vector.
328
+ * @param id - The ID of the vector to delete.
329
+ * @returns A promise that resolves when the deletion is complete.
330
+ * @throws Will throw an error if the deletion operation fails.
331
+ */
332
+ async deleteVector({ id }) {
333
+ try {
334
+ const collection = await this.getCollection();
335
+ try {
336
+ await collection.get(id);
337
+ } catch (err) {
338
+ if (err.code === 13 || err.message?.includes("document not found")) throw new Error(`Vector with id ${id} does not exist`);
339
+ throw err;
340
+ }
341
+ await collection.remove(id);
342
+ } catch (error) {
343
+ throw new _mastra_core_error.MastraError({
344
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "DELETE_VECTOR", "FAILED"),
345
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
346
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
347
+ details: { ...id && { id } }
348
+ }, error);
349
+ }
350
+ }
351
+ async deleteVectors({ indexName, filter, ids }) {
352
+ throw new _mastra_core_error.MastraError({
353
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "DELETE_VECTORS", "NOT_SUPPORTED"),
354
+ text: "deleteVectors is not yet implemented for Couchbase vector store",
355
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
356
+ category: _mastra_core_error.ErrorCategory.SYSTEM,
357
+ details: {
358
+ indexName,
359
+ ...filter && { filter: JSON.stringify(filter) },
360
+ ...ids && { idsCount: ids.length }
361
+ }
362
+ });
363
+ }
364
+ async disconnect() {
365
+ try {
366
+ if (!this.cluster) return;
367
+ await this.cluster.close();
368
+ } catch (error) {
369
+ throw new _mastra_core_error.MastraError({
370
+ id: (0, _mastra_core_storage.createVectorErrorId)("COUCHBASE", "DISCONNECT", "FAILED"),
371
+ domain: _mastra_core_error.ErrorDomain.STORAGE,
372
+ category: _mastra_core_error.ErrorCategory.THIRD_PARTY
373
+ }, error);
374
+ }
375
+ }
483
376
  };
484
-
377
+ //#endregion
485
378
  exports.CouchbaseVector = CouchbaseVector;
486
379
  exports.DISTANCE_MAPPING = DISTANCE_MAPPING;
487
- //# sourceMappingURL=index.cjs.map
380
+
488
381
  //# sourceMappingURL=index.cjs.map