@mastra/dynamodb 0.0.0-working-memory-per-user-20250620163010 → 0.0.0-zod-v4-compat-part-2-20250822105954

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