@mastra/qdrant 1.0.0-beta.0 → 1.0.0-beta.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/qdrant
2
2
 
3
+ ## 1.0.0-beta.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Standardize error IDs across all storage and vector stores using centralized helper functions (`createStorageErrorId` and `createVectorErrorId`). This ensures consistent error ID patterns (`MASTRA_STORAGE_{STORE}_{OPERATION}_{STATUS}` and `MASTRA_VECTOR_{STORE}_{OPERATION}_{STATUS}`) across the codebase for better error tracking and debugging. ([#10913](https://github.com/mastra-ai/mastra/pull/10913))
8
+
9
+ - Updated dependencies [[`3076c67`](https://github.com/mastra-ai/mastra/commit/3076c6778b18988ae7d5c4c5c466366974b2d63f), [`85d7ee1`](https://github.com/mastra-ai/mastra/commit/85d7ee18ff4e14d625a8a30ec6656bb49804989b), [`c6c1092`](https://github.com/mastra-ai/mastra/commit/c6c1092f8fbf76109303f69e000e96fd1960c4ce), [`81dc110`](https://github.com/mastra-ai/mastra/commit/81dc11008d147cf5bdc8996ead1aa61dbdebb6fc), [`7aedb74`](https://github.com/mastra-ai/mastra/commit/7aedb74883adf66af38e270e4068fd42e7a37036), [`8f02d80`](https://github.com/mastra-ai/mastra/commit/8f02d800777397e4b45d7f1ad041988a8b0c6630), [`d7aad50`](https://github.com/mastra-ai/mastra/commit/d7aad501ce61646b76b4b511e558ac4eea9884d0), [`ce0a73a`](https://github.com/mastra-ai/mastra/commit/ce0a73abeaa75b10ca38f9e40a255a645d50ebfb), [`a02e542`](https://github.com/mastra-ai/mastra/commit/a02e542d23179bad250b044b17ff023caa61739f), [`a372c64`](https://github.com/mastra-ai/mastra/commit/a372c640ad1fd12e8f0613cebdc682fc156b4d95), [`8846867`](https://github.com/mastra-ai/mastra/commit/8846867ffa9a3746767618e314bebac08eb77d87), [`42a42cf`](https://github.com/mastra-ai/mastra/commit/42a42cf3132b9786feecbb8c13c583dce5b0e198), [`ae08bf0`](https://github.com/mastra-ai/mastra/commit/ae08bf0ebc6a4e4da992b711c4a389c32ba84cf4), [`21735a7`](https://github.com/mastra-ai/mastra/commit/21735a7ef306963554a69a89b44f06c3bcd85141), [`1d877b8`](https://github.com/mastra-ai/mastra/commit/1d877b8d7b536a251c1a7a18db7ddcf4f68d6f8b)]:
10
+ - @mastra/core@1.0.0-beta.7
11
+
12
+ ## 1.0.0-beta.1
13
+
14
+ ### Patch Changes
15
+
16
+ - Add new deleteVectors, updateVector by filter ([#10408](https://github.com/mastra-ai/mastra/pull/10408))
17
+
18
+ - Updated dependencies [[`21a15de`](https://github.com/mastra-ai/mastra/commit/21a15de369fe82aac26bb642ed7be73505475e8b), [`feb7ee4`](https://github.com/mastra-ai/mastra/commit/feb7ee4d09a75edb46c6669a3beaceec78811747), [`b0e2ea5`](https://github.com/mastra-ai/mastra/commit/b0e2ea5b52c40fae438b9e2f7baee6f0f89c5442), [`c456e01`](https://github.com/mastra-ai/mastra/commit/c456e0149e3c176afcefdbd9bb1d2c5917723725), [`ab035c2`](https://github.com/mastra-ai/mastra/commit/ab035c2ef6d8cc7bb25f06f1a38508bd9e6f126b), [`1a46a56`](https://github.com/mastra-ai/mastra/commit/1a46a566f45a3fcbadc1cf36bf86d351f264bfa3), [`3cf540b`](https://github.com/mastra-ai/mastra/commit/3cf540b9fbfea8f4fc8d3a2319a4e6c0b0cbfd52), [`1c6ce51`](https://github.com/mastra-ai/mastra/commit/1c6ce51f875915ab57fd36873623013699a2a65d), [`898a972`](https://github.com/mastra-ai/mastra/commit/898a9727d286c2510d6b702dfd367e6aaf5c6b0f), [`a97003a`](https://github.com/mastra-ai/mastra/commit/a97003aa1cf2f4022a41912324a1e77263b326b8), [`ccc141e`](https://github.com/mastra-ai/mastra/commit/ccc141ed27da0abc3a3fc28e9e5128152e8e37f4), [`fe3b897`](https://github.com/mastra-ai/mastra/commit/fe3b897c2ccbcd2b10e81b099438c7337feddf89), [`00123ba`](https://github.com/mastra-ai/mastra/commit/00123ba96dc9e5cd0b110420ebdba56d8f237b25), [`29c4309`](https://github.com/mastra-ai/mastra/commit/29c4309f818b24304c041bcb4a8f19b5f13f6b62), [`16785ce`](https://github.com/mastra-ai/mastra/commit/16785ced928f6f22638f4488cf8a125d99211799), [`de8239b`](https://github.com/mastra-ai/mastra/commit/de8239bdcb1d8c0cfa06da21f1569912a66bbc8a), [`b5e6cd7`](https://github.com/mastra-ai/mastra/commit/b5e6cd77fc8c8e64e0494c1d06cee3d84e795d1e), [`3759cb0`](https://github.com/mastra-ai/mastra/commit/3759cb064935b5f74c65ac2f52a1145f7352899d), [`651e772`](https://github.com/mastra-ai/mastra/commit/651e772eb1475fb13e126d3fcc01751297a88214), [`b61b93f`](https://github.com/mastra-ai/mastra/commit/b61b93f9e058b11dd2eec169853175d31dbdd567), [`bae33d9`](https://github.com/mastra-ai/mastra/commit/bae33d91a63fbb64d1e80519e1fc1acaed1e9013), [`c0b731f`](https://github.com/mastra-ai/mastra/commit/c0b731fb27d712dc8582e846df5c0332a6a0c5ba), [`43ca8f2`](https://github.com/mastra-ai/mastra/commit/43ca8f2c7334851cc7b4d3d2f037d8784bfbdd5f), [`2ca67cc`](https://github.com/mastra-ai/mastra/commit/2ca67cc3bb1f6a617353fdcab197d9efebe60d6f), [`9e67002`](https://github.com/mastra-ai/mastra/commit/9e67002b52c9be19936c420a489dbee9c5fd6a78), [`35edc49`](https://github.com/mastra-ai/mastra/commit/35edc49ac0556db609189641d6341e76771b81fc)]:
19
+ - @mastra/core@1.0.0-beta.5
20
+
3
21
  ## 1.0.0-beta.0
4
22
 
5
23
  ### Major Changes
package/README.md CHANGED
@@ -72,6 +72,9 @@ The following distance metrics are supported:
72
72
  - `createIndex({ indexName, dimension, metric? })`: Create a new collection
73
73
  - `upsert({ indexName, vectors, metadata?, ids? })`: Add or update vectors
74
74
  - `query({ indexName, queryVector, topK?, filter?, includeVector? })`: Search for similar vectors
75
+ - `updateVector({ indexName, id?, filter?, update })`: Update a single vector by ID or metadata filter
76
+ - `deleteVector({ indexName, id })`: Delete a single vector by ID
77
+ - `deleteVectors({ indexName, ids?, filter? })`: Delete multiple vectors by IDs or metadata filter
75
78
  - `listIndexes()`: List all collections
76
79
  - `describeIndex(indexName)`: Get collection statistics
77
80
  - `deleteIndex(indexName)`: Delete a collection
package/dist/index.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var error = require('@mastra/core/error');
4
+ var storage = require('@mastra/core/storage');
4
5
  var vector = require('@mastra/core/vector');
5
6
  var jsClientRest = require('@qdrant/js-client-rest');
6
7
  var filter = require('@mastra/core/vector/filter');
@@ -271,7 +272,7 @@ var QdrantVector = class extends vector.MastraVector {
271
272
  } catch (error$1) {
272
273
  throw new error.MastraError(
273
274
  {
274
- id: "STORAGE_QDRANT_VECTOR_UPSERT_FAILED",
275
+ id: storage.createVectorErrorId("QDRANT", "UPSERT", "FAILED"),
275
276
  domain: error.ErrorDomain.STORAGE,
276
277
  category: error.ErrorCategory.THIRD_PARTY,
277
278
  details: { indexName, vectorCount: vectors.length }
@@ -291,7 +292,7 @@ var QdrantVector = class extends vector.MastraVector {
291
292
  } catch (validationError) {
292
293
  throw new error.MastraError(
293
294
  {
294
- id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_INVALID_ARGS",
295
+ id: storage.createVectorErrorId("QDRANT", "CREATE_INDEX", "INVALID_ARGS"),
295
296
  domain: error.ErrorDomain.STORAGE,
296
297
  category: error.ErrorCategory.USER,
297
298
  details: { indexName, dimension, metric }
@@ -314,7 +315,7 @@ var QdrantVector = class extends vector.MastraVector {
314
315
  }
315
316
  throw new error.MastraError(
316
317
  {
317
- id: "STORAGE_QDRANT_VECTOR_CREATE_INDEX_FAILED",
318
+ id: storage.createVectorErrorId("QDRANT", "CREATE_INDEX", "FAILED"),
318
319
  domain: error.ErrorDomain.STORAGE,
319
320
  category: error.ErrorCategory.THIRD_PARTY,
320
321
  details: { indexName, dimension, metric }
@@ -362,7 +363,7 @@ var QdrantVector = class extends vector.MastraVector {
362
363
  } catch (error$1) {
363
364
  throw new error.MastraError(
364
365
  {
365
- id: "STORAGE_QDRANT_VECTOR_QUERY_FAILED",
366
+ id: storage.createVectorErrorId("QDRANT", "QUERY", "FAILED"),
366
367
  domain: error.ErrorDomain.STORAGE,
367
368
  category: error.ErrorCategory.THIRD_PARTY,
368
369
  details: { indexName, topK }
@@ -378,7 +379,7 @@ var QdrantVector = class extends vector.MastraVector {
378
379
  } catch (error$1) {
379
380
  throw new error.MastraError(
380
381
  {
381
- id: "STORAGE_QDRANT_VECTOR_LIST_INDEXES_FAILED",
382
+ id: storage.createVectorErrorId("QDRANT", "LIST_INDEXES", "FAILED"),
382
383
  domain: error.ErrorDomain.STORAGE,
383
384
  category: error.ErrorCategory.THIRD_PARTY
384
385
  },
@@ -405,7 +406,7 @@ var QdrantVector = class extends vector.MastraVector {
405
406
  } catch (error$1) {
406
407
  throw new error.MastraError(
407
408
  {
408
- id: "STORAGE_QDRANT_VECTOR_DESCRIBE_INDEX_FAILED",
409
+ id: storage.createVectorErrorId("QDRANT", "DESCRIBE_INDEX", "FAILED"),
409
410
  domain: error.ErrorDomain.STORAGE,
410
411
  category: error.ErrorCategory.THIRD_PARTY,
411
412
  details: { indexName }
@@ -418,9 +419,14 @@ var QdrantVector = class extends vector.MastraVector {
418
419
  try {
419
420
  await this.client.deleteCollection(indexName);
420
421
  } catch (error$1) {
422
+ const errorMessage = error$1?.message || error$1?.toString() || "";
423
+ if (error$1?.status === 404 || errorMessage.toLowerCase().includes("not found") || errorMessage.toLowerCase().includes("not exist")) {
424
+ this.logger.info(`Collection ${indexName} does not exist, treating as already deleted`);
425
+ return;
426
+ }
421
427
  throw new error.MastraError(
422
428
  {
423
- id: "STORAGE_QDRANT_VECTOR_DELETE_INDEX_FAILED",
429
+ id: storage.createVectorErrorId("QDRANT", "DELETE_INDEX", "FAILED"),
424
430
  domain: error.ErrorDomain.STORAGE,
425
431
  category: error.ErrorCategory.THIRD_PARTY,
426
432
  details: { indexName }
@@ -430,66 +436,143 @@ var QdrantVector = class extends vector.MastraVector {
430
436
  }
431
437
  }
432
438
  /**
433
- * Updates a vector by its ID with the provided vector and/or metadata.
434
- * @param indexName - The name of the index containing the vector.
435
- * @param id - The ID of the vector to update.
439
+ * Updates a vector by its ID or multiple vectors matching a filter.
440
+ * @param indexName - The name of the index containing the vector(s).
441
+ * @param id - The ID of the vector to update (mutually exclusive with filter).
442
+ * @param filter - Filter to match multiple vectors to update (mutually exclusive with id).
436
443
  * @param update - An object containing the vector and/or metadata to update.
437
444
  * @param update.vector - An optional array of numbers representing the new vector.
438
445
  * @param update.metadata - An optional record containing the new metadata.
439
446
  * @returns A promise that resolves when the update is complete.
440
447
  * @throws Will throw an error if no updates are provided or if the update operation fails.
441
448
  */
442
- async updateVector({ indexName, id, update }) {
443
- try {
444
- if (!update.vector && !update.metadata) {
445
- throw new Error("No updates provided");
446
- }
447
- } catch (validationError) {
448
- throw new error.MastraError(
449
- {
450
- id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
451
- domain: error.ErrorDomain.STORAGE,
452
- category: error.ErrorCategory.USER,
453
- details: { indexName, id }
454
- },
455
- validationError
456
- );
449
+ async updateVector({ indexName, id, filter, update }) {
450
+ if (id && filter) {
451
+ throw new error.MastraError({
452
+ id: storage.createVectorErrorId("QDRANT", "UPDATE_VECTOR", "MUTUALLY_EXCLUSIVE"),
453
+ text: "Cannot specify both id and filter - they are mutually exclusive",
454
+ domain: error.ErrorDomain.STORAGE,
455
+ category: error.ErrorCategory.USER,
456
+ details: { indexName }
457
+ });
458
+ }
459
+ if (!id && !filter) {
460
+ throw new error.MastraError({
461
+ id: storage.createVectorErrorId("QDRANT", "UPDATE_VECTOR", "NO_TARGET"),
462
+ text: "Either id or filter must be provided",
463
+ domain: error.ErrorDomain.STORAGE,
464
+ category: error.ErrorCategory.USER,
465
+ details: { indexName }
466
+ });
467
+ }
468
+ if (!update.vector && !update.metadata) {
469
+ throw new error.MastraError({
470
+ id: storage.createVectorErrorId("QDRANT", "UPDATE_VECTOR", "NO_PAYLOAD"),
471
+ text: "No updates provided",
472
+ domain: error.ErrorDomain.STORAGE,
473
+ category: error.ErrorCategory.USER,
474
+ details: {
475
+ indexName,
476
+ ...id && { id }
477
+ }
478
+ });
479
+ }
480
+ if (filter && Object.keys(filter).length === 0) {
481
+ throw new error.MastraError({
482
+ id: storage.createVectorErrorId("QDRANT", "UPDATE_VECTOR", "EMPTY_FILTER"),
483
+ text: "Filter cannot be an empty filter object",
484
+ domain: error.ErrorDomain.STORAGE,
485
+ category: error.ErrorCategory.USER,
486
+ details: { indexName }
487
+ });
457
488
  }
458
- const pointId = this.parsePointId(id);
459
489
  try {
460
- if (update.metadata && !update.vector) {
461
- await this.client.setPayload(indexName, { payload: update.metadata, points: [pointId] });
462
- return;
463
- }
464
- if (update.vector && !update.metadata) {
465
- await this.client.updateVectors(indexName, {
466
- points: [
467
- {
468
- id: pointId,
469
- vector: update.vector
470
- }
471
- ]
472
- });
473
- return;
474
- }
475
- if (update.vector && update.metadata) {
476
- const point = {
477
- id: pointId,
478
- vector: update.vector,
479
- payload: update.metadata
480
- };
481
- await this.client.upsert(indexName, {
482
- points: [point]
483
- });
484
- return;
490
+ if (id) {
491
+ const pointId = this.parsePointId(id);
492
+ if (update.metadata && !update.vector) {
493
+ await this.client.setPayload(indexName, { payload: update.metadata, points: [pointId] });
494
+ return;
495
+ }
496
+ if (update.vector && !update.metadata) {
497
+ await this.client.updateVectors(indexName, {
498
+ points: [
499
+ {
500
+ id: pointId,
501
+ vector: update.vector
502
+ }
503
+ ]
504
+ });
505
+ return;
506
+ }
507
+ if (update.vector && update.metadata) {
508
+ const point = {
509
+ id: pointId,
510
+ vector: update.vector,
511
+ payload: update.metadata
512
+ };
513
+ await this.client.upsert(indexName, {
514
+ points: [point]
515
+ });
516
+ return;
517
+ }
518
+ } else if (filter) {
519
+ const translatedFilter = this.transformFilter(filter);
520
+ const matchingPoints = [];
521
+ let offset = void 0;
522
+ do {
523
+ const scrollResult = await this.client.scroll(indexName, {
524
+ filter: translatedFilter,
525
+ limit: 100,
526
+ offset,
527
+ with_payload: false,
528
+ with_vector: update.vector ? false : true
529
+ // Only fetch vectors if not updating them
530
+ });
531
+ matchingPoints.push(
532
+ ...scrollResult.points.map((point) => ({
533
+ id: point.id,
534
+ vector: Array.isArray(point.vector) ? point.vector : void 0
535
+ }))
536
+ );
537
+ const nextOffset = scrollResult.next_page_offset;
538
+ offset = typeof nextOffset === "string" || typeof nextOffset === "number" ? nextOffset : void 0;
539
+ } while (offset !== void 0);
540
+ if (matchingPoints.length === 0) {
541
+ return;
542
+ }
543
+ const pointIds = matchingPoints.map((p) => p.id);
544
+ if (update.metadata && !update.vector) {
545
+ await this.client.setPayload(indexName, { payload: update.metadata, points: pointIds });
546
+ return;
547
+ }
548
+ if (update.vector) {
549
+ const points = matchingPoints.map((p) => ({
550
+ id: p.id,
551
+ vector: update.vector,
552
+ payload: update.metadata || {}
553
+ }));
554
+ for (let i = 0; i < points.length; i += BATCH_SIZE) {
555
+ const batch = points.slice(i, i + BATCH_SIZE);
556
+ await this.client.upsert(indexName, {
557
+ points: batch,
558
+ wait: true
559
+ });
560
+ }
561
+ return;
562
+ }
485
563
  }
486
564
  } catch (error$1) {
565
+ if (error$1 instanceof error.MastraError) throw error$1;
487
566
  throw new error.MastraError(
488
567
  {
489
- id: "STORAGE_QDRANT_VECTOR_UPDATE_VECTOR_FAILED",
568
+ id: storage.createVectorErrorId("QDRANT", "UPDATE_VECTOR", "FAILED"),
490
569
  domain: error.ErrorDomain.STORAGE,
491
570
  category: error.ErrorCategory.THIRD_PARTY,
492
- details: { indexName, id }
571
+ details: {
572
+ indexName,
573
+ ...id && { id },
574
+ ...filter && { filter: JSON.stringify(filter) }
575
+ }
493
576
  },
494
577
  error$1
495
578
  );
@@ -511,10 +594,13 @@ var QdrantVector = class extends vector.MastraVector {
511
594
  } catch (error$1) {
512
595
  throw new error.MastraError(
513
596
  {
514
- id: "STORAGE_QDRANT_VECTOR_DELETE_VECTOR_FAILED",
597
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTOR", "FAILED"),
515
598
  domain: error.ErrorDomain.STORAGE,
516
599
  category: error.ErrorCategory.THIRD_PARTY,
517
- details: { indexName, id }
600
+ details: {
601
+ indexName,
602
+ ...id && { id }
603
+ }
518
604
  },
519
605
  error$1
520
606
  );
@@ -555,6 +641,90 @@ var QdrantVector = class extends vector.MastraVector {
555
641
  }
556
642
  return id;
557
643
  }
644
+ /**
645
+ * Deletes multiple vectors by IDs or filter.
646
+ * @param indexName - The name of the index containing the vectors.
647
+ * @param ids - Array of vector IDs to delete (mutually exclusive with filter).
648
+ * @param filter - Filter to match vectors to delete (mutually exclusive with ids).
649
+ * @returns A promise that resolves when the deletion is complete.
650
+ * @throws Will throw an error if both ids and filter are provided, or if neither is provided.
651
+ */
652
+ async deleteVectors({ indexName, filter, ids }) {
653
+ if (ids && filter) {
654
+ throw new error.MastraError({
655
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTORS", "MUTUALLY_EXCLUSIVE"),
656
+ text: "Cannot specify both ids and filter - they are mutually exclusive",
657
+ domain: error.ErrorDomain.STORAGE,
658
+ category: error.ErrorCategory.USER,
659
+ details: { indexName }
660
+ });
661
+ }
662
+ if (!ids && !filter) {
663
+ throw new error.MastraError({
664
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTORS", "NO_TARGET"),
665
+ text: "Either filter or ids must be provided",
666
+ domain: error.ErrorDomain.STORAGE,
667
+ category: error.ErrorCategory.USER,
668
+ details: { indexName }
669
+ });
670
+ }
671
+ if (ids && ids.length === 0) {
672
+ throw new error.MastraError({
673
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTORS", "EMPTY_IDS"),
674
+ text: "Cannot delete with empty ids array",
675
+ domain: error.ErrorDomain.STORAGE,
676
+ category: error.ErrorCategory.USER,
677
+ details: { indexName }
678
+ });
679
+ }
680
+ if (filter && Object.keys(filter).length === 0) {
681
+ throw new error.MastraError({
682
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTORS", "EMPTY_FILTER"),
683
+ text: "Cannot delete with empty filter object",
684
+ domain: error.ErrorDomain.STORAGE,
685
+ category: error.ErrorCategory.USER,
686
+ details: { indexName }
687
+ });
688
+ }
689
+ try {
690
+ if (ids) {
691
+ const pointIds = ids.map((id) => this.parsePointId(id));
692
+ try {
693
+ await this.client.delete(indexName, {
694
+ points: pointIds,
695
+ wait: true
696
+ });
697
+ } catch (error) {
698
+ const message = error?.message || error?.toString() || "";
699
+ if (message.toLowerCase().includes("bad request")) {
700
+ return;
701
+ }
702
+ throw error;
703
+ }
704
+ } else if (filter) {
705
+ const translatedFilter = this.transformFilter(filter) ?? {};
706
+ await this.client.delete(indexName, {
707
+ filter: translatedFilter,
708
+ wait: true
709
+ });
710
+ }
711
+ } catch (error$1) {
712
+ if (error$1 instanceof error.MastraError) throw error$1;
713
+ throw new error.MastraError(
714
+ {
715
+ id: storage.createVectorErrorId("QDRANT", "DELETE_VECTORS", "FAILED"),
716
+ domain: error.ErrorDomain.STORAGE,
717
+ category: error.ErrorCategory.THIRD_PARTY,
718
+ details: {
719
+ indexName,
720
+ ...filter && { filter: JSON.stringify(filter) },
721
+ ...ids && { idsCount: ids.length }
722
+ }
723
+ },
724
+ error$1
725
+ );
726
+ }
727
+ }
558
728
  };
559
729
 
560
730
  // src/vector/prompt.ts