@mastra/dynamodb 0.0.0-netlify-no-bundle-20251127120354 → 0.0.0-partial-response-backport-20251204204441

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.
package/dist/index.cjs CHANGED
@@ -6,7 +6,7 @@ var error = require('@mastra/core/error');
6
6
  var storage = require('@mastra/core/storage');
7
7
  var electrodb = require('electrodb');
8
8
  var agent = require('@mastra/core/agent');
9
- var evals = require('@mastra/core/evals');
9
+ var scores = require('@mastra/core/scores');
10
10
 
11
11
  // src/storage/index.ts
12
12
 
@@ -568,7 +568,7 @@ var scoreEntity = new electrodb.Entity({
568
568
  return value;
569
569
  }
570
570
  },
571
- requestContext: {
571
+ runtimeContext: {
572
572
  type: "string",
573
573
  required: false,
574
574
  set: (value) => {
@@ -939,6 +939,187 @@ function getElectroDbService(client, tableName) {
939
939
  }
940
940
  );
941
941
  }
942
+ var LegacyEvalsDynamoDB = class extends storage.LegacyEvalsStorage {
943
+ service;
944
+ tableName;
945
+ constructor({ service, tableName }) {
946
+ super();
947
+ this.service = service;
948
+ this.tableName = tableName;
949
+ }
950
+ // Eval operations
951
+ async getEvalsByAgentName(agentName, type) {
952
+ this.logger.debug("Getting evals for agent", { agentName, type });
953
+ try {
954
+ const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
955
+ const results = await query.go({ order: "desc", limit: 100 });
956
+ if (!results.data.length) {
957
+ return [];
958
+ }
959
+ let filteredData = results.data;
960
+ if (type) {
961
+ filteredData = filteredData.filter((evalRecord) => {
962
+ try {
963
+ const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
964
+ if (type === "test" && !testInfo) {
965
+ return false;
966
+ }
967
+ if (type === "live" && testInfo) {
968
+ return false;
969
+ }
970
+ } catch (e) {
971
+ this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
972
+ }
973
+ return true;
974
+ });
975
+ }
976
+ return filteredData.map((evalRecord) => {
977
+ try {
978
+ return {
979
+ input: evalRecord.input,
980
+ output: evalRecord.output,
981
+ // Safely parse result and test_info
982
+ result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
983
+ agentName: evalRecord.agent_name,
984
+ createdAt: evalRecord.created_at,
985
+ // Keep as string from DDB?
986
+ metricName: evalRecord.metric_name,
987
+ instructions: evalRecord.instructions,
988
+ runId: evalRecord.run_id,
989
+ globalRunId: evalRecord.global_run_id,
990
+ testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
991
+ };
992
+ } catch (parseError) {
993
+ this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
994
+ return {
995
+ agentName: evalRecord.agent_name,
996
+ createdAt: evalRecord.created_at,
997
+ runId: evalRecord.run_id,
998
+ globalRunId: evalRecord.global_run_id
999
+ };
1000
+ }
1001
+ });
1002
+ } catch (error$1) {
1003
+ throw new error.MastraError(
1004
+ {
1005
+ id: "STORAGE_DYNAMODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
1006
+ domain: error.ErrorDomain.STORAGE,
1007
+ category: error.ErrorCategory.THIRD_PARTY,
1008
+ details: { agentName }
1009
+ },
1010
+ error$1
1011
+ );
1012
+ }
1013
+ }
1014
+ async getEvals(options = {}) {
1015
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
1016
+ this.logger.debug("Getting evals with pagination", { agentName, type, page, perPage, dateRange });
1017
+ try {
1018
+ let query;
1019
+ if (agentName) {
1020
+ query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
1021
+ } else {
1022
+ query = this.service.entities.eval.query.byEntity({ entity: "eval" });
1023
+ }
1024
+ const results = await query.go({
1025
+ order: "desc",
1026
+ pages: "all"
1027
+ // Get all pages to apply filtering and pagination
1028
+ });
1029
+ if (!results.data.length) {
1030
+ return {
1031
+ evals: [],
1032
+ total: 0,
1033
+ page,
1034
+ perPage,
1035
+ hasMore: false
1036
+ };
1037
+ }
1038
+ let filteredData = results.data;
1039
+ if (type) {
1040
+ filteredData = filteredData.filter((evalRecord) => {
1041
+ try {
1042
+ const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
1043
+ if (type === "test" && !testInfo) {
1044
+ return false;
1045
+ }
1046
+ if (type === "live" && testInfo) {
1047
+ return false;
1048
+ }
1049
+ } catch (e) {
1050
+ this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
1051
+ }
1052
+ return true;
1053
+ });
1054
+ }
1055
+ if (dateRange) {
1056
+ const fromDate = dateRange.start;
1057
+ const toDate = dateRange.end;
1058
+ filteredData = filteredData.filter((evalRecord) => {
1059
+ const recordDate = new Date(evalRecord.created_at);
1060
+ if (fromDate && recordDate < fromDate) {
1061
+ return false;
1062
+ }
1063
+ if (toDate && recordDate > toDate) {
1064
+ return false;
1065
+ }
1066
+ return true;
1067
+ });
1068
+ }
1069
+ const total = filteredData.length;
1070
+ const start = page * perPage;
1071
+ const end = start + perPage;
1072
+ const paginatedData = filteredData.slice(start, end);
1073
+ const evals = paginatedData.map((evalRecord) => {
1074
+ try {
1075
+ return {
1076
+ input: evalRecord.input,
1077
+ output: evalRecord.output,
1078
+ result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
1079
+ agentName: evalRecord.agent_name,
1080
+ createdAt: evalRecord.created_at,
1081
+ metricName: evalRecord.metric_name,
1082
+ instructions: evalRecord.instructions,
1083
+ runId: evalRecord.run_id,
1084
+ globalRunId: evalRecord.global_run_id,
1085
+ testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
1086
+ };
1087
+ } catch (parseError) {
1088
+ this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
1089
+ return {
1090
+ agentName: evalRecord.agent_name,
1091
+ createdAt: evalRecord.created_at,
1092
+ runId: evalRecord.run_id,
1093
+ globalRunId: evalRecord.global_run_id
1094
+ };
1095
+ }
1096
+ });
1097
+ const hasMore = end < total;
1098
+ return {
1099
+ evals,
1100
+ total,
1101
+ page,
1102
+ perPage,
1103
+ hasMore
1104
+ };
1105
+ } catch (error$1) {
1106
+ throw new error.MastraError(
1107
+ {
1108
+ id: "STORAGE_DYNAMODB_STORE_GET_EVALS_FAILED",
1109
+ domain: error.ErrorDomain.STORAGE,
1110
+ category: error.ErrorCategory.THIRD_PARTY,
1111
+ details: {
1112
+ agentName: agentName || "all",
1113
+ type: type || "all",
1114
+ page,
1115
+ perPage
1116
+ }
1117
+ },
1118
+ error$1
1119
+ );
1120
+ }
1121
+ }
1122
+ };
942
1123
  var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
943
1124
  service;
944
1125
  constructor({ service }) {
@@ -957,17 +1138,17 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
957
1138
  };
958
1139
  }
