@mastra/dynamodb 0.0.0-pass-headers-for-create-mastra-client-20250529200245 → 0.0.0-pgvector-index-fix-20250905222058

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +864 -0
  2. package/LICENSE.md +11 -42
  3. package/dist/entities/eval.d.ts +102 -0
  4. package/dist/entities/eval.d.ts.map +1 -0
  5. package/dist/entities/index.d.ts +746 -0
  6. package/dist/entities/index.d.ts.map +1 -0
  7. package/dist/entities/message.d.ts +100 -0
  8. package/dist/entities/message.d.ts.map +1 -0
  9. package/dist/entities/resource.d.ts +54 -0
  10. package/dist/entities/resource.d.ts.map +1 -0
  11. package/dist/entities/score.d.ts +229 -0
  12. package/dist/entities/score.d.ts.map +1 -0
  13. package/dist/entities/thread.d.ts +69 -0
  14. package/dist/entities/thread.d.ts.map +1 -0
  15. package/dist/entities/trace.d.ts +127 -0
  16. package/dist/entities/trace.d.ts.map +1 -0
  17. package/dist/entities/utils.d.ts +21 -0
  18. package/dist/entities/utils.d.ts.map +1 -0
  19. package/dist/entities/workflow-snapshot.d.ts +74 -0
  20. package/dist/entities/workflow-snapshot.d.ts.map +1 -0
  21. package/dist/index.cjs +2296 -447
  22. package/dist/index.cjs.map +1 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +2299 -450
  26. package/dist/index.js.map +1 -0
  27. package/dist/storage/domains/legacy-evals/index.d.ts +19 -0
  28. package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
  29. package/dist/storage/domains/memory/index.d.ts +89 -0
  30. package/dist/storage/domains/memory/index.d.ts.map +1 -0
  31. package/dist/storage/domains/operations/index.d.ts +69 -0
  32. package/dist/storage/domains/operations/index.d.ts.map +1 -0
  33. package/dist/storage/domains/score/index.d.ts +43 -0
  34. package/dist/storage/domains/score/index.d.ts.map +1 -0
  35. package/dist/storage/domains/traces/index.d.ts +28 -0
  36. package/dist/storage/domains/traces/index.d.ts.map +1 -0
  37. package/dist/storage/domains/workflows/index.d.ts +50 -0
  38. package/dist/storage/domains/workflows/index.d.ts.map +1 -0
  39. package/dist/storage/index.d.ts +249 -0
  40. package/dist/storage/index.d.ts.map +1 -0
  41. package/package.json +43 -19
  42. package/src/entities/eval.ts +0 -102
  43. package/src/entities/index.ts +0 -23
  44. package/src/entities/message.ts +0 -143
  45. package/src/entities/thread.ts +0 -66
  46. package/src/entities/trace.ts +0 -129
  47. package/src/entities/utils.ts +0 -51
  48. package/src/entities/workflow-snapshot.ts +0 -56
  49. package/src/index.ts +0 -1
  50. package/src/storage/docker-compose.yml +0 -16
  51. package/src/storage/index.test.ts +0 -1053
  52. package/src/storage/index.ts +0 -1059
package/dist/index.cjs CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  var clientDynamodb = require('@aws-sdk/client-dynamodb');
4
4
  var libDynamodb = require('@aws-sdk/lib-dynamodb');
5
- var agent = require('@mastra/core/agent');
5
+ var error = require('@mastra/core/error');
6
6
  var storage = require('@mastra/core/storage');
7
7
  var electrodb = require('electrodb');
8
+ var agent = require('@mastra/core/agent');
8
9
 
9
10
  // src/storage/index.ts
10
11
 
@@ -295,9 +296,9 @@ var messageEntity = new electrodb.Entity({
295
296
  }
296
297
  }
297
298
  });
