@mastra/dynamodb 0.0.0-scorers-api-v2-20250801171841 → 0.0.0-scorers-logs-20251208093427

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 (44) hide show
  1. package/CHANGELOG.md +1605 -0
  2. package/README.md +0 -4
  3. package/dist/entities/index.d.ts +20 -1
  4. package/dist/entities/index.d.ts.map +1 -1
  5. package/dist/entities/score.d.ts +20 -1
  6. package/dist/entities/score.d.ts.map +1 -1
  7. package/dist/index.cjs +474 -728
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.js +475 -729
  11. package/dist/index.js.map +1 -1
  12. package/dist/storage/domains/memory/index.d.ts +15 -31
  13. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  14. package/dist/storage/domains/operations/index.d.ts.map +1 -1
  15. package/dist/storage/domains/score/index.d.ts +22 -5
  16. package/dist/storage/domains/score/index.d.ts.map +1 -1
  17. package/dist/storage/domains/workflows/index.d.ts +23 -11
  18. package/dist/storage/domains/workflows/index.d.ts.map +1 -1
  19. package/dist/storage/index.d.ts +73 -69
  20. package/dist/storage/index.d.ts.map +1 -1
  21. package/package.json +29 -16
  22. package/dist/storage/domains/legacy-evals/index.d.ts +0 -19
  23. package/dist/storage/domains/legacy-evals/index.d.ts.map +0 -1
  24. package/dist/storage/domains/traces/index.d.ts +0 -28
  25. package/dist/storage/domains/traces/index.d.ts.map +0 -1
  26. package/src/entities/eval.ts +0 -102
  27. package/src/entities/index.ts +0 -27
  28. package/src/entities/message.ts +0 -143
  29. package/src/entities/resource.ts +0 -57
  30. package/src/entities/score.ts +0 -317
  31. package/src/entities/thread.ts +0 -66
  32. package/src/entities/trace.ts +0 -129
  33. package/src/entities/utils.ts +0 -51
  34. package/src/entities/workflow-snapshot.ts +0 -56
  35. package/src/index.ts +0 -1
  36. package/src/storage/docker-compose.yml +0 -16
  37. package/src/storage/domains/legacy-evals/index.ts +0 -243
  38. package/src/storage/domains/memory/index.ts +0 -894
  39. package/src/storage/domains/operations/index.ts +0 -433
  40. package/src/storage/domains/score/index.ts +0 -288
  41. package/src/storage/domains/traces/index.ts +0 -286
  42. package/src/storage/domains/workflows/index.ts +0 -297
  43. package/src/storage/index.test.ts +0 -1420
  44. package/src/storage/index.ts +0 -483
package/dist/index.js CHANGED
@@ -1,9 +1,10 @@
1
1
  import { DynamoDBClient, DescribeTableCommand } from '@aws-sdk/client-dynamodb';
2
2
  import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
3
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';
4
+ import { MastraStorage, createStorageErrorId, StoreOperations, WorkflowsStorage, normalizePerPage, MemoryStorage, calculatePagination, ScoresStorage, SCORERS_SCHEMA, TABLE_SPANS, TABLE_RESOURCES, TABLE_TRACES, TABLE_SCORERS, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, TABLE_THREADS } from '@mastra/core/storage';
5
5
  import { Entity, Service } from 'electrodb';
6
6
  import { MessageList } from '@mastra/core/agent';
7
+ import { saveScorePayloadSchema } from '@mastra/core/evals';
7
8
 
8
9
  // src/storage/index.ts
9
10
 