959
1140
  // Helper function to transform and sort threads
960
- transformAndSortThreads(rawThreads, field, direction) {
1141
+ transformAndSortThreads(rawThreads, orderBy, sortDirection) {
961
1142
  return rawThreads.map((data) => ({
962
1143
  ...data,
963
1144
  // Convert date strings back to Date objects for consistency
964
1145
  createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
965
1146
  updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
966
1147
  })).sort((a, b) => {
967
- const fieldA = field === "createdAt" ? a.createdAt : a.updatedAt;
968
- const fieldB = field === "createdAt" ? b.createdAt : b.updatedAt;
1148
+ const fieldA = orderBy === "createdAt" ? a.createdAt : a.updatedAt;
1149
+ const fieldB = orderBy === "createdAt" ? b.createdAt : b.updatedAt;
969
1150
  const comparison = fieldA.getTime() - fieldB.getTime();
970
- return direction === "DESC" ? -comparison : comparison;
1151
+ return sortDirection === "DESC" ? -comparison : comparison;
971
1152
  });
972
1153
  }
973
1154
  async getThreadById({ threadId }) {
@@ -998,6 +1179,32 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
998
1179
  );
999
1180
  }
1000
1181
  }
1182
+ /**
1183
+ * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
1184
+ */
1185
+ async getThreadsByResourceId(args) {
1186
+ const resourceId = args.resourceId;
1187
+ const orderBy = this.castThreadOrderBy(args.orderBy);
1188
+ const sortDirection = this.castThreadSortDirection(args.sortDirection);
1189
+ this.logger.debug("Getting threads by resource ID", { resourceId, orderBy, sortDirection });
1190
+ try {
1191
+ const result = await this.service.entities.thread.query.byResource({ entity: "thread", resourceId }).go();
1192
+ if (!result.data.length) {
1193
+ return [];
1194
+ }
1195
+ return this.transformAndSortThreads(result.data, orderBy, sortDirection);
1196
+ } catch (error$1) {
1197
+ throw new error.MastraError(
1198
+ {
1199
+ id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1200
+ domain: error.ErrorDomain.STORAGE,
1201
+ category: error.ErrorCategory.THIRD_PARTY,
1202
+ details: { resourceId }
1203
+ },
1204
+ error$1
1205
+ );
1206
+ }
1207
+ }
1001
1208
  async saveThread({ thread }) {
1002
1209
  this.logger.debug("Saving thread", { threadId: thread.id });
1003
1210
  const now = /* @__PURE__ */ new Date();
@@ -1017,7 +1224,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1017
1224
  resourceId: thread.resourceId,
1018
1225
  title: threadData.title,
1019
1226
  createdAt: thread.createdAt || now,
1020
- updatedAt: thread.updatedAt || now,
1227
+ updatedAt: now,
1021
1228
  metadata: thread.metadata
1022
1229
  };
