@mastra/qdrant 0.10.3 → 0.10.4-alpha.0

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/qdrant@0.10.3-alpha.0 build /home/runner/work/mastra/mastra/stores/qdrant
2
+ > @mastra/qdrant@0.10.4-alpha.0 build /home/runner/work/mastra/mastra/stores/qdrant
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 7578ms
9
+ TSC ⚡️ Build success in 7453ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/qdrant/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/qdrant/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 10357ms
16
+ DTS ⚡️ Build success in 9897ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- ESM dist/index.js 18.24 KB
21
- ESM ⚡️ Build success in 687ms
22
- CJS dist/index.cjs 18.30 KB
23
- CJS ⚡️ Build success in 691ms
20
+ CJS dist/index.cjs 21.22 KB
21
+ CJS ⚡️ Build success in 959ms
22
+ ESM dist/index.js 20.99 KB
23
+ ESM ⚡️ Build success in 962ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @mastra/qdrant
2
2
 
3
+ ## 0.10.4-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 0e17048: Throw mastra errors in storage packages
8
+ - Updated dependencies [d1baedb]
9
+ - Updated dependencies [4d21bf2]
10
+ - Updated dependencies [2097952]
11
+ - Updated dependencies [4fb0cc2]
12
+ - Updated dependencies [d2a7a31]
13
+ - Updated dependencies [0e17048]
14
+ - @mastra/core@0.10.7-alpha.1
15
+
3
16
  ## 0.10.3
4
17
 
5
18
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var error = require('@mastra/core/error');
3
4
  var vector = require('@mastra/core/vector');
4
5
  var jsClientRest = require('@qdrant/js-client-rest');
5
6
  var filter = require('@mastra/core/vector/filter');
@@ -267,22 +268,46 @@ var QdrantVector = class extends vector.MastraVector {
267
268
  vector,
268
269
  payload: metadata?.[i] || {}
269
270
  }));
270
- for (let i = 0; i < records.length; i += BATCH_SIZE) {
271
- const batch = records.slice(i, i + BATCH_SIZE);
272
- await this.client.upsert(indexName, {
273
- // @ts-expect-error
274
- points: batch,
275
- wait: true
276
- });
271
+ try {
272
+ for (let i = 0; i < records.length; i += BATCH_SIZE) {
273
+ const batch = records.slice(i, i + BATCH_SIZE);
274
+ await this.client.upsert(indexName, {
275
+ // @ts-expect-error
276
+ points: batch,
277
+ wait: true
278
+ });
279
+ }
280
+ return pointIds;
281
+ } catch (error$1) {
282
+ throw new error.MastraError(
283
+ {
284
+ id: "STORAGE_QDRANT_VECTOR_UPSERT_FAILED",
285
+ domain: error.ErrorDomain.STORAGE,
286
+ category: error.ErrorCategory.THIRD_PARTY,
287
+ details: { indexName, vectorCount: vectors.length }
288
+ },
289
+ error$1
290
+ );
277
291
  }
278
- return pointIds;
279
292
  }
