@mastra/dynamodb 0.0.0-pass-headers-for-create-mastra-client-20250529200245 → 0.0.0-scorers-api-v2-20250801171841

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