1023
1230
  } catch (error$1) {
@@ -1077,7 +1284,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1077
1284
  async deleteThread({ threadId }) {
1078
1285
  this.logger.debug("Deleting thread", { threadId });
1079
1286
  try {
1080
- const { messages } = await this.listMessages({ threadId, perPage: false });
1287
+ const messages = await this.getMessages({ threadId });
1081
1288
  if (messages.length > 0) {
1082
1289
  const batchSize = 25;
1083
1290
  for (let i = 0; i < messages.length; i += batchSize) {
@@ -1106,175 +1313,104 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1106
1313
  );
1107
1314
  }
1108
1315
  }
1109
- async listMessagesById({ messageIds }) {
1110
- this.logger.debug("Getting messages by ID", { messageIds });
1111
- if (messageIds.length === 0) return { messages: [] };
1316
+ async getMessages({
1317
+ threadId,
1318
+ resourceId,
1319
+ selectBy,
1320
+ format
1321
+ }) {
1322
+ this.logger.debug("Getting messages", { threadId, selectBy });
1112
1323
  try {
1113
- const results = await Promise.all(
1114
- messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
1115
- );
1116
- const data = results.map((result) => result.data).flat(1);
1117
- let parsedMessages = data.map((data2) => this.parseMessageData(data2)).filter((msg) => "content" in msg);
1118
- const uniqueMessages = parsedMessages.filter(
1324
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1325
+ const messages = [];
1326
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1327
+ if (selectBy?.include?.length) {
1328
+ const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1329
+ if (includeMessages) {
1330
+ messages.push(...includeMessages);
1331
+ }
1332
+ }
1333
+ if (limit !== 0) {
1334
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1335
+ let results;
1336
+ if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1337
+ results = await query.go({ limit, order: "desc" });
1338
+ results.data = results.data.reverse();
1339
+ } else {
1340
+ results = await query.go();
1341
+ }
1342
+ let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1343
+ allThreadMessages.sort((a, b) => {
1344
+ const timeA = a.createdAt.getTime();
1345
+ const timeB = b.createdAt.getTime();
1346
+ if (timeA === timeB) {
1347
+ return a.id.localeCompare(b.id);
1348
+ }
1349
+ return timeA - timeB;
1350
+ });
1351
+ messages.push(...allThreadMessages);
1352
+ }
1353
+ messages.sort((a, b) => {
1354
+ const timeA = a.createdAt.getTime();
1355
+ const timeB = b.createdAt.getTime();
1356
+ if (timeA === timeB) {
1357
+ return a.id.localeCompare(b.id);
1358
+ }
1359
+ return timeA - timeB;
1360
+ });
1361
+ const uniqueMessages = messages.filter(
1119
1362
  (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1120
1363
  );
1121
- const list = new agent.MessageList().add(uniqueMessages, "memory");
1122
- return { messages: list.get.all.db() };
1364
+ const list = new agent.MessageList({ threadId, resourceId }).add(uniqueMessages, "memory");
1365
+ if (format === `v2`) return list.get.all.v2();
1366
+ return list.get.all.v1();
1123
1367
  } catch (error$1) {
1124
1368
  throw new error.MastraError(
1125
1369
  {
1126
- id: "STORAGE_DYNAMODB_STORE_LIST_MESSAGES_BY_ID_FAILED",
1370
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_FAILED",
1127
1371
  domain: error.ErrorDomain.STORAGE,
1128
1372
  category: error.ErrorCategory.THIRD_PARTY,
1129
- details: { messageIds: JSON.stringify(messageIds) }
1373
+ details: { threadId, resourceId: resourceId ?? "" }
1130
1374
  },
1131
1375
  error$1
1132
1376
  );
1133
1377
  }
1134
1378
  }
1135
- async listMessages(args) {
1136
- const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1137
- if (!threadId.trim()) {
1138
- throw new error.MastraError(
1139
- {
1140
- id: "STORAGE_DYNAMODB_LIST_MESSAGES_INVALID_THREAD_ID",
1141
- domain: error.ErrorDomain.STORAGE,
1142
- category: error.ErrorCategory.THIRD_PARTY,
1143
- details: { threadId }
1144
- },
1145
- new Error("threadId must be a non-empty string")
1146
- );
1147
- }
1148
- const perPage = storage.normalizePerPage(perPageInput, 40);
1149
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1379
+ async getMessagesById({
1380
+ messageIds,
1381
+ format
1382
+ }) {
1383
+ this.logger.debug("Getting messages by ID", { messageIds });
1384
+ if (messageIds.length === 0) return [];
1150
1385
  try {
1151
- if (page < 0) {
1152
- throw new error.MastraError(
1153
- {
1154
- id: "STORAGE_DYNAMODB_LIST_MESSAGES_INVALID_PAGE",
1155
- domain: error.ErrorDomain.STORAGE,
1156
- category: error.ErrorCategory.USER,
1157
- details: { page }
1158
- },
1159
- new Error("page must be >= 0")
1160
- );
1161
- }
1162
- const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1163
- this.logger.debug("Getting messages with listMessages", {
1164
- threadId,
1165
- resourceId,
1166
- perPageInput,
1167
- offset,
1168
- perPage,
1169
- page,
1170
- field,
1171
- direction
1172
- });
1173
- const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1174
- const results = await query.go();
1175
- let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
1176
- if (resourceId) {
1177
- allThreadMessages = allThreadMessages.filter((msg) => msg.resourceId === resourceId);
1178
- }
1179
- if (filter?.dateRange) {
1180
- const dateRange = filter.dateRange;
1181
- allThreadMessages = allThreadMessages.filter((msg) => {
1182
- const createdAt = new Date(msg.createdAt).getTime();
1183
- if (dateRange.start) {
1184
- const startTime = dateRange.start instanceof Date ? dateRange.start.getTime() : new Date(dateRange.start).getTime();
1185
- if (createdAt < startTime) return false;
1186
- }
1187
- if (dateRange.end) {
1188
- const endTime = dateRange.end instanceof Date ? dateRange.end.getTime() : new Date(dateRange.end).getTime();
1189
- if (createdAt > endTime) return false;
1190
- }
1191
- return true;
1192
- });
1193
- }
1194
- allThreadMessages.sort((a, b) => {
1195
- const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1196
- const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1197
- if (aValue === bValue) {
1198
- return a.id.localeCompare(b.id);
1199
- }
1200
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
1201
- });
1202
- const total = allThreadMessages.length;
1203
- const paginatedMessages = allThreadMessages.slice(offset, offset + perPage);
1204
- const paginatedCount = paginatedMessages.length;
1205
- if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
1206
- return {
1207
- messages: [],
1208
- total: 0,
1209
- page,
1210
- perPage: perPageForResponse,
1211
- hasMore: false
1212
- };
1213
- }
1214
- const messageIds = new Set(paginatedMessages.map((m) => m.id));
1215
- let includeMessages = [];
1216
- if (include && include.length > 0) {
1217
- const selectBy = { include };
1218
- includeMessages = await this._getIncludedMessages(threadId, selectBy);
1219
- for (const includeMsg of includeMessages) {
1220
- if (!messageIds.has(includeMsg.id)) {
1221
- paginatedMessages.push(includeMsg);
1222
- messageIds.add(includeMsg.id);
1223
- }
1224
- }
1225
- }
1226
- const list = new agent.MessageList().add(paginatedMessages, "memory");
1227
- let finalMessages = list.get.all.db();
1228
- finalMessages = finalMessages.sort((a, b) => {
1229
- const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1230
- const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1231
- if (aValue === bValue) {
1232
- return a.id.localeCompare(b.id);
1233
- }
1234
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
1235
- });
1236
- const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1237
- const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1238
- let hasMore = false;
1239
- if (perPageInput !== false && !allThreadMessagesReturned) {
1240
- hasMore = offset + paginatedCount < total;
1241
- }
1242
- return {
1243
- messages: finalMessages,
1244
- total,
1245
- page,
1246
- perPage: perPageForResponse,
1247
- hasMore
1248
- };
1386
+ const results = await Promise.all(
1387
+ messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
1388
+ );
1389
+ const data = results.map((result) => result.data).flat(1);
1390
+ let parsedMessages = data.map((data2) => this.parseMessageData(data2)).filter((msg) => "content" in msg);
1391
+ const uniqueMessages = parsedMessages.filter(
1392
+ (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1393
+ );
1394
+ const list = new agent.MessageList().add(uniqueMessages, "memory");
1395
+ if (format === `v1`) return list.get.all.v1();
1396
+ return list.get.all.v2();
1249
1397
  } catch (error$1) {
1250
- const mastraError = new error.MastraError(
1398
+ throw new error.MastraError(
1251
1399
  {
1252
- id: "STORAGE_DYNAMODB_STORE_LIST_MESSAGES_FAILED",
1400
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_BY_ID_FAILED",
1253
1401
  domain: error.ErrorDomain.STORAGE,
1254
1402
  category: error.ErrorCategory.THIRD_PARTY,
1255
- details: {
1256
- threadId,
1257
- resourceId: resourceId ?? ""
1258
- }
1403
+ details: { messageIds: JSON.stringify(messageIds) }
1259
1404
  },
1260
1405
  error$1
1261
1406
  );
1262
- this.logger?.error?.(mastraError.toString());
1263
- this.logger?.trackException?.(mastraError);
1264
- return {
1265
- messages: [],
1266
- total: 0,
1267
- page,
1268
- perPage: perPageForResponse,
1269
- hasMore: false
1270
- };
1271
1407
  }
1272
1408
  }
1273
1409
  async saveMessages(args) {
1274
- const { messages } = args;
1410
+ const { messages, format = "v1" } = args;
1275
1411
  this.logger.debug("Saving messages", { count: messages.length });
1276
1412
  if (!messages.length) {
1277
- return { messages: [] };
1413
+ return [];
1278
1414
  }
1279
1415
  const threadId = messages[0]?.threadId;
1280
1416
  if (!threadId) {
@@ -1328,7 +1464,8 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1328
1464
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1329
1465
  }).go();
1330
1466
  const list = new agent.MessageList().add(messages, "memory");
1331
- return { messages: list.get.all.db() };
1467
+ if (format === `v1`) return list.get.all.v1();
1468
+ return list.get.all.v2();
1332
1469
  } catch (error$1) {
1333
1470
  throw new error.MastraError(
1334
1471
  {
@@ -1341,48 +1478,37 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1341
1478
  );
1342
1479
  }
1343
1480
  }
1344
- async listThreadsByResourceId(args) {
1345
- const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
1346
- const perPage = storage.normalizePerPage(perPageInput, 100);
1347
- if (page < 0) {
1348
- throw new error.MastraError(
1349
- {
1350
- id: "STORAGE_DYNAMODB_LIST_THREADS_BY_RESOURCE_ID_INVALID_PAGE",
1351
- domain: error.ErrorDomain.STORAGE,
1352
- category: error.ErrorCategory.USER,
1353
- details: { page }
1354
- },
1355
- new Error("page must be >= 0")
1356
- );
1357
- }
1358
- const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1359
- const { field, direction } = this.parseOrderBy(orderBy);
1481
+ async getThreadsByResourceIdPaginated(args) {
1482
+ const { resourceId, page = 0, perPage = 100 } = args;
1483
+ const orderBy = this.castThreadOrderBy(args.orderBy);
1484
+ const sortDirection = this.castThreadSortDirection(args.sortDirection);
1360
1485
  this.logger.debug("Getting threads by resource ID with pagination", {
1361
1486
  resourceId,
1362
1487
  page,
1363
1488
  perPage,
1364
- field,
1365
- direction
1489
+ orderBy,
1490
+ sortDirection
1366
1491
  });
1367
1492
  try {
1368
1493
  const query = this.service.entities.thread.query.byResource({ entity: "thread", resourceId });
1369
1494
  const results = await query.go();
1370
- const allThreads = this.transformAndSortThreads(results.data, field, direction);
1371
- const endIndex = offset + perPage;
1372
- const paginatedThreads = allThreads.slice(offset, endIndex);
1495
+ const allThreads = this.transformAndSortThreads(results.data, orderBy, sortDirection);
1496
+ const startIndex = page * perPage;
1497
+ const endIndex = startIndex + perPage;
1498
+ const paginatedThreads = allThreads.slice(startIndex, endIndex);
1373
1499
  const total = allThreads.length;
1374
- const hasMore = offset + perPage < total;
1500
+ const hasMore = endIndex < total;
1375
1501
  return {
1376
1502
  threads: paginatedThreads,
1377
1503
  total,
1378
1504
  page,
1379
- perPage: perPageForResponse,
1505
+ perPage,
1380
1506
  hasMore
1381
1507
  };
1382
1508
  } catch (error$1) {
1383
1509
  throw new error.MastraError(
1384
1510
  {
1385
- id: "DYNAMODB_STORAGE_LIST_THREADS_BY_RESOURCE_ID_FAILED",
1511
+ id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1386
1512
  domain: error.ErrorDomain.STORAGE,
1387
1513
  category: error.ErrorCategory.THIRD_PARTY,
1388
1514
  details: { resourceId, page, perPage }
@@ -1391,6 +1517,85 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1391
1517
  );
1392
1518
  }
1393
1519
  }
1520
+ async getMessagesPaginated(args) {
1521
+ const { threadId, resourceId, selectBy, format = "v1" } = args;
1522
+ const { page = 0, perPage = 40, dateRange } = selectBy?.pagination || {};
1523
+ const fromDate = dateRange?.start;
1524
+ const toDate = dateRange?.end;
1525
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1526
+ this.logger.debug("Getting messages with pagination", { threadId, page, perPage, fromDate, toDate, limit });
1527
+ try {
1528
+ if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1529
+ let messages = [];
1530
+ if (selectBy?.include?.length) {
1531
+ const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1532
+ if (includeMessages) {
1533
+ messages.push(...includeMessages);
1534
+ }
1535
+ }
1536
+ if (limit !== 0) {
1537
+ const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1538
+ let results;
1539
+ if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1540
+ results = await query.go({ limit, order: "desc" });
1541
+ results.data = results.data.reverse();
1542
+ } else {
1543
+ results = await query.go();
1544
+ }
1545
+ let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1546
+ allThreadMessages.sort((a, b) => {
1547
+ const timeA = a.createdAt.getTime();
1548
+ const timeB = b.createdAt.getTime();
1549
+ if (timeA === timeB) {
1550
+ return a.id.localeCompare(b.id);
1551
+ }
1552
+ return timeA - timeB;
1553
+ });
1554
+ const excludeIds = messages.map((m) => m.id);
1555
+ if (excludeIds.length > 0) {
1556
+ allThreadMessages = allThreadMessages.filter((msg) => !excludeIds.includes(msg.id));
1557
+ }
1558
+ messages.push(...allThreadMessages);
1559
+ }
1560
+ messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1561
+ if (fromDate || toDate) {
1562
+ messages = messages.filter((msg) => {
1563
+ const createdAt = new Date(msg.createdAt).getTime();
1564
+ if (fromDate && createdAt < new Date(fromDate).getTime()) return false;
1565
+ if (toDate && createdAt > new Date(toDate).getTime()) return false;
1566
+ return true;
1567
+ });
1568
+ }
1569
+ const total = messages.length;
1570
+ const start = page * perPage;
1571
+ const end = start + perPage;
1572
+ const paginatedMessages = messages.slice(start, end);
1573
+ const hasMore = end < total;
1574
+ const list = new agent.MessageList({ threadId, resourceId }).add(paginatedMessages, "memory");
1575
+ let finalMessages = format === "v2" ? list.get.all.v2() : list.get.all.v1();
1576
+ finalMessages = finalMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1577
+ return {
1578
+ messages: finalMessages,
1579
+ total,
1580
+ page,
1581
+ perPage,
1582
+ hasMore
1583
+ };
1584
+ } catch (error$1) {
1585
+ const mastraError = new error.MastraError(
1586
+ {
1587
+ id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
1588
+ domain: error.ErrorDomain.STORAGE,
1589
+ category: error.ErrorCategory.THIRD_PARTY,
1590
+ details: { threadId, resourceId: resourceId ?? "" }
1591
+ },
1592
+ error$1
1593
+ );
1594
+ this.logger?.trackException?.(mastraError);
1595
+ this.logger?.error?.(mastraError.toString());
1596
+ return { messages: [], total: 0, page, perPage, hasMore: false };
1597
+ }
1598
+ }
1394
1599
  // Helper method to get included messages with context
1395
1600
  async _getIncludedMessages(threadId, selectBy) {
1396
1601
  if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
@@ -1657,10 +1862,11 @@ var StoreOperationsDynamoDB = class extends storage.StoreOperations {
1657
1862
  [storage.TABLE_THREADS]: "thread",
1658
1863
  [storage.TABLE_MESSAGES]: "message",
1659
1864
  [storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
1865
+ [storage.TABLE_EVALS]: "eval",
1660
1866
  [storage.TABLE_SCORERS]: "score",
1661
1867
  [storage.TABLE_TRACES]: "trace",
1662
1868
  [storage.TABLE_RESOURCES]: "resource",
1663
- [storage.TABLE_SPANS]: "ai_span"
1869
+ [storage.TABLE_AI_SPANS]: "ai_span"
1664
1870
  };
1665
1871
  return mapping[tableName] || null;
1666
1872
  }
@@ -1845,10 +2051,6 @@ var StoreOperationsDynamoDB = class extends storage.StoreOperations {
1845
2051
  if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
1846
2052
  key.id = item.id;
1847
2053
  break;
1848
- case "resource":
1849
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'resource'`);
1850
- key.id = item.id;
1851
- break;
1852
2054
  default:
1853
2055
  this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
1854
2056
  throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
@@ -2002,7 +2204,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2002
2204
  async saveScore(score) {
2003
2205
  let validatedScore;
2004
2206
  try {
2005
- validatedScore = evals.saveScorePayloadSchema.parse(score);
2207
+ validatedScore = scores.saveScorePayloadSchema.parse(score);
2006
2208
  } catch (error$1) {
2007
2209
  throw new error.MastraError(
2008
2210
  {
@@ -2015,33 +2217,35 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2015
2217
  }
2016
2218
  const now = /* @__PURE__ */ new Date();
2017
2219
  const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
2018
- const scorer = typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer);
2019
- const preprocessStepResult = typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult);
2020
- const analyzeStepResult = typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult);
2021
- const input = typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input);
2022
- const output = typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output);
2023
- const requestContext = typeof validatedScore.requestContext === "string" ? validatedScore.requestContext : JSON.stringify(validatedScore.requestContext);
2024
- const entity = typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity);
2025
- const scoreData = Object.fromEntries(
2026
- Object.entries({
2027
- ...validatedScore,
2028
- entity: "score",
2029
- id: scoreId,
2030
- scorer,
2031
- preprocessStepResult,
2032
- analyzeStepResult,
2033
- input,
2034
- output,
2035
- requestContext,
2036
- entityData: entity,
2037
- traceId: validatedScore.traceId || "",
2038
- resourceId: validatedScore.resourceId || "",
2039
- threadId: validatedScore.threadId || "",
2040
- spanId: validatedScore.spanId || "",
2041
- createdAt: now.toISOString(),
2042
- updatedAt: now.toISOString()
2043
- }).filter(([_, value]) => value !== void 0 && value !== null)
2044
- );
2220
+ const scoreData = {
2221
+ entity: "score",
2222
+ id: scoreId,
2223
+ scorerId: validatedScore.scorerId,
2224
+ traceId: validatedScore.traceId || "",
2225
+ spanId: validatedScore.spanId || "",
2226
+ runId: validatedScore.runId,
2227
+ scorer: typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer),
2228
+ preprocessStepResult: typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult),
2229
+ analyzeStepResult: typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult),
2230
+ score: validatedScore.score,
2231
+ reason: validatedScore.reason,
2232
+ preprocessPrompt: validatedScore.preprocessPrompt,
2233
+ generateScorePrompt: validatedScore.generateScorePrompt,
2234
+ generateReasonPrompt: validatedScore.generateReasonPrompt,
2235
+ analyzePrompt: validatedScore.analyzePrompt,
2236
+ input: typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input),
2237
+ output: typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output),
2238
+ additionalContext: typeof validatedScore.additionalContext === "string" ? validatedScore.additionalContext : JSON.stringify(validatedScore.additionalContext),
2239
+ runtimeContext: typeof validatedScore.runtimeContext === "string" ? validatedScore.runtimeContext : JSON.stringify(validatedScore.runtimeContext),
2240
+ entityType: validatedScore.entityType,
2241
+ entityData: typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity),
2242
+ entityId: validatedScore.entityId,
2243
+ source: validatedScore.source,
2244
+ resourceId: validatedScore.resourceId || "",
2245
+ threadId: validatedScore.threadId || "",
2246
+ createdAt: now.toISOString(),
2247
+ updatedAt: now.toISOString()
2248
+ };
2045
2249
  try {
2046
2250
  await this.service.entities.score.upsert(scoreData).go();
2047
2251
  const savedScore = {
@@ -2063,7 +2267,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2063
2267
  );
2064
2268
  }
2065
2269
  }
2066
- async listScoresByScorerId({
2270
+ async getScoresByScorerId({
2067
2271
  scorerId,
2068
2272
  pagination,
2069
2273
  entityId,
@@ -2084,19 +2288,18 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2084
2288
  allScores = allScores.filter((score) => score.source === source);
2085
2289
  }
2086
2290
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2087
- const { page, perPage: perPageInput } = pagination;
2088
- const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2089
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2291
+ const startIndex = pagination.page * pagination.perPage;
2292
+ const endIndex = startIndex + pagination.perPage;
2293
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2090
2294
  const total = allScores.length;
2091
- const end = perPageInput === false ? allScores.length : start + perPage;
2092
- const paginatedScores = allScores.slice(start, end);
2295
+ const hasMore = endIndex < total;
2093
2296
  return {
2094
2297
  scores: paginatedScores,
2095
2298
  pagination: {
2096
2299
  total,
2097
- page,
2098
- perPage: perPageForResponse,
2099
- hasMore: end < total
2300
+ page: pagination.page,
2301
+ perPage: pagination.perPage,
2302
+ hasMore
2100
2303
  }
2101
2304
  };
2102
2305
  } catch (error$1) {
@@ -2118,7 +2321,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2118
2321
  );
2119
2322
  }
2120
2323
  }
2121
- async listScoresByRunId({
2324
+ async getScoresByRunId({
2122
2325
  runId,
2123
2326
  pagination
2124
2327
  }) {
@@ -2128,19 +2331,18 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2128
2331
  const results = await query.go();
2129
2332
  const allScores = results.data.map((data) => this.parseScoreData(data));
2130
2333
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2131
- const { page, perPage: perPageInput } = pagination;
2132
- const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2133
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2334
+ const startIndex = pagination.page * pagination.perPage;
2335
+ const endIndex = startIndex + pagination.perPage;
2336
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2134
2337
  const total = allScores.length;
2135
- const end = perPageInput === false ? allScores.length : start + perPage;
2136
- const paginatedScores = allScores.slice(start, end);
2338
+ const hasMore = endIndex < total;
2137
2339
  return {
2138
2340
  scores: paginatedScores,
2139
2341
  pagination: {
2140
2342
  total,
2141
- page,
2142
- perPage: perPageForResponse,
2143
- hasMore: end < total
2343
+ page: pagination.page,
2344
+ perPage: pagination.perPage,
2345
+ hasMore
2144
2346
  }
2145
2347
  };
2146
2348
  } catch (error$1) {
@@ -2155,7 +2357,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2155
2357
  );
2156
2358
  }
2157
2359
  }
2158
- async listScoresByEntityId({
2360
+ async getScoresByEntityId({
2159
2361
  entityId,
2160
2362
  entityType,
2161
2363
  pagination
@@ -2167,19 +2369,18 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2167
2369
  let allScores = results.data.map((data) => this.parseScoreData(data));
2168
2370
  allScores = allScores.filter((score) => score.entityType === entityType);
2169
2371
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2170
- const { page, perPage: perPageInput } = pagination;
2171
- const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2172
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2372
+ const startIndex = pagination.page * pagination.perPage;
2373
+ const endIndex = startIndex + pagination.perPage;
2374
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2173
2375
  const total = allScores.length;
2174
- const end = perPageInput === false ? allScores.length : start + perPage;
2175
- const paginatedScores = allScores.slice(start, end);
2376
+ const hasMore = endIndex < total;
2176
2377
  return {
2177
2378
  scores: paginatedScores,
2178
2379
  pagination: {
2179
2380
  total,
2180
- page,
2181
- perPage: perPageForResponse,
2182
- hasMore: end < total
2381
+ page: pagination.page,
2382
+ perPage: pagination.perPage,
2383
+ hasMore
2183
2384
  }
2184
2385
  };
2185
2386
  } catch (error$1) {
@@ -2194,7 +2395,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2194
2395
  );
2195
2396
  }
2196
2397
  }
2197
- async listScoresBySpan({
2398
+ async getScoresBySpan({
2198
2399
  traceId,
2199
2400
  spanId,
2200
2401
  pagination
@@ -2205,19 +2406,18 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2205
2406
  const results = await query.go();
2206
2407
  const allScores = results.data.map((data) => this.parseScoreData(data));
2207
2408
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2208
- const { page, perPage: perPageInput } = pagination;
2209
- const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2210
- const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2409
+ const startIndex = pagination.page * pagination.perPage;
2410
+ const endIndex = startIndex + pagination.perPage;
2411
+ const paginatedScores = allScores.slice(startIndex, endIndex);
2211
2412
  const total = allScores.length;
2212
- const end = perPageInput === false ? allScores.length : start + perPage;
2213
- const paginatedScores = allScores.slice(start, end);
2413
+ const hasMore = endIndex < total;
2214
2414
  return {
2215
2415
  scores: paginatedScores,
2216
2416
  pagination: {
2217
2417
  total,
2218
- page,
2219
- perPage: perPageForResponse,
2220
- hasMore: end < total
2418
+ page: pagination.page,
2419
+ perPage: pagination.perPage,
2420
+ hasMore
2221
2421
  }
2222
2422
  };
2223
2423
  } catch (error$1) {
@@ -2233,6 +2433,239 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2233
2433
  }
2234
2434
  }
2235
2435
  };
2436
+ var TracesStorageDynamoDB = class extends storage.TracesStorage {
2437
+ service;
2438
+ operations;
2439
+ constructor({ service, operations }) {
2440
+ super();
2441
+ this.service = service;
2442
+ this.operations = operations;
2443
+ }
2444
+ // Trace operations
2445
+ async getTraces(args) {
2446
+ const { name, scope, page, perPage } = args;
2447
+ this.logger.debug("Getting traces", { name, scope, page, perPage });
2448
+ try {
2449
+ let query;
2450
+ if (name) {
2451
+ query = this.service.entities.trace.query.byName({ entity: "trace", name });
2452
+ } else if (scope) {
2453
+ query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
2454
+ } else {
2455
+ this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
2456
+ query = this.service.entities.trace.scan;
2457
+ }
2458
+ let items = [];
2459
+ let cursor = null;
2460
+ let pagesFetched = 0;
2461
+ const startPage = page > 0 ? page : 1;
2462
+ do {
2463
+ const results = await query.go({ cursor, limit: perPage });
2464
+ pagesFetched++;
2465
+ if (pagesFetched === startPage) {
2466
+ items = results.data;
2467
+ break;
2468
+ }
2469
+ cursor = results.cursor;
2470
+ if (!cursor && results.data.length > 0 && pagesFetched < startPage) {
2471
+ break;
2472
+ }
2473
+ } while (cursor && pagesFetched < startPage);
2474
+ return items;
2475
+ } catch (error$1) {
2476
+ throw new error.MastraError(
2477
+ {
2478
+ id: "STORAGE_DYNAMODB_STORE_GET_TRACES_FAILED",
2479
+ domain: error.ErrorDomain.STORAGE,
2480
+ category: error.ErrorCategory.THIRD_PARTY
2481
+ },
2482
+ error$1
2483
+ );
2484
+ }
2485
+ }
2486
+ async batchTraceInsert({ records }) {
2487
+ this.logger.debug("Batch inserting traces", { count: records.length });
2488
+ if (!records.length) {
2489
+ return;
2490
+ }
2491
+ try {
2492
+ const recordsToSave = records.map((rec) => ({ entity: "trace", ...rec }));
2493
+ await this.operations.batchInsert({
2494
+ tableName: storage.TABLE_TRACES,
2495
+ records: recordsToSave
2496
+ // Pass records with 'entity' included
2497
+ });
2498
+ } catch (error$1) {
2499
+ throw new error.MastraError(
2500
+ {
2501
+ id: "STORAGE_DYNAMODB_STORE_BATCH_TRACE_INSERT_FAILED",
2502
+ domain: error.ErrorDomain.STORAGE,
2503
+ category: error.ErrorCategory.THIRD_PARTY,
2504
+ details: { count: records.length }
2505
+ },
2506
+ error$1
2507
+ );
2508
+ }
2509
+ }
2510
+ async getTracesPaginated(args) {
2511
+ const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
2512
+ this.logger.debug("Getting traces with pagination", { name, scope, page, perPage, attributes, filters, dateRange });
2513
+ try {
2514
+ let query;
2515
+ if (name) {
2516
+ query = this.service.entities.trace.query.byName({ entity: "trace", name });
2517
+ } else if (scope) {
2518
+ query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
2519
+ } else {
2520
+ this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
2521
+ query = this.service.entities.trace.scan;
2522
+ }
2523
+ const results = await query.go({
2524
+ order: "desc",
2525
+ pages: "all"
2526
+ // Get all pages to apply filtering and pagination
2527
+ });
2528
+ if (!results.data.length) {
2529
+ return {
2530
+ traces: [],
2531
+ total: 0,
2532
+ page,
2533
+ perPage,
2534
+ hasMore: false
2535
+ };
2536
+ }
2537
+ let filteredData = results.data;
2538
+ if (attributes) {
2539
+ filteredData = filteredData.filter((item) => {
2540
+ try {
2541
+ let itemAttributes = {};
2542
+ if (item.attributes) {
2543
+ if (typeof item.attributes === "string") {
2544
+ if (item.attributes === "[object Object]") {
2545
+ itemAttributes = {};
2546
+ } else {
2547
+ try {
2548
+ itemAttributes = JSON.parse(item.attributes);
2549
+ } catch {
2550
+ itemAttributes = {};
2551
+ }
2552
+ }
2553
+ } else if (typeof item.attributes === "object") {
2554
+ itemAttributes = item.attributes;
2555
+ }
2556
+ }
2557
+ return Object.entries(attributes).every(([key, value]) => itemAttributes[key] === value);
2558
+ } catch (e) {
2559
+ this.logger.warn("Failed to parse attributes during filtering", { item, error: e });
2560
+ return false;
2561
+ }
2562
+ });
2563
+ }
2564
+ if (dateRange?.start) {
2565
+ filteredData = filteredData.filter((item) => {
2566
+ const itemDate = new Date(item.createdAt);
2567
+ return itemDate >= dateRange.start;
2568
+ });
2569
+ }
2570
+ if (dateRange?.end) {
2571
+ filteredData = filteredData.filter((item) => {
2572
+ const itemDate = new Date(item.createdAt);
2573
+ return itemDate <= dateRange.end;
2574
+ });
2575
+ }
2576
+ const total = filteredData.length;
2577
+ const start = page * perPage;
2578
+ const end = start + perPage;
2579
+ const paginatedData = filteredData.slice(start, end);
2580
+ const traces = paginatedData.map((item) => {
2581
+ let attributes2;
2582
+ if (item.attributes) {
2583
+ if (typeof item.attributes === "string") {
2584
+ if (item.attributes === "[object Object]") {
2585
+ attributes2 = void 0;
2586
+ } else {
2587
+ try {
2588
+ attributes2 = JSON.parse(item.attributes);
2589
+ } catch {
2590
+ attributes2 = void 0;
2591
+ }
2592
+ }
2593
+ } else if (typeof item.attributes === "object") {
2594
+ attributes2 = item.attributes;
2595
+ }
2596
+ }
2597
+ let status;
2598
+ if (item.status) {
2599
+ if (typeof item.status === "string") {
2600
+ try {
2601
+ status = JSON.parse(item.status);
2602
+ } catch {
2603
+ status = void 0;
2604
+ }
2605
+ } else if (typeof item.status === "object") {
2606
+ status = item.status;
2607
+ }
2608
+ }
2609
+ let events;
2610
+ if (item.events) {
2611
+ if (typeof item.events === "string") {
2612
+ try {
2613
+ events = JSON.parse(item.events);
2614
+ } catch {
2615
+ events = void 0;
2616
+ }
2617
+ } else if (Array.isArray(item.events)) {
2618
+ events = item.events;
2619
+ }
2620
+ }
2621
+ let links;
2622
+ if (item.links) {
2623
+ if (typeof item.links === "string") {
2624
+ try {
2625
+ links = JSON.parse(item.links);
2626
+ } catch {
2627
+ links = void 0;
2628
+ }
2629
+ } else if (Array.isArray(item.links)) {
2630
+ links = item.links;
2631
+ }
2632
+ }
2633
+ return {
2634
+ id: item.id,
2635
+ parentSpanId: item.parentSpanId,
2636
+ name: item.name,
2637
+ traceId: item.traceId,
2638
+ scope: item.scope,
2639
+ kind: item.kind,
2640
+ attributes: attributes2,
2641
+ status,
2642
+ events,
2643
+ links,
2644
+ other: item.other,
2645
+ startTime: item.startTime,
2646
+ endTime: item.endTime,
2647
+ createdAt: item.createdAt
2648
+ };
2649
+ });
2650
+ return {
2651
+ traces,
2652
+ total,
2653
+ page,
2654
+ perPage,
2655
+ hasMore: end < total
2656
+ };
2657
+ } catch (error$1) {
2658
+ throw new error.MastraError(
2659
+ {
2660
+ id: "STORAGE_DYNAMODB_STORE_GET_TRACES_PAGINATED_FAILED",
2661
+ domain: error.ErrorDomain.STORAGE,
2662
+ category: error.ErrorCategory.THIRD_PARTY
2663
+ },
2664
+ error$1
2665
+ );
2666
+ }
2667
+ }
2668
+ };
2236
2669
  function formatWorkflowRun(snapshotData) {
2237
2670
  return {
2238
2671
  workflowName: snapshotData.workflow_name,
@@ -2254,7 +2687,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2254
2687
  // runId,
2255
2688
  // stepId,
2256
2689
  // result,
2257
- // requestContext,
2690
+ // runtimeContext,
2258
2691
  }) {
2259
2692
  throw new Error("Method not implemented.");
2260
2693
  }
@@ -2326,24 +2759,11 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2326
2759
  );
2327
2760
  }
2328
2761
  }
2329
- async listWorkflowRuns(args) {
2762
+ async getWorkflowRuns(args) {
2330
2763
  this.logger.debug("Getting workflow runs", { args });
2331
2764
  try {
2332
- const perPage = args?.perPage !== void 0 ? args.perPage : 10;
2333
- const page = args?.page !== void 0 ? args.page : 0;
2334
- if (page < 0) {
2335
- throw new error.MastraError(
2336
- {
2337
- id: "DYNAMODB_STORE_INVALID_PAGE",
2338
- domain: error.ErrorDomain.STORAGE,
2339
- category: error.ErrorCategory.USER,
2340
- details: { page }
2341
- },
2342
- new Error("page must be >= 0")
2343
- );
2344
- }
2345
- const normalizedPerPage = storage.normalizePerPage(perPage, 10);
2346
- const offset = page * normalizedPerPage;
2765
+ const limit = args?.limit || 10;
2766
+ const offset = args?.offset || 0;
2347
2767
  let query;
2348
2768
  if (args?.workflowName) {
2349
2769
  query = this.service.entities.workflow_snapshot.query.primary({
@@ -2395,7 +2815,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2395
2815
  return { runs: [], total: 0 };
2396
2816
  }
2397
2817
  const total = allMatchingSnapshots.length;
2398
- const paginatedData = allMatchingSnapshots.slice(offset, offset + normalizedPerPage);
2818
+ const paginatedData = allMatchingSnapshots.slice(offset, offset + limit);
2399
2819
  const runs = paginatedData.map((snapshot) => formatWorkflowRun(snapshot));
2400
2820
  return {
2401
2821
  runs,
@@ -2404,7 +2824,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2404
2824
  } catch (error$1) {
2405
2825
  throw new error.MastraError(
2406
2826
  {
2407
- id: "STORAGE_DYNAMODB_STORE_LIST_WORKFLOW_RUNS_FAILED",
2827
+ id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUNS_FAILED",
2408
2828
  domain: error.ErrorDomain.STORAGE,
2409
2829
  category: error.ErrorCategory.THIRD_PARTY,
2410
2830
  details: { workflowName: args?.workflowName || "", resourceId: args?.resourceId || "" }
@@ -2477,7 +2897,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2477
2897
  hasInitialized = null;
2478
2898
  stores;
2479
2899
  constructor({ name, config }) {
2480
- super({ id: config.id, name });
2900
+ super({ name });
2481
2901
  try {
2482
2902
  if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
2483
2903
  throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
@@ -2500,11 +2920,14 @@ var DynamoDBStore = class extends storage.MastraStorage {
2500
2920
  tableName: this.tableName,
2501
2921
  client: this.client
2502
2922
  });
2923
+ const traces = new TracesStorageDynamoDB({ service: this.service, operations });
2503
2924
  const workflows = new WorkflowStorageDynamoDB({ service: this.service });
2504
2925
  const memory = new MemoryStorageDynamoDB({ service: this.service });
2505
2926
  const scores = new ScoresStorageDynamoDB({ service: this.service });
2506
2927
  this.stores = {
2507
2928
  operations,
2929
+ legacyEvals: new LegacyEvalsDynamoDB({ service: this.service, tableName: this.tableName }),
2930
+ traces,
2508
2931
  workflows,
2509
2932
  memory,
2510
2933
  scores
@@ -2527,7 +2950,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2527
2950
  hasColumn: false,
2528
2951
  createTable: false,
2529
2952
  deleteMessages: false,
2530
- listScoresBySpan: true
2953
+ getScoresBySpan: true
2531
2954
  };
2532
2955
  }
2533
2956
  /**
@@ -2622,6 +3045,9 @@ var DynamoDBStore = class extends storage.MastraStorage {
2622
3045
  async getThreadById({ threadId }) {
2623
3046
  return this.stores.memory.getThreadById({ threadId });
2624
3047
  }
3048
+ async getThreadsByResourceId(args) {
3049
+ return this.stores.memory.getThreadsByResourceId(args);
3050
+ }
2625
3051
  async saveThread({ thread }) {
2626
3052
  return this.stores.memory.saveThread({ thread });
2627
3053
  }
@@ -2635,24 +3061,51 @@ var DynamoDBStore = class extends storage.MastraStorage {
2635
3061
  async deleteThread({ threadId }) {
2636
3062
  return this.stores.memory.deleteThread({ threadId });
2637
3063
  }
2638
- async listMessagesById(args) {
2639
- return this.stores.memory.listMessagesById(args);
3064
+ async getMessages({
3065
+ threadId,
3066
+ resourceId,
3067
+ selectBy,
3068
+ format
3069
+ }) {
3070
+ return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
3071
+ }
3072
+ async getMessagesById({
3073
+ messageIds,
3074
+ format
3075
+ }) {
3076
+ return this.stores.memory.getMessagesById({ messageIds, format });
2640
3077
  }
2641
3078
  async saveMessages(args) {
2642
3079
  return this.stores.memory.saveMessages(args);
2643
3080
  }
3081
+ async getThreadsByResourceIdPaginated(args) {
3082
+ return this.stores.memory.getThreadsByResourceIdPaginated(args);
3083
+ }
3084
+ async getMessagesPaginated(args) {
3085
+ return this.stores.memory.getMessagesPaginated(args);
3086
+ }
2644
3087
  async updateMessages(_args) {
2645
3088
  return this.stores.memory.updateMessages(_args);
2646
3089
  }
3090
+ // Trace operations
3091
+ async getTraces(args) {
3092
+ return this.stores.traces.getTraces(args);
3093
+ }
3094
+ async batchTraceInsert({ records }) {
3095
+ return this.stores.traces.batchTraceInsert({ records });
3096
+ }
3097
+ async getTracesPaginated(_args) {
3098
+ return this.stores.traces.getTracesPaginated(_args);
3099
+ }
2647
3100
  // Workflow operations
2648
3101
  async updateWorkflowResults({
2649
3102
  workflowName,
2650
3103
  runId,
2651
3104
  stepId,
2652
3105
  result,
2653
- requestContext
3106
+ runtimeContext
2654
3107
  }) {
2655
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
3108
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
2656
3109
  }
2657
3110
  async updateWorkflowState({
2658
3111
  workflowName,
@@ -2675,8 +3128,8 @@ var DynamoDBStore = class extends storage.MastraStorage {
2675
3128
  }) {
2676
3129
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2677
3130
  }
2678
- async listWorkflowRuns(args) {
2679
- return this.stores.workflows.listWorkflowRuns(args);
3131
+ async getWorkflowRuns(args) {
3132
+ return this.stores.workflows.getWorkflowRuns(args);
2680
3133
  }
2681
3134
  async getWorkflowRunById(args) {
2682
3135
  return this.stores.workflows.getWorkflowRunById(args);
@@ -2694,6 +3147,13 @@ var DynamoDBStore = class extends storage.MastraStorage {
2694
3147
  }) {
2695
3148
  return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
2696
3149
  }
3150
+ // Eval operations
3151
+ async getEvalsByAgentName(agentName, type) {
3152
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
3153
+ }
3154
+ async getEvals(options) {
3155
+ return this.stores.legacyEvals.getEvals(options);
3156
+ }
2697
3157
  /**
2698
3158
  * Closes the DynamoDB client connection and cleans up resources.
2699
3159
  * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
@@ -2723,38 +3183,38 @@ var DynamoDBStore = class extends storage.MastraStorage {
2723
3183
  async saveScore(_score) {
2724
3184
  return this.stores.scores.saveScore(_score);
2725
3185
  }
2726
- async listScoresByRunId({
3186
+ async getScoresByRunId({
2727
3187
  runId: _runId,
2728
3188
  pagination: _pagination
2729
3189
  }) {
2730
- return this.stores.scores.listScoresByRunId({ runId: _runId, pagination: _pagination });
3190
+ return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
2731
3191
  }
2732
- async listScoresByEntityId({
3192
+ async getScoresByEntityId({
2733
3193
  entityId: _entityId,
2734
3194
  entityType: _entityType,
2735
3195
  pagination: _pagination
2736
3196
  }) {
2737
- return this.stores.scores.listScoresByEntityId({
3197
+ return this.stores.scores.getScoresByEntityId({
2738
3198
  entityId: _entityId,
2739
3199
  entityType: _entityType,
2740
3200
  pagination: _pagination
2741
3201
  });
2742
3202
  }
2743
- async listScoresByScorerId({
3203
+ async getScoresByScorerId({
2744
3204
  scorerId,
2745
3205
  source,
2746
3206
  entityId,
2747
3207
  entityType,
2748
3208
  pagination
2749
3209
  }) {
2750
- return this.stores.scores.listScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
3210
+ return this.stores.scores.getScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
2751
3211
  }
2752
- async listScoresBySpan({
3212
+ async getScoresBySpan({
2753
3213
  traceId,
2754
3214
  spanId,
2755
3215
  pagination
2756
3216
  }) {
2757
- return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
3217
+ return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
2758
3218
  }
2759
3219
  };
2760
3220