280
293
  async createIndex({ indexName, dimension, metric = "cosine" }) {
281
- if (!Number.isInteger(dimension) || dimension <= 0) {
282
- throw new Error("Dimension must be a positive integer");
283
- }
284
- if (!DISTANCE_MAPPING[metric]) {
285
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
294
+ try {
295
+ if (!Number.isInteger(dimension) || dimension <= 0) {
296
+ throw new Error("Dimension must be a positive integer");
297
+ }
298
+ if (!DISTANCE_MAPPING[metric]) {
299
+ throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
300
+ }
301
+ } catch (validationError) {
302
+ throw new error.MastraError(
303
+ {
304
+ id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_INVALID_ARGS",
305
+ domain: error.ErrorDomain.STORAGE,
306
+ category: error.ErrorCategory.USER,
307
+ details: { indexName, dimension, metric }
308
+ },
309
+ validationError
310
+ );
286
311
  }
287
312
  try {
288
313
  await this.client.createCollection(indexName, {
@@ -291,12 +316,21 @@ var QdrantVector = class extends vector.MastraVector {
291
316
  distance: DISTANCE_MAPPING[metric]
292
317
  }
293
318
  });
294
- } catch (error) {
295
- const message = error?.message || error?.toString();
296
- if (error?.status === 409 || typeof message === "string" && message.toLowerCase().includes("exists")) {
319
+ } catch (error$1) {
320
+ const message = error$1?.message || error$1?.toString();
321
+ if (error$1?.status === 409 || typeof message === "string" && message.toLowerCase().includes("exists")) {
297
322
  await this.validateExistingIndex(indexName, dimension, metric);
298
323
  return;
299
324
  }
325
+ throw new error.MastraError(
326
+ {
327
+ id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_FAILED",
328
+ domain: error.ErrorDomain.STORAGE,
329
+ category: error.ErrorCategory.THIRD_PARTY,
330
+ details: { indexName, dimension, metric }
331
+ },
332
+ error$1
333
+ );
300
334
  }
301
335
  }
302
336
  transformFilter(filter) {
@@ -311,33 +345,56 @@ var QdrantVector = class extends vector.MastraVector {
311
345
  includeVector = false
312
346
  }) {
313
347
  const translatedFilter = this.transformFilter(filter) ?? {};
314
- const results = (await this.client.query(indexName, {
315
- query: queryVector,
316
- limit: topK,
317
- filter: translatedFilter,
318
- with_payload: true,
319
- with_vector: includeVector
320
- })).points;
321
- return results.map((match) => {
322
- let vector = [];
323
- if (includeVector) {
324
- if (Array.isArray(match.vector)) {
325
- vector = match.vector;
326
- } else if (typeof match.vector === "object" && match.vector !== null) {
327
- vector = Object.values(match.vector).filter((v) => typeof v === "number");
348
+ try {
349
+ const results = (await this.client.query(indexName, {
350
+ query: queryVector,
351
+ limit: topK,
352
+ filter: translatedFilter,
353
+ with_payload: true,
354
+ with_vector: includeVector
355
+ })).points;
356
+ return results.map((match) => {
357
+ let vector = [];
358
+ if (includeVector) {
359
+ if (Array.isArray(match.vector)) {
360
+ vector = match.vector;
361
+ } else if (typeof match.vector === "object" && match.vector !== null) {
362
+ vector = Object.values(match.vector).filter((v) => typeof v === "number");
363
+ }
328
364
  }
329
- }
330
- return {
331
- id: match.id,
332
- score: match.score || 0,
333
- metadata: match.payload,
334
- ...includeVector && { vector }
335
- };
336
- });
365
+ return {
366
+ id: match.id,
367
+ score: match.score || 0,
368
+ metadata: match.payload,
369
+ ...includeVector && { vector }
370
+ };
371
+ });
372
+ } catch (error$1) {
373
+ throw new error.MastraError(
374
+ {
375
+ id: "STORAGE_QDRANT_VECTOR_QUERY_FAILED",
376
+ domain: error.ErrorDomain.STORAGE,
377
+ category: error.ErrorCategory.THIRD_PARTY,
378
+ details: { indexName, topK }
379
+ },
380
+ error$1
381
+ );
382
+ }
337
383
  }
338
384
  async listIndexes() {
339
- const response = await this.client.getCollections();
340
- return response.collections.map((collection) => collection.name) || [];
385
+ try {
386
+ const response = await this.client.getCollections();
387
+ return response.collections.map((collection) => collection.name) || [];
388
+ } catch (error$1) {
389
+ throw new error.MastraError(
390
+ {
391
+ id: "STORAGE_QDRANT_VECTOR_LIST_INDEXES_FAILED",
392
+ domain: error.ErrorDomain.STORAGE,
393
+ category: error.ErrorCategory.THIRD_PARTY
394
+ },
395
+ error$1
396
+ );
397
+ }
341
398
  }
342
399
  /**
343
400
  * Retrieves statistics about a vector index.
@@ -346,17 +403,41 @@ var QdrantVector = class extends vector.MastraVector {
346
403
  * @returns A promise that resolves to the index statistics including dimension, count and metric
347
404
  */
348
405
  async describeIndex({ indexName }) {
349
- const { config, points_count } = await this.client.getCollection(indexName);
350
- const distance = config.params.vectors?.distance;
351
- return {
352
- dimension: config.params.vectors?.size,
353
- count: points_count || 0,
354
- // @ts-expect-error
355
- metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === distance)
356
- };
406
+ try {
407
+ const { config, points_count } = await this.client.getCollection(indexName);
408
+ const distance = config.params.vectors?.distance;
409
+ return {
410
+ dimension: config.params.vectors?.size,
411
+ count: points_count || 0,
412
+ // @ts-expect-error
413
+ metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === distance)
414
+ };
415
+ } catch (error$1) {
416
+ throw new error.MastraError(
417
+ {
418
+ id: "STORAGE_QDRANT_VECTOR_DESCRIBE_INDEX_FAILED",
419
+ domain: error.ErrorDomain.STORAGE,
420
+ category: error.ErrorCategory.THIRD_PARTY,
421
+ details: { indexName }
422
+ },
423
+ error$1
424
+ );
425
+ }
357
426
  }
358
427
  async deleteIndex({ indexName }) {
359
- await this.client.deleteCollection(indexName);
428
+ try {
429
+ await this.client.deleteCollection(indexName);
430
+ } catch (error$1) {
431
+ throw new error.MastraError(
432
+ {
433
+ id: "STORAGE_QDRANT_VECTOR_DELETE_INDEX_FAILED",
434
+ domain: error.ErrorDomain.STORAGE,
435
+ category: error.ErrorCategory.THIRD_PARTY,
436
+ details: { indexName }
437
+ },
438
+ error$1
439
+ );
440
+ }
360
441
  }
361
442
  /**
362
443
  * Updates a vector by its ID with the provided vector and/or metadata.
@@ -369,8 +450,20 @@ var QdrantVector = class extends vector.MastraVector {
369
450
  * @throws Will throw an error if no updates are provided or if the update operation fails.
370
451
  */
371
452
  async updateVector({ indexName, id, update }) {
372
- if (!update.vector && !update.metadata) {
373
- throw new Error("No updates provided");
453
+ try {
454
+ if (!update.vector && !update.metadata) {
455
+ throw new Error("No updates provided");
456
+ }
457
+ } catch (validationError) {
458
+ throw new error.MastraError(
459
+ {
460
+ id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
461
+ domain: error.ErrorDomain.STORAGE,
462
+ category: error.ErrorCategory.USER,
463
+ details: { indexName, id }
464
+ },
465
+ validationError
466
+ );
374
467
  }
375
468
  const pointId = this.parsePointId(id);
376
469
  try {
@@ -400,9 +493,16 @@ var QdrantVector = class extends vector.MastraVector {
400
493
  });
401
494
  return;
402
495
  }
403
- } catch (error) {
404
- console.error(`Failed to update vector by id: ${id} for index name: ${indexName}:`, error);
405
- throw error;
496
+ } catch (error$1) {
497
+ throw new error.MastraError(
498
+ {
499
+ id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_FAILED",
500
+ domain: error.ErrorDomain.STORAGE,
501
+ category: error.ErrorCategory.THIRD_PARTY,
502
+ details: { indexName, id }
503
+ },
504
+ error$1
505
+ );
406
506
  }
407
507
  }