298
- var threadEntity = new electrodb.Entity({
299
+ var resourceEntity = new electrodb.Entity({
299
300
  model: {
300
- entity: "thread",
301
+ entity: "resource",
301
302
  version: "1",
302
303
  service: "mastra"
303
304
  },
@@ -311,25 +312,21 @@ var threadEntity = new electrodb.Entity({
311
312
  type: "string",
312
313
  required: true
313
314
  },
314
- resourceId: {
315
- type: "string",
316
- required: true
317
- },
318
- title: {
315
+ workingMemory: {
319
316
  type: "string",
320
- required: true
317
+ required: false
321
318
  },
322
319
  metadata: {
323
320
  type: "string",
324
321
  required: false,
325
- // Stringify metadata object on set if it's not already a string
322
+ // Stringify content object on set if it's not already a string
326
323
  set: (value) => {
327
324
  if (value && typeof value !== "string") {
328
325
  return JSON.stringify(value);
329
326
  }
330
327
  return value;
331
328
  },
332
- // Parse JSON string to object on get
329
+ // Parse JSON string to object on get ONLY if it looks like JSON
333
330
  get: (value) => {
334
331
  if (value && typeof value === "string") {
335
332
  try {
@@ -347,18 +344,13 @@ var threadEntity = new electrodb.Entity({
347
344
  indexes: {
348
345
  primary: {
349
346
  pk: { field: "pk", composite: ["entity", "id"] },
350
- sk: { field: "sk", composite: ["id"] }
351
- },
352
- byResource: {
353
- index: "gsi1",
354
- pk: { field: "gsi1pk", composite: ["entity", "resourceId"] },
355
- sk: { field: "gsi1sk", composite: ["createdAt"] }
347
+ sk: { field: "sk", composite: ["entity"] }
356
348
  }
357
349
  }
358
350
  });
359
- var traceEntity = new electrodb.Entity({
351
+ var scoreEntity = new electrodb.Entity({
360
352
  model: {
361
- entity: "trace",
353
+ entity: "score",
362
354
  version: "1",
363
355
  service: "mastra"
364
356
  },
@@ -372,123 +364,306 @@ var traceEntity = new electrodb.Entity({
372
364
  type: "string",
373
365
  required: true
374
366
  },
375
- parentSpanId: {
367
+ scorerId: {
368
+ type: "string",
369
+ required: true
370
+ },
371
+ traceId: {
376
372
  type: "string",
377
373
  required: false
378
374
  },
379
- name: {
375
+ runId: {
380
376
  type: "string",
381
377
  required: true
382
378
  },
383
- traceId: {
379
+ scorer: {
384
380
  type: "string",
385
- required: true
381
+ required: true,
382
+ set: (value) => {
383
+ if (value && typeof value !== "string") {
384
+ return JSON.stringify(value);
385
+ }
386
+ return value;
387
+ },
388
+ get: (value) => {
389
+ if (value && typeof value === "string") {
390
+ try {
391
+ if (value.startsWith("{") || value.startsWith("[")) {
392
+ return JSON.parse(value);
393
+ }
394
+ } catch {
395
+ return value;
396
+ }
397
+ }
398
+ return value;
399
+ }
386
400
  },
387
- scope: {
401
+ extractStepResult: {
388
402
  type: "string",
389
- required: true
403
+ required: false,
404
+ set: (value) => {
405
+ if (value && typeof value !== "string") {
406
+ return JSON.stringify(value);
407
+ }
408
+ return value;
409
+ },
410
+ get: (value) => {
411
+ if (value && typeof value === "string") {
412
+ try {
413
+ if (value.startsWith("{") || value.startsWith("[")) {
414
+ return JSON.parse(value);
415
+ }
416
+ } catch {
417
+ return value;
418
+ }
419
+ }
420
+ return value;
421
+ }
390
422
  },
391
- kind: {
423
+ preprocessStepResult: {
424
+ type: "string",
425
+ required: false,
426
+ set: (value) => {
427
+ if (value && typeof value !== "string") {
428
+ return JSON.stringify(value);
429
+ }
430
+ return value;
431
+ },
432
+ get: (value) => {
433
+ if (value && typeof value === "string") {
434
+ try {
435
+ if (value.startsWith("{") || value.startsWith("[")) {
436
+ return JSON.parse(value);
437
+ }
438
+ } catch {
439
+ return value;
440
+ }
441
+ }
442
+ return value;
443
+ }
444
+ },
445
+ analyzeStepResult: {
446
+ type: "string",
447
+ required: false,
448
+ set: (value) => {
449
+ if (value && typeof value !== "string") {
450
+ return JSON.stringify(value);
451
+ }
452
+ return value;
453
+ },
454
+ get: (value) => {
455
+ if (value && typeof value === "string") {
456
+ try {
457
+ if (value.startsWith("{") || value.startsWith("[")) {
458
+ return JSON.parse(value);
459
+ }
460
+ } catch {
461
+ return value;
462
+ }
463
+ }
464
+ return value;
465
+ }
466
+ },
467
+ score: {
392
468
  type: "number",
393
469
  required: true
394
470
  },
395
- attributes: {
471
+ reason: {
396
472
  type: "string",
397
- // JSON stringified
398
- required: false,
399
- // Stringify object on set
473
+ required: false
474
+ },
475
+ extractPrompt: {
476
+ type: "string",
477
+ required: false
478
+ },
479
+ analyzePrompt: {
480
+ type: "string",
481
+ required: false
482
+ },
483
+ // Deprecated in favor of generateReasonPrompt
484
+ reasonPrompt: {
485
+ type: "string",
486
+ required: false
487
+ },
488
+ generateScorePrompt: {
489
+ type: "string",
490
+ required: false
491
+ },
492
+ generateReasonPrompt: {
493
+ type: "string",
494
+ required: false
495
+ },
496
+ input: {
497
+ type: "string",
498
+ required: true,
400
499
  set: (value) => {
401
500
  if (value && typeof value !== "string") {
402
501
  return JSON.stringify(value);
403
502
  }
404
503
  return value;
405
504
  },
406
- // Parse JSON string to object on get
407
505
  get: (value) => {
408
- return value ? JSON.parse(value) : value;
506
+ if (value && typeof value === "string") {
507
+ try {
508
+ if (value.startsWith("{") || value.startsWith("[")) {
509
+ return JSON.parse(value);
510
+ }
511
+ } catch {
512
+ return value;
513
+ }
514
+ }
515
+ return value;
409
516
  }
410
517
  },
411
- status: {
518
+ output: {
519
+ type: "string",
520
+ required: true,
521
+ set: (value) => {
522
+ if (value && typeof value !== "string") {
523
+ return JSON.stringify(value);
524
+ }
525
+ return value;
526
+ },
527
+ get: (value) => {
528
+ if (value && typeof value === "string") {
529
+ try {
530
+ if (value.startsWith("{") || value.startsWith("[")) {
531
+ return JSON.parse(value);
532
+ }
533
+ } catch {
534
+ return value;
535
+ }
536
+ }
537
+ return value;
538
+ }
539
+ },
540
+ additionalContext: {
412
541
  type: "string",
413
- // JSON stringified
414
542
  required: false,
415
- // Stringify object on set
416
543
  set: (value) => {
417
544
  if (value && typeof value !== "string") {
418
545
  return JSON.stringify(value);
419
546
  }
420
547
  return value;
421
548
  },
422
- // Parse JSON string to object on get
423
549
  get: (value) => {
550
+ if (value && typeof value === "string") {
551
+ try {
552
+ if (value.startsWith("{") || value.startsWith("[")) {
553
+ return JSON.parse(value);
554
+ }
555
+ } catch {
556
+ return value;
557
+ }
558
+ }
424
559
  return value;
425
560
  }
426
561
  },
427
- events: {
562
+ runtimeContext: {
428
563
  type: "string",
429
- // JSON stringified
430
564
  required: false,
431
- // Stringify object on set
432
565
  set: (value) => {
433
566
  if (value && typeof value !== "string") {
434
567
  return JSON.stringify(value);
435
568
  }
436
569
  return value;
437
570
  },
438
- // Parse JSON string to object on get
439
571
  get: (value) => {
572
+ if (value && typeof value === "string") {
573
+ try {
574
+ if (value.startsWith("{") || value.startsWith("[")) {
575
+ return JSON.parse(value);
576
+ }
577
+ } catch {
578
+ return value;
579
+ }
580
+ }
440
581
  return value;
441
582
  }
442
583
  },
443
- links: {
584
+ entityType: {
585
+ type: "string",
586
+ required: false
587
+ },
588
+ entityData: {
444
589
  type: "string",
445
- // JSON stringified
446
590
  required: false,
447
- // Stringify object on set
448
591
  set: (value) => {
449
592
  if (value && typeof value !== "string") {
450
593
  return JSON.stringify(value);
451
594
  }
452
595
  return value;
453
596
  },
454
- // Parse JSON string to object on get
455
597
  get: (value) => {
598
+ if (value && typeof value === "string") {
599
+ try {
600
+ if (value.startsWith("{") || value.startsWith("[")) {
601
+ return JSON.parse(value);
602
+ }
603
+ } catch {
604
+ return value;
605
+ }
606
+ }
456
607
  return value;
457
608
  }
458
609
  },
459
- other: {
610
+ entityId: {
460
611
  type: "string",
461
612
  required: false
462
613
  },
463
- startTime: {
464
- type: "number",
614
+ source: {
615
+ type: "string",
465
616
  required: true
466
617
  },
467
- endTime: {
468
- type: "number",
469
- required: true
618
+ resourceId: {
619
+ type: "string",
620
+ required: false
621
+ },
622
+ threadId: {
623
+ type: "string",
624
+ required: false
470
625
  }
471
626
  },
472
627
  indexes: {
473
628
  primary: {
474
629
  pk: { field: "pk", composite: ["entity", "id"] },
475
- sk: { field: "sk", composite: [] }
630
+ sk: { field: "sk", composite: ["entity"] }
476
631
  },
477
- byName: {
632
+ byScorer: {
478
633
  index: "gsi1",
479
- pk: { field: "gsi1pk", composite: ["entity", "name"] },
480
- sk: { field: "gsi1sk", composite: ["startTime"] }
634
+ pk: { field: "gsi1pk", composite: ["entity", "scorerId"] },
635
+ sk: { field: "gsi1sk", composite: ["createdAt"] }
481
636
  },
482
- byScope: {
637
+ byRun: {
483
638
  index: "gsi2",
484
- pk: { field: "gsi2pk", composite: ["entity", "scope"] },
485
- sk: { field: "gsi2sk", composite: ["startTime"] }
639
+ pk: { field: "gsi2pk", composite: ["entity", "runId"] },
640
+ sk: { field: "gsi2sk", composite: ["createdAt"] }
641
+ },
642
+ byTrace: {
643
+ index: "gsi3",
644
+ pk: { field: "gsi3pk", composite: ["entity", "traceId"] },
645
+ sk: { field: "gsi3sk", composite: ["createdAt"] }
646
+ },
647
+ byEntityData: {
648
+ index: "gsi4",
649
+ pk: { field: "gsi4pk", composite: ["entity", "entityId"] },
650
+ sk: { field: "gsi4sk", composite: ["createdAt"] }
651
+ },
652
+ byResource: {
653
+ index: "gsi5",
654
+ pk: { field: "gsi5pk", composite: ["entity", "resourceId"] },
655
+ sk: { field: "gsi5sk", composite: ["createdAt"] }
656
+ },
657
+ byThread: {
658
+ index: "gsi6",
659
+ pk: { field: "gsi6pk", composite: ["entity", "threadId"] },
660
+ sk: { field: "gsi6sk", composite: ["createdAt"] }
486
661
  }
487
662
  }
488
663
  });
489
- var workflowSnapshotEntity = new electrodb.Entity({
664
+ var threadEntity = new electrodb.Entity({
490
665
  model: {
491
- entity: "workflow_snapshot",
666
+ entity: "thread",
492
667
  version: "1",
493
668
  service: "mastra"
494
669
  },
@@ -498,18 +673,209 @@ var workflowSnapshotEntity = new electrodb.Entity({
498
673
  required: true
499
674
  },
500
675
  ...baseAttributes,
501
- workflow_name: {
676
+ id: {
502
677
  type: "string",
503
678
  required: true
504
679
  },
505
- run_id: {
680
+ resourceId: {
506
681
  type: "string",
507
682
  required: true
508
683
  },
509
- snapshot: {
684
+ title: {
510
685
  type: "string",
511
- // JSON stringified
512
- required: true,
686
+ required: true
687
+ },
688
+ metadata: {
689
+ type: "string",
690
+ required: false,
691
+ // Stringify metadata object on set if it's not already a string
692
+ set: (value) => {
693
+ if (value && typeof value !== "string") {
694
+ return JSON.stringify(value);
695
+ }
696
+ return value;
697
+ },
698
+ // Parse JSON string to object on get
699
+ get: (value) => {
700
+ if (value && typeof value === "string") {
701
+ try {
702
+ if (value.startsWith("{") || value.startsWith("[")) {
703
+ return JSON.parse(value);
704
+ }
705
+ } catch {
706
+ return value;
707
+ }
708
+ }
709
+ return value;
710
+ }
711
+ }
712
+ },
713
+ indexes: {
714
+ primary: {
715
+ pk: { field: "pk", composite: ["entity", "id"] },
716
+ sk: { field: "sk", composite: ["id"] }
717
+ },
718
+ byResource: {
719
+ index: "gsi1",
720
+ pk: { field: "gsi1pk", composite: ["entity", "resourceId"] },
721
+ sk: { field: "gsi1sk", composite: ["createdAt"] }
722
+ }
723
+ }
724
+ });
725
+ var traceEntity = new electrodb.Entity({
726
+ model: {
727
+ entity: "trace",
728
+ version: "1",
729
+ service: "mastra"
730
+ },
731
+ attributes: {
732
+ entity: {
733
+ type: "string",
734
+ required: true
735
+ },
736
+ ...baseAttributes,
737
+ id: {
738
+ type: "string",
739
+ required: true
740
+ },
741
+ parentSpanId: {
742
+ type: "string",
743
+ required: false
744
+ },
745
+ name: {
746
+ type: "string",
747
+ required: true
748
+ },
749
+ traceId: {
750
+ type: "string",
751
+ required: true
752
+ },
753
+ scope: {
754
+ type: "string",
755
+ required: true
756
+ },
757
+ kind: {
758
+ type: "number",
759
+ required: true
760
+ },
761
+ attributes: {
762
+ type: "string",
763
+ // JSON stringified
764
+ required: false,
765
+ // Stringify object on set
766
+ set: (value) => {
767
+ if (value && typeof value !== "string") {
768
+ return JSON.stringify(value);
769
+ }
770
+ return value;
771
+ },
772
+ // Parse JSON string to object on get
773
+ get: (value) => {
774
+ return value ? JSON.parse(value) : value;
775
+ }
776
+ },
777
+ status: {
778
+ type: "string",
779
+ // JSON stringified
780
+ required: false,
781
+ // Stringify object on set
782
+ set: (value) => {
783
+ if (value && typeof value !== "string") {
784
+ return JSON.stringify(value);
785
+ }
786
+ return value;
787
+ },
788
+ // Parse JSON string to object on get
789
+ get: (value) => {
790
+ return value;
791
+ }
792
+ },
793
+ events: {
794
+ type: "string",
795
+ // JSON stringified
796
+ required: false,
797
+ // Stringify object on set
798
+ set: (value) => {
799
+ if (value && typeof value !== "string") {
800
+ return JSON.stringify(value);
801
+ }
802
+ return value;
803
+ },
804
+ // Parse JSON string to object on get
805
+ get: (value) => {
806
+ return value;
807
+ }
808
+ },
809
+ links: {
810
+ type: "string",
811
+ // JSON stringified
812
+ required: false,
813
+ // Stringify object on set
814
+ set: (value) => {
815
+ if (value && typeof value !== "string") {
816
+ return JSON.stringify(value);
817
+ }
818
+ return value;
819
+ },
820
+ // Parse JSON string to object on get
821
+ get: (value) => {
822
+ return value;
823
+ }
824
+ },
825
+ other: {
826
+ type: "string",
827
+ required: false
828
+ },
829
+ startTime: {
830
+ type: "number",
831
+ required: true
832
+ },
833
+ endTime: {
834
+ type: "number",
835
+ required: true
836
+ }
837
+ },
838
+ indexes: {
839
+ primary: {
840
+ pk: { field: "pk", composite: ["entity", "id"] },
841
+ sk: { field: "sk", composite: [] }
842
+ },
843
+ byName: {
844
+ index: "gsi1",
845
+ pk: { field: "gsi1pk", composite: ["entity", "name"] },
846
+ sk: { field: "gsi1sk", composite: ["startTime"] }
847
+ },
848
+ byScope: {
849
+ index: "gsi2",
850
+ pk: { field: "gsi2pk", composite: ["entity", "scope"] },
851
+ sk: { field: "gsi2sk", composite: ["startTime"] }
852
+ }
853
+ }
854
+ });
855
+ var workflowSnapshotEntity = new electrodb.Entity({
856
+ model: {
857
+ entity: "workflow_snapshot",
858
+ version: "1",
859
+ service: "mastra"
860
+ },
861
+ attributes: {
862
+ entity: {
863
+ type: "string",
864
+ required: true
865
+ },
866
+ ...baseAttributes,
867
+ workflow_name: {
868
+ type: "string",
869
+ required: true
870
+ },
871
+ run_id: {
872
+ type: "string",
873
+ required: true
874
+ },
875
+ snapshot: {
876
+ type: "string",
877
+ // JSON stringified
878
+ required: true,
513
879
  // Stringify snapshot object on set
514
880
  set: (value) => {
515
881
  if (value && typeof value !== "string") {
@@ -549,7 +915,9 @@ function getElectroDbService(client, tableName) {
549
915
  message: messageEntity,
550
916
  eval: evalEntity,
551
917
  trace: traceEntity,
552
- workflowSnapshot: workflowSnapshotEntity
918
+ workflow_snapshot: workflowSnapshotEntity,
919
+ resource: resourceEntity,
920
+ score: scoreEntity
553
921
  },
554
922
  {
555
923
  client,
@@ -557,28 +925,1002 @@ function getElectroDbService(client, tableName) {
557
925
  }
558
926
  );
559
927
  }
560
-
561
- // src/storage/index.ts
562
- var DynamoDBStore = class extends storage.MastraStorage {
563
- constructor({ name, config }) {
564
- super({ name });
565
- this.hasInitialized = null;
566
- if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
567
- throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
928
+ var LegacyEvalsDynamoDB = class extends storage.LegacyEvalsStorage {
929
+ service;
930
+ tableName;
931
+ constructor({ service, tableName }) {
932
+ super();
933
+ this.service = service;
934
+ this.tableName = tableName;
935
+ }
936
+ // Eval operations
937
+ async getEvalsByAgentName(agentName, type) {
938
+ this.logger.debug("Getting evals for agent", { agentName, type });
939
+ try {
940
+ const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
941
+ const results = await query.go({ order: "desc", limit: 100 });
942
+ if (!results.data.length) {
943
+ return [];
944
+ }
945
+ let filteredData = results.data;
946
+ if (type) {
947
+ filteredData = filteredData.filter((evalRecord) => {
948
+ try {
949
+ const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
950
+ if (type === "test" && !testInfo) {
951
+ return false;
952
+ }
953
+ if (type === "live" && testInfo) {
954
+ return false;
955
+ }
956
+ } catch (e) {
957
+ this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
958
+ }
959
+ return true;
960
+ });
961
+ }
962
+ return filteredData.map((evalRecord) => {
963
+ try {
964
+ return {
965
+ input: evalRecord.input,
966
+ output: evalRecord.output,
967
+ // Safely parse result and test_info
968
+ result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
969
+ agentName: evalRecord.agent_name,
970
+ createdAt: evalRecord.created_at,
971
+ // Keep as string from DDB?
972
+ metricName: evalRecord.metric_name,
973
+ instructions: evalRecord.instructions,
974
+ runId: evalRecord.run_id,
975
+ globalRunId: evalRecord.global_run_id,
976
+ testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
977
+ };
978
+ } catch (parseError) {
979
+ this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
980
+ return {
981
+ agentName: evalRecord.agent_name,
982
+ createdAt: evalRecord.created_at,
983
+ runId: evalRecord.run_id,
984
+ globalRunId: evalRecord.global_run_id
985
+ };
986
+ }
987
+ });
988
+ } catch (error$1) {
989
+ throw new error.MastraError(
990
+ {
991
+ id: "STORAGE_DYNAMODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
992
+ domain: error.ErrorDomain.STORAGE,
993
+ category: error.ErrorCategory.THIRD_PARTY,
994
+ details: { agentName }
995
+ },
996
+ error$1
997
+ );
568
998
  }
569
- if (!/^[a-zA-Z0-9_.-]{3,255}$/.test(config.tableName)) {
570
- throw new Error(
571
- `DynamoDBStore: config.tableName "${config.tableName}" contains invalid characters or is not between 3 and 255 characters long.`
999
+ }
1000
+ async getEvals(options = {}) {
1001
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
1002
+ this.logger.debug("Getting evals with pagination", { agentName, type, page, perPage, dateRange });
1003
+ try {
1004
+ let query;
1005
+ if (agentName) {
1006
+ query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
1007
+ } else {
1008
+ query = this.service.entities.eval.query.byEntity({ entity: "eval" });
1009
+ }
1010
+ const results = await query.go({
1011
+ order: "desc",
1012
+ pages: "all"
1013
+ // Get all pages to apply filtering and pagination
1014
+ });
1015
+ if (!results.data.length) {
1016
+ return {
1017
+ evals: [],
1018
+ total: 0,
1019
+ page,
1020
+ perPage,
1021
+ hasMore: false
1022
+ };
1023
+ }
1024
+ let filteredData = results.data;
1025
+ if (type) {
1026
+ filteredData = filteredData.filter((evalRecord) => {
1027
+ try {
1028
+ const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
1029
+ if (type === "test" && !testInfo) {
1030
+ return false;
1031
+ }
1032
+ if (type === "live" && testInfo) {
1033
+ return false;
1034
+ }
1035
+ } catch (e) {
1036
+ this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
1037
+ }
1038
+ return true;
1039
+ });
1040
+ }
1041
+ if (dateRange) {
1042
+ const fromDate = dateRange.start;
1043
+ const toDate = dateRange.end;
1044
+ filteredData = filteredData.filter((evalRecord) => {
1045
+ const recordDate = new Date(evalRecord.created_at);
1046
+ if (fromDate && recordDate < fromDate) {
1047
+ return false;
1048
+ }
1049
+ if (toDate && recordDate > toDate) {
1050
+ return false;
1051
+ }
1052
+ return true;
1053
+ });
1054
+ }
1055
+ const total = filteredData.length;
1056
+ const start = page * perPage;
1057
+ const end = start + perPage;
1058
+ const paginatedData = filteredData.slice(start, end);
1059
+ const evals = paginatedData.map((evalRecord) => {
1060
+ try {
1061
+ return {
1062
+ input: evalRecord.input,
1063
+ output: evalRecord.output,
1064
+ result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
1065
+ agentName: evalRecord.agent_name,
1066
+ createdAt: evalRecord.created_at,
1067
+ metricName: evalRecord.metric_name,
1068
+ instructions: evalRecord.instructions,
1069
+ runId: evalRecord.run_id,
1070
+ globalRunId: evalRecord.global_run_id,
1071
+ testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
1072
+ };
1073
+ } catch (parseError) {
1074
+ this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
1075
+ return {
1076
+ agentName: evalRecord.agent_name,
1077
+ createdAt: evalRecord.created_at,
1078
+ runId: evalRecord.run_id,
1079
+ globalRunId: evalRecord.global_run_id
1080
+ };
1081
+ }
1082
+ });
1083
+ const hasMore = end < total;
1084
+ return {
1085
+ evals,
1086
+ total,
1087
+ page,
1088
+ perPage,
1089
+ hasMore
1090
+ };
1091
+ } catch (error$1) {
1092
+ throw new error.MastraError(
1093
+ {
1094
+ id: "STORAGE_DYNAMODB_STORE_GET_EVALS_FAILED",
1095
+ domain: error.ErrorDomain.STORAGE,
1096
+ category: error.ErrorCategory.THIRD_PARTY,
1097
+ details: {
1098
+ agentName: agentName || "all",
1099
+ type: type || "all",
1100
+ page,
1101
+ perPage
1102
+ }
1103
+ },
1104
+ error$1
1105
+ );
1106
+ }
1107
+ }
1108
+ };
1109
+ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1110
+ service;
1111
+ constructor({ service }) {
1112
+ super();
1113
+ this.service = service;
1114
+ }
1115
+ // Helper function to parse message data (handle JSON fields)
1116
+ parseMessageData(data) {
1117
+ return {
1118
+ ...data,
1119
+ // Ensure dates are Date objects if needed (ElectroDB might return strings)
1120
+ createdAt: data.createdAt ? new Date(data.createdAt) : void 0,
1121
+ updatedAt: data.updatedAt ? new Date(data.updatedAt) : void 0
1122
+ // Other fields like content, toolCallArgs etc. are assumed to be correctly
1123
+ // transformed by the ElectroDB entity getters.
1124
+ };
1125
+ }
1126
+ // Helper function to transform and sort threads
1127
+ transformAndSortThreads(rawThreads, orderBy, sortDirection) {
1128
+ return rawThreads.map((data) => ({
1129
+ ...data,
1130
+ // Convert date strings back to Date objects for consistency
1131
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
1132
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
1133
+ })).sort((a, b) => {
1134
+ const fieldA = orderBy === "createdAt" ? a.createdAt : a.updatedAt;
1135
+ const fieldB = orderBy === "createdAt" ? b.createdAt : b.updatedAt;
1136
+ const comparison = fieldA.getTime() - fieldB.getTime();
1137
+ return sortDirection === "DESC" ? -comparison : comparison;
1138
+ });
1139
+ }
1140
+ async getThreadById({ threadId }) {
1141
+ this.logger.debug("Getting thread by ID", { threadId });
1142
+ try {
1143
+ const result = await this.service.entities.thread.get({ entity: "thread", id: threadId }).go();
1144
+ if (!result.data) {
1145
+ return null;
1146
+ }
1147
+ const data = result.data;
1148
+ return {
1149
+ ...data,
1150
+ // Convert date strings back to Date objects for consistency
1151
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
1152
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
1153
+ // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
1154
+ // metadata is already transformed by the entity's getter
1155
+ };
1156
+ } catch (error$1) {
1157
+ throw new error.MastraError(
1158
+ {
1159
+ id: "STORAGE_DYNAMODB_STORE_GET_THREAD_BY_ID_FAILED",
1160
+ domain: error.ErrorDomain.STORAGE,
1161
+ category: error.ErrorCategory.THIRD_PARTY,
1162
+ details: { threadId }
1163
+ },
1164
+ error$1
1165
+ );
1166
+ }
1167
+ }
1168
+ /**
1169
+ * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
1170
+ */
1171
+ async getThreadsByResourceId(args) {
1172
+ const resourceId = args.resourceId;
1173
+ const orderBy = this.castThreadOrderBy(args.orderBy);
1174
+ const sortDirection = this.castThreadSortDirection(args.sortDirection);
1175
+ this.logger.debug("Getting threads by resource ID", { resourceId, orderBy, sortDirection });
1176
+ try {
1177
+ const result = await this.service.entities.thread.query.byResource({ entity: "thread", resourceId }).go();
1178
+ if (!result.data.length) {
1179
+ return [];
1180
+ }
1181
+ return this.transformAndSortThreads(result.data, orderBy, sortDirection);
1182
+ } catch (error$1) {
1183
+ throw new error.MastraError(
1184
+ {
1185
+ id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1186
+ domain: error.ErrorDomain.STORAGE,
1187
+ category: error.ErrorCategory.THIRD_PARTY,
1188
+ details: { resourceId }
1189
+ },
1190
+ error$1
1191
+ );
1192
+ }
1193
+ }
1194
+ async saveThread({ thread }) {
1195
+ this.logger.debug("Saving thread", { threadId: thread.id });
1196
+ const now = /* @__PURE__ */ new Date();
1197
+ const threadData = {
1198
+ entity: "thread",
1199
+ id: thread.id,
1200
+ resourceId: thread.resourceId,
1201
+ title: thread.title || `Thread ${thread.id}`,
1202
+ createdAt: thread.createdAt?.toISOString() || now.toISOString(),
1203
+ updatedAt: thread.updatedAt?.toISOString() || now.toISOString(),
1204
+ metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
1205
+ };
1206
+ try {
1207
+ await this.service.entities.thread.upsert(threadData).go();
1208
+ return {
1209
+ id: thread.id,
1210
+ resourceId: thread.resourceId,
1211
+ title: threadData.title,
1212
+ createdAt: thread.createdAt || now,
1213
+ updatedAt: now,
1214
+ metadata: thread.metadata
1215
+ };
1216
+ } catch (error$1) {
1217
+ throw new error.MastraError(
1218
+ {
1219
+ id: "STORAGE_DYNAMODB_STORE_SAVE_THREAD_FAILED",
1220
+ domain: error.ErrorDomain.STORAGE,
1221
+ category: error.ErrorCategory.THIRD_PARTY,
1222
+ details: { threadId: thread.id }
1223
+ },
1224
+ error$1
1225
+ );
1226
+ }
1227
+ }
1228
+ async updateThread({
1229
+ id,
1230
+ title,
1231
+ metadata
1232
+ }) {
1233
+ this.logger.debug("Updating thread", { threadId: id });
1234
+ try {
1235
+ const existingThread = await this.getThreadById({ threadId: id });
1236
+ if (!existingThread) {
1237
+ throw new Error(`Thread not found: ${id}`);
1238
+ }
1239
+ const now = /* @__PURE__ */ new Date();
1240
+ const updateData = {
1241
+ updatedAt: now.toISOString()
1242
+ };
1243
+ if (title) {
1244
+ updateData.title = title;
1245
+ }
1246
+ if (metadata) {
1247
+ const existingMetadata = existingThread.metadata ? typeof existingThread.metadata === "string" ? JSON.parse(existingThread.metadata) : existingThread.metadata : {};
1248
+ const mergedMetadata = { ...existingMetadata, ...metadata };
1249
+ updateData.metadata = JSON.stringify(mergedMetadata);
1250
+ }
1251
+ await this.service.entities.thread.update({ entity: "thread", id }).set(updateData).go();
1252
+ return {
1253
+ ...existingThread,
1254
+ title: title || existingThread.title,
1255
+ metadata: metadata ? { ...existingThread.metadata, ...metadata } : existingThread.metadata,
1256
+ updatedAt: now
1257
+ };
1258
+ } catch (error$1) {
1259
+ throw new error.MastraError(
1260
+ {
1261
+ id: "STORAGE_DYNAMODB_STORE_UPDATE_THREAD_FAILED",
1262
+ domain: error.ErrorDomain.STORAGE,
1263
+ category: error.ErrorCategory.THIRD_PARTY,
1264
+ details: { threadId: id }
1265
+ },
1266
+ error$1
1267
+ );
1268
+ }
1269
+ }
1270
+ async deleteThread({ threadId }) {
1271
+ this.logger.debug("Deleting thread", { threadId });
1272
+ try {
1273
+ const messages = await this.getMessages({ threadId });
1274
+ if (messages.length > 0) {
1275
+ const batchSize = 25;
1276
+ for (let i = 0; i < messages.length; i += batchSize) {
1277
+ const batch = messages.slice(i, i + batchSize);
1278
+ await Promise.all(
1279
+ batch.map(
1280
+ (message) => this.service.entities.message.delete({
1281
+ entity: "message",
1282
+ id: message.id,
1283
+ threadId: message.threadId
1284
+ }).go()
1285
+ )
1286
+ );
1287
+ }
1288
+ }
1289
+ await this.service.entities.thread.delete({ entity: "thread", id: threadId }).go();
1290
+ } catch (error$1) {
1291
+ throw new error.MastraError(
1292
+ {
1293
+ id: "STORAGE_DYNAMODB_STORE_DELETE_THREAD_FAILED",
1294
+ domain: error.ErrorDomain.STORAGE,
1295
+ category: error.ErrorCategory.THIRD_PARTY,
1296
+ details: { threadId }
1297
+ },
1298
+ error$1
1299
+ );
1300
+ }
1301
+ }
1302
+ async getMessages({
1303
+ threadId,
1304
+ resourceId,
1305
+ selectBy,
1306
+ format
1307
+ }) {
1308
+ this.logger.debug("Getting messages", { threadId, selectBy });
1309
+ try {
1310
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1311
+ const messages = [];
1312
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1313
+ if (selectBy?.include?.length) {
1314
+ const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1315
+ if (includeMessages) {
1316
+ messages.push(...includeMessages);
1317
+ }
1318
+ }
1319
+ if (limit !== 0) {
1320
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1321
+ let results;
1322
+ if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1323
+ results = await query.go({ limit, order: "desc" });
1324
+ results.data = results.data.reverse();
1325
+ } else {
1326
+ results = await query.go();
1327
+ }
1328
+ let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1329
+ allThreadMessages.sort((a, b) => {
1330
+ const timeA = a.createdAt.getTime();
1331
+ const timeB = b.createdAt.getTime();
1332
+ if (timeA === timeB) {
1333
+ return a.id.localeCompare(b.id);
1334
+ }
1335
+ return timeA - timeB;
1336
+ });
1337
+ messages.push(...allThreadMessages);
1338
+ }
1339
+ messages.sort((a, b) => {
1340
+ const timeA = a.createdAt.getTime();
1341
+ const timeB = b.createdAt.getTime();
1342
+ if (timeA === timeB) {
1343
+ return a.id.localeCompare(b.id);
1344
+ }
1345
+ return timeA - timeB;
1346
+ });
1347
+ const uniqueMessages = messages.filter(
1348
+ (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1349
+ );
1350
+ const list = new agent.MessageList({ threadId, resourceId }).add(uniqueMessages, "memory");
1351
+ if (format === `v2`) return list.get.all.v2();
1352
+ return list.get.all.v1();
1353
+ } catch (error$1) {
1354
+ throw new error.MastraError(
1355
+ {
1356
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_FAILED",
1357
+ domain: error.ErrorDomain.STORAGE,
1358
+ category: error.ErrorCategory.THIRD_PARTY,
1359
+ details: { threadId, resourceId: resourceId ?? "" }
1360
+ },
1361
+ error$1
1362
+ );
1363
+ }
1364
+ }
1365
+ async getMessagesById({
1366
+ messageIds,
1367
+ format
1368
+ }) {
1369
+ this.logger.debug("Getting messages by ID", { messageIds });
1370
+ if (messageIds.length === 0) return [];
1371
+ try {
1372
+ const results = await Promise.all(
1373
+ messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
1374
+ );
1375
+ const data = results.map((result) => result.data).flat(1);
1376
+ let parsedMessages = data.map((data2) => this.parseMessageData(data2)).filter((msg) => "content" in msg);
1377
+ const uniqueMessages = parsedMessages.filter(
1378
+ (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1379
+ );
1380
+ const list = new agent.MessageList().add(uniqueMessages, "memory");
1381
+ if (format === `v1`) return list.get.all.v1();
1382
+ return list.get.all.v2();
1383
+ } catch (error$1) {
1384
+ throw new error.MastraError(
1385
+ {
1386
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_BY_ID_FAILED",
1387
+ domain: error.ErrorDomain.STORAGE,
1388
+ category: error.ErrorCategory.THIRD_PARTY,
1389
+ details: { messageIds: JSON.stringify(messageIds) }
1390
+ },
1391
+ error$1
1392
+ );
1393
+ }
1394
+ }
1395
+ async saveMessages(args) {
1396
+ const { messages, format = "v1" } = args;
1397
+ this.logger.debug("Saving messages", { count: messages.length });
1398
+ if (!messages.length) {
1399
+ return [];
1400
+ }
1401
+ const threadId = messages[0]?.threadId;
1402
+ if (!threadId) {
1403
+ throw new Error("Thread ID is required");
1404
+ }
1405
+ const messagesToSave = messages.map((msg) => {
1406
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1407
+ return {
1408
+ entity: "message",
1409
+ // Add entity type
1410
+ id: msg.id,
1411
+ threadId: msg.threadId,
1412
+ role: msg.role,
1413
+ type: msg.type,
1414
+ resourceId: msg.resourceId,
1415
+ // Ensure complex fields are stringified if not handled by attribute setters
1416
+ content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content),
1417
+ toolCallArgs: `toolCallArgs` in msg && msg.toolCallArgs ? JSON.stringify(msg.toolCallArgs) : void 0,
1418
+ toolCallIds: `toolCallIds` in msg && msg.toolCallIds ? JSON.stringify(msg.toolCallIds) : void 0,
1419
+ toolNames: `toolNames` in msg && msg.toolNames ? JSON.stringify(msg.toolNames) : void 0,
1420
+ createdAt: msg.createdAt instanceof Date ? msg.createdAt.toISOString() : msg.createdAt || now,
1421
+ updatedAt: now
1422
+ // Add updatedAt
1423
+ };
1424
+ });
1425
+ try {
1426
+ const savedMessageIds = [];
1427
+ for (const messageData of messagesToSave) {
1428
+ if (!messageData.entity) {
1429
+ this.logger.error("Missing entity property in message data for create", { messageData });
1430
+ throw new Error("Internal error: Missing entity property during saveMessages");
1431
+ }
1432
+ try {
1433
+ await this.service.entities.message.put(messageData).go();
1434
+ savedMessageIds.push(messageData.id);
1435
+ } catch (error) {
1436
+ for (const savedId of savedMessageIds) {
1437
+ try {
1438
+ await this.service.entities.message.delete({ entity: "message", id: savedId }).go();
1439
+ } catch (rollbackError) {
1440
+ this.logger.error("Failed to rollback message during save error", {
1441
+ messageId: savedId,
1442
+ error: rollbackError
1443
+ });
1444
+ }
1445
+ }
1446
+ throw error;
1447
+ }
1448
+ }
1449
+ await this.service.entities.thread.update({ entity: "thread", id: threadId }).set({
1450
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1451
+ }).go();
1452
+ const list = new agent.MessageList().add(messages, "memory");
1453
+ if (format === `v1`) return list.get.all.v1();
1454
+ return list.get.all.v2();
1455
+ } catch (error$1) {
1456
+ throw new error.MastraError(
1457
+ {
1458
+ id: "STORAGE_DYNAMODB_STORE_SAVE_MESSAGES_FAILED",
1459
+ domain: error.ErrorDomain.STORAGE,
1460
+ category: error.ErrorCategory.THIRD_PARTY,
1461
+ details: { count: messages.length }
1462
+ },
1463
+ error$1
1464
+ );
1465
+ }
1466
+ }
1467
+ async getThreadsByResourceIdPaginated(args) {
1468
+ const { resourceId, page = 0, perPage = 100 } = args;
1469
+ const orderBy = this.castThreadOrderBy(args.orderBy);
1470
+ const sortDirection = this.castThreadSortDirection(args.sortDirection);
1471
+ this.logger.debug("Getting threads by resource ID with pagination", {
1472
+ resourceId,
1473
+ page,
1474
+ perPage,
1475
+ orderBy,
1476
+ sortDirection
1477
+ });
1478
+ try {
1479
+ const query = this.service.entities.thread.query.byResource({ entity: "thread", resourceId });
1480
+ const results = await query.go();
1481
+ const allThreads = this.transformAndSortThreads(results.data, orderBy, sortDirection);
1482
+ const startIndex = page * perPage;
1483
+ const endIndex = startIndex + perPage;
1484
+ const paginatedThreads = allThreads.slice(startIndex, endIndex);
1485
+ const total = allThreads.length;
1486
+ const hasMore = endIndex < total;
1487
+ return {
1488
+ threads: paginatedThreads,
1489
+ total,
1490
+ page,
1491
+ perPage,
1492
+ hasMore
1493
+ };
1494
+ } catch (error$1) {
1495
+ throw new error.MastraError(
1496
+ {
1497
+ id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1498
+ domain: error.ErrorDomain.STORAGE,
1499
+ category: error.ErrorCategory.THIRD_PARTY,
1500
+ details: { resourceId, page, perPage }
1501
+ },
1502
+ error$1
1503
+ );
1504
+ }
1505
+ }
1506
+ async getMessagesPaginated(args) {
1507
+ const { threadId, resourceId, selectBy, format = "v1" } = args;
1508
+ const { page = 0, perPage = 40, dateRange } = selectBy?.pagination || {};
1509
+ const fromDate = dateRange?.start;
1510
+ const toDate = dateRange?.end;
1511
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1512
+ this.logger.debug("Getting messages with pagination", { threadId, page, perPage, fromDate, toDate, limit });
1513
+ try {
1514
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1515
+ let messages = [];
1516
+ if (selectBy?.include?.length) {
1517
+ const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1518
+ if (includeMessages) {
1519
+ messages.push(...includeMessages);
1520
+ }
1521
+ }
1522
+ if (limit !== 0) {
1523
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1524
+ let results;
1525
+ if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1526
+ results = await query.go({ limit, order: "desc" });
1527
+ results.data = results.data.reverse();
1528
+ } else {
1529
+ results = await query.go();
1530
+ }
1531
+ let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1532
+ allThreadMessages.sort((a, b) => {
1533
+ const timeA = a.createdAt.getTime();
1534
+ const timeB = b.createdAt.getTime();
1535
+ if (timeA === timeB) {
1536
+ return a.id.localeCompare(b.id);
1537
+ }
1538
+ return timeA - timeB;
1539
+ });
1540
+ const excludeIds = messages.map((m) => m.id);
1541
+ if (excludeIds.length > 0) {
1542
+ allThreadMessages = allThreadMessages.filter((msg) => !excludeIds.includes(msg.id));
1543
+ }
1544
+ messages.push(...allThreadMessages);
1545
+ }
1546
+ messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1547
+ if (fromDate || toDate) {
1548
+ messages = messages.filter((msg) => {
1549
+ const createdAt = new Date(msg.createdAt).getTime();
1550
+ if (fromDate && createdAt < new Date(fromDate).getTime()) return false;
1551
+ if (toDate && createdAt > new Date(toDate).getTime()) return false;
1552
+ return true;
1553
+ });
1554
+ }
1555
+ const total = messages.length;
1556
+ const start = page * perPage;
1557
+ const end = start + perPage;
1558
+ const paginatedMessages = messages.slice(start, end);
1559
+ const hasMore = end < total;
1560
+ const list = new agent.MessageList({ threadId, resourceId }).add(paginatedMessages, "memory");
1561
+ const finalMessages = format === "v2" ? list.get.all.v2() : list.get.all.v1();
1562
+ return {
1563
+ messages: finalMessages,
1564
+ total,
1565
+ page,
1566
+ perPage,
1567
+ hasMore
1568
+ };
1569
+ } catch (error$1) {
1570
+ const mastraError = new error.MastraError(
1571
+ {
1572
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
1573
+ domain: error.ErrorDomain.STORAGE,
1574
+ category: error.ErrorCategory.THIRD_PARTY,
1575
+ details: { threadId, resourceId: resourceId ?? "" }
1576
+ },
1577
+ error$1
1578
+ );
1579
+ this.logger?.trackException?.(mastraError);
1580
+ this.logger?.error?.(mastraError.toString());
1581
+ return { messages: [], total: 0, page, perPage, hasMore: false };
1582
+ }
1583
+ }
1584
+ // Helper method to get included messages with context
1585
+ async _getIncludedMessages(threadId, selectBy) {
1586
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1587
+ if (!selectBy?.include?.length) {
1588
+ return [];
1589
+ }
1590
+ const includeMessages = [];
1591
+ for (const includeItem of selectBy.include) {
1592
+ try {
1593
+ const { id, threadId: targetThreadId, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1594
+ const searchThreadId = targetThreadId || threadId;
1595
+ this.logger.debug("Getting included messages for", {
1596
+ id,
1597
+ targetThreadId,
1598
+ searchThreadId,
1599
+ withPreviousMessages,
1600
+ withNextMessages
1601
+ });
1602
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId: searchThreadId });
1603
+ const results = await query.go();
1604
+ const allMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
1605
+ this.logger.debug("Found messages in thread", {
1606
+ threadId: searchThreadId,
1607
+ messageCount: allMessages.length,
1608
+ messageIds: allMessages.map((m) => m.id)
1609
+ });
1610
+ allMessages.sort((a, b) => {
1611
+ const timeA = a.createdAt.getTime();
1612
+ const timeB = b.createdAt.getTime();
1613
+ if (timeA === timeB) {
1614
+ return a.id.localeCompare(b.id);
1615
+ }
1616
+ return timeA - timeB;
1617
+ });
1618
+ const targetIndex = allMessages.findIndex((msg) => msg.id === id);
1619
+ if (targetIndex === -1) {
1620
+ this.logger.warn("Target message not found", { id, threadId: searchThreadId });
1621
+ continue;
1622
+ }
1623
+ this.logger.debug("Found target message at index", { id, targetIndex, totalMessages: allMessages.length });
1624
+ const startIndex = Math.max(0, targetIndex - withPreviousMessages);
1625
+ const endIndex = Math.min(allMessages.length, targetIndex + withNextMessages + 1);
1626
+ const contextMessages = allMessages.slice(startIndex, endIndex);
1627
+ this.logger.debug("Context messages", {
1628
+ startIndex,
1629
+ endIndex,
1630
+ contextCount: contextMessages.length,
1631
+ contextIds: contextMessages.map((m) => m.id)
1632
+ });
1633
+ includeMessages.push(...contextMessages);
1634
+ } catch (error) {
1635
+ this.logger.warn("Failed to get included message", { messageId: includeItem.id, error });
1636
+ }
1637
+ }
1638
+ this.logger.debug("Total included messages", {
1639
+ count: includeMessages.length,
1640
+ ids: includeMessages.map((m) => m.id)
1641
+ });
1642
+ return includeMessages;
1643
+ }
1644
+ async updateMessages(args) {
1645
+ const { messages } = args;
1646
+ this.logger.debug("Updating messages", { count: messages.length });
1647
+ if (!messages.length) {
1648
+ return [];
1649
+ }
1650
+ const updatedMessages = [];
1651
+ const affectedThreadIds = /* @__PURE__ */ new Set();
1652
+ try {
1653
+ for (const updateData of messages) {
1654
+ const { id, ...updates } = updateData;
1655
+ const existingMessage = await this.service.entities.message.get({ entity: "message", id }).go();
1656
+ if (!existingMessage.data) {
1657
+ this.logger.warn("Message not found for update", { id });
1658
+ continue;
1659
+ }
1660
+ const existingMsg = this.parseMessageData(existingMessage.data);
1661
+ const originalThreadId = existingMsg.threadId;
1662
+ affectedThreadIds.add(originalThreadId);
1663
+ const updatePayload = {
1664
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1665
+ };
1666
+ if ("role" in updates && updates.role !== void 0) updatePayload.role = updates.role;
1667
+ if ("type" in updates && updates.type !== void 0) updatePayload.type = updates.type;
1668
+ if ("resourceId" in updates && updates.resourceId !== void 0) updatePayload.resourceId = updates.resourceId;
1669
+ if ("threadId" in updates && updates.threadId !== void 0 && updates.threadId !== null) {
1670
+ updatePayload.threadId = updates.threadId;
1671
+ affectedThreadIds.add(updates.threadId);
1672
+ }
1673
+ if (updates.content) {
1674
+ const existingContent = existingMsg.content;
1675
+ let newContent = { ...existingContent };
1676
+ if (updates.content.metadata !== void 0) {
1677
+ newContent.metadata = {
1678
+ ...existingContent.metadata || {},
1679
+ ...updates.content.metadata || {}
1680
+ };
1681
+ }
1682
+ if (updates.content.content !== void 0) {
1683
+ newContent.content = updates.content.content;
1684
+ }
1685
+ if ("parts" in updates.content && updates.content.parts !== void 0) {
1686
+ newContent.parts = updates.content.parts;
1687
+ }
1688
+ updatePayload.content = JSON.stringify(newContent);
1689
+ }
1690
+ await this.service.entities.message.update({ entity: "message", id }).set(updatePayload).go();
1691
+ const updatedMessage = await this.service.entities.message.get({ entity: "message", id }).go();
1692
+ if (updatedMessage.data) {
1693
+ updatedMessages.push(this.parseMessageData(updatedMessage.data));
1694
+ }
1695
+ }
1696
+ for (const threadId of affectedThreadIds) {
1697
+ await this.service.entities.thread.update({ entity: "thread", id: threadId }).set({
1698
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1699
+ }).go();
1700
+ }
1701
+ return updatedMessages;
1702
+ } catch (error$1) {
1703
+ throw new error.MastraError(
1704
+ {
1705
+ id: "STORAGE_DYNAMODB_STORE_UPDATE_MESSAGES_FAILED",
1706
+ domain: error.ErrorDomain.STORAGE,
1707
+ category: error.ErrorCategory.THIRD_PARTY,
1708
+ details: { count: messages.length }
1709
+ },
1710
+ error$1
1711
+ );
1712
+ }
1713
+ }
1714
+ async getResourceById({ resourceId }) {
1715
+ this.logger.debug("Getting resource by ID", { resourceId });
1716
+ try {
1717
+ const result = await this.service.entities.resource.get({ entity: "resource", id: resourceId }).go();
1718
+ if (!result.data) {
1719
+ return null;
1720
+ }
1721
+ const data = result.data;
1722
+ return {
1723
+ ...data,
1724
+ // Convert date strings back to Date objects for consistency
1725
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
1726
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt,
1727
+ // Ensure workingMemory is always returned as a string, regardless of automatic parsing
1728
+ workingMemory: typeof data.workingMemory === "object" ? JSON.stringify(data.workingMemory) : data.workingMemory
1729
+ // metadata is already transformed by the entity's getter
1730
+ };
1731
+ } catch (error$1) {
1732
+ throw new error.MastraError(
1733
+ {
1734
+ id: "STORAGE_DYNAMODB_STORE_GET_RESOURCE_BY_ID_FAILED",
1735
+ domain: error.ErrorDomain.STORAGE,
1736
+ category: error.ErrorCategory.THIRD_PARTY,
1737
+ details: { resourceId }
1738
+ },
1739
+ error$1
1740
+ );
1741
+ }
1742
+ }
1743
+ async saveResource({ resource }) {
1744
+ this.logger.debug("Saving resource", { resourceId: resource.id });
1745
+ const now = /* @__PURE__ */ new Date();
1746
+ const resourceData = {
1747
+ entity: "resource",
1748
+ id: resource.id,
1749
+ workingMemory: resource.workingMemory,
1750
+ metadata: resource.metadata ? JSON.stringify(resource.metadata) : void 0,
1751
+ createdAt: resource.createdAt?.toISOString() || now.toISOString(),
1752
+ updatedAt: now.toISOString()
1753
+ };
1754
+ try {
1755
+ await this.service.entities.resource.upsert(resourceData).go();
1756
+ return {
1757
+ id: resource.id,
1758
+ workingMemory: resource.workingMemory,
1759
+ metadata: resource.metadata,
1760
+ createdAt: resource.createdAt || now,
1761
+ updatedAt: now
1762
+ };
1763
+ } catch (error$1) {
1764
+ throw new error.MastraError(
1765
+ {
1766
+ id: "STORAGE_DYNAMODB_STORE_SAVE_RESOURCE_FAILED",
1767
+ domain: error.ErrorDomain.STORAGE,
1768
+ category: error.ErrorCategory.THIRD_PARTY,
1769
+ details: { resourceId: resource.id }
1770
+ },
1771
+ error$1
1772
+ );
1773
+ }
1774
+ }
1775
+ async updateResource({
1776
+ resourceId,
1777
+ workingMemory,
1778
+ metadata
1779
+ }) {
1780
+ this.logger.debug("Updating resource", { resourceId });
1781
+ try {
1782
+ const existingResource = await this.getResourceById({ resourceId });
1783
+ if (!existingResource) {
1784
+ const newResource = {
1785
+ id: resourceId,
1786
+ workingMemory,
1787
+ metadata: metadata || {},
1788
+ createdAt: /* @__PURE__ */ new Date(),
1789
+ updatedAt: /* @__PURE__ */ new Date()
1790
+ };
1791
+ return this.saveResource({ resource: newResource });
1792
+ }
1793
+ const now = /* @__PURE__ */ new Date();
1794
+ const updateData = {
1795
+ updatedAt: now.toISOString()
1796
+ };
1797
+ if (workingMemory !== void 0) {
1798
+ updateData.workingMemory = workingMemory;
1799
+ }
1800
+ if (metadata) {
1801
+ const existingMetadata = existingResource.metadata || {};
1802
+ const mergedMetadata = { ...existingMetadata, ...metadata };
1803
+ updateData.metadata = JSON.stringify(mergedMetadata);
1804
+ }
1805
+ await this.service.entities.resource.update({ entity: "resource", id: resourceId }).set(updateData).go();
1806
+ return {
1807
+ ...existingResource,
1808
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
1809
+ metadata: metadata ? { ...existingResource.metadata, ...metadata } : existingResource.metadata,
1810
+ updatedAt: now
1811
+ };
1812
+ } catch (error$1) {
1813
+ throw new error.MastraError(
1814
+ {
1815
+ id: "STORAGE_DYNAMODB_STORE_UPDATE_RESOURCE_FAILED",
1816
+ domain: error.ErrorDomain.STORAGE,
1817
+ category: error.ErrorCategory.THIRD_PARTY,
1818
+ details: { resourceId }
1819
+ },
1820
+ error$1
1821
+ );
1822
+ }
1823
+ }
1824
+ };
1825
+ var StoreOperationsDynamoDB = class extends storage.StoreOperations {
1826
+ client;
1827
+ tableName;
1828
+ service;
1829
+ constructor({
1830
+ service,
1831
+ tableName,
1832
+ client
1833
+ }) {
1834
+ super();
1835
+ this.service = service;
1836
+ this.client = client;
1837
+ this.tableName = tableName;
1838
+ }
1839
+ async hasColumn() {
1840
+ return true;
1841
+ }
1842
+ async dropTable() {
1843
+ }
1844
+ // Helper methods for entity/table mapping
1845
+ getEntityNameForTable(tableName) {
1846
+ const mapping = {
1847
+ [storage.TABLE_THREADS]: "thread",
1848
+ [storage.TABLE_MESSAGES]: "message",
1849
+ [storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
1850
+ [storage.TABLE_EVALS]: "eval",
1851
+ [storage.TABLE_SCORERS]: "score",
1852
+ [storage.TABLE_TRACES]: "trace",
1853
+ [storage.TABLE_RESOURCES]: "resource",
1854
+ [storage.TABLE_AI_SPANS]: "ai_span"
1855
+ };
1856
+ return mapping[tableName] || null;
1857
+ }
1858
+ /**
1859
+ * Pre-processes a record to ensure Date objects are converted to ISO strings
1860
+ * This is necessary because ElectroDB validation happens before setters are applied
1861
+ */
1862
+ preprocessRecord(record) {
1863
+ const processed = { ...record };
1864
+ if (processed.createdAt instanceof Date) {
1865
+ processed.createdAt = processed.createdAt.toISOString();
1866
+ }
1867
+ if (processed.updatedAt instanceof Date) {
1868
+ processed.updatedAt = processed.updatedAt.toISOString();
1869
+ }
1870
+ if (processed.created_at instanceof Date) {
1871
+ processed.created_at = processed.created_at.toISOString();
1872
+ }
1873
+ if (processed.result && typeof processed.result === "object") {
1874
+ processed.result = JSON.stringify(processed.result);
1875
+ }
1876
+ if (processed.test_info && typeof processed.test_info === "object") {
1877
+ processed.test_info = JSON.stringify(processed.test_info);
1878
+ } else if (processed.test_info === void 0 || processed.test_info === null) {
1879
+ delete processed.test_info;
1880
+ }
1881
+ if (processed.snapshot && typeof processed.snapshot === "object") {
1882
+ processed.snapshot = JSON.stringify(processed.snapshot);
1883
+ }
1884
+ if (processed.attributes && typeof processed.attributes === "object") {
1885
+ processed.attributes = JSON.stringify(processed.attributes);
1886
+ }
1887
+ if (processed.status && typeof processed.status === "object") {
1888
+ processed.status = JSON.stringify(processed.status);
1889
+ }
1890
+ if (processed.events && typeof processed.events === "object") {
1891
+ processed.events = JSON.stringify(processed.events);
1892
+ }
1893
+ if (processed.links && typeof processed.links === "object") {
1894
+ processed.links = JSON.stringify(processed.links);
1895
+ }
1896
+ return processed;
1897
+ }
1898
+ /**
1899
+ * Validates that the required DynamoDB table exists and is accessible.
1900
+ * This does not check the table structure - it assumes the table
1901
+ * was created with the correct structure via CDK/CloudFormation.
1902
+ */
1903
+ async validateTableExists() {
1904
+ try {
1905
+ const command = new clientDynamodb.DescribeTableCommand({
1906
+ TableName: this.tableName
1907
+ });
1908
+ await this.client.send(command);
1909
+ return true;
1910
+ } catch (error$1) {
1911
+ if (error$1.name === "ResourceNotFoundException") {
1912
+ return false;
1913
+ }
1914
+ throw new error.MastraError(
1915
+ {
1916
+ id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
1917
+ domain: error.ErrorDomain.STORAGE,
1918
+ category: error.ErrorCategory.THIRD_PARTY,
1919
+ details: { tableName: this.tableName }
1920
+ },
1921
+ error$1
572
1922
  );
573
1923
  }
574
- const dynamoClient = new clientDynamodb.DynamoDBClient({
575
- region: config.region || "us-east-1",
576
- endpoint: config.endpoint,
577
- credentials: config.credentials
578
- });
579
- this.tableName = config.tableName;
580
- this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
581
- this.service = getElectroDbService(this.client, this.tableName);
582
1924
  }
583
1925
  /**
584
1926
  * This method is modified for DynamoDB with ElectroDB single-table design.
@@ -600,61 +1942,47 @@ var DynamoDBStore = class extends storage.MastraStorage {
600
1942
  );
601
1943
  }
602
1944
  this.logger.debug(`Table ${this.tableName} exists and is accessible`);
603
- } catch (error) {
604
- this.logger.error("Error validating table access", { tableName: this.tableName, error });
605
- throw error;
1945
+ } catch (error$1) {
1946
+ this.logger.error("Error validating table access", { tableName: this.tableName, error: error$1 });
1947
+ throw new error.MastraError(
1948
+ {
1949
+ id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_ACCESS_FAILED",
1950
+ domain: error.ErrorDomain.STORAGE,
1951
+ category: error.ErrorCategory.THIRD_PARTY,
1952
+ details: { tableName: this.tableName }
1953
+ },
1954
+ error$1
1955
+ );
606
1956
  }
607
1957
  }
608
- /**
609
- * Validates that the required DynamoDB table exists and is accessible.
610
- * This does not check the table structure - it assumes the table
611
- * was created with the correct structure via CDK/CloudFormation.
612
- */
613
- async validateTableExists() {
614
- try {
615
- const command = new clientDynamodb.DescribeTableCommand({
616
- TableName: this.tableName
1958
+ async insert({ tableName, record }) {
1959
+ this.logger.debug("DynamoDB insert called", { tableName });
1960
+ const entityName = this.getEntityNameForTable(tableName);
1961
+ if (!entityName || !this.service.entities[entityName]) {
1962
+ throw new error.MastraError({
1963
+ id: "STORAGE_DYNAMODB_STORE_INSERT_INVALID_ARGS",
1964
+ domain: error.ErrorDomain.STORAGE,
1965
+ category: error.ErrorCategory.USER,
1966
+ text: "No entity defined for tableName",
1967
+ details: { tableName }
617
1968
  });
618
- await this.client.send(command);
619
- return true;
620
- } catch (error) {
621
- if (error.name === "ResourceNotFoundException") {
622
- return false;
623
- }
624
- throw error;
625
- }
626
- }
627
- /**
628
- * Initialize storage, validating the externally managed table is accessible.
629
- * For the single-table design, we only validate once that we can access
630
- * the table that was created via CDK/CloudFormation.
631
- */
632
- async init() {
633
- if (this.hasInitialized === null) {
634
- this.hasInitialized = this._performInitializationAndStore();
635
1969
  }
636
1970
  try {
637
- await this.hasInitialized;
638
- } catch (error) {
639
- throw error;
1971
+ const dataToSave = { entity: entityName, ...this.preprocessRecord(record) };
1972
+ await this.service.entities[entityName].create(dataToSave).go();
1973
+ } catch (error$1) {
1974
+ throw new error.MastraError(
1975
+ {
1976
+ id: "STORAGE_DYNAMODB_STORE_INSERT_FAILED",
1977
+ domain: error.ErrorDomain.STORAGE,
1978
+ category: error.ErrorCategory.THIRD_PARTY,
1979
+ details: { tableName }
1980
+ },
1981
+ error$1
1982
+ );
640
1983
  }
641
1984
  }
642
- /**
643
- * Performs the actual table validation and stores the promise.
644
- * Handles resetting the stored promise on failure to allow retries.
645
- */
646
- _performInitializationAndStore() {
647
- return this.validateTableExists().then((exists) => {
648
- if (!exists) {
649
- throw new Error(
650
- `Table ${this.tableName} does not exist or is not accessible. Ensure it's created via CDK/CloudFormation before using this store.`
651
- );
652
- }
653
- return true;
654
- }).catch((err) => {
655
- this.hasInitialized = null;
656
- throw err;
657
- });
1985
+ async alterTable(_args) {
658
1986
  }
659
1987
  /**
660
1988
  * Clear all items from a logical "table" (entity type)
@@ -663,7 +1991,13 @@ var DynamoDBStore = class extends storage.MastraStorage {
663
1991
  this.logger.debug("DynamoDB clearTable called", { tableName });
664
1992
  const entityName = this.getEntityNameForTable(tableName);
665
1993
  if (!entityName || !this.service.entities[entityName]) {
666
- throw new Error(`No entity defined for ${tableName}`);
1994
+ throw new error.MastraError({
1995
+ id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_INVALID_ARGS",
1996
+ domain: error.ErrorDomain.STORAGE,
1997
+ category: error.ErrorCategory.USER,
1998
+ text: "No entity defined for tableName",
1999
+ details: { tableName }
2000
+ });
667
2001
  }
668
2002
  try {
669
2003
  const result = await this.service.entities[entityName].scan.go({ pages: "all" });
@@ -683,10 +2017,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
683
2017
  if (!item.id) throw new Error(`Missing required key 'id' for entity 'message'`);
684
2018
  key.id = item.id;
685
2019
  break;
686
- case "workflowSnapshot":
2020
+ case "workflow_snapshot":
687
2021
  if (!item.workflow_name)
688
- throw new Error(`Missing required key 'workflow_name' for entity 'workflowSnapshot'`);
689
- if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'workflowSnapshot'`);
2022
+ throw new Error(`Missing required key 'workflow_name' for entity 'workflow_snapshot'`);
2023
+ if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'workflow_snapshot'`);
690
2024
  key.workflow_name = item.workflow_name;
691
2025
  key.run_id = item.run_id;
692
2026
  break;
@@ -698,6 +2032,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
698
2032
  if (!item.id) throw new Error(`Missing required key 'id' for entity 'trace'`);
699
2033
  key.id = item.id;
700
2034
  break;
2035
+ case "score":
2036
+ if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
2037
+ key.id = item.id;
2038
+ break;
701
2039
  default:
702
2040
  this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
703
2041
  throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
@@ -710,26 +2048,16 @@ var DynamoDBStore = class extends storage.MastraStorage {
710
2048
  await this.service.entities[entityName].delete(batchKeys).go();
711
2049
  }
712
2050
  this.logger.debug(`Successfully cleared all records for ${tableName}`);
713
- } catch (error) {
714
- this.logger.error("Failed to clear table", { tableName, error });
715
- throw error;
716
- }
717
- }
718
- /**
719
- * Insert a record into the specified "table" (entity)
720
- */
721
- async insert({ tableName, record }) {
722
- this.logger.debug("DynamoDB insert called", { tableName });
723
- const entityName = this.getEntityNameForTable(tableName);
724
- if (!entityName || !this.service.entities[entityName]) {
725
- throw new Error(`No entity defined for ${tableName}`);
726
- }
727
- try {
728
- const dataToSave = { entity: entityName, ...record };
729
- await this.service.entities[entityName].create(dataToSave).go();
730
- } catch (error) {
731
- this.logger.error("Failed to insert record", { tableName, error });
732
- throw error;
2051
+ } catch (error$1) {
2052
+ throw new error.MastraError(
2053
+ {
2054
+ id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_FAILED",
2055
+ domain: error.ErrorDomain.STORAGE,
2056
+ category: error.ErrorCategory.THIRD_PARTY,
2057
+ details: { tableName }
2058
+ },
2059
+ error$1
2060
+ );
733
2061
  }
734
2062
  }
735
2063
  /**
@@ -739,9 +2067,15 @@ var DynamoDBStore = class extends storage.MastraStorage {
739
2067
  this.logger.debug("DynamoDB batchInsert called", { tableName, count: records.length });
740
2068
  const entityName = this.getEntityNameForTable(tableName);
741
2069
  if (!entityName || !this.service.entities[entityName]) {
742
- throw new Error(`No entity defined for ${tableName}`);
2070
+ throw new error.MastraError({
2071
+ id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_INVALID_ARGS",
2072
+ domain: error.ErrorDomain.STORAGE,
2073
+ category: error.ErrorCategory.USER,
2074
+ text: "No entity defined for tableName",
2075
+ details: { tableName }
2076
+ });
743
2077
  }
744
- const recordsToSave = records.map((rec) => ({ entity: entityName, ...rec }));
2078
+ const recordsToSave = records.map((rec) => ({ entity: entityName, ...this.preprocessRecord(rec) }));
745
2079
  const batchSize = 25;
746
2080
  const batches = [];
747
2081
  for (let i = 0; i < recordsToSave.length; i += batchSize) {
@@ -759,9 +2093,16 @@ var DynamoDBStore = class extends storage.MastraStorage {
759
2093
  await this.service.entities[entityName].create(recordData).go();
760
2094
  }
761
2095
  }
762
- } catch (error) {
763
- this.logger.error("Failed to batch insert records", { tableName, error });
764
- throw error;
2096
+ } catch (error$1) {
2097
+ throw new error.MastraError(
2098
+ {
2099
+ id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_FAILED",
2100
+ domain: error.ErrorDomain.STORAGE,
2101
+ category: error.ErrorCategory.THIRD_PARTY,
2102
+ details: { tableName }
2103
+ },
2104
+ error$1
2105
+ );
765
2106
  }
766
2107
  }
767
2108
  /**
@@ -771,7 +2112,13 @@ var DynamoDBStore = class extends storage.MastraStorage {
771
2112
  this.logger.debug("DynamoDB load called", { tableName, keys });
772
2113
  const entityName = this.getEntityNameForTable(tableName);
773
2114
  if (!entityName || !this.service.entities[entityName]) {
774
- throw new Error(`No entity defined for ${tableName}`);
2115
+ throw new error.MastraError({
2116
+ id: "STORAGE_DYNAMODB_STORE_LOAD_INVALID_ARGS",
2117
+ domain: error.ErrorDomain.STORAGE,
2118
+ category: error.ErrorCategory.USER,
2119
+ text: "No entity defined for tableName",
2120
+ details: { tableName }
2121
+ });
775
2122
  }
776
2123
  try {
777
2124
  const keyObject = { entity: entityName, ...keys };
@@ -781,206 +2128,244 @@ var DynamoDBStore = class extends storage.MastraStorage {
781
2128
  }
782
2129
  let data = result.data;
783
2130
  return data;
784
- } catch (error) {
785
- this.logger.error("Failed to load record", { tableName, keys, error });
786
- throw error;
2131
+ } catch (error$1) {
2132
+ throw new error.MastraError(
2133
+ {
2134
+ id: "STORAGE_DYNAMODB_STORE_LOAD_FAILED",
2135
+ domain: error.ErrorDomain.STORAGE,
2136
+ category: error.ErrorCategory.THIRD_PARTY,
2137
+ details: { tableName }
2138
+ },
2139
+ error$1
2140
+ );
787
2141
  }
788
2142
  }
789
- // Thread operations
790
- async getThreadById({ threadId }) {
791
- this.logger.debug("Getting thread by ID", { threadId });
2143
+ };
2144
+ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2145
+ service;
2146
+ constructor({ service }) {
2147
+ super();
2148
+ this.service = service;
2149
+ }
2150
+ // Helper function to parse score data (handle JSON fields)
2151
+ parseScoreData(data) {
2152
+ return {
2153
+ ...data,
2154
+ // Convert date strings back to Date objects for consistency
2155
+ createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
2156
+ updatedAt: data.updatedAt ? new Date(data.updatedAt) : /* @__PURE__ */ new Date()
2157
+ // JSON fields are already transformed by the entity's getters
2158
+ };
2159
+ }
2160
+ async getScoreById({ id }) {
2161
+ this.logger.debug("Getting score by ID", { id });
792
2162
  try {
793
- const result = await this.service.entities.thread.get({ entity: "thread", id: threadId }).go();
2163
+ const result = await this.service.entities.score.get({ entity: "score", id }).go();
794
2164
  if (!result.data) {
795
2165
  return null;
796
2166
  }
797
- const data = result.data;
798
- return {
799
- ...data
800
- // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
801
- // metadata is already transformed by the entity's getter
802
- };
803
- } catch (error) {
804
- this.logger.error("Failed to get thread by ID", { threadId, error });
805
- throw error;
806
- }
807
- }
808
- async getThreadsByResourceId({ resourceId }) {
809
- this.logger.debug("Getting threads by resource ID", { resourceId });
810
- try {
811
- const result = await this.service.entities.thread.query.byResource({ entity: "thread", resourceId }).go();
812
- if (!result.data.length) {
813
- return [];
814
- }
815
- return result.data.map((data) => ({
816
- ...data
817
- // metadata: data.metadata ? JSON.parse(data.metadata) : undefined, // REMOVED by AI
818
- // metadata is already transformed by the entity's getter
819
- }));
820
- } catch (error) {
821
- this.logger.error("Failed to get threads by resource ID", { resourceId, error });
822
- throw error;
2167
+ return this.parseScoreData(result.data);
2168
+ } catch (error$1) {
2169
+ throw new error.MastraError(
2170
+ {
2171
+ id: "STORAGE_DYNAMODB_STORE_GET_SCORE_BY_ID_FAILED",
2172
+ domain: error.ErrorDomain.STORAGE,
2173
+ category: error.ErrorCategory.THIRD_PARTY,
2174
+ details: { id }
2175
+ },
2176
+ error$1
2177
+ );
823
2178
  }
824
2179
  }
825
- async saveThread({ thread }) {
826
- this.logger.debug("Saving thread", { threadId: thread.id });
2180
+ async saveScore(score) {
2181
+ this.logger.debug("Saving score", { scorerId: score.scorerId, runId: score.runId });
827
2182
  const now = /* @__PURE__ */ new Date();
828
- const threadData = {
829
- entity: "thread",
830
- id: thread.id,
831
- resourceId: thread.resourceId,
832
- title: thread.title || `Thread ${thread.id}`,
833
- createdAt: thread.createdAt?.toISOString() || now.toISOString(),
834
- updatedAt: now.toISOString(),
835
- metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
2183
+ const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
2184
+ const scoreData = {
2185
+ entity: "score",
2186
+ id: scoreId,
2187
+ scorerId: score.scorerId,
2188
+ traceId: score.traceId || "",
2189
+ runId: score.runId,
2190
+ scorer: typeof score.scorer === "string" ? score.scorer : JSON.stringify(score.scorer),
2191
+ preprocessStepResult: typeof score.preprocessStepResult === "string" ? score.preprocessStepResult : JSON.stringify(score.preprocessStepResult),
2192
+ analyzeStepResult: typeof score.analyzeStepResult === "string" ? score.analyzeStepResult : JSON.stringify(score.analyzeStepResult),
2193
+ score: score.score,
2194
+ reason: score.reason,
2195
+ preprocessPrompt: score.preprocessPrompt,
2196
+ generateScorePrompt: score.generateScorePrompt,
2197
+ analyzePrompt: score.analyzePrompt,
2198
+ reasonPrompt: score.reasonPrompt,
2199
+ input: typeof score.input === "string" ? score.input : JSON.stringify(score.input),
2200
+ output: typeof score.output === "string" ? score.output : JSON.stringify(score.output),
2201
+ additionalContext: typeof score.additionalContext === "string" ? score.additionalContext : JSON.stringify(score.additionalContext),
2202
+ runtimeContext: typeof score.runtimeContext === "string" ? score.runtimeContext : JSON.stringify(score.runtimeContext),
2203
+ entityType: score.entityType,
2204
+ entityData: typeof score.entity === "string" ? score.entity : JSON.stringify(score.entity),
2205
+ entityId: score.entityId,
2206
+ source: score.source,
2207
+ resourceId: score.resourceId || "",
2208
+ threadId: score.threadId || "",
2209
+ createdAt: now.toISOString(),
2210
+ updatedAt: now.toISOString()
836
2211
  };
837
2212
  try {
838
- await this.service.entities.thread.create(threadData).go();
839
- return {
840
- id: thread.id,
841
- resourceId: thread.resourceId,
842
- title: threadData.title,
843
- createdAt: thread.createdAt || now,
844
- updatedAt: now,
845
- metadata: thread.metadata
2213
+ await this.service.entities.score.upsert(scoreData).go();
2214
+ const savedScore = {
2215
+ ...score,
2216
+ id: scoreId,
2217
+ createdAt: now,
2218
+ updatedAt: now
846
2219
  };
847
- } catch (error) {
848
- this.logger.error("Failed to save thread", { threadId: thread.id, error });
849
- throw error;
2220
+ return { score: savedScore };
2221
+ } catch (error$1) {
2222
+ throw new error.MastraError(
2223
+ {
2224
+ id: "STORAGE_DYNAMODB_STORE_SAVE_SCORE_FAILED",
2225
+ domain: error.ErrorDomain.STORAGE,
2226
+ category: error.ErrorCategory.THIRD_PARTY,
2227
+ details: { scorerId: score.scorerId, runId: score.runId }
2228
+ },
2229
+ error$1
2230
+ );
850
2231
  }
851
2232
  }
852
- async updateThread({
853
- id,
854
- title,
855
- metadata
2233
+ async getScoresByScorerId({
2234
+ scorerId,
2235
+ pagination,
2236
+ entityId,
2237
+ entityType,
2238
+ source
856
2239
  }) {
857
- this.logger.debug("Updating thread", { threadId: id });
858
2240
  try {
859
- const existingThread = await this.getThreadById({ threadId: id });
860
- if (!existingThread) {
861
- throw new Error(`Thread not found: ${id}`);
2241
+ const query = this.service.entities.score.query.byScorer({ entity: "score", scorerId });
2242
+ const results = await query.go();
2243
+ let allScores = results.data.map((data) => this.parseScoreData(data));
2244
+ if (entityId) {
2245
+ allScores = allScores.filter((score) => score.entityId === entityId);
862
2246
  }
863
- const now = /* @__PURE__ */ new Date();
864
- const updateData = {
865
- updatedAt: now.toISOString()
866
- };
867
- if (title) {
868
- updateData.title = title;
2247
+ if (entityType) {
2248
+ allScores = allScores.filter((score) => score.entityType === entityType);
869
2249
  }
870
- if (metadata) {
871
- updateData.metadata = JSON.stringify(metadata);
2250
+ if (source) {
2251
+ allScores = allScores.filter((score) => score.source === source);
872
2252
  }
873
- await this.service.entities.thread.update({ entity: "thread", id }).set(updateData).go();
2253
+ allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2254
+ const startIndex = pagination.page * pagination.perPage;
2255
+ const endIndex = startIndex + pagination.perPage;
2256
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2257
+ const total = allScores.length;
2258
+ const hasMore = endIndex < total;
874
2259
  return {
875
- ...existingThread,
876
- title: title || existingThread.title,
877
- metadata: metadata || existingThread.metadata,
878
- updatedAt: now
2260
+ scores: paginatedScores,
2261
+ pagination: {
2262
+ total,
2263
+ page: pagination.page,
2264
+ perPage: pagination.perPage,
2265
+ hasMore
2266
+ }
879
2267
  };
880
- } catch (error) {
881
- this.logger.error("Failed to update thread", { threadId: id, error });
882
- throw error;
883
- }
884
- }
885
- async deleteThread({ threadId }) {
886
- this.logger.debug("Deleting thread", { threadId });
887
- try {
888
- await this.service.entities.thread.delete({ entity: "thread", id: threadId }).go();
889
- } catch (error) {
890
- this.logger.error("Failed to delete thread", { threadId, error });
891
- throw error;
2268
+ } catch (error$1) {
2269
+ throw new error.MastraError(
2270
+ {
2271
+ id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_SCORER_ID_FAILED",
2272
+ domain: error.ErrorDomain.STORAGE,
2273
+ category: error.ErrorCategory.THIRD_PARTY,
2274
+ details: {
2275
+ scorerId: scorerId || "",
2276
+ entityId: entityId || "",
2277
+ entityType: entityType || "",
2278
+ source: source || "",
2279
+ page: pagination.page,
2280
+ perPage: pagination.perPage
2281
+ }
2282
+ },
2283
+ error$1
2284
+ );
892
2285
  }
893
2286
  }
894
- async getMessages({
895
- threadId,
896
- resourceId,
897
- selectBy,
898
- format
2287
+ async getScoresByRunId({
2288
+ runId,
2289
+ pagination
899
2290
  }) {
900
- this.logger.debug("Getting messages", { threadId, selectBy });
2291
+ this.logger.debug("Getting scores by run ID", { runId, pagination });
901
2292
  try {
902
- const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
903
- if (selectBy?.last && typeof selectBy.last === "number") {
904
- const results2 = await query.go({ limit: selectBy.last, reverse: true });
905
- const list2 = new agent.MessageList({ threadId, resourceId }).add(
906
- results2.data.map((data) => this.parseMessageData(data)),
907
- "memory"
908
- );
909
- if (format === `v2`) return list2.get.all.mastra();
910
- return list2.get.all.v1();
911
- }
2293
+ const query = this.service.entities.score.query.byRun({ entity: "score", runId });
912
2294
  const results = await query.go();
913
- const list = new agent.MessageList({ threadId, resourceId }).add(
914
- results.data.map((data) => this.parseMessageData(data)),
915
- "memory"
2295
+ const allScores = results.data.map((data) => this.parseScoreData(data));
2296
+ allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2297
+ const startIndex = pagination.page * pagination.perPage;
2298
+ const endIndex = startIndex + pagination.perPage;
2299
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2300
+ const total = allScores.length;
2301
+ const hasMore = endIndex < total;
2302
+ return {
2303
+ scores: paginatedScores,
2304
+ pagination: {
2305
+ total,
2306
+ page: pagination.page,
2307
+ perPage: pagination.perPage,
2308
+ hasMore
2309
+ }
2310
+ };
2311
+ } catch (error$1) {
2312
+ throw new error.MastraError(
2313
+ {
2314
+ id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_RUN_ID_FAILED",
2315
+ domain: error.ErrorDomain.STORAGE,
2316
+ category: error.ErrorCategory.THIRD_PARTY,
2317
+ details: { runId, page: pagination.page, perPage: pagination.perPage }
2318
+ },
2319
+ error$1
916
2320
  );
917
- if (format === `v2`) return list.get.all.mastra();
918
- return list.get.all.v1();
919
- } catch (error) {
920
- this.logger.error("Failed to get messages", { threadId, error });
921
- throw error;
922
2321
  }
923
2322
  }
924
- async saveMessages(args) {
925
- const { messages, format = "v1" } = args;
926
- this.logger.debug("Saving messages", { count: messages.length });
927
- if (!messages.length) {
928
- return [];
929
- }
930
- const messagesToSave = messages.map((msg) => {
931
- const now = (/* @__PURE__ */ new Date()).toISOString();
932
- return {
933
- entity: "message",
934
- // Add entity type
935
- id: msg.id,
936
- threadId: msg.threadId,
937
- role: msg.role,
938
- type: msg.type,
939
- resourceId: msg.resourceId,
940
- // Ensure complex fields are stringified if not handled by attribute setters
941
- content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content),
942
- toolCallArgs: `toolCallArgs` in msg && msg.toolCallArgs ? JSON.stringify(msg.toolCallArgs) : void 0,
943
- toolCallIds: `toolCallIds` in msg && msg.toolCallIds ? JSON.stringify(msg.toolCallIds) : void 0,
944
- toolNames: `toolNames` in msg && msg.toolNames ? JSON.stringify(msg.toolNames) : void 0,
945
- createdAt: msg.createdAt instanceof Date ? msg.createdAt.toISOString() : msg.createdAt || now,
946
- updatedAt: now
947
- // Add updatedAt
948
- };
949
- });
2323
+ async getScoresByEntityId({
2324
+ entityId,
2325
+ entityType,
2326
+ pagination
2327
+ }) {
2328
+ this.logger.debug("Getting scores by entity ID", { entityId, entityType, pagination });
950
2329
  try {
951
- const batchSize = 25;
952
- const batches = [];
953
- for (let i = 0; i < messagesToSave.length; i += batchSize) {
954
- const batch = messagesToSave.slice(i, i + batchSize);
955
- batches.push(batch);
956
- }
957
- for (const batch of batches) {
958
- for (const messageData of batch) {
959
- if (!messageData.entity) {
960
- this.logger.error("Missing entity property in message data for create", { messageData });
961
- throw new Error("Internal error: Missing entity property during saveMessages");
962
- }
963
- await this.service.entities.message.create(messageData).go();
2330
+ const query = this.service.entities.score.query.byEntityData({ entity: "score", entityId });
2331
+ const results = await query.go();
2332
+ let allScores = results.data.map((data) => this.parseScoreData(data));
2333
+ allScores = allScores.filter((score) => score.entityType === entityType);
2334
+ allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2335
+ const startIndex = pagination.page * pagination.perPage;
2336
+ const endIndex = startIndex + pagination.perPage;
2337
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2338
+ const total = allScores.length;
2339
+ const hasMore = endIndex < total;
2340
+ return {
2341
+ scores: paginatedScores,
2342
+ pagination: {
2343
+ total,
2344
+ page: pagination.page,
2345
+ perPage: pagination.perPage,
2346
+ hasMore
964
2347
  }
965
- }
966
- const list = new agent.MessageList().add(messages, "memory");
967
- if (format === `v1`) return list.get.all.v1();
968
- return list.get.all.mastra();
969
- } catch (error) {
970
- this.logger.error("Failed to save messages", { error });
971
- throw error;
2348
+ };
2349
+ } catch (error$1) {
2350
+ throw new error.MastraError(
2351
+ {
2352
+ id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_ENTITY_ID_FAILED",
2353
+ domain: error.ErrorDomain.STORAGE,
2354
+ category: error.ErrorCategory.THIRD_PARTY,
2355
+ details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
2356
+ },
2357
+ error$1
2358
+ );
972
2359
  }
973
2360
  }
974
- // Helper function to parse message data (handle JSON fields)
975
- parseMessageData(data) {
976
- return {
977
- ...data,
978
- // Ensure dates are Date objects if needed (ElectroDB might return strings)
979
- createdAt: data.createdAt ? new Date(data.createdAt) : void 0,
980
- updatedAt: data.updatedAt ? new Date(data.updatedAt) : void 0
981
- // Other fields like content, toolCallArgs etc. are assumed to be correctly
982
- // transformed by the ElectroDB entity getters.
983
- };
2361
+ };
2362
+ var TracesStorageDynamoDB = class extends storage.TracesStorage {
2363
+ service;
2364
+ operations;
2365
+ constructor({ service, operations }) {
2366
+ super();
2367
+ this.service = service;
2368
+ this.operations = operations;
984
2369
  }
985
2370
  // Trace operations
986
2371
  async getTraces(args) {
@@ -1007,34 +2392,238 @@ var DynamoDBStore = class extends storage.MastraStorage {
1007
2392
  items = results.data;
1008
2393
  break;
1009
2394
  }
1010
- cursor = results.cursor;
1011
- if (!cursor && results.data.length > 0 && pagesFetched < startPage) {
1012
- break;
2395
+ cursor = results.cursor;
2396
+ if (!cursor && results.data.length > 0 && pagesFetched < startPage) {
2397
+ break;
2398
+ }
2399
+ } while (cursor && pagesFetched < startPage);
2400
+ return items;
2401
+ } catch (error$1) {
2402
+ throw new error.MastraError(
2403
+ {
2404
+ id: "STORAGE_DYNAMODB_STORE_GET_TRACES_FAILED",
2405
+ domain: error.ErrorDomain.STORAGE,
2406
+ category: error.ErrorCategory.THIRD_PARTY
2407
+ },
2408
+ error$1
2409
+ );
2410
+ }
2411
+ }
2412
+ async batchTraceInsert({ records }) {
2413
+ this.logger.debug("Batch inserting traces", { count: records.length });
2414
+ if (!records.length) {
2415
+ return;
2416
+ }
2417
+ try {
2418
+ const recordsToSave = records.map((rec) => ({ entity: "trace", ...rec }));
2419
+ await this.operations.batchInsert({
2420
+ tableName: storage.TABLE_TRACES,
2421
+ records: recordsToSave
2422
+ // Pass records with 'entity' included
2423
+ });
2424
+ } catch (error$1) {
2425
+ throw new error.MastraError(
2426
+ {
2427
+ id: "STORAGE_DYNAMODB_STORE_BATCH_TRACE_INSERT_FAILED",
2428
+ domain: error.ErrorDomain.STORAGE,
2429
+ category: error.ErrorCategory.THIRD_PARTY,
2430
+ details: { count: records.length }
2431
+ },
2432
+ error$1
2433
+ );
2434
+ }
2435
+ }
2436
+ async getTracesPaginated(args) {
2437
+ const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
2438
+ this.logger.debug("Getting traces with pagination", { name, scope, page, perPage, attributes, filters, dateRange });
2439
+ try {
2440
+ let query;
2441
+ if (name) {
2442
+ query = this.service.entities.trace.query.byName({ entity: "trace", name });
2443
+ } else if (scope) {
2444
+ query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
2445
+ } else {
2446
+ this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
2447
+ query = this.service.entities.trace.scan;
2448
+ }
2449
+ const results = await query.go({
2450
+ order: "desc",
2451
+ pages: "all"
2452
+ // Get all pages to apply filtering and pagination
2453
+ });
2454
+ if (!results.data.length) {
2455
+ return {
2456
+ traces: [],
2457
+ total: 0,
2458
+ page,
2459
+ perPage,
2460
+ hasMore: false
2461
+ };
2462
+ }
2463
+ let filteredData = results.data;
2464
+ if (attributes) {
2465
+ filteredData = filteredData.filter((item) => {
2466
+ try {
2467
+ let itemAttributes = {};
2468
+ if (item.attributes) {
2469
+ if (typeof item.attributes === "string") {
2470
+ if (item.attributes === "[object Object]") {
2471
+ itemAttributes = {};
2472
+ } else {
2473
+ try {
2474
+ itemAttributes = JSON.parse(item.attributes);
2475
+ } catch {
2476
+ itemAttributes = {};
2477
+ }
2478
+ }
2479
+ } else if (typeof item.attributes === "object") {
2480
+ itemAttributes = item.attributes;
2481
+ }
2482
+ }
2483
+ return Object.entries(attributes).every(([key, value]) => itemAttributes[key] === value);
2484
+ } catch (e) {
2485
+ this.logger.warn("Failed to parse attributes during filtering", { item, error: e });
2486
+ return false;
2487
+ }
2488
+ });
2489
+ }
2490
+ if (dateRange?.start) {
2491
+ filteredData = filteredData.filter((item) => {
2492
+ const itemDate = new Date(item.createdAt);
2493
+ return itemDate >= dateRange.start;
2494
+ });
2495
+ }
2496
+ if (dateRange?.end) {
2497
+ filteredData = filteredData.filter((item) => {
2498
+ const itemDate = new Date(item.createdAt);
2499
+ return itemDate <= dateRange.end;
2500
+ });
2501
+ }
2502
+ const total = filteredData.length;
2503
+ const start = page * perPage;
2504
+ const end = start + perPage;
2505
+ const paginatedData = filteredData.slice(start, end);
2506
+ const traces = paginatedData.map((item) => {
2507
+ let attributes2;
2508
+ if (item.attributes) {
2509
+ if (typeof item.attributes === "string") {
2510
+ if (item.attributes === "[object Object]") {
2511
+ attributes2 = void 0;
2512
+ } else {
2513
+ try {
2514
+ attributes2 = JSON.parse(item.attributes);
2515
+ } catch {
2516
+ attributes2 = void 0;
2517
+ }
2518
+ }
2519
+ } else if (typeof item.attributes === "object") {
2520
+ attributes2 = item.attributes;
2521
+ }
2522
+ }
2523
+ let status;
2524
+ if (item.status) {
2525
+ if (typeof item.status === "string") {
2526
+ try {
2527
+ status = JSON.parse(item.status);
2528
+ } catch {
2529
+ status = void 0;
2530
+ }
2531
+ } else if (typeof item.status === "object") {
2532
+ status = item.status;
2533
+ }
1013
2534
  }
1014
- } while (cursor && pagesFetched < startPage);
1015
- return items;
1016
- } catch (error) {
1017
- this.logger.error("Failed to get traces", { error });
1018
- throw error;
1019
- }
1020
- }
1021
- async batchTraceInsert({ records }) {
1022
- this.logger.debug("Batch inserting traces", { count: records.length });
1023
- if (!records.length) {
1024
- return;
1025
- }
1026
- try {
1027
- const recordsToSave = records.map((rec) => ({ entity: "trace", ...rec }));
1028
- await this.batchInsert({
1029
- tableName: storage.TABLE_TRACES,
1030
- records: recordsToSave
1031
- // Pass records with 'entity' included
2535
+ let events;
2536
+ if (item.events) {
2537
+ if (typeof item.events === "string") {
2538
+ try {
2539
+ events = JSON.parse(item.events);
2540
+ } catch {
2541
+ events = void 0;
2542
+ }
2543
+ } else if (Array.isArray(item.events)) {
2544
+ events = item.events;
2545
+ }
2546
+ }
2547
+ let links;
2548
+ if (item.links) {
2549
+ if (typeof item.links === "string") {
2550
+ try {
2551
+ links = JSON.parse(item.links);
2552
+ } catch {
2553
+ links = void 0;
2554
+ }
2555
+ } else if (Array.isArray(item.links)) {
2556
+ links = item.links;
2557
+ }
2558
+ }
2559
+ return {
2560
+ id: item.id,
2561
+ parentSpanId: item.parentSpanId,
2562
+ name: item.name,
2563
+ traceId: item.traceId,
2564
+ scope: item.scope,
2565
+ kind: item.kind,
2566
+ attributes: attributes2,
2567
+ status,
2568
+ events,
2569
+ links,
2570
+ other: item.other,
2571
+ startTime: item.startTime,
2572
+ endTime: item.endTime,
2573
+ createdAt: item.createdAt
2574
+ };
1032
2575
  });
1033
- } catch (error) {
1034
- this.logger.error("Failed to batch insert traces", { error });
1035
- throw error;
2576
+ return {
2577
+ traces,
2578
+ total,
2579
+ page,
2580
+ perPage,
2581
+ hasMore: end < total
2582
+ };
2583
+ } catch (error$1) {
2584
+ throw new error.MastraError(
2585
+ {
2586
+ id: "STORAGE_DYNAMODB_STORE_GET_TRACES_PAGINATED_FAILED",
2587
+ domain: error.ErrorDomain.STORAGE,
2588
+ category: error.ErrorCategory.THIRD_PARTY
2589
+ },
2590
+ error$1
2591
+ );
1036
2592
  }
1037
2593
  }
2594
+ };
2595
+ function formatWorkflowRun(snapshotData) {
2596
+ return {
2597
+ workflowName: snapshotData.workflow_name,
2598
+ runId: snapshotData.run_id,
2599
+ snapshot: snapshotData.snapshot,
2600
+ createdAt: new Date(snapshotData.createdAt),
2601
+ updatedAt: new Date(snapshotData.updatedAt),
2602
+ resourceId: snapshotData.resourceId
2603
+ };
2604
+ }
2605
+ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2606
+ service;
2607
+ constructor({ service }) {
2608
+ super();
2609
+ this.service = service;
2610
+ }
2611
+ updateWorkflowResults({
2612
+ // workflowName,
2613
+ // runId,
2614
+ // stepId,
2615
+ // result,
2616
+ // runtimeContext,
2617
+ }) {
2618
+ throw new Error("Method not implemented.");
2619
+ }
2620
+ updateWorkflowState({
2621
+ // workflowName,
2622
+ // runId,
2623
+ // opts,
2624
+ }) {
2625
+ throw new Error("Method not implemented.");
2626
+ }
1038
2627
  // Workflow operations
1039
2628
  async persistWorkflowSnapshot({
1040
2629
  workflowName,
@@ -1056,10 +2645,17 @@ var DynamoDBStore = class extends storage.MastraStorage {
1056
2645
  updatedAt: now,
1057
2646
  resourceId
1058
2647
  };
1059
- await this.service.entities.workflowSnapshot.create(data).go();
1060
- } catch (error) {
1061
- this.logger.error("Failed to persist workflow snapshot", { workflowName, runId, error });
1062
- throw error;
2648
+ await this.service.entities.workflow_snapshot.upsert(data).go();
2649
+ } catch (error$1) {
2650
+ throw new error.MastraError(
2651
+ {
2652
+ id: "STORAGE_DYNAMODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
2653
+ domain: error.ErrorDomain.STORAGE,
2654
+ category: error.ErrorCategory.THIRD_PARTY,
2655
+ details: { workflowName, runId }
2656
+ },
2657
+ error$1
2658
+ );
1063
2659
  }
1064
2660
  }
1065
2661
  async loadWorkflowSnapshot({
@@ -1068,7 +2664,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
1068
2664
  }) {
1069
2665
  this.logger.debug("Loading workflow snapshot", { workflowName, runId });
1070
2666
  try {
1071
- const result = await this.service.entities.workflowSnapshot.get({
2667
+ const result = await this.service.entities.workflow_snapshot.get({
1072
2668
  entity: "workflow_snapshot",
1073
2669
  // Add entity type
1074
2670
  workflow_name: workflowName,
@@ -1078,9 +2674,16 @@ var DynamoDBStore = class extends storage.MastraStorage {
1078
2674
  return null;
1079
2675
  }
1080
2676
  return result.data.snapshot;
1081
- } catch (error) {
1082
- this.logger.error("Failed to load workflow snapshot", { workflowName, runId, error });
1083
- throw error;
2677
+ } catch (error$1) {
2678
+ throw new error.MastraError(
2679
+ {
2680
+ id: "STORAGE_DYNAMODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
2681
+ domain: error.ErrorDomain.STORAGE,
2682
+ category: error.ErrorCategory.THIRD_PARTY,
2683
+ details: { workflowName, runId }
2684
+ },
2685
+ error$1
2686
+ );
1084
2687
  }
1085
2688
  }
1086
2689
  async getWorkflowRuns(args) {
@@ -1090,14 +2693,14 @@ var DynamoDBStore = class extends storage.MastraStorage {
1090
2693
  const offset = args?.offset || 0;
1091
2694
  let query;
1092
2695
  if (args?.workflowName) {
1093
- query = this.service.entities.workflowSnapshot.query.primary({
2696
+ query = this.service.entities.workflow_snapshot.query.primary({
1094
2697
  entity: "workflow_snapshot",
1095
2698
  // Add entity type
1096
2699
  workflow_name: args.workflowName
1097
2700
  });
1098
2701
  } else {
1099
2702
  this.logger.warn("Performing a scan operation on workflow snapshots - consider using a more specific query");
1100
- query = this.service.entities.workflowSnapshot.scan;
2703
+ query = this.service.entities.workflow_snapshot.scan;
1101
2704
  }
1102
2705
  const allMatchingSnapshots = [];
1103
2706
  let cursor = null;
@@ -1135,28 +2738,38 @@ var DynamoDBStore = class extends storage.MastraStorage {
1135
2738
  }
1136
2739
  const total = allMatchingSnapshots.length;
1137
2740
  const paginatedData = allMatchingSnapshots.slice(offset, offset + limit);
1138
- const runs = paginatedData.map((snapshot) => this.formatWorkflowRun(snapshot));
2741
+ const runs = paginatedData.map((snapshot) => formatWorkflowRun(snapshot));
1139
2742
  return {
1140
2743
  runs,
1141
2744
  total
1142
2745
  };
1143
- } catch (error) {
1144
- this.logger.error("Failed to get workflow runs", { error });
1145
- throw error;
2746
+ } catch (error$1) {
2747
+ throw new error.MastraError(
2748
+ {
2749
+ id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUNS_FAILED",
2750
+ domain: error.ErrorDomain.STORAGE,
2751
+ category: error.ErrorCategory.THIRD_PARTY,
2752
+ details: { workflowName: args?.workflowName || "", resourceId: args?.resourceId || "" }
2753
+ },
2754
+ error$1
2755
+ );
1146
2756
  }
1147
2757
  }
1148
2758
  async getWorkflowRunById(args) {
1149
2759
  const { runId, workflowName } = args;
1150
2760
  this.logger.debug("Getting workflow run by ID", { runId, workflowName });
2761
+ console.log("workflowName", workflowName);
2762
+ console.log("runId", runId);
1151
2763
  try {
1152
2764
  if (workflowName) {
1153
2765
  this.logger.debug("WorkflowName provided, using direct GET operation.");
1154
- const result2 = await this.service.entities.workflowSnapshot.get({
2766
+ const result2 = await this.service.entities.workflow_snapshot.get({
1155
2767
  entity: "workflow_snapshot",
1156
2768
  // Entity type for PK
1157
2769
  workflow_name: workflowName,
1158
2770
  run_id: runId
1159
2771
  }).go();
2772
+ console.log("result", result2);
1160
2773
  if (!result2.data) {
1161
2774
  return null;
1162
2775
  }
@@ -1173,7 +2786,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
1173
2786
  this.logger.debug(
1174
2787
  'WorkflowName not provided. Attempting to find workflow run by runId using GSI. Ensure GSI (e.g., "byRunId") is defined on the workflowSnapshot entity with run_id as its key and provisioned in DynamoDB.'
1175
2788
  );
1176
- const result = await this.service.entities.workflowSnapshot.query.gsi2({ entity: "workflow_snapshot", run_id: runId }).go();
2789
+ const result = await this.service.entities.workflow_snapshot.query.gsi2({ entity: "workflow_snapshot", run_id: runId }).go();
1177
2790
  const matchingRunDbItem = result.data && result.data.length > 0 ? result.data[0] : null;
1178
2791
  if (!matchingRunDbItem) {
1179
2792
  return null;
@@ -1187,90 +2800,283 @@ var DynamoDBStore = class extends storage.MastraStorage {
1187
2800
  updatedAt: new Date(matchingRunDbItem.updatedAt),
1188
2801
  resourceId: matchingRunDbItem.resourceId
1189
2802
  };
1190
- } catch (error) {
1191
- this.logger.error("Failed to get workflow run by ID", { runId, workflowName, error });
1192
- throw error;
2803
+ } catch (error$1) {
2804
+ throw new error.MastraError(
2805
+ {
2806
+ id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2807
+ domain: error.ErrorDomain.STORAGE,
2808
+ category: error.ErrorCategory.THIRD_PARTY,
2809
+ details: { runId, workflowName: args?.workflowName || "" }
2810
+ },
2811
+ error$1
2812
+ );
1193
2813
  }
1194
2814
  }
1195
- // Helper function to format workflow run
1196
- formatWorkflowRun(snapshotData) {
1197
- return {
1198
- workflowName: snapshotData.workflow_name,
1199
- runId: snapshotData.run_id,
1200
- snapshot: snapshotData.snapshot,
1201
- createdAt: new Date(snapshotData.createdAt),
1202
- updatedAt: new Date(snapshotData.updatedAt),
1203
- resourceId: snapshotData.resourceId
1204
- };
2815
+ };
2816
+
2817
+ // src/storage/index.ts
2818
+ var DynamoDBStore = class extends storage.MastraStorage {
2819
+ tableName;
2820
+ client;
2821
+ service;
2822
+ hasInitialized = null;
2823
+ stores;
2824
+ constructor({ name, config }) {
2825
+ super({ name });
2826
+ try {
2827
+ if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
2828
+ throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
2829
+ }
2830
+ if (!/^[a-zA-Z0-9_.-]{3,255}$/.test(config.tableName)) {
2831
+ throw new Error(
2832
+ `DynamoDBStore: config.tableName "${config.tableName}" contains invalid characters or is not between 3 and 255 characters long.`
2833
+ );
2834
+ }
2835
+ const dynamoClient = new clientDynamodb.DynamoDBClient({
2836
+ region: config.region || "us-east-1",
2837
+ endpoint: config.endpoint,
2838
+ credentials: config.credentials
2839
+ });
2840
+ this.tableName = config.tableName;
2841
+ this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
2842
+ this.service = getElectroDbService(this.client, this.tableName);
2843
+ const operations = new StoreOperationsDynamoDB({
2844
+ service: this.service,
2845
+ tableName: this.tableName,
2846
+ client: this.client
2847
+ });
2848
+ const traces = new TracesStorageDynamoDB({ service: this.service, operations });
2849
+ const workflows = new WorkflowStorageDynamoDB({ service: this.service });
2850
+ const memory = new MemoryStorageDynamoDB({ service: this.service });
2851
+ const scores = new ScoresStorageDynamoDB({ service: this.service });
2852
+ this.stores = {
2853
+ operations,
2854
+ legacyEvals: new LegacyEvalsDynamoDB({ service: this.service, tableName: this.tableName }),
2855
+ traces,
2856
+ workflows,
2857
+ memory,
2858
+ scores
2859
+ };
2860
+ } catch (error$1) {
2861
+ throw new error.MastraError(
2862
+ {
2863
+ id: "STORAGE_DYNAMODB_STORE_CONSTRUCTOR_FAILED",
2864
+ domain: error.ErrorDomain.STORAGE,
2865
+ category: error.ErrorCategory.USER
2866
+ },
2867
+ error$1
2868
+ );
2869
+ }
1205
2870
  }
1206
- // Helper methods for entity/table mapping
1207
- getEntityNameForTable(tableName) {
1208
- const mapping = {
1209
- [storage.TABLE_THREADS]: "thread",
1210
- [storage.TABLE_MESSAGES]: "message",
1211
- [storage.TABLE_WORKFLOW_SNAPSHOT]: "workflowSnapshot",
1212
- [storage.TABLE_EVALS]: "eval",
1213
- [storage.TABLE_TRACES]: "trace"
2871
+ get supports() {
2872
+ return {
2873
+ selectByIncludeResourceScope: true,
2874
+ resourceWorkingMemory: true,
2875
+ hasColumn: false,
2876
+ createTable: false,
2877
+ deleteMessages: false
1214
2878
  };
1215
- return mapping[tableName] || null;
1216
2879
  }
1217
- // Eval operations
1218
- async getEvalsByAgentName(agentName, type) {
1219
- this.logger.debug("Getting evals for agent", { agentName, type });
2880
+ /**
2881
+ * Validates that the required DynamoDB table exists and is accessible.
2882
+ * This does not check the table structure - it assumes the table
2883
+ * was created with the correct structure via CDK/CloudFormation.
2884
+ */
2885
+ async validateTableExists() {
1220
2886
  try {
1221
- const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
1222
- const results = await query.go({ order: "desc", limit: 100 });
1223
- if (!results.data.length) {
1224
- return [];
1225
- }
1226
- let filteredData = results.data;
1227
- if (type) {
1228
- filteredData = filteredData.filter((evalRecord) => {
1229
- try {
1230
- const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
1231
- if (type === "test" && !testInfo) {
1232
- return false;
1233
- }
1234
- if (type === "live" && testInfo) {
1235
- return false;
1236
- }
1237
- } catch (e) {
1238
- this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
1239
- }
1240
- return true;
1241
- });
1242
- }
1243
- return filteredData.map((evalRecord) => {
1244
- try {
1245
- return {
1246
- input: evalRecord.input,
1247
- output: evalRecord.output,
1248
- // Safely parse result and test_info
1249
- result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
1250
- agentName: evalRecord.agent_name,
1251
- createdAt: evalRecord.created_at,
1252
- // Keep as string from DDB?
1253
- metricName: evalRecord.metric_name,
1254
- instructions: evalRecord.instructions,
1255
- runId: evalRecord.run_id,
1256
- globalRunId: evalRecord.global_run_id,
1257
- testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
1258
- };
1259
- } catch (parseError) {
1260
- this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
1261
- return {
1262
- agentName: evalRecord.agent_name,
1263
- createdAt: evalRecord.created_at,
1264
- runId: evalRecord.run_id,
1265
- globalRunId: evalRecord.global_run_id
1266
- };
1267
- }
2887
+ const command = new clientDynamodb.DescribeTableCommand({
2888
+ TableName: this.tableName
1268
2889
  });
1269
- } catch (error) {
1270
- this.logger.error("Failed to get evals by agent name", { agentName, type, error });
1271
- throw error;
2890
+ await this.client.send(command);
2891
+ return true;
2892
+ } catch (error$1) {
2893
+ if (error$1.name === "ResourceNotFoundException") {
2894
+ return false;
2895
+ }
2896
+ throw new error.MastraError(
2897
+ {
2898
+ id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
2899
+ domain: error.ErrorDomain.STORAGE,
2900
+ category: error.ErrorCategory.THIRD_PARTY,
2901
+ details: { tableName: this.tableName }
2902
+ },
2903
+ error$1
2904
+ );
2905
+ }
2906
+ }
2907
+ /**
2908
+ * Initialize storage, validating the externally managed table is accessible.
2909
+ * For the single-table design, we only validate once that we can access
2910
+ * the table that was created via CDK/CloudFormation.
2911
+ */
2912
+ async init() {
2913
+ if (this.hasInitialized === null) {
2914
+ this.hasInitialized = this._performInitializationAndStore();
2915
+ }
2916
+ try {
2917
+ await this.hasInitialized;
2918
+ } catch (error$1) {
2919
+ throw new error.MastraError(
2920
+ {
2921
+ id: "STORAGE_DYNAMODB_STORE_INIT_FAILED",
2922
+ domain: error.ErrorDomain.STORAGE,
2923
+ category: error.ErrorCategory.THIRD_PARTY,
2924
+ details: { tableName: this.tableName }
2925
+ },
2926
+ error$1
2927
+ );
1272
2928
  }
1273
2929
  }
2930
+ /**
2931
+ * Performs the actual table validation and stores the promise.
2932
+ * Handles resetting the stored promise on failure to allow retries.
2933
+ */
2934
+ _performInitializationAndStore() {
2935
+ return this.validateTableExists().then((exists) => {
2936
+ if (!exists) {
2937
+ throw new Error(
2938
+ `Table ${this.tableName} does not exist or is not accessible. Ensure it's created via CDK/CloudFormation before using this store.`
2939
+ );
2940
+ }
2941
+ return true;
2942
+ }).catch((err) => {
2943
+ this.hasInitialized = null;
2944
+ throw err;
2945
+ });
2946
+ }
2947
+ async createTable({ tableName, schema }) {
2948
+ return this.stores.operations.createTable({ tableName, schema });
2949
+ }
2950
+ async alterTable(_args) {
2951
+ return this.stores.operations.alterTable(_args);
2952
+ }
2953
+ async clearTable({ tableName }) {
2954
+ return this.stores.operations.clearTable({ tableName });
2955
+ }
2956
+ async dropTable({ tableName }) {
2957
+ return this.stores.operations.dropTable({ tableName });
2958
+ }
2959
+ async insert({ tableName, record }) {
2960
+ return this.stores.operations.insert({ tableName, record });
2961
+ }
2962
+ async batchInsert({ tableName, records }) {
2963
+ return this.stores.operations.batchInsert({ tableName, records });
2964
+ }
2965
+ async load({ tableName, keys }) {
2966
+ return this.stores.operations.load({ tableName, keys });
2967
+ }
2968
+ // Thread operations
2969
+ async getThreadById({ threadId }) {
2970
+ return this.stores.memory.getThreadById({ threadId });
2971
+ }
2972
+ async getThreadsByResourceId(args) {
2973
+ return this.stores.memory.getThreadsByResourceId(args);
2974
+ }
2975
+ async saveThread({ thread }) {
2976
+ return this.stores.memory.saveThread({ thread });
2977
+ }
2978
+ async updateThread({
2979
+ id,
2980
+ title,
2981
+ metadata
2982
+ }) {
2983
+ return this.stores.memory.updateThread({ id, title, metadata });
2984
+ }
2985
+ async deleteThread({ threadId }) {
2986
+ return this.stores.memory.deleteThread({ threadId });
2987
+ }
2988
+ async getMessages({
2989
+ threadId,
2990
+ resourceId,
2991
+ selectBy,
2992
+ format
2993
+ }) {
2994
+ return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
2995
+ }
2996
+ async getMessagesById({
2997
+ messageIds,
2998
+ format
2999
+ }) {
3000
+ return this.stores.memory.getMessagesById({ messageIds, format });
3001
+ }
3002
+ async saveMessages(args) {
3003
+ return this.stores.memory.saveMessages(args);
3004
+ }
3005
+ async getThreadsByResourceIdPaginated(args) {
3006
+ return this.stores.memory.getThreadsByResourceIdPaginated(args);
3007
+ }
3008
+ async getMessagesPaginated(args) {
3009
+ return this.stores.memory.getMessagesPaginated(args);
3010
+ }
3011
+ async updateMessages(_args) {
3012
+ return this.stores.memory.updateMessages(_args);
3013
+ }
3014
+ // Trace operations
3015
+ async getTraces(args) {
3016
+ return this.stores.traces.getTraces(args);
3017
+ }
3018
+ async batchTraceInsert({ records }) {
3019
+ return this.stores.traces.batchTraceInsert({ records });
3020
+ }
3021
+ async getTracesPaginated(_args) {
3022
+ return this.stores.traces.getTracesPaginated(_args);
3023
+ }
3024
+ // Workflow operations
3025
+ async updateWorkflowResults({
3026
+ workflowName,
3027
+ runId,
3028
+ stepId,
3029
+ result,
3030
+ runtimeContext
3031
+ }) {
3032
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
3033
+ }
3034
+ async updateWorkflowState({
3035
+ workflowName,
3036
+ runId,
3037
+ opts
3038
+ }) {
3039
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
3040
+ }
3041
+ async persistWorkflowSnapshot({
3042
+ workflowName,
3043
+ runId,
3044
+ snapshot
3045
+ }) {
3046
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
3047
+ }
3048
+ async loadWorkflowSnapshot({
3049
+ workflowName,
3050
+ runId
3051
+ }) {
3052
+ return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
3053
+ }
3054
+ async getWorkflowRuns(args) {
3055
+ return this.stores.workflows.getWorkflowRuns(args);
3056
+ }
3057
+ async getWorkflowRunById(args) {
3058
+ return this.stores.workflows.getWorkflowRunById(args);
3059
+ }
3060
+ async getResourceById({ resourceId }) {
3061
+ return this.stores.memory.getResourceById({ resourceId });
3062
+ }
3063
+ async saveResource({ resource }) {
3064
+ return this.stores.memory.saveResource({ resource });
3065
+ }
3066
+ async updateResource({
3067
+ resourceId,
3068
+ workingMemory,
3069
+ metadata
3070
+ }) {
3071
+ return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
3072
+ }
3073
+ // Eval operations
3074
+ async getEvalsByAgentName(agentName, type) {
3075
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
3076
+ }
3077
+ async getEvals(options) {
3078
+ return this.stores.legacyEvals.getEvals(options);
3079
+ }
1274
3080
  /**
1275
3081
  * Closes the DynamoDB client connection and cleans up resources.
1276
3082
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
@@ -1280,11 +3086,54 @@ var DynamoDBStore = class extends storage.MastraStorage {
1280
3086
  try {
1281
3087
  this.client.destroy();
1282
3088
  this.logger.debug("DynamoDB client closed successfully for store:", { name: this.name });
1283
- } catch (error) {
1284
- this.logger.error("Error closing DynamoDB client for store:", { name: this.name, error });
1285
- throw error;
3089
+ } catch (error$1) {
3090
+ throw new error.MastraError(
3091
+ {
3092
+ id: "STORAGE_DYNAMODB_STORE_CLOSE_FAILED",
3093
+ domain: error.ErrorDomain.STORAGE,
3094
+ category: error.ErrorCategory.THIRD_PARTY
3095
+ },
3096
+ error$1
3097
+ );
1286
3098
  }
1287
3099
  }
3100
+ /**
3101
+ * SCORERS - Not implemented
3102
+ */
3103
+ async getScoreById({ id: _id }) {
3104
+ return this.stores.scores.getScoreById({ id: _id });
3105
+ }
3106
+ async saveScore(_score) {
3107
+ return this.stores.scores.saveScore(_score);
3108
+ }
3109
+ async getScoresByRunId({
3110
+ runId: _runId,
3111
+ pagination: _pagination
3112
+ }) {
3113
+ return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
3114
+ }
3115
+ async getScoresByEntityId({
3116
+ entityId: _entityId,
3117
+ entityType: _entityType,
3118
+ pagination: _pagination
3119
+ }) {
3120
+ return this.stores.scores.getScoresByEntityId({
3121
+ entityId: _entityId,
3122
+ entityType: _entityType,
3123
+ pagination: _pagination
3124
+ });
3125
+ }
3126
+ async getScoresByScorerId({
3127
+ scorerId,
3128
+ source,
3129
+ entityId,
3130
+ entityType,
3131
+ pagination
3132
+ }) {
3133
+ return this.stores.scores.getScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
3134
+ }
1288
3135
  };
1289
3136
 
1290
3137
  exports.DynamoDBStore = DynamoDBStore;
3138
+ //# sourceMappingURL=index.cjs.map
3139
+ //# sourceMappingURL=index.cjs.map