@@ -370,6 +371,10 @@ var scoreEntity = new Entity({
370
371
  type: "string",
371
372
  required: false
372
373
  },
374
+ spanId: {
375
+ type: "string",
376
+ required: false
377
+ },
373
378
  runId: {
374
379
  type: "string",
375
380
  required: true
@@ -418,6 +423,10 @@ var scoreEntity = new Entity({
418
423
  return value;
419
424
  }
420
425
  },
426
+ preprocessPrompt: {
427
+ type: "string",
428
+ required: false
429
+ },
421
430
  preprocessStepResult: {
422
431
  type: "string",
423
432
  required: false,
@@ -557,7 +566,7 @@ var scoreEntity = new Entity({
557
566
  return value;
558
567
  }
559
568
  },
560
- runtimeContext: {
569
+ requestContext: {
561
570
  type: "string",
562
571
  required: false,
563
572
  set: (value) => {
@@ -656,6 +665,11 @@ var scoreEntity = new Entity({
656
665
  index: "gsi6",
657
666
  pk: { field: "gsi6pk", composite: ["entity", "threadId"] },
658
667
  sk: { field: "gsi6sk", composite: ["createdAt"] }
668
+ },
669
+ bySpan: {
670
+ index: "gsi7",
671
+ pk: { field: "gsi7pk", composite: ["entity", "traceId", "spanId"] },
672
+ sk: { field: "gsi7sk", composite: ["createdAt"] }
659
673
  }
660
674
  }
661
675
  });
@@ -923,187 +937,6 @@ function getElectroDbService(client, tableName) {
923
937
  }
924
938
  );
925
939
  }
926
- var LegacyEvalsDynamoDB = class extends LegacyEvalsStorage {
927
- service;
928
- tableName;
929
- constructor({ service, tableName }) {
930
- super();
931
- this.service = service;
932
- this.tableName = tableName;
933
- }
934
- // Eval operations
935
- async getEvalsByAgentName(agentName, type) {
936
- this.logger.debug("Getting evals for agent", { agentName, type });
937
- try {
938
- const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
939
- const results = await query.go({ order: "desc", limit: 100 });
940
- if (!results.data.length) {
941
- return [];
942
- }
943
- let filteredData = results.data;
944
- if (type) {
945
- filteredData = filteredData.filter((evalRecord) => {
946
- try {
947
- const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
948
- if (type === "test" && !testInfo) {
949
- return false;
950
- }
951
- if (type === "live" && testInfo) {
952
- return false;
953
- }
954
- } catch (e) {
955
- this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
956
- }
957
- return true;
958
- });
959
- }
960
- return filteredData.map((evalRecord) => {
961
- try {
962
- return {
963
- input: evalRecord.input,
964
- output: evalRecord.output,
965
- // Safely parse result and test_info
966
- result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
967
- agentName: evalRecord.agent_name,
968
- createdAt: evalRecord.created_at,
969
- // Keep as string from DDB?
970
- metricName: evalRecord.metric_name,
971
- instructions: evalRecord.instructions,
972
- runId: evalRecord.run_id,
973
- globalRunId: evalRecord.global_run_id,
974
- testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
975
- };
976
- } catch (parseError) {
977
- this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
978
- return {
979
- agentName: evalRecord.agent_name,
980
- createdAt: evalRecord.created_at,
981
- runId: evalRecord.run_id,
982
- globalRunId: evalRecord.global_run_id
983
- };
984
- }
985
- });
986
- } catch (error) {
987
- throw new MastraError(
988
- {
989
- id: "STORAGE_DYNAMODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
990
- domain: ErrorDomain.STORAGE,
991
- category: ErrorCategory.THIRD_PARTY,
992
- details: { agentName }
993
- },
994
- error
995
- );
996
- }
997
- }
998
- async getEvals(options = {}) {
999
- const { agentName, type, page = 0, perPage = 100, dateRange } = options;
1000
- this.logger.debug("Getting evals with pagination", { agentName, type, page, perPage, dateRange });
1001
- try {
1002
- let query;
1003
- if (agentName) {
1004
- query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
1005
- } else {
1006
- query = this.service.entities.eval.query.byEntity({ entity: "eval" });
1007
- }
1008
- const results = await query.go({
1009
- order: "desc",
1010
- pages: "all"
1011
- // Get all pages to apply filtering and pagination
1012
- });
1013
- if (!results.data.length) {
1014
- return {
1015
- evals: [],
1016
- total: 0,
1017
- page,
1018
- perPage,
1019
- hasMore: false
1020
- };
1021
- }
1022
- let filteredData = results.data;
1023
- if (type) {
1024
- filteredData = filteredData.filter((evalRecord) => {
1025
- try {
1026
- const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
1027
- if (type === "test" && !testInfo) {
1028
- return false;
1029
- }
1030
- if (type === "live" && testInfo) {
1031
- return false;
1032
- }
1033
- } catch (e) {
1034
- this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
1035
- }
1036
- return true;
1037
- });
1038
- }
1039
- if (dateRange) {
1040
- const fromDate = dateRange.start;
1041
- const toDate = dateRange.end;
1042
- filteredData = filteredData.filter((evalRecord) => {
1043
- const recordDate = new Date(evalRecord.created_at);
1044
- if (fromDate && recordDate < fromDate) {
1045
- return false;
1046
- }
1047
- if (toDate && recordDate > toDate) {
1048
- return false;
1049
- }
1050
- return true;
1051
- });
1052
- }
1053
- const total = filteredData.length;
1054
- const start = page * perPage;
1055
- const end = start + perPage;
1056
- const paginatedData = filteredData.slice(start, end);
1057
- const evals = paginatedData.map((evalRecord) => {
1058
- try {
1059
- return {
1060
- input: evalRecord.input,
1061
- output: evalRecord.output,
1062
- result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
1063
- agentName: evalRecord.agent_name,
1064
- createdAt: evalRecord.created_at,
1065
- metricName: evalRecord.metric_name,
1066
- instructions: evalRecord.instructions,
1067
- runId: evalRecord.run_id,
1068
- globalRunId: evalRecord.global_run_id,
1069
- testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
1070
- };
1071
- } catch (parseError) {
1072
- this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
1073
- return {
1074
- agentName: evalRecord.agent_name,
1075
- createdAt: evalRecord.created_at,
1076
- runId: evalRecord.run_id,
1077
- globalRunId: evalRecord.global_run_id
1078
- };
1079
- }
1080
- });
1081
- const hasMore = end < total;
1082
- return {
1083
- evals,
1084
- total,
1085
- page,
1086
- perPage,
1087
- hasMore
1088
- };
1089
- } catch (error) {
1090
- throw new MastraError(
1091
- {
1092
- id: "STORAGE_DYNAMODB_STORE_GET_EVALS_FAILED",
1093
- domain: ErrorDomain.STORAGE,
1094
- category: ErrorCategory.THIRD_PARTY,
1095
- details: {
1096
- agentName: agentName || "all",
1097
- type: type || "all",
1098
- page,
1099
- perPage
1100
- }
1101
- },
1102
- error
1103
- );
1104
- }
1105
- }
1106
- };
1107
940
  var MemoryStorageDynamoDB = class extends MemoryStorage {
1108
941
  service;
1109
942
  constructor({ service }) {
@@ -1121,6 +954,20 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1121
954
  // transformed by the ElectroDB entity getters.
1122
955
  };
1123
956
  }
957
+ // Helper function to transform and sort threads
958
+ transformAndSortThreads(rawThreads, field, direction) {
959
+ return rawThreads.map((data) => ({
960
+ ...data,
961
+ // Convert date strings back to Date objects for consistency
962
+ createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
963
+ updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
964
+ })).sort((a, b) => {
965
+ const fieldA = field === "createdAt" ? a.createdAt : a.updatedAt;
966
+ const fieldB = field === "createdAt" ? b.createdAt : b.updatedAt;
967
+ const comparison = fieldA.getTime() - fieldB.getTime();
968
+ return direction === "DESC" ? -comparison : comparison;
969
+ });
970
+ }
1124
971
  async getThreadById({ threadId }) {
1125
972
  this.logger.debug("Getting thread by ID", { threadId });
1126
973
  try {
@@ -1140,7 +987,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1140
987
  } catch (error) {
1141
988
  throw new MastraError(
1142
989
  {
1143
- id: "STORAGE_DYNAMODB_STORE_GET_THREAD_BY_ID_FAILED",
990
+ id: createStorageErrorId("DYNAMODB", "GET_THREAD_BY_ID", "FAILED"),
1144
991
  domain: ErrorDomain.STORAGE,
1145
992
  category: ErrorCategory.THIRD_PARTY,
1146
993
  details: { threadId }
@@ -1149,33 +996,6 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1149
996
  );
1150
997
  }
1151
998
  }
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
999
  async saveThread({ thread }) {
1180
1000
  this.logger.debug("Saving thread", { threadId: thread.id });
1181
1001
  const now = /* @__PURE__ */ new Date();
@@ -1185,7 +1005,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1185
1005
  resourceId: thread.resourceId,
1186
1006
  title: thread.title || `Thread ${thread.id}`,
1187
1007
  createdAt: thread.createdAt?.toISOString() || now.toISOString(),
1188
- updatedAt: now.toISOString(),
1008
+ updatedAt: thread.updatedAt?.toISOString() || now.toISOString(),
1189
1009
  metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
1190
1010
  };
1191
1011
  try {
@@ -1195,13 +1015,13 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1195
1015
  resourceId: thread.resourceId,
1196
1016
  title: threadData.title,
1197
1017
  createdAt: thread.createdAt || now,
1198
- updatedAt: now,
1018
+ updatedAt: thread.updatedAt || now,
1199
1019
  metadata: thread.metadata
1200
1020
  };
1201
1021
  } catch (error) {
1202
1022
  throw new MastraError(
1203
1023
  {
1204
- id: "STORAGE_DYNAMODB_STORE_SAVE_THREAD_FAILED",
1024
+ id: createStorageErrorId("DYNAMODB", "SAVE_THREAD", "FAILED"),
1205
1025
  domain: ErrorDomain.STORAGE,
1206
1026
  category: ErrorCategory.THIRD_PARTY,
1207
1027
  details: { threadId: thread.id }
@@ -1243,7 +1063,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1243
1063
  } catch (error) {
1244
1064
  throw new MastraError(
1245
1065
  {
1246
- id: "STORAGE_DYNAMODB_STORE_UPDATE_THREAD_FAILED",
1066
+ id: createStorageErrorId("DYNAMODB", "UPDATE_THREAD", "FAILED"),
1247
1067
  domain: ErrorDomain.STORAGE,
1248
1068
  category: ErrorCategory.THIRD_PARTY,
1249
1069
  details: { threadId: id }
@@ -1255,7 +1075,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1255
1075
  async deleteThread({ threadId }) {
1256
1076
  this.logger.debug("Deleting thread", { threadId });
1257
1077
  try {
1258
- const messages = await this.getMessages({ threadId });
1078
+ const { messages } = await this.listMessages({ threadId, perPage: false });
1259
1079
  if (messages.length > 0) {
1260
1080
  const batchSize = 25;
1261
1081
  for (let i = 0; i < messages.length; i += batchSize) {
@@ -1275,7 +1095,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1275
1095
  } catch (error) {
1276
1096
  throw new MastraError(
1277
1097
  {
1278
- id: "STORAGE_DYNAMODB_STORE_DELETE_THREAD_FAILED",
1098
+ id: createStorageErrorId("DYNAMODB", "DELETE_THREAD", "FAILED"),
1279
1099
  domain: ErrorDomain.STORAGE,
1280
1100
  category: ErrorCategory.THIRD_PARTY,
1281
1101
  details: { threadId }
@@ -1284,73 +1104,176 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1284
1104
  );
1285
1105
  }
1286
1106
  }
1287
- async getMessages({
1288
- threadId,
1289
- resourceId,
1290
- selectBy,
1291
- format
1292
- }) {
1293
- this.logger.debug("Getting messages", { threadId, selectBy });
1107
+ async listMessagesById({ messageIds }) {
1108
+ this.logger.debug("Getting messages by ID", { messageIds });
1109
+ if (messageIds.length === 0) return { messages: [] };
1294
1110
  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
- }
1111
+ const results = await Promise.all(
1112
+ messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
1113
+ );
1114
+ const data = results.map((result) => result.data).flat(1);
1115
+ let parsedMessages = data.map((data2) => this.parseMessageData(data2)).filter((msg) => "content" in msg);
1116
+ const uniqueMessages = parsedMessages.filter(
1117
+ (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1118
+ );
1119
+ const list = new MessageList().add(uniqueMessages, "memory");
1120
+ return { messages: list.get.all.db() };
1121
+ } catch (error) {
1122
+ throw new MastraError(
1123
+ {
1124
+ id: createStorageErrorId("DYNAMODB", "LIST_MESSAGES_BY_ID", "FAILED"),
1125
+ domain: ErrorDomain.STORAGE,
1126
+ category: ErrorCategory.THIRD_PARTY,
1127
+ details: { messageIds: JSON.stringify(messageIds) }
1128
+ },
1129
+ error
1130
+ );
1131
+ }
1132
+ }
1133
+ async listMessages(args) {
1134
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1135
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
1136
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
1137
+ throw new MastraError(
1138
+ {
1139
+ id: createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_THREAD_ID"),
1140
+ domain: ErrorDomain.STORAGE,
1141
+ category: ErrorCategory.THIRD_PARTY,
1142
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
1143
+ },
1144
+ new Error("threadId must be a non-empty string or array of non-empty strings")
1145
+ );
1146
+ }
1147
+ const perPage = normalizePerPage(perPageInput, 40);
1148
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1149
+ try {
1150
+ if (page < 0) {
1151
+ throw new MastraError(
1152
+ {
1153
+ id: createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_PAGE"),
1154
+ domain: ErrorDomain.STORAGE,
1155
+ category: ErrorCategory.USER,
1156
+ details: { page }
1157
+ },
1158
+ new Error("page must be >= 0")
1159
+ );
1302
1160
  }
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);
1161
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1162
+ this.logger.debug("Getting messages with listMessages", {
1163
+ threadId,
1164
+ resourceId,
1165
+ perPageInput,
1166
+ offset,
1167
+ perPage,
1168
+ page,
1169
+ field,
1170
+ direction
1171
+ });
1172
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1173
+ const results = await query.go();
1174
+ let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
1175
+ if (resourceId) {
1176
+ allThreadMessages = allThreadMessages.filter((msg) => msg.resourceId === resourceId);
1177
+ }
1178
+ if (filter?.dateRange) {
1179
+ const dateRange = filter.dateRange;
1180
+ allThreadMessages = allThreadMessages.filter((msg) => {
1181
+ const createdAt = new Date(msg.createdAt).getTime();
1182
+ if (dateRange.start) {
1183
+ const startTime = dateRange.start instanceof Date ? dateRange.start.getTime() : new Date(dateRange.start).getTime();
1184
+ if (createdAt < startTime) return false;
1318
1185
  }
1319
- return timeA - timeB;
1186
+ if (dateRange.end) {
1187
+ const endTime = dateRange.end instanceof Date ? dateRange.end.getTime() : new Date(dateRange.end).getTime();
1188
+ if (createdAt > endTime) return false;
1189
+ }
1190
+ return true;
1320
1191
  });
1321
- messages.push(...allThreadMessages);
1322
1192
  }
1323
- messages.sort((a, b) => {
1324
- const timeA = a.createdAt.getTime();
1325
- const timeB = b.createdAt.getTime();
1326
- if (timeA === timeB) {
1193
+ allThreadMessages.sort((a, b) => {
1194
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1195
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1196
+ if (aValue === bValue) {
1327
1197
  return a.id.localeCompare(b.id);
1328
1198
  }
1329
- return timeA - timeB;
1199
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
1330
1200
  });
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();
1201
+ const total = allThreadMessages.length;
1202
+ const paginatedMessages = allThreadMessages.slice(offset, offset + perPage);
1203
+ const paginatedCount = paginatedMessages.length;
1204
+ if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
1205
+ return {
1206
+ messages: [],
1207
+ total: 0,
1208
+ page,
1209
+ perPage: perPageForResponse,
1210
+ hasMore: false
1211
+ };
1212
+ }
1213
+ const messageIds = new Set(paginatedMessages.map((m) => m.id));
1214
+ let includeMessages = [];
1215
+ if (include && include.length > 0) {
1216
+ const selectBy = { include };
1217
+ includeMessages = await this._getIncludedMessages(selectBy);
1218
+ for (const includeMsg of includeMessages) {
1219
+ if (!messageIds.has(includeMsg.id)) {
1220
+ paginatedMessages.push(includeMsg);
1221
+ messageIds.add(includeMsg.id);
1222
+ }
1223
+ }
1224
+ }
1225
+ const list = new MessageList().add(paginatedMessages, "memory");
1226
+ let finalMessages = list.get.all.db();
1227
+ finalMessages = finalMessages.sort((a, b) => {
1228
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1229
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1230
+ if (aValue === bValue) {
1231
+ return a.id.localeCompare(b.id);
1232
+ }
1233
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
1234
+ });
1235
+ const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1236
+ const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1237
+ let hasMore = false;
1238
+ if (perPageInput !== false && !allThreadMessagesReturned) {
1239
+ hasMore = offset + paginatedCount < total;
1240
+ }
1241
+ return {
1242
+ messages: finalMessages,
1243
+ total,
1244
+ page,
1245
+ perPage: perPageForResponse,
1246
+ hasMore
1247
+ };
1337
1248
  } catch (error) {
1338
- throw new MastraError(
1249
+ const mastraError = new MastraError(
1339
1250
  {
1340
- id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_FAILED",
1251
+ id: createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "FAILED"),
1341
1252
  domain: ErrorDomain.STORAGE,
1342
1253
  category: ErrorCategory.THIRD_PARTY,
1343
- details: { threadId }
1254
+ details: {
1255
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1256
+ resourceId: resourceId ?? ""
1257
+ }
1344
1258
  },
1345
1259
  error
1346
1260
  );
1261
+ this.logger?.error?.(mastraError.toString());
1262
+ this.logger?.trackException?.(mastraError);
1263
+ return {
1264
+ messages: [],
1265
+ total: 0,
1266
+ page,
1267
+ perPage: perPageForResponse,
1268
+ hasMore: false
1269
+ };
1347
1270
  }
1348
1271
  }
1349
1272
  async saveMessages(args) {
1350
- const { messages, format = "v1" } = args;
1273
+ const { messages } = args;
1351
1274
  this.logger.debug("Saving messages", { count: messages.length });
1352
1275
  if (!messages.length) {
1353
- return [];
1276
+ return { messages: [] };
1354
1277
  }
1355
1278
  const threadId = messages[0]?.threadId;
1356
1279
  if (!threadId) {
@@ -1404,12 +1327,11 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1404
1327
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1405
1328
  }).go();
1406
1329
  const list = new MessageList().add(messages, "memory");
1407
- if (format === `v1`) return list.get.all.v1();
1408
- return list.get.all.v2();
1330
+ return { messages: list.get.all.db() };
1409
1331
  } catch (error) {
1410
1332
  throw new MastraError(
1411
1333
  {
1412
- id: "STORAGE_DYNAMODB_STORE_SAVE_MESSAGES_FAILED",
1334
+ id: createStorageErrorId("DYNAMODB", "SAVE_MESSAGES", "FAILED"),
1413
1335
  domain: ErrorDomain.STORAGE,
1414
1336
  category: ErrorCategory.THIRD_PARTY,
1415
1337
  details: { count: messages.length }
@@ -1418,124 +1340,74 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1418
1340
  );
1419
1341
  }
1420
1342
  }
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) {
1343
+ async listThreadsByResourceId(args) {
1344
+ const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
1345
+ const perPage = normalizePerPage(perPageInput, 100);
1346
+ if (page < 0) {
1441
1347
  throw new MastraError(
1442
1348
  {
1443
- id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1349
+ id: createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
1444
1350
  domain: ErrorDomain.STORAGE,
1445
- category: ErrorCategory.THIRD_PARTY,
1446
- details: { resourceId, page, perPage }
1351
+ category: ErrorCategory.USER,
1352
+ details: { page }
1447
1353
  },
1448
- error
1354
+ new Error("page must be >= 0")
1449
1355
  );
1450
1356
  }
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 });
1357
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1358
+ const { field, direction } = this.parseOrderBy(orderBy);
1359
+ this.logger.debug("Getting threads by resource ID with pagination", {
1360
+ resourceId,
1361
+ page,
1362
+ perPage,
1363
+ field,
1364
+ direction
1365
+ });
1459
1366
  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();
1367
+ const query = this.service.entities.thread.query.byResource({ entity: "thread", resourceId });
1368
+ const results = await query.go();
1369
+ const allThreads = this.transformAndSortThreads(results.data, field, direction);
1370
+ const endIndex = offset + perPage;
1371
+ const paginatedThreads = allThreads.slice(offset, endIndex);
1372
+ const total = allThreads.length;
1373
+ const hasMore = offset + perPage < total;
1507
1374
  return {
1508
- messages: finalMessages,
1375
+ threads: paginatedThreads,
1509
1376
  total,
1510
1377
  page,
1511
- perPage,
1378
+ perPage: perPageForResponse,
1512
1379
  hasMore
1513
1380
  };
1514
1381
  } catch (error) {
1515
1382
  throw new MastraError(
1516
1383
  {
1517
- id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
1384
+ id: createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
1518
1385
  domain: ErrorDomain.STORAGE,
1519
1386
  category: ErrorCategory.THIRD_PARTY,
1520
- details: { threadId }
1387
+ details: { resourceId, page, perPage }
1521
1388
  },
1522
1389
  error
1523
1390
  );
1524
1391
  }
1525
1392
  }
1526
1393
  // Helper method to get included messages with context
1527
- async _getIncludedMessages(threadId, selectBy) {
1394
+ async _getIncludedMessages(selectBy) {
1528
1395
  if (!selectBy?.include?.length) {
1529
1396
  return [];
1530
1397
  }
1531
1398
  const includeMessages = [];
1532
1399
  for (const includeItem of selectBy.include) {
1533
1400
  try {
1534
- const { id, threadId: targetThreadId, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1535
- const searchThreadId = targetThreadId || threadId;
1401
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1402
+ const targetResult = await this.service.entities.message.get({ entity: "message", id }).go();
1403
+ if (!targetResult.data) {
1404
+ this.logger.warn("Target message not found", { id });
1405
+ continue;
1406
+ }
1407
+ const targetMessageData = targetResult.data;
1408
+ const searchThreadId = targetMessageData.threadId;
1536
1409
  this.logger.debug("Getting included messages for", {
1537
1410
  id,
1538
- targetThreadId,
1539
1411
  searchThreadId,
1540
1412
  withPreviousMessages,
1541
1413
  withNextMessages
@@ -1558,7 +1430,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1558
1430
  });
1559
1431
  const targetIndex = allMessages.findIndex((msg) => msg.id === id);
1560
1432
  if (targetIndex === -1) {
1561
- this.logger.warn("Target message not found", { id, threadId: searchThreadId });
1433
+ this.logger.warn("Target message not found in thread", { id, threadId: searchThreadId });
1562
1434
  continue;
1563
1435
  }
1564
1436
  this.logger.debug("Found target message at index", { id, targetIndex, totalMessages: allMessages.length });
@@ -1643,7 +1515,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1643
1515
  } catch (error) {
1644
1516
  throw new MastraError(
1645
1517
  {
1646
- id: "STORAGE_DYNAMODB_STORE_UPDATE_MESSAGES_FAILED",
1518
+ id: createStorageErrorId("DYNAMODB", "UPDATE_MESSAGES", "FAILED"),
1647
1519
  domain: ErrorDomain.STORAGE,
1648
1520
  category: ErrorCategory.THIRD_PARTY,
1649
1521
  details: { count: messages.length }
@@ -1672,7 +1544,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1672
1544
  } catch (error) {
1673
1545
  throw new MastraError(
1674
1546
  {
1675
- id: "STORAGE_DYNAMODB_STORE_GET_RESOURCE_BY_ID_FAILED",
1547
+ id: createStorageErrorId("DYNAMODB", "GET_RESOURCE_BY_ID", "FAILED"),
1676
1548
  domain: ErrorDomain.STORAGE,
1677
1549
  category: ErrorCategory.THIRD_PARTY,
1678
1550
  details: { resourceId }
@@ -1704,7 +1576,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1704
1576
  } catch (error) {
1705
1577
  throw new MastraError(
1706
1578
  {
1707
- id: "STORAGE_DYNAMODB_STORE_SAVE_RESOURCE_FAILED",
1579
+ id: createStorageErrorId("DYNAMODB", "SAVE_RESOURCE", "FAILED"),
1708
1580
  domain: ErrorDomain.STORAGE,
1709
1581
  category: ErrorCategory.THIRD_PARTY,
1710
1582
  details: { resourceId: resource.id }
@@ -1753,7 +1625,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
1753
1625
  } catch (error) {
1754
1626
  throw new MastraError(
1755
1627
  {
1756
- id: "STORAGE_DYNAMODB_STORE_UPDATE_RESOURCE_FAILED",
1628
+ id: createStorageErrorId("DYNAMODB", "UPDATE_RESOURCE", "FAILED"),
1757
1629
  domain: ErrorDomain.STORAGE,
1758
1630
  category: ErrorCategory.THIRD_PARTY,
1759
1631
  details: { resourceId }
@@ -1788,10 +1660,11 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1788
1660
  [TABLE_THREADS]: "thread",
1789
1661
  [TABLE_MESSAGES]: "message",
1790
1662
  [TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
1791
- [TABLE_EVALS]: "eval",
1792
1663
  [TABLE_SCORERS]: "score",
1793
1664
  [TABLE_TRACES]: "trace",
1794
- [TABLE_RESOURCES]: "resource"
1665
+ [TABLE_RESOURCES]: "resource",
1666
+ [TABLE_SPANS]: "ai_span",
1667
+ mastra_agents: "agent"
1795
1668
  };
1796
1669
  return mapping[tableName] || null;
1797
1670
  }
@@ -1853,7 +1726,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1853
1726
  }
1854
1727
  throw new MastraError(
1855
1728
  {
1856
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
1729
+ id: createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_EXISTS", "FAILED"),
1857
1730
  domain: ErrorDomain.STORAGE,
1858
1731
  category: ErrorCategory.THIRD_PARTY,
1859
1732
  details: { tableName: this.tableName }
@@ -1886,7 +1759,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1886
1759
  this.logger.error("Error validating table access", { tableName: this.tableName, error });
1887
1760
  throw new MastraError(
1888
1761
  {
1889
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_ACCESS_FAILED",
1762
+ id: createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_ACCESS", "FAILED"),
1890
1763
  domain: ErrorDomain.STORAGE,
1891
1764
  category: ErrorCategory.THIRD_PARTY,
1892
1765
  details: { tableName: this.tableName }
@@ -1900,7 +1773,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1900
1773
  const entityName = this.getEntityNameForTable(tableName);
1901
1774
  if (!entityName || !this.service.entities[entityName]) {
1902
1775
  throw new MastraError({
1903
- id: "STORAGE_DYNAMODB_STORE_INSERT_INVALID_ARGS",
1776
+ id: createStorageErrorId("DYNAMODB", "INSERT", "INVALID_ARGS"),
1904
1777
  domain: ErrorDomain.STORAGE,
1905
1778
  category: ErrorCategory.USER,
1906
1779
  text: "No entity defined for tableName",
@@ -1913,7 +1786,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1913
1786
  } catch (error) {
1914
1787
  throw new MastraError(
1915
1788
  {
1916
- id: "STORAGE_DYNAMODB_STORE_INSERT_FAILED",
1789
+ id: createStorageErrorId("DYNAMODB", "INSERT", "FAILED"),
1917
1790
  domain: ErrorDomain.STORAGE,
1918
1791
  category: ErrorCategory.THIRD_PARTY,
1919
1792
  details: { tableName }
@@ -1932,7 +1805,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1932
1805
  const entityName = this.getEntityNameForTable(tableName);
1933
1806
  if (!entityName || !this.service.entities[entityName]) {
1934
1807
  throw new MastraError({
1935
- id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_INVALID_ARGS",
1808
+ id: createStorageErrorId("DYNAMODB", "CLEAR_TABLE", "INVALID_ARGS"),
1936
1809
  domain: ErrorDomain.STORAGE,
1937
1810
  category: ErrorCategory.USER,
1938
1811
  text: "No entity defined for tableName",
@@ -1976,6 +1849,10 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1976
1849
  if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
1977
1850
  key.id = item.id;
1978
1851
  break;
1852
+ case "resource":
1853
+ if (!item.id) throw new Error(`Missing required key 'id' for entity 'resource'`);
1854
+ key.id = item.id;
1855
+ break;
1979
1856
  default:
1980
1857
  this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
1981
1858
  throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
@@ -1991,7 +1868,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
1991
1868
  } catch (error) {
1992
1869
  throw new MastraError(
1993
1870
  {
1994
- id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_FAILED",
1871
+ id: createStorageErrorId("DYNAMODB", "CLEAR_TABLE", "FAILED"),
1995
1872
  domain: ErrorDomain.STORAGE,
1996
1873
  category: ErrorCategory.THIRD_PARTY,
1997
1874
  details: { tableName }
@@ -2008,7 +1885,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
2008
1885
  const entityName = this.getEntityNameForTable(tableName);
2009
1886
  if (!entityName || !this.service.entities[entityName]) {
2010
1887
  throw new MastraError({
2011
- id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_INVALID_ARGS",
1888
+ id: createStorageErrorId("DYNAMODB", "BATCH_INSERT", "INVALID_ARGS"),
2012
1889
  domain: ErrorDomain.STORAGE,
2013
1890
  category: ErrorCategory.USER,
2014
1891
  text: "No entity defined for tableName",
@@ -2036,7 +1913,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
2036
1913
  } catch (error) {
2037
1914
  throw new MastraError(
2038
1915
  {
2039
- id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_FAILED",
1916
+ id: createStorageErrorId("DYNAMODB", "BATCH_INSERT", "FAILED"),
2040
1917
  domain: ErrorDomain.STORAGE,
2041
1918
  category: ErrorCategory.THIRD_PARTY,
2042
1919
  details: { tableName }
@@ -2053,7 +1930,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
2053
1930
  const entityName = this.getEntityNameForTable(tableName);
2054
1931
  if (!entityName || !this.service.entities[entityName]) {
2055
1932
  throw new MastraError({
2056
- id: "STORAGE_DYNAMODB_STORE_LOAD_INVALID_ARGS",
1933
+ id: createStorageErrorId("DYNAMODB", "LOAD", "INVALID_ARGS"),
2057
1934
  domain: ErrorDomain.STORAGE,
2058
1935
  category: ErrorCategory.USER,
2059
1936
  text: "No entity defined for tableName",
@@ -2071,7 +1948,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
2071
1948
  } catch (error) {
2072
1949
  throw new MastraError(
2073
1950
  {
2074
- id: "STORAGE_DYNAMODB_STORE_LOAD_FAILED",
1951
+ id: createStorageErrorId("DYNAMODB", "LOAD", "FAILED"),
2075
1952
  domain: ErrorDomain.STORAGE,
2076
1953
  category: ErrorCategory.THIRD_PARTY,
2077
1954
  details: { tableName }
@@ -2087,14 +1964,28 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2087
1964
  super();
2088
1965
  this.service = service;
2089
1966
  }
2090
- // Helper function to parse score data (handle JSON fields)
1967
+ /**
1968
+ * DynamoDB-specific score row transformation.
1969
+ *
1970
+ * Note: This implementation does NOT use coreTransformScoreRow because:
1971
+ * 1. ElectroDB already parses JSON fields via its entity getters
1972
+ * 2. DynamoDB stores empty strings for null values (which need special handling)
1973
+ * 3. 'entity' is a reserved ElectroDB key, so we use 'entityData' column
1974
+ */
2091
1975
  parseScoreData(data) {
1976
+ const result = {};
1977
+ for (const key of Object.keys(SCORERS_SCHEMA)) {
1978
+ if (["traceId", "resourceId", "threadId", "spanId"].includes(key)) {
1979
+ result[key] = data[key] === "" ? null : data[key];
1980
+ continue;
1981
+ }
1982
+ result[key] = data[key];
1983
+ }
1984
+ result.entity = data.entityData ?? null;
2092
1985
  return {
2093
- ...data,
2094
- // Convert date strings back to Date objects for consistency
1986
+ ...result,
2095
1987
  createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
2096
1988
  updatedAt: data.updatedAt ? new Date(data.updatedAt) : /* @__PURE__ */ new Date()
2097
- // JSON fields are already transformed by the entity's getters
2098
1989
  };
2099
1990
  }
2100
1991
  async getScoreById({ id }) {
@@ -2108,7 +1999,7 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2108
1999
  } catch (error) {
2109
2000
  throw new MastraError(
2110
2001
  {
2111
- id: "STORAGE_DYNAMODB_STORE_GET_SCORE_BY_ID_FAILED",
2002
+ id: createStorageErrorId("DYNAMODB", "GET_SCORE_BY_ID", "FAILED"),
2112
2003
  domain: ErrorDomain.STORAGE,
2113
2004
  category: ErrorCategory.THIRD_PARTY,
2114
2005
  details: { id }
@@ -2118,50 +2009,69 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2118
2009
  }
2119
2010
  }
2120
2011
  async saveScore(score) {
2121
- this.logger.debug("Saving score", { scorerId: score.scorerId, runId: score.runId });
2012
+ let validatedScore;
2013
+ try {
2014
+ validatedScore = saveScorePayloadSchema.parse(score);
2015
+ } catch (error) {
2016
+ throw new MastraError(
2017
+ {
2018
+ id: createStorageErrorId("DYNAMODB", "SAVE_SCORE", "VALIDATION_FAILED"),
2019
+ domain: ErrorDomain.STORAGE,
2020
+ category: ErrorCategory.USER,
2021
+ details: {
2022
+ scorer: score.scorer?.id ?? "unknown",
2023
+ entityId: score.entityId ?? "unknown",
2024
+ entityType: score.entityType ?? "unknown",
2025
+ traceId: score.traceId ?? "",
2026
+ spanId: score.spanId ?? ""
2027
+ }
2028
+ },
2029
+ error
2030
+ );
2031
+ }
2122
2032
  const now = /* @__PURE__ */ new Date();
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()
2151
- };
2033
+ const scoreId = crypto.randomUUID();
2034
+ const scorer = typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer);
2035
+ const preprocessStepResult = typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult);
2036
+ const analyzeStepResult = typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult);
2037
+ const input = typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input);
2038
+ const output = typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output);
2039
+ const requestContext = typeof validatedScore.requestContext === "string" ? validatedScore.requestContext : JSON.stringify(validatedScore.requestContext);
2040
+ const entity = typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity);
2041
+ const scoreData = Object.fromEntries(
2042
+ Object.entries({
2043
+ ...validatedScore,
2044
+ entity: "score",
2045
+ id: scoreId,
2046
+ scorer,
2047
+ preprocessStepResult,
2048
+ analyzeStepResult,
2049
+ input,
2050
+ output,
2051
+ requestContext,
2052
+ entityData: entity,
2053
+ traceId: validatedScore.traceId || "",
2054
+ resourceId: validatedScore.resourceId || "",
2055
+ threadId: validatedScore.threadId || "",
2056
+ spanId: validatedScore.spanId || "",
2057
+ createdAt: now.toISOString(),
2058
+ updatedAt: now.toISOString()
2059
+ }).filter(([_, value]) => value !== void 0 && value !== null)
2060
+ );
2152
2061
  try {
2153
2062
  await this.service.entities.score.upsert(scoreData).go();
2154
- const savedScore = {
2155
- ...score,
2156
- id: scoreId,
2157
- createdAt: now,
2158
- updatedAt: now
2063
+ return {
2064
+ score: {
2065
+ ...validatedScore,
2066
+ id: scoreId,
2067
+ createdAt: now,
2068
+ updatedAt: now
2069
+ }
2159
2070
  };
2160
- return { score: savedScore };
2161
2071
  } catch (error) {
2162
2072
  throw new MastraError(
2163
2073
  {
2164
- id: "STORAGE_DYNAMODB_STORE_SAVE_SCORE_FAILED",
2074
+ id: createStorageErrorId("DYNAMODB", "SAVE_SCORE", "FAILED"),
2165
2075
  domain: ErrorDomain.STORAGE,
2166
2076
  category: ErrorCategory.THIRD_PARTY,
2167
2077
  details: { scorerId: score.scorerId, runId: score.runId }
@@ -2170,13 +2080,13 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2170
2080
  );
2171
2081
  }
2172
2082
  }
2173
- async getScoresByScorerId({
2083
+ async listScoresByScorerId({
2174
2084
  scorerId,
2175
2085
  pagination,
2176
2086
  entityId,
2177
- entityType
2087
+ entityType,
2088
+ source
2178
2089
  }) {
2179
- this.logger.debug("Getting scores by scorer ID", { scorerId, pagination, entityId, entityType });
2180
2090
  try {
2181
2091
  const query = this.service.entities.score.query.byScorer({ entity: "score", scorerId });
2182
2092
  const results = await query.go();
@@ -2187,31 +2097,36 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2187
2097
  if (entityType) {
2188
2098
  allScores = allScores.filter((score) => score.entityType === entityType);
2189
2099
  }
2100
+ if (source) {
2101
+ allScores = allScores.filter((score) => score.source === source);
2102
+ }
2190
2103
  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);
2104
+ const { page, perPage: perPageInput } = pagination;
2105
+ const perPage = normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2106
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2194
2107
  const total = allScores.length;
2195
- const hasMore = endIndex < total;
2108
+ const end = perPageInput === false ? allScores.length : start + perPage;
2109
+ const paginatedScores = allScores.slice(start, end);
2196
2110
  return {
2197
2111
  scores: paginatedScores,
2198
2112
  pagination: {
2199
2113
  total,
2200
- page: pagination.page,
2201
- perPage: pagination.perPage,
2202
- hasMore
2114
+ page,
2115
+ perPage: perPageForResponse,
2116
+ hasMore: end < total
2203
2117
  }
2204
2118
  };
2205
2119
  } catch (error) {
2206
2120
  throw new MastraError(
2207
2121
  {
2208
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_SCORER_ID_FAILED",
2122
+ id: createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
2209
2123
  domain: ErrorDomain.STORAGE,
2210
2124
  category: ErrorCategory.THIRD_PARTY,
2211
2125
  details: {
2212
2126
  scorerId: scorerId || "",
2213
2127
  entityId: entityId || "",
2214
2128
  entityType: entityType || "",
2129
+ source: source || "",
2215
2130
  page: pagination.page,
2216
2131
  perPage: pagination.perPage
2217
2132
  }
@@ -2220,7 +2135,7 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2220
2135
  );
2221
2136
  }
2222
2137
  }
2223
- async getScoresByRunId({
2138
+ async listScoresByRunId({
2224
2139
  runId,
2225
2140
  pagination
2226
2141
  }) {
@@ -2230,24 +2145,25 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2230
2145
  const results = await query.go();
2231
2146
  const allScores = results.data.map((data) => this.parseScoreData(data));
2232
2147
  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);
2148
+ const { page, perPage: perPageInput } = pagination;
2149
+ const perPage = normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2150
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2236
2151
  const total = allScores.length;
2237
- const hasMore = endIndex < total;
2152
+ const end = perPageInput === false ? allScores.length : start + perPage;
2153
+ const paginatedScores = allScores.slice(start, end);
2238
2154
  return {
2239
2155
  scores: paginatedScores,
2240
2156
  pagination: {
2241
2157
  total,
2242
- page: pagination.page,
2243
- perPage: pagination.perPage,
2244
- hasMore
2158
+ page,
2159
+ perPage: perPageForResponse,
2160
+ hasMore: end < total
2245
2161
  }
2246
2162
  };
2247
2163
  } catch (error) {
2248
2164
  throw new MastraError(
2249
2165
  {
2250
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_RUN_ID_FAILED",
2166
+ id: createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_RUN_ID", "FAILED"),
2251
2167
  domain: ErrorDomain.STORAGE,
2252
2168
  category: ErrorCategory.THIRD_PARTY,
2253
2169
  details: { runId, page: pagination.page, perPage: pagination.perPage }
@@ -2256,7 +2172,7 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2256
2172
  );
2257
2173
  }
2258
2174
  }
2259
- async getScoresByEntityId({
2175
+ async listScoresByEntityId({
2260
2176
  entityId,
2261
2177
  entityType,
2262
2178
  pagination
@@ -2268,24 +2184,25 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2268
2184
  let allScores = results.data.map((data) => this.parseScoreData(data));
2269
2185
  allScores = allScores.filter((score) => score.entityType === entityType);
2270
2186
  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);
2187
+ const { page, perPage: perPageInput } = pagination;
2188
+ const perPage = normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2189
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2274
2190
  const total = allScores.length;
2275
- const hasMore = endIndex < total;
2191
+ const end = perPageInput === false ? allScores.length : start + perPage;
2192
+ const paginatedScores = allScores.slice(start, end);
2276
2193
  return {
2277
2194
  scores: paginatedScores,
2278
2195
  pagination: {
2279
2196
  total,
2280
- page: pagination.page,
2281
- perPage: pagination.perPage,
2282
- hasMore
2197
+ page,
2198
+ perPage: perPageForResponse,
2199
+ hasMore: end < total
2283
2200
  }
2284
2201
  };
2285
2202
  } catch (error) {
2286
2203
  throw new MastraError(
2287
2204
  {
2288
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_ENTITY_ID_FAILED",
2205
+ id: createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
2289
2206
  domain: ErrorDomain.STORAGE,
2290
2207
  category: ErrorCategory.THIRD_PARTY,
2291
2208
  details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
@@ -2294,234 +2211,39 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
2294
2211
  );
2295
2212
  }
2296
2213
  }
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;
2305
- }
2306
- // Trace operations
2307
- async getTraces(args) {
2308
- const { name, scope, page, perPage } = args;
2309
- this.logger.debug("Getting traces", { name, scope, page, perPage });
2310
- try {
2311
- let query;
2312
- if (name) {
2313
- query = this.service.entities.trace.query.byName({ entity: "trace", name });
2314
- } else if (scope) {
2315
- query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
2316
- } else {
2317
- this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
2318
- query = this.service.entities.trace.scan;
2319
- }
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 });
2214
+ async listScoresBySpan({
2215
+ traceId,
2216
+ spanId,
2217
+ pagination
2218
+ }) {
2219
+ this.logger.debug("Getting scores by span", { traceId, spanId, pagination });
2375
2220
  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,
2221
+ const query = this.service.entities.score.query.bySpan({ entity: "score", traceId, spanId });
2222
+ const results = await query.go();
2223
+ const allScores = results.data.map((data) => this.parseScoreData(data));
2224
+ allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2225
+ const { page, perPage: perPageInput } = pagination;
2226
+ const perPage = normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2227
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
2228
+ const total = allScores.length;
2229
+ const end = perPageInput === false ? allScores.length : start + perPage;
2230
+ const paginatedScores = allScores.slice(start, end);
2231
+ return {
2232
+ scores: paginatedScores,
2233
+ pagination: {
2234
+ total,
2394
2235
  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
- }
2236
+ perPage: perPageForResponse,
2237
+ hasMore: end < total
2458
2238
  }
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
- }
2470
- }
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
- };
2511
- });
2512
- return {
2513
- traces,
2514
- total,
2515
- page,
2516
- perPage,
2517
- hasMore: end < total
2518
2239
  };
2519
2240
  } catch (error) {
2520
2241
  throw new MastraError(
2521
2242
  {
2522
- id: "STORAGE_DYNAMODB_STORE_GET_TRACES_PAGINATED_FAILED",
2243
+ id: createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SPAN", "FAILED"),
2523
2244
  domain: ErrorDomain.STORAGE,
2524
- category: ErrorCategory.THIRD_PARTY
2245
+ category: ErrorCategory.THIRD_PARTY,
2246
+ details: { traceId, spanId, page: pagination.page, perPage: pagination.perPage }
2525
2247
  },
2526
2248
  error
2527
2249
  );
@@ -2544,15 +2266,31 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2544
2266
  super();
2545
2267
  this.service = service;
2546
2268
  }
2269
+ updateWorkflowResults({
2270
+ // workflowName,
2271
+ // runId,
2272
+ // stepId,
2273
+ // result,
2274
+ // requestContext,
2275
+ }) {
2276
+ throw new Error("Method not implemented.");
2277
+ }
2278
+ updateWorkflowState({
2279
+ // workflowName,
2280
+ // runId,
2281
+ // opts,
2282
+ }) {
2283
+ throw new Error("Method not implemented.");
2284
+ }
2547
2285
  // Workflow operations
2548
2286
  async persistWorkflowSnapshot({
2549
2287
  workflowName,
2550
2288
  runId,
2289
+ resourceId,
2551
2290
  snapshot
2552
2291
  }) {
2553
2292
  this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
2554
2293
  try {
2555
- const resourceId = "resourceId" in snapshot ? snapshot.resourceId : void 0;
2556
2294
  const now = (/* @__PURE__ */ new Date()).toISOString();
2557
2295
  const data = {
2558
2296
  entity: "workflow_snapshot",
@@ -2560,7 +2298,6 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2560
2298
  workflow_name: workflowName,
2561
2299
  run_id: runId,
2562
2300
  snapshot: JSON.stringify(snapshot),
2563
- // Stringify the snapshot object
2564
2301
  createdAt: now,
2565
2302
  updatedAt: now,
2566
2303
  resourceId
@@ -2569,7 +2306,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2569
2306
  } catch (error) {
2570
2307
  throw new MastraError(
2571
2308
  {
2572
- id: "STORAGE_DYNAMODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
2309
+ id: createStorageErrorId("DYNAMODB", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
2573
2310
  domain: ErrorDomain.STORAGE,
2574
2311
  category: ErrorCategory.THIRD_PARTY,
2575
2312
  details: { workflowName, runId }
@@ -2597,7 +2334,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2597
2334
  } catch (error) {
2598
2335
  throw new MastraError(
2599
2336
  {
2600
- id: "STORAGE_DYNAMODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
2337
+ id: createStorageErrorId("DYNAMODB", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
2601
2338
  domain: ErrorDomain.STORAGE,
2602
2339
  category: ErrorCategory.THIRD_PARTY,
2603
2340
  details: { workflowName, runId }
@@ -2606,11 +2343,24 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2606
2343
  );
2607
2344
  }
2608
2345
  }
2609
- async getWorkflowRuns(args) {
2346
+ async listWorkflowRuns(args) {
2610
2347
  this.logger.debug("Getting workflow runs", { args });
2611
2348
  try {
2612
- const limit = args?.limit || 10;
2613
- const offset = args?.offset || 0;
2349
+ const perPage = args?.perPage !== void 0 ? args.perPage : 10;
2350
+ const page = args?.page !== void 0 ? args.page : 0;
2351
+ if (page < 0) {
2352
+ throw new MastraError(
2353
+ {
2354
+ id: createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "INVALID_PAGE"),
2355
+ domain: ErrorDomain.STORAGE,
2356
+ category: ErrorCategory.USER,
2357
+ details: { page }
2358
+ },
2359
+ new Error("page must be >= 0")
2360
+ );
2361
+ }
2362
+ const normalizedPerPage = normalizePerPage(perPage, 10);
2363
+ const offset = page * normalizedPerPage;
2614
2364
  let query;
2615
2365
  if (args?.workflowName) {
2616
2366
  query = this.service.entities.workflow_snapshot.query.primary({
@@ -2632,6 +2382,11 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2632
2382
  });
2633
2383
  if (pageResults.data && pageResults.data.length > 0) {
2634
2384
  let pageFilteredData = pageResults.data;
2385
+ if (args?.status) {
2386
+ pageFilteredData = pageFilteredData.filter((snapshot) => {
2387
+ return snapshot.snapshot.status === args.status;
2388
+ });
2389
+ }
2635
2390
  if (args?.fromDate || args?.toDate) {
2636
2391
  pageFilteredData = pageFilteredData.filter((snapshot) => {
2637
2392
  const createdAt = new Date(snapshot.createdAt);
@@ -2657,7 +2412,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2657
2412
  return { runs: [], total: 0 };
2658
2413
  }
2659
2414
  const total = allMatchingSnapshots.length;
2660
- const paginatedData = allMatchingSnapshots.slice(offset, offset + limit);
2415
+ const paginatedData = allMatchingSnapshots.slice(offset, offset + normalizedPerPage);
2661
2416
  const runs = paginatedData.map((snapshot) => formatWorkflowRun(snapshot));
2662
2417
  return {
2663
2418
  runs,
@@ -2666,7 +2421,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2666
2421
  } catch (error) {
2667
2422
  throw new MastraError(
2668
2423
  {
2669
- id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUNS_FAILED",
2424
+ id: createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "FAILED"),
2670
2425
  domain: ErrorDomain.STORAGE,
2671
2426
  category: ErrorCategory.THIRD_PARTY,
2672
2427
  details: { workflowName: args?.workflowName || "", resourceId: args?.resourceId || "" }
@@ -2678,8 +2433,6 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2678
2433
  async getWorkflowRunById(args) {
2679
2434
  const { runId, workflowName } = args;
2680
2435
  this.logger.debug("Getting workflow run by ID", { runId, workflowName });
2681
- console.log("workflowName", workflowName);
2682
- console.log("runId", runId);
2683
2436
  try {
2684
2437
  if (workflowName) {
2685
2438
  this.logger.debug("WorkflowName provided, using direct GET operation.");
@@ -2689,7 +2442,6 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2689
2442
  workflow_name: workflowName,
2690
2443
  run_id: runId
2691
2444
  }).go();
2692
- console.log("result", result2);
2693
2445
  if (!result2.data) {
2694
2446
  return null;
2695
2447
  }
@@ -2723,7 +2475,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
2723
2475
  } catch (error) {
2724
2476
  throw new MastraError(
2725
2477
  {
2726
- id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2478
+ id: createStorageErrorId("DYNAMODB", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
2727
2479
  domain: ErrorDomain.STORAGE,
2728
2480
  category: ErrorCategory.THIRD_PARTY,
2729
2481
  details: { runId, workflowName: args?.workflowName || "" }
@@ -2742,7 +2494,7 @@ var DynamoDBStore = class extends MastraStorage {
2742
2494
  hasInitialized = null;
2743
2495
  stores;
2744
2496
  constructor({ name, config }) {
2745
- super({ name });
2497
+ super({ id: config.id, name, disableInit: config.disableInit });
2746
2498
  try {
2747
2499
  if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
2748
2500
  throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
@@ -2765,14 +2517,11 @@ var DynamoDBStore = class extends MastraStorage {
2765
2517
  tableName: this.tableName,
2766
2518
  client: this.client
2767
2519
  });
2768
- const traces = new TracesStorageDynamoDB({ service: this.service, operations });
2769
2520
  const workflows = new WorkflowStorageDynamoDB({ service: this.service });
2770
2521
  const memory = new MemoryStorageDynamoDB({ service: this.service });
2771
2522
  const scores = new ScoresStorageDynamoDB({ service: this.service });
2772
2523
  this.stores = {
2773
2524
  operations,
2774
- legacyEvals: new LegacyEvalsDynamoDB({ service: this.service, tableName: this.tableName }),
2775
- traces,
2776
2525
  workflows,
2777
2526
  memory,
2778
2527
  scores
@@ -2780,7 +2529,7 @@ var DynamoDBStore = class extends MastraStorage {
2780
2529
  } catch (error) {
2781
2530
  throw new MastraError(
2782
2531
  {
2783
- id: "STORAGE_DYNAMODB_STORE_CONSTRUCTOR_FAILED",
2532
+ id: createStorageErrorId("DYNAMODB", "CONSTRUCTOR", "FAILED"),
2784
2533
  domain: ErrorDomain.STORAGE,
2785
2534
  category: ErrorCategory.USER
2786
2535
  },
@@ -2794,7 +2543,8 @@ var DynamoDBStore = class extends MastraStorage {
2794
2543
  resourceWorkingMemory: true,
2795
2544
  hasColumn: false,
2796
2545
  createTable: false,
2797
- deleteMessages: false
2546
+ deleteMessages: false,
2547
+ listScoresBySpan: true
2798
2548
  };
2799
2549
  }
2800
2550
  /**
@@ -2815,7 +2565,7 @@ var DynamoDBStore = class extends MastraStorage {
2815
2565
  }
2816
2566
  throw new MastraError(
2817
2567
  {
2818
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
2568
+ id: createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_EXISTS", "FAILED"),
2819
2569
  domain: ErrorDomain.STORAGE,
2820
2570
  category: ErrorCategory.THIRD_PARTY,
2821
2571
  details: { tableName: this.tableName }
@@ -2838,7 +2588,7 @@ var DynamoDBStore = class extends MastraStorage {
2838
2588
  } catch (error) {
2839
2589
  throw new MastraError(
2840
2590
  {
2841
- id: "STORAGE_DYNAMODB_STORE_INIT_FAILED",
2591
+ id: createStorageErrorId("DYNAMODB", "INIT", "FAILED"),
2842
2592
  domain: ErrorDomain.STORAGE,
2843
2593
  category: ErrorCategory.THIRD_PARTY,
2844
2594
  details: { tableName: this.tableName }
@@ -2889,9 +2639,6 @@ var DynamoDBStore = class extends MastraStorage {
2889
2639
  async getThreadById({ threadId }) {
2890
2640
  return this.stores.memory.getThreadById({ threadId });
2891
2641
  }
2892
- async getThreadsByResourceId({ resourceId }) {
2893
- return this.stores.memory.getThreadsByResourceId({ resourceId });
2894
- }
2895
2642
  async saveThread({ thread }) {
2896
2643
  return this.stores.memory.saveThread({ thread });
2897
2644
  }
@@ -2905,43 +2652,39 @@ var DynamoDBStore = class extends MastraStorage {
2905
2652
  async deleteThread({ threadId }) {
2906
2653
  return this.stores.memory.deleteThread({ threadId });
2907
2654
  }
2908
- async getMessages({
2909
- threadId,
2910
- resourceId,
2911
- selectBy,
2912
- format
2913
- }) {
2914
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
2655
+ async listMessagesById(args) {
2656
+ return this.stores.memory.listMessagesById(args);
2915
2657
  }
2916
2658
  async saveMessages(args) {
2917
2659
  return this.stores.memory.saveMessages(args);
2918
2660
  }
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
2661
  async updateMessages(_args) {
2926
2662
  return this.stores.memory.updateMessages(_args);
2927
2663
  }
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 });
2664
+ // Workflow operations
2665
+ async updateWorkflowResults({
2666
+ workflowName,
2667
+ runId,
2668
+ stepId,
2669
+ result,
2670
+ requestContext
2671
+ }) {
2672
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
2934
2673
  }
2935
- async getTracesPaginated(_args) {
2936
- return this.stores.traces.getTracesPaginated(_args);
2674
+ async updateWorkflowState({
2675
+ workflowName,
2676
+ runId,
2677
+ opts
2678
+ }) {
2679
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
2937
2680
  }
2938
- // Workflow operations
2939
2681
  async persistWorkflowSnapshot({
2940
2682
  workflowName,
2941
2683
  runId,
2684
+ resourceId,
2942
2685
  snapshot
2943
2686
  }) {
2944
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2687
+ return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2945
2688
  }
2946
2689
  async loadWorkflowSnapshot({
2947
2690
  workflowName,
@@ -2949,8 +2692,8 @@ var DynamoDBStore = class extends MastraStorage {
2949
2692
  }) {
2950
2693
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2951
2694
  }
2952
- async getWorkflowRuns(args) {
2953
- return this.stores.workflows.getWorkflowRuns(args);
2695
+ async listWorkflowRuns(args) {
2696
+ return this.stores.workflows.listWorkflowRuns(args);
2954
2697
  }
2955
2698
  async getWorkflowRunById(args) {
2956
2699
  return this.stores.workflows.getWorkflowRunById(args);
@@ -2968,13 +2711,6 @@ var DynamoDBStore = class extends MastraStorage {
2968
2711
  }) {
2969
2712
  return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
2970
2713
  }
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
- }
2978
2714
  /**
2979
2715
  * Closes the DynamoDB client connection and cleans up resources.
2980
2716
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
@@ -2987,7 +2723,7 @@ var DynamoDBStore = class extends MastraStorage {
2987
2723
  } catch (error) {
2988
2724
  throw new MastraError(
2989
2725
  {
2990
- id: "STORAGE_DYNAMODB_STORE_CLOSE_FAILED",
2726
+ id: createStorageErrorId("DYNAMODB", "CLOSE", "FAILED"),
2991
2727
  domain: ErrorDomain.STORAGE,
2992
2728
  category: ErrorCategory.THIRD_PARTY
2993
2729
  },
@@ -3001,31 +2737,41 @@ var DynamoDBStore = class extends MastraStorage {
3001
2737
  async getScoreById({ id: _id }) {
3002
2738
  return this.stores.scores.getScoreById({ id: _id });
3003
2739
  }
3004
- async saveScore(_score) {
3005
- return this.stores.scores.saveScore(_score);
2740
+ async saveScore(score) {
2741
+ return this.stores.scores.saveScore(score);
3006
2742
  }
3007
- async getScoresByRunId({
2743
+ async listScoresByRunId({
3008
2744
  runId: _runId,
3009
2745
  pagination: _pagination
3010
2746
  }) {
3011
- return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
2747
+ return this.stores.scores.listScoresByRunId({ runId: _runId, pagination: _pagination });
3012
2748
  }
3013
- async getScoresByEntityId({
2749
+ async listScoresByEntityId({
3014
2750
  entityId: _entityId,
3015
2751
  entityType: _entityType,
3016
2752
  pagination: _pagination
3017
2753
  }) {
3018
- return this.stores.scores.getScoresByEntityId({
2754
+ return this.stores.scores.listScoresByEntityId({
3019
2755
  entityId: _entityId,
3020
2756
  entityType: _entityType,
3021
2757
  pagination: _pagination
3022
2758
  });
3023
2759
  }
3024
- async getScoresByScorerId({
3025
- scorerId: _scorerId,
3026
- pagination: _pagination
2760
+ async listScoresByScorerId({
2761
+ scorerId,
2762
+ source,
2763
+ entityId,
2764
+ entityType,
2765
+ pagination
2766
+ }) {
2767
+ return this.stores.scores.listScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
2768
+ }
2769
+ async listScoresBySpan({
2770
+ traceId,
2771
+ spanId,
2772
+ pagination
3027
2773
  }) {
3028
- return this.stores.scores.getScoresByScorerId({ scorerId: _scorerId, pagination: _pagination });
2774
+ return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
3029
2775
  }
3030
2776
  };
3031
2777