408
508
  /**
@@ -418,8 +518,16 @@ var QdrantVector = class extends vector.MastraVector {
418
518
  await this.client.delete(indexName, {
419
519
  points: [pointId]
420
520
  });
421
- } catch (error) {
422
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
521
+ } catch (error$1) {
522
+ throw new error.MastraError(
523
+ {
524
+ id: "STORAGE_QDRANT_VECTOR_DELETE_VECTOR_FAILED",
525
+ domain: error.ErrorDomain.STORAGE,
526
+ category: error.ErrorCategory.THIRD_PARTY,
527
+ details: { indexName, id }
528
+ },
529
+ error$1
530
+ );
423
531
  }
424
532
  }
425
533
  /**
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import { QdrantClient } from '@qdrant/js-client-rest';
3
4
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -265,22 +266,46 @@ var QdrantVector = class extends MastraVector {
265
266
  vector,
266
267
  payload: metadata?.[i] || {}
267
268
  }));
268
- for (let i = 0; i < records.length; i += BATCH_SIZE) {
269
- const batch = records.slice(i, i + BATCH_SIZE);
270
- await this.client.upsert(indexName, {
271
- // @ts-expect-error
272
- points: batch,
273
- wait: true
274
- });
269
+ try {
270
+ for (let i = 0; i < records.length; i += BATCH_SIZE) {
271
+ const batch = records.slice(i, i + BATCH_SIZE);
272
+ await this.client.upsert(indexName, {
273
+ // @ts-expect-error
274
+ points: batch,
275
+ wait: true
276
+ });
277
+ }
278
+ return pointIds;
279
+ } catch (error) {
280
+ throw new MastraError(
281
+ {
282
+ id: "STORAGE_QDRANT_VECTOR_UPSERT_FAILED",
283
+ domain: ErrorDomain.STORAGE,
284
+ category: ErrorCategory.THIRD_PARTY,
285
+ details: { indexName, vectorCount: vectors.length }
286
+ },
287
+ error
288
+ );
275
289
  }
276
- return pointIds;
277
290
  }
278
291
  async createIndex({ indexName, dimension, metric = "cosine" }) {
279
- if (!Number.isInteger(dimension) || dimension <= 0) {
280
- throw new Error("Dimension must be a positive integer");
281
- }
282
- if (!DISTANCE_MAPPING[metric]) {
283
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
292
+ try {
293
+ if (!Number.isInteger(dimension) || dimension <= 0) {
294
+ throw new Error("Dimension must be a positive integer");
295
+ }
296
+ if (!DISTANCE_MAPPING[metric]) {
297
+ throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
298
+ }
299
+ } catch (validationError) {
300
+ throw new MastraError(
301
+ {
302
+ id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_INVALID_ARGS",
303
+ domain: ErrorDomain.STORAGE,
304
+ category: ErrorCategory.USER,
305
+ details: { indexName, dimension, metric }
306
+ },
307
+ validationError
308
+ );
284
309
  }
285
310
  try {
286
311
  await this.client.createCollection(indexName, {
@@ -295,6 +320,15 @@ var QdrantVector = class extends MastraVector {
295
320
  await this.validateExistingIndex(indexName, dimension, metric);
296
321
  return;
297
322
  }
323
+ throw new MastraError(
324
+ {
325
+ id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_FAILED",
326
+ domain: ErrorDomain.STORAGE,
327
+ category: ErrorCategory.THIRD_PARTY,
328
+ details: { indexName, dimension, metric }
329
+ },
330
+ error
331
+ );
298
332
  }
299
333
  }
300
334
  transformFilter(filter) {
@@ -309,33 +343,56 @@ var QdrantVector = class extends MastraVector {
309
343
  includeVector = false
310
344
  }) {
311
345
  const translatedFilter = this.transformFilter(filter) ?? {};
312
- const results = (await this.client.query(indexName, {
313
- query: queryVector,
314
- limit: topK,
315
- filter: translatedFilter,
316
- with_payload: true,
317
- with_vector: includeVector
318
- })).points;
319
- return results.map((match) => {
320
- let vector = [];
321
- if (includeVector) {
322
- if (Array.isArray(match.vector)) {
323
- vector = match.vector;
324
- } else if (typeof match.vector === "object" && match.vector !== null) {
325
- vector = Object.values(match.vector).filter((v) => typeof v === "number");
346
+ try {
347
+ const results = (await this.client.query(indexName, {
348
+ query: queryVector,
349
+ limit: topK,
350
+ filter: translatedFilter,
351
+ with_payload: true,
352
+ with_vector: includeVector
353
+ })).points;
354
+ return results.map((match) => {
355
+ let vector = [];
356
+ if (includeVector) {
357
+ if (Array.isArray(match.vector)) {
358
+ vector = match.vector;
359
+ } else if (typeof match.vector === "object" && match.vector !== null) {
360
+ vector = Object.values(match.vector).filter((v) => typeof v === "number");
361
+ }
326
362
  }
327
- }
328
- return {
329
- id: match.id,
330
- score: match.score || 0,
331
- metadata: match.payload,
332
- ...includeVector && { vector }
333
- };
334
- });
363
+ return {
364
+ id: match.id,
365
+ score: match.score || 0,
366
+ metadata: match.payload,
367
+ ...includeVector && { vector }
368
+ };
369
+ });
370
+ } catch (error) {
371
+ throw new MastraError(
372
+ {
373
+ id: "STORAGE_QDRANT_VECTOR_QUERY_FAILED",
374
+ domain: ErrorDomain.STORAGE,
375
+ category: ErrorCategory.THIRD_PARTY,
376
+ details: { indexName, topK }
377
+ },
378
+ error
379
+ );
380
+ }
335
381
  }
336
382
  async listIndexes() {
337
- const response = await this.client.getCollections();
338
- return response.collections.map((collection) => collection.name) || [];
383
+ try {
384
+ const response = await this.client.getCollections();
385
+ return response.collections.map((collection) => collection.name) || [];
386
+ } catch (error) {
387
+ throw new MastraError(
388
+ {
389
+ id: "STORAGE_QDRANT_VECTOR_LIST_INDEXES_FAILED",
390
+ domain: ErrorDomain.STORAGE,
391
+ category: ErrorCategory.THIRD_PARTY
392
+ },
393
+ error
394
+ );
395
+ }
339
396
  }
340
397
  /**
341
398
  * Retrieves statistics about a vector index.
@@ -344,17 +401,41 @@ var QdrantVector = class extends MastraVector {
344
401
  * @returns A promise that resolves to the index statistics including dimension, count and metric
345
402
  */
