@mastra/opensearch 0.10.3-alpha.0 → 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.
- package/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +36 -0
- package/dist/index.cjs +127 -51
- package/dist/index.js +119 -43
- package/package.json +3 -3
- package/src/vector/index.ts +127 -50
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/opensearch@0.10.
|
|
2
|
+
> @mastra/opensearch@0.10.4-alpha.0 build /home/runner/work/mastra/mastra/stores/opensearch
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.5.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 9284ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/opensearch/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.3
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/opensearch/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 10960ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
21
|
-
[32mESM[39m ⚡️ Build success in
|
|
22
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
23
|
-
[32mCJS[39m ⚡️ Build success in
|
|
20
|
+
[32mESM[39m [1mdist/index.js [22m[32m23.60 KB[39m
|
|
21
|
+
[32mESM[39m ⚡️ Build success in 784ms
|
|
22
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m23.81 KB[39m
|
|
23
|
+
[32mCJS[39m ⚡️ Build success in 784ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# @mastra/opensearch
|
|
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
|
+
|
|
16
|
+
## 0.10.3
|
|
17
|
+
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
- 63f6b7d: dependencies updates:
|
|
21
|
+
- Updated dependency [`@opensearch-project/opensearch@^3.5.1` ↗︎](https://www.npmjs.com/package/@opensearch-project/opensearch/v/3.5.1) (from `^3.4.0`, in `dependencies`)
|
|
22
|
+
- Updated dependencies [63f6b7d]
|
|
23
|
+
- Updated dependencies [12a95fc]
|
|
24
|
+
- Updated dependencies [4b0f8a6]
|
|
25
|
+
- Updated dependencies [51264a5]
|
|
26
|
+
- Updated dependencies [8e6f677]
|
|
27
|
+
- Updated dependencies [d70c420]
|
|
28
|
+
- Updated dependencies [ee9af57]
|
|
29
|
+
- Updated dependencies [36f1c36]
|
|
30
|
+
- Updated dependencies [2a16996]
|
|
31
|
+
- Updated dependencies [10d352e]
|
|
32
|
+
- Updated dependencies [9589624]
|
|
33
|
+
- Updated dependencies [53d3c37]
|
|
34
|
+
- Updated dependencies [751c894]
|
|
35
|
+
- Updated dependencies [577ce3a]
|
|
36
|
+
- Updated dependencies [9260b3a]
|
|
37
|
+
- @mastra/core@0.10.6
|
|
38
|
+
|
|
3
39
|
## 0.10.3-alpha.0
|
|
4
40
|
|
|
5
41
|
### 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 opensearch = require('@opensearch-project/opensearch');
|
|
5
6
|
var filter = require('@mastra/core/vector/filter');
|
|
@@ -383,7 +384,13 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
383
384
|
*/
|
|
384
385
|
async createIndex({ indexName, dimension, metric = "cosine" }) {
|
|
385
386
|
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
386
|
-
throw new
|
|
387
|
+
throw new error.MastraError({
|
|
388
|
+
id: "STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_INVALID_ARGS",
|
|
389
|
+
domain: error.ErrorDomain.STORAGE,
|
|
390
|
+
category: error.ErrorCategory.USER,
|
|
391
|
+
text: "Dimension must be a positive integer",
|
|
392
|
+
details: { indexName, dimension }
|
|
393
|
+
});
|
|
387
394
|
}
|
|
388
395
|
try {
|
|
389
396
|
await this.client.indices.create({
|
|
@@ -408,14 +415,21 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
408
415
|
}
|
|
409
416
|
}
|
|
410
417
|
});
|
|
411
|
-
} catch (error) {
|
|
412
|
-
const message = error?.message || error?.toString();
|
|
418
|
+
} catch (error$1) {
|
|
419
|
+
const message = error$1?.message || error$1?.toString();
|
|
413
420
|
if (message && message.toLowerCase().includes("already exists")) {
|
|
414
421
|
await this.validateExistingIndex(indexName, dimension, metric);
|
|
415
422
|
return;
|
|
416
423
|
}
|
|
417
|
-
|
|
418
|
-
|
|
424
|
+
throw new error.MastraError(
|
|
425
|
+
{
|
|
426
|
+
id: "STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_FAILED",
|
|
427
|
+
domain: error.ErrorDomain.STORAGE,
|
|
428
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
429
|
+
details: { indexName, dimension, metric }
|
|
430
|
+
},
|
|
431
|
+
error$1
|
|
432
|
+
);
|
|
419
433
|
}
|
|
420
434
|
}
|
|
421
435
|
/**
|
|
@@ -428,9 +442,15 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
428
442
|
const response = await this.client.cat.indices({ format: "json" });
|
|
429
443
|
const indexes = response.body.map((record) => record.index).filter((index) => index !== void 0);
|
|
430
444
|
return indexes;
|
|
431
|
-
} catch (error) {
|
|
432
|
-
|
|
433
|
-
|
|
445
|
+
} catch (error$1) {
|
|
446
|
+
throw new error.MastraError(
|
|
447
|
+
{
|
|
448
|
+
id: "STORAGE_OPENSEARCH_VECTOR_LIST_INDEXES_FAILED",
|
|
449
|
+
domain: error.ErrorDomain.STORAGE,
|
|
450
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
451
|
+
},
|
|
452
|
+
error$1
|
|
453
|
+
);
|
|
434
454
|
}
|
|
435
455
|
}
|
|
436
456
|
/**
|
|
@@ -460,8 +480,18 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
460
480
|
async deleteIndex({ indexName }) {
|
|
461
481
|
try {
|
|
462
482
|
await this.client.indices.delete({ index: indexName });
|
|
463
|
-
} catch (error) {
|
|
464
|
-
|
|
483
|
+
} catch (error$1) {
|
|
484
|
+
const mastraError = new error.MastraError(
|
|
485
|
+
{
|
|
486
|
+
id: "STORAGE_OPENSEARCH_VECTOR_DELETE_INDEX_FAILED",
|
|
487
|
+
domain: error.ErrorDomain.STORAGE,
|
|
488
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
489
|
+
details: { indexName }
|
|
490
|
+
},
|
|
491
|
+
error$1
|
|
492
|
+
);
|
|
493
|
+
this.logger?.error(mastraError.toString());
|
|
494
|
+
this.logger?.trackException(mastraError);
|
|
465
495
|
}
|
|
466
496
|
}
|
|
467
497
|
/**
|
|
@@ -476,31 +506,38 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
476
506
|
async upsert({ indexName, vectors, metadata = [], ids }) {
|
|
477
507
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
478
508
|
const operations = [];
|
|
479
|
-
const indexInfo = await this.describeIndex({ indexName });
|
|
480
|
-
this.validateVectorDimensions(vectors, indexInfo.dimension);
|
|
481
|
-
for (let i = 0; i < vectors.length; i++) {
|
|
482
|
-
const operation = {
|
|
483
|
-
index: {
|
|
484
|
-
_index: indexName,
|
|
485
|
-
_id: vectorIds[i]
|
|
486
|
-
}
|
|
487
|
-
};
|
|
488
|
-
const document = {
|
|
489
|
-
id: vectorIds[i],
|
|
490
|
-
embedding: vectors[i],
|
|
491
|
-
metadata: metadata[i] || {}
|
|
492
|
-
};
|
|
493
|
-
operations.push(operation);
|
|
494
|
-
operations.push(document);
|
|
495
|
-
}
|
|
496
509
|
try {
|
|
510
|
+
const indexInfo = await this.describeIndex({ indexName });
|
|
511
|
+
this.validateVectorDimensions(vectors, indexInfo.dimension);
|
|
512
|
+
for (let i = 0; i < vectors.length; i++) {
|
|
513
|
+
const operation = {
|
|
514
|
+
index: {
|
|
515
|
+
_index: indexName,
|
|
516
|
+
_id: vectorIds[i]
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
const document = {
|
|
520
|
+
id: vectorIds[i],
|
|
521
|
+
embedding: vectors[i],
|
|
522
|
+
metadata: metadata[i] || {}
|
|
523
|
+
};
|
|
524
|
+
operations.push(operation);
|
|
525
|
+
operations.push(document);
|
|
526
|
+
}
|
|
497
527
|
if (operations.length > 0) {
|
|
498
528
|
await this.client.bulk({ body: operations, refresh: true });
|
|
499
529
|
}
|
|
500
530
|
return vectorIds;
|
|
501
|
-
} catch (error) {
|
|
502
|
-
|
|
503
|
-
|
|
531
|
+
} catch (error$1) {
|
|
532
|
+
throw new error.MastraError(
|
|
533
|
+
{
|
|
534
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPSERT_FAILED",
|
|
535
|
+
domain: error.ErrorDomain.STORAGE,
|
|
536
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
537
|
+
details: { indexName, vectorCount: vectors?.length || 0 }
|
|
538
|
+
},
|
|
539
|
+
error$1
|
|
540
|
+
);
|
|
504
541
|
}
|
|
505
542
|
}
|
|
506
543
|
/**
|
|
@@ -544,9 +581,16 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
544
581
|
};
|
|
545
582
|
});
|
|
546
583
|
return results;
|
|
547
|
-
} catch (error) {
|
|
548
|
-
|
|
549
|
-
|
|
584
|
+
} catch (error$1) {
|
|
585
|
+
throw new error.MastraError(
|
|
586
|
+
{
|
|
587
|
+
id: "STORAGE_OPENSEARCH_VECTOR_QUERY_FAILED",
|
|
588
|
+
domain: error.ErrorDomain.STORAGE,
|
|
589
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
590
|
+
details: { indexName, topK }
|
|
591
|
+
},
|
|
592
|
+
error$1
|
|
593
|
+
);
|
|
550
594
|
}
|
|
551
595
|
}
|
|
552
596
|
/**
|
|
@@ -582,44 +626,68 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
582
626
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
583
627
|
*/
|
|
584
628
|
async updateVector({ indexName, id, update }) {
|
|
585
|
-
|
|
586
|
-
throw new Error("No updates provided");
|
|
587
|
-
}
|
|
629
|
+
let existingDoc;
|
|
588
630
|
try {
|
|
589
|
-
|
|
631
|
+
if (!update.vector && !update.metadata) {
|
|
632
|
+
throw new Error("No updates provided");
|
|
633
|
+
}
|
|
634
|
+
const { body } = await this.client.get({
|
|
590
635
|
index: indexName,
|
|
591
636
|
id
|
|
592
637
|
}).catch(() => {
|
|
593
638
|
throw new Error(`Document with ID ${id} not found in index ${indexName}`);
|
|
594
639
|
});
|
|
595
|
-
if (!
|
|
640
|
+
if (!body || !body._source) {
|
|
596
641
|
throw new Error(`Document with ID ${id} has no source data in index ${indexName}`);
|
|
597
642
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
643
|
+
existingDoc = body;
|
|
644
|
+
} catch (error$1) {
|
|
645
|
+
throw new error.MastraError(
|
|
646
|
+
{
|
|
647
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
648
|
+
domain: error.ErrorDomain.STORAGE,
|
|
649
|
+
category: error.ErrorCategory.USER,
|
|
650
|
+
details: { indexName, id }
|
|
651
|
+
},
|
|
652
|
+
error$1
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
const source = existingDoc._source;
|
|
656
|
+
const updatedDoc = {
|
|
657
|
+
id: source?.id || id
|
|
658
|
+
};
|
|
659
|
+
try {
|
|
602
660
|
if (update.vector) {
|
|
661
|
+
console.log(`1`);
|
|
603
662
|
const indexInfo = await this.describeIndex({ indexName });
|
|
663
|
+
console.log(`2`);
|
|
604
664
|
this.validateVectorDimensions([update.vector], indexInfo.dimension);
|
|
605
665
|
updatedDoc.embedding = update.vector;
|
|
606
|
-
} else if (source
|
|
666
|
+
} else if (source?.embedding) {
|
|
607
667
|
updatedDoc.embedding = source.embedding;
|
|
608
668
|
}
|
|
609
669
|
if (update.metadata) {
|
|
610
670
|
updatedDoc.metadata = update.metadata;
|
|
611
671
|
} else {
|
|
612
|
-
updatedDoc.metadata = source
|
|
672
|
+
updatedDoc.metadata = source?.metadata || {};
|
|
613
673
|
}
|
|
674
|
+
console.log(`3`);
|
|
614
675
|
await this.client.index({
|
|
615
676
|
index: indexName,
|
|
616
677
|
id,
|
|
617
678
|
body: updatedDoc,
|
|
618
679
|
refresh: true
|
|
619
680
|
});
|
|
620
|
-
} catch (error) {
|
|
621
|
-
|
|
622
|
-
|
|
681
|
+
} catch (error$1) {
|
|
682
|
+
throw new error.MastraError(
|
|
683
|
+
{
|
|
684
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
685
|
+
domain: error.ErrorDomain.STORAGE,
|
|
686
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
687
|
+
details: { indexName, id }
|
|
688
|
+
},
|
|
689
|
+
error$1
|
|
690
|
+
);
|
|
623
691
|
}
|
|
624
692
|
}
|
|
625
693
|
/**
|
|
@@ -636,11 +704,19 @@ var OpenSearchVector = class extends vector.MastraVector {
|
|
|
636
704
|
id,
|
|
637
705
|
refresh: true
|
|
638
706
|
});
|
|
639
|
-
} catch (error) {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
throw error;
|
|
707
|
+
} catch (error$1) {
|
|
708
|
+
if (error$1 && typeof error$1 === "object" && "statusCode" in error$1 && error$1.statusCode === 404) {
|
|
709
|
+
return;
|
|
643
710
|
}
|
|
711
|
+
throw new error.MastraError(
|
|
712
|
+
{
|
|
713
|
+
id: "STORAGE_OPENSEARCH_VECTOR_DELETE_VECTOR_FAILED",
|
|
714
|
+
domain: error.ErrorDomain.STORAGE,
|
|
715
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
716
|
+
details: { indexName, id }
|
|
717
|
+
},
|
|
718
|
+
error$1
|
|
719
|
+
);
|
|
644
720
|
}
|
|
645
721
|
}
|
|
646
722
|
};
|
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 { Client } from '@opensearch-project/opensearch';
|
|
3
4
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
@@ -381,7 +382,13 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
381
382
|
*/
|
|
382
383
|
async createIndex({ indexName, dimension, metric = "cosine" }) {
|
|
383
384
|
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
384
|
-
throw new
|
|
385
|
+
throw new MastraError({
|
|
386
|
+
id: "STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_INVALID_ARGS",
|
|
387
|
+
domain: ErrorDomain.STORAGE,
|
|
388
|
+
category: ErrorCategory.USER,
|
|
389
|
+
text: "Dimension must be a positive integer",
|
|
390
|
+
details: { indexName, dimension }
|
|
391
|
+
});
|
|
385
392
|
}
|
|
386
393
|
try {
|
|
387
394
|
await this.client.indices.create({
|
|
@@ -412,8 +419,15 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
412
419
|
await this.validateExistingIndex(indexName, dimension, metric);
|
|
413
420
|
return;
|
|
414
421
|
}
|
|
415
|
-
|
|
416
|
-
|
|
422
|
+
throw new MastraError(
|
|
423
|
+
{
|
|
424
|
+
id: "STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_FAILED",
|
|
425
|
+
domain: ErrorDomain.STORAGE,
|
|
426
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
427
|
+
details: { indexName, dimension, metric }
|
|
428
|
+
},
|
|
429
|
+
error
|
|
430
|
+
);
|
|
417
431
|
}
|
|
418
432
|
}
|
|
419
433
|
/**
|
|
@@ -427,8 +441,14 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
427
441
|
const indexes = response.body.map((record) => record.index).filter((index) => index !== void 0);
|
|
428
442
|
return indexes;
|
|
429
443
|
} catch (error) {
|
|
430
|
-
|
|
431
|
-
|
|
444
|
+
throw new MastraError(
|
|
445
|
+
{
|
|
446
|
+
id: "STORAGE_OPENSEARCH_VECTOR_LIST_INDEXES_FAILED",
|
|
447
|
+
domain: ErrorDomain.STORAGE,
|
|
448
|
+
category: ErrorCategory.THIRD_PARTY
|
|
449
|
+
},
|
|
450
|
+
error
|
|
451
|
+
);
|
|
432
452
|
}
|
|
433
453
|
}
|
|
434
454
|
/**
|
|
@@ -459,7 +479,17 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
459
479
|
try {
|
|
460
480
|
await this.client.indices.delete({ index: indexName });
|
|
461
481
|
} catch (error) {
|
|
462
|
-
|
|
482
|
+
const mastraError = new MastraError(
|
|
483
|
+
{
|
|
484
|
+
id: "STORAGE_OPENSEARCH_VECTOR_DELETE_INDEX_FAILED",
|
|
485
|
+
domain: ErrorDomain.STORAGE,
|
|
486
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
487
|
+
details: { indexName }
|
|
488
|
+
},
|
|
489
|
+
error
|
|
490
|
+
);
|
|
491
|
+
this.logger?.error(mastraError.toString());
|
|
492
|
+
this.logger?.trackException(mastraError);
|
|
463
493
|
}
|
|
464
494
|
}
|
|
465
495
|
/**
|
|
@@ -474,31 +504,38 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
474
504
|
async upsert({ indexName, vectors, metadata = [], ids }) {
|
|
475
505
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
476
506
|
const operations = [];
|
|
477
|
-
const indexInfo = await this.describeIndex({ indexName });
|
|
478
|
-
this.validateVectorDimensions(vectors, indexInfo.dimension);
|
|
479
|
-
for (let i = 0; i < vectors.length; i++) {
|
|
480
|
-
const operation = {
|
|
481
|
-
index: {
|
|
482
|
-
_index: indexName,
|
|
483
|
-
_id: vectorIds[i]
|
|
484
|
-
}
|
|
485
|
-
};
|
|
486
|
-
const document = {
|
|
487
|
-
id: vectorIds[i],
|
|
488
|
-
embedding: vectors[i],
|
|
489
|
-
metadata: metadata[i] || {}
|
|
490
|
-
};
|
|
491
|
-
operations.push(operation);
|
|
492
|
-
operations.push(document);
|
|
493
|
-
}
|
|
494
507
|
try {
|
|
508
|
+
const indexInfo = await this.describeIndex({ indexName });
|
|
509
|
+
this.validateVectorDimensions(vectors, indexInfo.dimension);
|
|
510
|
+
for (let i = 0; i < vectors.length; i++) {
|
|
511
|
+
const operation = {
|
|
512
|
+
index: {
|
|
513
|
+
_index: indexName,
|
|
514
|
+
_id: vectorIds[i]
|
|
515
|
+
}
|
|
516
|
+
};
|
|
517
|
+
const document = {
|
|
518
|
+
id: vectorIds[i],
|
|
519
|
+
embedding: vectors[i],
|
|
520
|
+
metadata: metadata[i] || {}
|
|
521
|
+
};
|
|
522
|
+
operations.push(operation);
|
|
523
|
+
operations.push(document);
|
|
524
|
+
}
|
|
495
525
|
if (operations.length > 0) {
|
|
496
526
|
await this.client.bulk({ body: operations, refresh: true });
|
|
497
527
|
}
|
|
498
528
|
return vectorIds;
|
|
499
529
|
} catch (error) {
|
|
500
|
-
|
|
501
|
-
|
|
530
|
+
throw new MastraError(
|
|
531
|
+
{
|
|
532
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPSERT_FAILED",
|
|
533
|
+
domain: ErrorDomain.STORAGE,
|
|
534
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
535
|
+
details: { indexName, vectorCount: vectors?.length || 0 }
|
|
536
|
+
},
|
|
537
|
+
error
|
|
538
|
+
);
|
|
502
539
|
}
|
|
503
540
|
}
|
|
504
541
|
/**
|
|
@@ -543,8 +580,15 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
543
580
|
});
|
|
544
581
|
return results;
|
|
545
582
|
} catch (error) {
|
|
546
|
-
|
|
547
|
-
|
|
583
|
+
throw new MastraError(
|
|
584
|
+
{
|
|
585
|
+
id: "STORAGE_OPENSEARCH_VECTOR_QUERY_FAILED",
|
|
586
|
+
domain: ErrorDomain.STORAGE,
|
|
587
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
588
|
+
details: { indexName, topK }
|
|
589
|
+
},
|
|
590
|
+
error
|
|
591
|
+
);
|
|
548
592
|
}
|
|
549
593
|
}
|
|
550
594
|
/**
|
|
@@ -580,35 +624,52 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
580
624
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
581
625
|
*/
|
|
582
626
|
async updateVector({ indexName, id, update }) {
|
|
583
|
-
|
|
584
|
-
throw new Error("No updates provided");
|
|
585
|
-
}
|
|
627
|
+
let existingDoc;
|
|
586
628
|
try {
|
|
587
|
-
|
|
629
|
+
if (!update.vector && !update.metadata) {
|
|
630
|
+
throw new Error("No updates provided");
|
|
631
|
+
}
|
|
632
|
+
const { body } = await this.client.get({
|
|
588
633
|
index: indexName,
|
|
589
634
|
id
|
|
590
635
|
}).catch(() => {
|
|
591
636
|
throw new Error(`Document with ID ${id} not found in index ${indexName}`);
|
|
592
637
|
});
|
|
593
|
-
if (!
|
|
638
|
+
if (!body || !body._source) {
|
|
594
639
|
throw new Error(`Document with ID ${id} has no source data in index ${indexName}`);
|
|
595
640
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
641
|
+
existingDoc = body;
|
|
642
|
+
} catch (error) {
|
|
643
|
+
throw new MastraError(
|
|
644
|
+
{
|
|
645
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
646
|
+
domain: ErrorDomain.STORAGE,
|
|
647
|
+
category: ErrorCategory.USER,
|
|
648
|
+
details: { indexName, id }
|
|
649
|
+
},
|
|
650
|
+
error
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
const source = existingDoc._source;
|
|
654
|
+
const updatedDoc = {
|
|
655
|
+
id: source?.id || id
|
|
656
|
+
};
|
|
657
|
+
try {
|
|
600
658
|
if (update.vector) {
|
|
659
|
+
console.log(`1`);
|
|
601
660
|
const indexInfo = await this.describeIndex({ indexName });
|
|
661
|
+
console.log(`2`);
|
|
602
662
|
this.validateVectorDimensions([update.vector], indexInfo.dimension);
|
|
603
663
|
updatedDoc.embedding = update.vector;
|
|
604
|
-
} else if (source
|
|
664
|
+
} else if (source?.embedding) {
|
|
605
665
|
updatedDoc.embedding = source.embedding;
|
|
606
666
|
}
|
|
607
667
|
if (update.metadata) {
|
|
608
668
|
updatedDoc.metadata = update.metadata;
|
|
609
669
|
} else {
|
|
610
|
-
updatedDoc.metadata = source
|
|
670
|
+
updatedDoc.metadata = source?.metadata || {};
|
|
611
671
|
}
|
|
672
|
+
console.log(`3`);
|
|
612
673
|
await this.client.index({
|
|
613
674
|
index: indexName,
|
|
614
675
|
id,
|
|
@@ -616,8 +677,15 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
616
677
|
refresh: true
|
|
617
678
|
});
|
|
618
679
|
} catch (error) {
|
|
619
|
-
|
|
620
|
-
|
|
680
|
+
throw new MastraError(
|
|
681
|
+
{
|
|
682
|
+
id: "STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
683
|
+
domain: ErrorDomain.STORAGE,
|
|
684
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
685
|
+
details: { indexName, id }
|
|
686
|
+
},
|
|
687
|
+
error
|
|
688
|
+
);
|
|
621
689
|
}
|
|
622
690
|
}
|
|
623
691
|
/**
|
|
@@ -635,10 +703,18 @@ var OpenSearchVector = class extends MastraVector {
|
|
|
635
703
|
refresh: true
|
|
636
704
|
});
|
|
637
705
|
} catch (error) {
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
throw error;
|
|
706
|
+
if (error && typeof error === "object" && "statusCode" in error && error.statusCode === 404) {
|
|
707
|
+
return;
|
|
641
708
|
}
|
|
709
|
+
throw new MastraError(
|
|
710
|
+
{
|
|
711
|
+
id: "STORAGE_OPENSEARCH_VECTOR_DELETE_VECTOR_FAILED",
|
|
712
|
+
domain: ErrorDomain.STORAGE,
|
|
713
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
714
|
+
details: { indexName, id }
|
|
715
|
+
},
|
|
716
|
+
error
|
|
717
|
+
);
|
|
642
718
|
}
|
|
643
719
|
}
|
|
644
720
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/opensearch",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.4-alpha.0",
|
|
4
4
|
"description": "OpenSearch vector store provider for Mastra",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"tsup": "^8.5.0",
|
|
29
29
|
"typescript": "^5.8.3",
|
|
30
30
|
"vitest": "^3.2.3",
|
|
31
|
-
"@internal/lint": "0.0.
|
|
32
|
-
"@mastra/core": "0.10.
|
|
31
|
+
"@internal/lint": "0.0.13",
|
|
32
|
+
"@mastra/core": "0.10.7-alpha.1"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"@mastra/core": ">=0.10.4-0 <0.11.0"
|
package/src/vector/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
UpdateVectorParams,
|
|
10
10
|
UpsertVectorParams,
|
|
11
11
|
} from '@mastra/core';
|
|
12
|
+
import { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
|
|
12
13
|
import { MastraVector } from '@mastra/core/vector';
|
|
13
14
|
import type { VectorFilter } from '@mastra/core/vector/filter';
|
|
14
15
|
import { Client as OpenSearchClient } from '@opensearch-project/opensearch';
|
|
@@ -49,7 +50,13 @@ export class OpenSearchVector extends MastraVector {
|
|
|
49
50
|
*/
|
|
50
51
|
async createIndex({ indexName, dimension, metric = 'cosine' }: CreateIndexParams): Promise<void> {
|
|
51
52
|
if (!Number.isInteger(dimension) || dimension <= 0) {
|
|
52
|
-
throw new
|
|
53
|
+
throw new MastraError({
|
|
54
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_INVALID_ARGS',
|
|
55
|
+
domain: ErrorDomain.STORAGE,
|
|
56
|
+
category: ErrorCategory.USER,
|
|
57
|
+
text: 'Dimension must be a positive integer',
|
|
58
|
+
details: { indexName, dimension },
|
|
59
|
+
});
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
try {
|
|
@@ -82,8 +89,15 @@ export class OpenSearchVector extends MastraVector {
|
|
|
82
89
|
await this.validateExistingIndex(indexName, dimension, metric);
|
|
83
90
|
return;
|
|
84
91
|
}
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
throw new MastraError(
|
|
93
|
+
{
|
|
94
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_CREATE_INDEX_FAILED',
|
|
95
|
+
domain: ErrorDomain.STORAGE,
|
|
96
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
97
|
+
details: { indexName, dimension, metric },
|
|
98
|
+
},
|
|
99
|
+
error,
|
|
100
|
+
);
|
|
87
101
|
}
|
|
88
102
|
}
|
|
89
103
|
|
|
@@ -100,9 +114,15 @@ export class OpenSearchVector extends MastraVector {
|
|
|
100
114
|
.filter((index: string | undefined) => index !== undefined);
|
|
101
115
|
|
|
102
116
|
return indexes;
|
|
103
|
-
} catch (error
|
|
104
|
-
|
|
105
|
-
|
|
117
|
+
} catch (error) {
|
|
118
|
+
throw new MastraError(
|
|
119
|
+
{
|
|
120
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_LIST_INDEXES_FAILED',
|
|
121
|
+
domain: ErrorDomain.STORAGE,
|
|
122
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
123
|
+
},
|
|
124
|
+
error,
|
|
125
|
+
);
|
|
106
126
|
}
|
|
107
127
|
}
|
|
108
128
|
|
|
@@ -137,7 +157,17 @@ export class OpenSearchVector extends MastraVector {
|
|
|
137
157
|
try {
|
|
138
158
|
await this.client.indices.delete({ index: indexName });
|
|
139
159
|
} catch (error) {
|
|
140
|
-
|
|
160
|
+
const mastraError = new MastraError(
|
|
161
|
+
{
|
|
162
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_DELETE_INDEX_FAILED',
|
|
163
|
+
domain: ErrorDomain.STORAGE,
|
|
164
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
165
|
+
details: { indexName },
|
|
166
|
+
},
|
|
167
|
+
error,
|
|
168
|
+
);
|
|
169
|
+
this.logger?.error(mastraError.toString());
|
|
170
|
+
this.logger?.trackException(mastraError);
|
|
141
171
|
}
|
|
142
172
|
}
|
|
143
173
|
|
|
@@ -154,39 +184,46 @@ export class OpenSearchVector extends MastraVector {
|
|
|
154
184
|
const vectorIds = ids || vectors.map(() => crypto.randomUUID());
|
|
155
185
|
const operations = [];
|
|
156
186
|
|
|
157
|
-
|
|
158
|
-
|
|
187
|
+
try {
|
|
188
|
+
// Get index stats to check dimension
|
|
189
|
+
const indexInfo = await this.describeIndex({ indexName });
|
|
159
190
|
|
|
160
|
-
|
|
161
|
-
|
|
191
|
+
// Validate vector dimensions
|
|
192
|
+
this.validateVectorDimensions(vectors, indexInfo.dimension);
|
|
162
193
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
194
|
+
for (let i = 0; i < vectors.length; i++) {
|
|
195
|
+
const operation = {
|
|
196
|
+
index: {
|
|
197
|
+
_index: indexName,
|
|
198
|
+
_id: vectorIds[i],
|
|
199
|
+
},
|
|
200
|
+
};
|
|
170
201
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
202
|
+
const document = {
|
|
203
|
+
id: vectorIds[i],
|
|
204
|
+
embedding: vectors[i],
|
|
205
|
+
metadata: metadata[i] || {},
|
|
206
|
+
};
|
|
176
207
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
208
|
+
operations.push(operation);
|
|
209
|
+
operations.push(document);
|
|
210
|
+
}
|
|
180
211
|
|
|
181
|
-
try {
|
|
182
212
|
if (operations.length > 0) {
|
|
183
213
|
await this.client.bulk({ body: operations, refresh: true });
|
|
184
214
|
}
|
|
185
215
|
|
|
186
216
|
return vectorIds;
|
|
187
217
|
} catch (error) {
|
|
188
|
-
|
|
189
|
-
|
|
218
|
+
throw new MastraError(
|
|
219
|
+
{
|
|
220
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_UPSERT_FAILED',
|
|
221
|
+
domain: ErrorDomain.STORAGE,
|
|
222
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
223
|
+
details: { indexName, vectorCount: vectors?.length || 0 },
|
|
224
|
+
},
|
|
225
|
+
error,
|
|
226
|
+
);
|
|
190
227
|
}
|
|
191
228
|
}
|
|
192
229
|
|
|
@@ -234,9 +271,16 @@ export class OpenSearchVector extends MastraVector {
|
|
|
234
271
|
});
|
|
235
272
|
|
|
236
273
|
return results;
|
|
237
|
-
} catch (error
|
|
238
|
-
|
|
239
|
-
|
|
274
|
+
} catch (error) {
|
|
275
|
+
throw new MastraError(
|
|
276
|
+
{
|
|
277
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_QUERY_FAILED',
|
|
278
|
+
domain: ErrorDomain.STORAGE,
|
|
279
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
280
|
+
details: { indexName, topK },
|
|
281
|
+
},
|
|
282
|
+
error,
|
|
283
|
+
);
|
|
240
284
|
}
|
|
241
285
|
}
|
|
242
286
|
|
|
@@ -275,13 +319,15 @@ export class OpenSearchVector extends MastraVector {
|
|
|
275
319
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
276
320
|
*/
|
|
277
321
|
async updateVector({ indexName, id, update }: UpdateVectorParams): Promise<void> {
|
|
278
|
-
|
|
279
|
-
throw new Error('No updates provided');
|
|
280
|
-
}
|
|
281
|
-
|
|
322
|
+
let existingDoc;
|
|
282
323
|
try {
|
|
324
|
+
if (!update.vector && !update.metadata) {
|
|
325
|
+
throw new Error('No updates provided');
|
|
326
|
+
}
|
|
327
|
+
|
|
283
328
|
// First get the current document to merge with updates
|
|
284
|
-
const { body
|
|
329
|
+
const { body } = await this.client
|
|
330
|
+
|
|
285
331
|
.get({
|
|
286
332
|
index: indexName,
|
|
287
333
|
id: id,
|
|
@@ -290,25 +336,40 @@ export class OpenSearchVector extends MastraVector {
|
|
|
290
336
|
throw new Error(`Document with ID ${id} not found in index ${indexName}`);
|
|
291
337
|
});
|
|
292
338
|
|
|
293
|
-
if (!
|
|
339
|
+
if (!body || !body._source) {
|
|
294
340
|
throw new Error(`Document with ID ${id} has no source data in index ${indexName}`);
|
|
295
341
|
}
|
|
342
|
+
existingDoc = body;
|
|
343
|
+
} catch (error) {
|
|
344
|
+
throw new MastraError(
|
|
345
|
+
{
|
|
346
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
347
|
+
domain: ErrorDomain.STORAGE,
|
|
348
|
+
category: ErrorCategory.USER,
|
|
349
|
+
details: { indexName, id },
|
|
350
|
+
},
|
|
351
|
+
error,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
296
354
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
355
|
+
const source = existingDoc._source;
|
|
356
|
+
const updatedDoc: Record<string, any> = {
|
|
357
|
+
id: source?.id || id,
|
|
358
|
+
};
|
|
301
359
|
|
|
360
|
+
try {
|
|
302
361
|
// Update vector if provided
|
|
303
362
|
if (update.vector) {
|
|
304
363
|
// Get index stats to check dimension
|
|
364
|
+
console.log(`1`);
|
|
305
365
|
const indexInfo = await this.describeIndex({ indexName });
|
|
306
366
|
|
|
307
367
|
// Validate vector dimensions
|
|
368
|
+
console.log(`2`);
|
|
308
369
|
this.validateVectorDimensions([update.vector], indexInfo.dimension);
|
|
309
370
|
|
|
310
371
|
updatedDoc.embedding = update.vector;
|
|
311
|
-
} else if (source
|
|
372
|
+
} else if (source?.embedding) {
|
|
312
373
|
updatedDoc.embedding = source.embedding;
|
|
313
374
|
}
|
|
314
375
|
|
|
@@ -316,10 +377,11 @@ export class OpenSearchVector extends MastraVector {
|
|
|
316
377
|
if (update.metadata) {
|
|
317
378
|
updatedDoc.metadata = update.metadata;
|
|
318
379
|
} else {
|
|
319
|
-
updatedDoc.metadata = source
|
|
380
|
+
updatedDoc.metadata = source?.metadata || {};
|
|
320
381
|
}
|
|
321
382
|
|
|
322
383
|
// Update the document
|
|
384
|
+
console.log(`3`);
|
|
323
385
|
await this.client.index({
|
|
324
386
|
index: indexName,
|
|
325
387
|
id: id,
|
|
@@ -327,8 +389,15 @@ export class OpenSearchVector extends MastraVector {
|
|
|
327
389
|
refresh: true,
|
|
328
390
|
});
|
|
329
391
|
} catch (error) {
|
|
330
|
-
|
|
331
|
-
|
|
392
|
+
throw new MastraError(
|
|
393
|
+
{
|
|
394
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
395
|
+
domain: ErrorDomain.STORAGE,
|
|
396
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
397
|
+
details: { indexName, id },
|
|
398
|
+
},
|
|
399
|
+
error,
|
|
400
|
+
);
|
|
332
401
|
}
|
|
333
402
|
}
|
|
334
403
|
|
|
@@ -347,11 +416,19 @@ export class OpenSearchVector extends MastraVector {
|
|
|
347
416
|
refresh: true,
|
|
348
417
|
});
|
|
349
418
|
} catch (error: unknown) {
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
throw error;
|
|
419
|
+
// Don't throw error if document doesn't exist (404)
|
|
420
|
+
if (error && typeof error === 'object' && 'statusCode' in error && error.statusCode === 404) {
|
|
421
|
+
return;
|
|
354
422
|
}
|
|
423
|
+
throw new MastraError(
|
|
424
|
+
{
|
|
425
|
+
id: 'STORAGE_OPENSEARCH_VECTOR_DELETE_VECTOR_FAILED',
|
|
426
|
+
domain: ErrorDomain.STORAGE,
|
|
427
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
428
|
+
details: { indexName, id },
|
|
429
|
+
},
|
|
430
|
+
error,
|
|
431
|
+
);
|
|
355
432
|
}
|
|
356
433
|
}
|
|
357
434
|
}
|