@mastra/dynamodb 0.0.0-share-agent-metadata-with-cloud-20250718110128 → 0.0.0-stream-vnext-usage-20250908171242

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