346
403
  async describeIndex({ indexName }) {
347
- const { config, points_count } = await this.client.getCollection(indexName);
348
- const distance = config.params.vectors?.distance;
349
- return {
350
- dimension: config.params.vectors?.size,
351
- count: points_count || 0,
352
- // @ts-expect-error
353
- metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === distance)
354
- };
404
+ try {
405
+ const { config, points_count } = await this.client.getCollection(indexName);
406
+ const distance = config.params.vectors?.distance;
407
+ return {
408
+ dimension: config.params.vectors?.size,
409
+ count: points_count || 0,
410
+ // @ts-expect-error
411
+ metric: Object.keys(DISTANCE_MAPPING).find((key) => DISTANCE_MAPPING[key] === distance)
412
+ };
413
+ } catch (error) {
414
+ throw new MastraError(
415
+ {
416
+ id: "STORAGE_QDRANT_VECTOR_DESCRIBE_INDEX_FAILED",
417
+ domain: ErrorDomain.STORAGE,
418
+ category: ErrorCategory.THIRD_PARTY,
419
+ details: { indexName }
420
+ },
421
+ error
422
+ );
423
+ }
355
424
  }
356
425
  async deleteIndex({ indexName }) {
357
- await this.client.deleteCollection(indexName);
426
+ try {
427
+ await this.client.deleteCollection(indexName);
428
+ } catch (error) {
429
+ throw new MastraError(
430
+ {
431
+ id: "STORAGE_QDRANT_VECTOR_DELETE_INDEX_FAILED",
432
+ domain: ErrorDomain.STORAGE,
433
+ category: ErrorCategory.THIRD_PARTY,
434
+ details: { indexName }
435
+ },
436
+ error
437
+ );
438
+ }
358
439
  }
359
440
  /**
360
441
  * Updates a vector by its ID with the provided vector and/or metadata.
@@ -367,8 +448,20 @@ var QdrantVector = class extends MastraVector {
367
448
  * @throws Will throw an error if no updates are provided or if the update operation fails.
368
449
  */
369
450
  async updateVector({ indexName, id, update }) {
370
- if (!update.vector && !update.metadata) {
371
- throw new Error("No updates provided");
451
+ try {
452
+ if (!update.vector && !update.metadata) {
453
+ throw new Error("No updates provided");
454
+ }
455
+ } catch (validationError) {
456
+ throw new MastraError(
457
+ {
458
+ id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
459
+ domain: ErrorDomain.STORAGE,
460
+ category: ErrorCategory.USER,
461
+ details: { indexName, id }
462
+ },
463
+ validationError
464
+ );
372
465
  }
373
466
  const pointId = this.parsePointId(id);
374
467
  try {
@@ -399,8 +492,15 @@ var QdrantVector = class extends MastraVector {
399
492
  return;
400
493
  }
401
494
  } catch (error) {
402
- console.error(`Failed to update vector by id: ${id} for index name: ${indexName}:`, error);
403
- throw error;
495
+ throw new MastraError(
496
+ {
497
+ id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_FAILED",
498
+ domain: ErrorDomain.STORAGE,
499
+ category: ErrorCategory.THIRD_PARTY,
500
+ details: { indexName, id }
501
+ },
502
+ error
503
+ );
404
504
  }
405
505
  }
406
506
  /**
@@ -417,7 +517,15 @@ var QdrantVector = class extends MastraVector {
417
517
  points: [pointId]
418
518
  });
419
519
  } catch (error) {
420
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
520
+ throw new MastraError(
521
+ {
522
+ id: "STORAGE_QDRANT_VECTOR_DELETE_VECTOR_FAILED",
523
+ domain: ErrorDomain.STORAGE,
524
+ category: ErrorCategory.THIRD_PARTY,
525
+ details: { indexName, id }
526
+ },
527
+ error
528
+ );
421
529
  }
422
530
  }
423
531
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/qdrant",
3
- "version": "0.10.3",
3
+ "version": "0.10.4-alpha.0",
4
4
  "description": "Qdrant vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "typescript": "^5.8.3",
31
31
  "vitest": "^3.2.3",
32
32
  "@internal/lint": "0.0.13",
33
- "@mastra/core": "0.10.6"
33
+ "@mastra/core": "0.10.7-alpha.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@mastra/core": ">=0.10.4-0 <0.11.0"
@@ -1,3 +1,4 @@
1
+ import { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
1
2
  import { MastraVector } from '@mastra/core/vector';
2
3
  import type {
3
4
  QueryResult,
@@ -58,25 +59,50 @@ export class QdrantVector extends MastraVector {
58
59
  payload: metadata?.[i] || {},
59
60
  }));
60
61
 
61
- for (let i = 0; i < records.length; i += BATCH_SIZE) {
62
- const batch = records.slice(i, i + BATCH_SIZE);
63
- await this.client.upsert(indexName, {
64
- // @ts-expect-error
65
- points: batch,
66
- wait: true,
67
- });
68
- }
62
+ try {
63
+ for (let i = 0; i < records.length; i += BATCH_SIZE) {
64
+ const batch = records.slice(i, i + BATCH_SIZE);
65
+ await this.client.upsert(indexName, {
66
+ // @ts-expect-error
67
+ points: batch,
68
+ wait: true,
69
+ });
70
+ }
69
71
 
70
- return pointIds;
72
+ return pointIds;
73
+ } catch (error) {
74
+ throw new MastraError(
75
+ {
76
+ id: 'STORAGE_QDRANT_VECTOR_UPSERT_FAILED',
77
+ domain: ErrorDomain.STORAGE,
78
+ category: ErrorCategory.THIRD_PARTY,
79
+ details: { indexName, vectorCount: vectors.length },
80
+ },
81
+ error,
82
+ );
83
+ }
71
84
  }
72
85
 
73
86
  async createIndex({ indexName, dimension, metric = 'cosine' }: CreateIndexParams): Promise<void> {
74
- if (!Number.isInteger(dimension) || dimension <= 0) {
75
- throw new Error('Dimension must be a positive integer');
76
- }
77
- if (!DISTANCE_MAPPING[metric]) {
78
- throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
87
+ try {
88
+ if (!Number.isInteger(dimension) || dimension <= 0) {
89
+ throw new Error('Dimension must be a positive integer');
90
+ }
91
+ if (!DISTANCE_MAPPING[metric]) {
92
+ throw new Error(`Invalid metric: "${metric}". Must be one of: cosine, euclidean, dotproduct`);
93
+ }
94
+ } catch (validationError) {
95
+ throw new MastraError(
96
+ {
97
+ id: 'STORAGE_QDRANT_VECTOR_CREATE_INDEX_INVALID_ARGS',
98
+ domain: ErrorDomain.STORAGE,
99
+ category: ErrorCategory.USER,
100
+ details: { indexName, dimension, metric },
101
+ },
102
+ validationError,
103
+ );
79
104
  }
105
+
80
106
  try {
81
107
  await this.client.createCollection(indexName, {
82
108
  vectors: {
@@ -92,6 +118,16 @@ export class QdrantVector extends MastraVector {
92
118
  await this.validateExistingIndex(indexName, dimension, metric);
93
119
  return;
94
120
  }
121
+
122
+ throw new MastraError(
123
+ {
124
+ id: 'STORAGE_QDRANT_VECTOR_CREATE_INDEX_FAILED',
125
+ domain: ErrorDomain.STORAGE,
126
+ category: ErrorCategory.THIRD_PARTY,
127
+ details: { indexName, dimension, metric },
128
+ },
129
+ error,
130
+ );
95
131
  }
96
132
  }
97
133
 
@@ -109,40 +145,63 @@ export class QdrantVector extends MastraVector {
109
145
  }: QueryVectorParams): Promise<QueryResult[]> {
110
146
  const translatedFilter = this.transformFilter(filter) ?? {};
111
147
 
112
- const results = (
113
- await this.client.query(indexName, {
114
- query: queryVector,
115
- limit: topK,
116
- filter: translatedFilter,
117
- with_payload: true,
118
- with_vector: includeVector,
119
- })
120
- ).points;
148
+ try {
149
+ const results = (
150
+ await this.client.query(indexName, {
151
+ query: queryVector,
152
+ limit: topK,
153
+ filter: translatedFilter,
154
+ with_payload: true,
155
+ with_vector: includeVector,
156
+ })
157
+ ).points;
121
158
 
122
- return results.map(match => {
123
- let vector: number[] = [];
124
- if (includeVector) {
125
- if (Array.isArray(match.vector)) {
126
- // If it's already an array of numbers
127
- vector = match.vector as number[];
128
- } else if (typeof match.vector === 'object' && match.vector !== null) {
129
- // If it's an object with vector data
130
- vector = Object.values(match.vector).filter(v => typeof v === 'number');
159
+ return results.map(match => {
160
+ let vector: number[] = [];
161
+ if (includeVector) {
162
+ if (Array.isArray(match.vector)) {
163
+ // If it's already an array of numbers
164
+ vector = match.vector as number[];
165
+ } else if (typeof match.vector === 'object' && match.vector !== null) {
166
+ // If it's an object with vector data
167
+ vector = Object.values(match.vector).filter(v => typeof v === 'number');
168
+ }
131
169
  }
132
- }
133
170
 
134
- return {
135
- id: match.id as string,
136
- score: match.score || 0,
137
- metadata: match.payload as Record<string, any>,
138
- ...(includeVector && { vector }),
139
- };
140
- });
171
+ return {
172
+ id: match.id as string,
173
+ score: match.score || 0,
174
+ metadata: match.payload as Record<string, any>,
175
+ ...(includeVector && { vector }),
176
+ };
177
+ });
178
+ } catch (error) {
179
+ throw new MastraError(
180
+ {
181
+ id: 'STORAGE_QDRANT_VECTOR_QUERY_FAILED',
182
+ domain: ErrorDomain.STORAGE,
183
+ category: ErrorCategory.THIRD_PARTY,
184
+ details: { indexName, topK },
185
+ },
186
+ error,
187
+ );
188
+ }
141
189
  }
142
190
 
143
191
  async listIndexes(): Promise<string[]> {
144
- const response = await this.client.getCollections();
145
- return response.collections.map(collection => collection.name) || [];
192
+ try {
193
+ const response = await this.client.getCollections();
194
+ return response.collections.map(collection => collection.name) || [];
195
+ } catch (error) {
196
+ throw new MastraError(
197
+ {
198
+ id: 'STORAGE_QDRANT_VECTOR_LIST_INDEXES_FAILED',
199
+ domain: ErrorDomain.STORAGE,
200
+ category: ErrorCategory.THIRD_PARTY,
201
+ },
202
+ error,
203
+ );
204
+ }
146
205
  }
147
206
 
148
207
  /**
@@ -152,19 +211,43 @@ export class QdrantVector extends MastraVector {
152
211
  * @returns A promise that resolves to the index statistics including dimension, count and metric
153
212
  */
154
213
  async describeIndex({ indexName }: DescribeIndexParams): Promise<IndexStats> {
155
- const { config, points_count } = await this.client.getCollection(indexName);
214
+ try {
215
+ const { config, points_count } = await this.client.getCollection(indexName);
156
216
 
157
- const distance = config.params.vectors?.distance as Schemas['Distance'];
158
- return {
159
- dimension: config.params.vectors?.size as number,
160
- count: points_count || 0,
161
- // @ts-expect-error
162
- metric: Object.keys(DISTANCE_MAPPING).find(key => DISTANCE_MAPPING[key] === distance),
163
- };
217
+ const distance = config.params.vectors?.distance as Schemas['Distance'];
218
+ return {
219
+ dimension: config.params.vectors?.size as number,
220
+ count: points_count || 0,
221
+ // @ts-expect-error
222
+ metric: Object.keys(DISTANCE_MAPPING).find(key => DISTANCE_MAPPING[key] === distance),
223
+ };
224
+ } catch (error) {
225
+ throw new MastraError(
226
+ {
227
+ id: 'STORAGE_QDRANT_VECTOR_DESCRIBE_INDEX_FAILED',
228
+ domain: ErrorDomain.STORAGE,
229
+ category: ErrorCategory.THIRD_PARTY,
230
+ details: { indexName },
231
+ },
232
+ error,
233
+ );
234
+ }
164
235
  }
165
236
 
166
237
  async deleteIndex({ indexName }: DeleteIndexParams): Promise<void> {
167
- await this.client.deleteCollection(indexName);
238
+ try {
239
+ await this.client.deleteCollection(indexName);
240
+ } catch (error) {
241
+ throw new MastraError(
242
+ {
243
+ id: 'STORAGE_QDRANT_VECTOR_DELETE_INDEX_FAILED',
244
+ domain: ErrorDomain.STORAGE,
245
+ category: ErrorCategory.THIRD_PARTY,
246
+ details: { indexName },
247
+ },
248
+ error,
249
+ );
250
+ }
168
251
  }
169
252
 
170
253
  /**
@@ -178,8 +261,20 @@ export class QdrantVector extends MastraVector {
178
261
  * @throws Will throw an error if no updates are provided or if the update operation fails.
179
262
  */
180
263
  async updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void> {
181
- if (!update.vector && !update.metadata) {
182
- throw new Error('No updates provided');
264
+ try {
265
+ if (!update.vector && !update.metadata) {
266
+ throw new Error('No updates provided');
267
+ }
268
+ } catch (validationError) {
269
+ throw new MastraError(
270
+ {
271
+ id: 'STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_INVALID_ARGS',
272
+ domain: ErrorDomain.STORAGE,
273
+ category: ErrorCategory.USER,
274
+ details: { indexName, id },
275
+ },
276
+ validationError,
277
+ );
183
278
  }
184
279
 
185
280
  const pointId = this.parsePointId(id);
@@ -219,8 +314,15 @@ export class QdrantVector extends MastraVector {
219
314
  return;
220
315
  }
221
316
  } catch (error) {
222
- console.error(`Failed to update vector by id: ${id} for index name: ${indexName}:`, error);
223
- throw error;
317
+ throw new MastraError(
318
+ {
319
+ id: 'STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_FAILED',
320
+ domain: ErrorDomain.STORAGE,
321
+ category: ErrorCategory.THIRD_PARTY,
322
+ details: { indexName, id },
323
+ },
324
+ error,
325
+ );
224
326
  }
225
327
  }
226
328
 
@@ -240,8 +342,16 @@ export class QdrantVector extends MastraVector {
240
342
  await this.client.delete(indexName, {
241
343
  points: [pointId],
242
344
  });
243
- } catch (error: any) {
244
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
345
+ } catch (error) {
346
+ throw new MastraError(
347
+ {
348
+ id: 'STORAGE_QDRANT_VECTOR_DELETE_VECTOR_FAILED',
349
+ domain: ErrorDomain.STORAGE,
350
+ category: ErrorCategory.THIRD_PARTY,
351
+ details: { indexName, id },
352
+ },
353
+ error,
354
+ );
245
355
  }
246
356
  }
247
357