@mastra/dynamodb 0.0.0-remove-unused-model-providers-api-20251030210744 → 0.0.0-remove-ai-peer-dep-from-evals-20260105220639

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 scores = require('@mastra/core/scores');
9
+ var evals = require('@mastra/core/evals');
10
10
 
11
11
  // src/storage/index.ts
12
12
 
@@ -425,6 +425,10 @@ var scoreEntity = new electrodb.Entity({
425
425
  return value;
426
426
  }
427
427
  },
428
+ preprocessPrompt: {
429
+ type: "string",
430
+ required: false
431
+ },
428
432
  preprocessStepResult: {
429
433
  type: "string",
430
434
  required: false,
@@ -935,11 +939,113 @@ function getElectroDbService(client, tableName) {
935
939
  }
936
940
  );
937
941
  }
942
+ function resolveDynamoDBConfig(config) {
943
+ if ("service" in config) {
944
+ return config.service;
945
+ }
946
+ const dynamoClient = new clientDynamodb.DynamoDBClient({
947
+ region: config.region || "us-east-1",
948
+ endpoint: config.endpoint,
949
+ credentials: config.credentials
950
+ });
951
+ const client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
952
+ return getElectroDbService(client, config.tableName);
953
+ }
954
+ var ENTITY_MAP = {
955
+ [storage.TABLE_THREADS]: "thread",
956
+ [storage.TABLE_MESSAGES]: "message",
957
+ [storage.TABLE_RESOURCES]: "resource",
958
+ [storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
959
+ [storage.TABLE_SCORERS]: "score"
960
+ };
961
+ function getDeleteKey(entityName, item) {
962
+ const key = { entity: entityName };
963
+ switch (entityName) {
964
+ case "thread":
965
+ case "message":
966
+ case "resource":
967
+ case "score":
968
+ key.id = item.id;
969
+ break;
970
+ case "workflow_snapshot":
971
+ key.workflow_name = item.workflow_name;
972
+ key.run_id = item.run_id;
973
+ break;
974
+ default:
975
+ key.id = item.id;
976
+ }
977
+ return key;
978
+ }
979
+ async function deleteTableData(service, tableName) {
980
+ const entityName = ENTITY_MAP[tableName];
981
+ if (!entityName || !service.entities[entityName]) {
982
+ throw new Error(`No entity mapping found for table: ${tableName}`);
983
+ }
984
+ const entity = service.entities[entityName];
985
+ const result = await entity.scan.go({ pages: "all" });
986
+ if (!result.data.length) {
987
+ return;
988
+ }
989
+ const batchSize = 25;
990
+ for (let i = 0; i < result.data.length; i += batchSize) {
991
+ const batch = result.data.slice(i, i + batchSize);
992
+ const keysToDelete = batch.map((item) => getDeleteKey(entityName, item));
993
+ await entity.delete(keysToDelete).go();
994
+ }
995
+ }
996
+
997
+ // src/storage/domains/memory/index.ts
938
998
  var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
939
999
  service;
940
- constructor({ service }) {
1000
+ constructor(config) {
941
1001
  super();
942
- this.service = service;
1002
+ this.service = resolveDynamoDBConfig(config);
1003
+ }
1004
+ async dangerouslyClearAll() {
1005
+ await deleteTableData(this.service, storage.TABLE_THREADS);
1006
+ await deleteTableData(this.service, storage.TABLE_MESSAGES);
1007
+ await deleteTableData(this.service, storage.TABLE_RESOURCES);
1008
+ }
1009
+ async deleteMessages(messageIds) {
1010
+ if (!messageIds || messageIds.length === 0) {
1011
+ return;
1012
+ }
1013
+ this.logger.debug("Deleting messages", { count: messageIds.length });
1014
+ try {
1015
+ const threadIds = /* @__PURE__ */ new Set();
1016
+ const batchSize = 25;
1017
+ for (let i = 0; i < messageIds.length; i += batchSize) {
1018
+ const batch = messageIds.slice(i, i + batchSize);
1019
+ const messagesToDelete = await Promise.all(
1020
+ batch.map(async (id) => {
1021
+ const result = await this.service.entities.message.get({ entity: "message", id }).go();
1022
+ return result.data;
1023
+ })
1024
+ );
1025
+ for (const message of messagesToDelete) {
1026
+ if (message) {
1027
+ if (message.threadId) {
1028
+ threadIds.add(message.threadId);
1029
+ }
1030
+ await this.service.entities.message.delete({ entity: "message", id: message.id }).go();
1031
+ }
1032
+ }
1033
+ }
1034
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1035
+ for (const threadId of threadIds) {
1036
+ await this.service.entities.thread.update({ entity: "thread", id: threadId }).set({ updatedAt: now }).go();
1037
+ }
1038
+ } catch (error$1) {
1039
+ throw new error.MastraError(
1040
+ {
1041
+ id: storage.createStorageErrorId("DYNAMODB", "DELETE_MESSAGES", "FAILED"),
1042
+ domain: error.ErrorDomain.STORAGE,
1043
+ category: error.ErrorCategory.THIRD_PARTY,
1044
+ details: { count: messageIds.length }
1045
+ },
1046
+ error$1
1047
+ );
1048
+ }
943
1049
  }
944
1050
  // Helper function to parse message data (handle JSON fields)
945
1051
  parseMessageData(data) {
@@ -953,17 +1059,17 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
953
1059
  };
954
1060
  }
955
1061
  // Helper function to transform and sort threads
956
- transformAndSortThreads(rawThreads, orderBy, sortDirection) {
1062
+ transformAndSortThreads(rawThreads, field, direction) {
957
1063
  return rawThreads.map((data) => ({
958
1064
  ...data,
959
1065
  // Convert date strings back to Date objects for consistency
960
1066
  createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
961
1067
  updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
962
1068
  })).sort((a, b) => {
963
- const fieldA = orderBy === "createdAt" ? a.createdAt : a.updatedAt;
964
- const fieldB = orderBy === "createdAt" ? b.createdAt : b.updatedAt;
1069
+ const fieldA = field === "createdAt" ? a.createdAt : a.updatedAt;
1070
+ const fieldB = field === "createdAt" ? b.createdAt : b.updatedAt;
965
1071
  const comparison = fieldA.getTime() - fieldB.getTime();
966
- return sortDirection === "DESC" ? -comparison : comparison;
1072
+ return direction === "DESC" ? -comparison : comparison;
967
1073
  });
968
1074
  }
969
1075
  async getThreadById({ threadId }) {
@@ -985,7 +1091,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
985
1091
  } catch (error$1) {
986
1092
  throw new error.MastraError(
987
1093
  {
988
- id: "STORAGE_DYNAMODB_STORE_GET_THREAD_BY_ID_FAILED",
1094
+ id: storage.createStorageErrorId("DYNAMODB", "GET_THREAD_BY_ID", "FAILED"),
989
1095
  domain: error.ErrorDomain.STORAGE,
990
1096
  category: error.ErrorCategory.THIRD_PARTY,
991
1097
  details: { threadId }
@@ -994,32 +1100,6 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
994
1100
  );
995
1101
  }
996
1102
  }
997
- /**
998
- * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
999
- */
1000
- async getThreadsByResourceId(args) {
1001
- const resourceId = args.resourceId;
1002
- const orderBy = this.castThreadOrderBy(args.orderBy);
1003
- const sortDirection = this.castThreadSortDirection(args.sortDirection);
1004
- this.logger.debug("Getting threads by resource ID", { resourceId, orderBy, sortDirection });
1005
- try {
1006
- const result = await this.service.entities.thread.query.byResource({ entity: "thread", resourceId }).go();
1007
- if (!result.data.length) {
1008
- return [];
1009
- }
1010
- return this.transformAndSortThreads(result.data, orderBy, sortDirection);
1011
- } catch (error$1) {
1012
- throw new error.MastraError(
1013
- {
1014
- id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1015
- domain: error.ErrorDomain.STORAGE,
1016
- category: error.ErrorCategory.THIRD_PARTY,
1017
- details: { resourceId }
1018
- },
1019
- error$1
1020
- );
1021
- }
1022
- }
1023
1103
  async saveThread({ thread }) {
1024
1104
  this.logger.debug("Saving thread", { threadId: thread.id });
1025
1105
  const now = /* @__PURE__ */ new Date();
@@ -1045,7 +1125,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1045
1125
  } catch (error$1) {
1046
1126
  throw new error.MastraError(
1047
1127
  {
1048
- id: "STORAGE_DYNAMODB_STORE_SAVE_THREAD_FAILED",
1128
+ id: storage.createStorageErrorId("DYNAMODB", "SAVE_THREAD", "FAILED"),
1049
1129
  domain: error.ErrorDomain.STORAGE,
1050
1130
  category: error.ErrorCategory.THIRD_PARTY,
1051
1131
  details: { threadId: thread.id }
@@ -1087,7 +1167,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1087
1167
  } catch (error$1) {
1088
1168
  throw new error.MastraError(
1089
1169
  {
1090
- id: "STORAGE_DYNAMODB_STORE_UPDATE_THREAD_FAILED",
1170
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_THREAD", "FAILED"),
1091
1171
  domain: error.ErrorDomain.STORAGE,
1092
1172
  category: error.ErrorCategory.THIRD_PARTY,
1093
1173
  details: { threadId: id }
@@ -1099,7 +1179,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1099
1179
  async deleteThread({ threadId }) {
1100
1180
  this.logger.debug("Deleting thread", { threadId });
1101
1181
  try {
1102
- const messages = await this.getMessages({ threadId });
1182
+ const { messages } = await this.listMessages({ threadId, perPage: false });
1103
1183
  if (messages.length > 0) {
1104
1184
  const batchSize = 25;
1105
1185
  for (let i = 0; i < messages.length; i += batchSize) {
@@ -1119,7 +1199,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1119
1199
  } catch (error$1) {
1120
1200
  throw new error.MastraError(
1121
1201
  {
1122
- id: "STORAGE_DYNAMODB_STORE_DELETE_THREAD_FAILED",
1202
+ id: storage.createStorageErrorId("DYNAMODB", "DELETE_THREAD", "FAILED"),
1123
1203
  domain: error.ErrorDomain.STORAGE,
1124
1204
  category: error.ErrorCategory.THIRD_PARTY,
1125
1205
  details: { threadId }
@@ -1128,72 +1208,9 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1128
1208
  );
1129
1209
  }
1130
1210
  }
1131
- async getMessages({
1132
- threadId,
1133
- resourceId,
1134
- selectBy,
1135
- format
1136
- }) {
1137
- this.logger.debug("Getting messages", { threadId, selectBy });
1138
- try {
1139
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1140
- const messages = [];
1141
- const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1142
- if (selectBy?.include?.length) {
1143
- const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1144
- if (includeMessages) {
1145
- messages.push(...includeMessages);
1146
- }
1147
- }
1148
- if (limit !== 0) {
1149
- const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1150
- let results;
1151
- if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1152
- results = await query.go({ limit, order: "desc" });
1153
- results.data = results.data.reverse();
1154
- } else {
1155
- results = await query.go();
1156
- }
1157
- let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1158
- allThreadMessages.sort((a, b) => {
1159
- const timeA = a.createdAt.getTime();
1160
- const timeB = b.createdAt.getTime();
1161
- if (timeA === timeB) {
1162
- return a.id.localeCompare(b.id);
1163
- }
1164
- return timeA - timeB;
1165
- });
1166
- messages.push(...allThreadMessages);
1167
- }
1168
- messages.sort((a, b) => {
1169
- const timeA = a.createdAt.getTime();
1170
- const timeB = b.createdAt.getTime();
1171
- if (timeA === timeB) {
1172
- return a.id.localeCompare(b.id);
1173
- }
1174
- return timeA - timeB;
1175
- });
1176
- const uniqueMessages = messages.filter(
1177
- (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1178
- );
1179
- const list = new agent.MessageList({ threadId, resourceId }).add(uniqueMessages, "memory");
1180
- if (format === `v2`) return list.get.all.v2();
1181
- return list.get.all.v1();
1182
- } catch (error$1) {
1183
- throw new error.MastraError(
1184
- {
1185
- id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_FAILED",
1186
- domain: error.ErrorDomain.STORAGE,
1187
- category: error.ErrorCategory.THIRD_PARTY,
1188
- details: { threadId, resourceId: resourceId ?? "" }
1189
- },
1190
- error$1
1191
- );
1192
- }
1193
- }
1194
1211
  async listMessagesById({ messageIds }) {
1195
1212
  this.logger.debug("Getting messages by ID", { messageIds });
1196
- if (messageIds.length === 0) return [];
1213
+ if (messageIds.length === 0) return { messages: [] };
1197
1214
  try {
1198
1215
  const results = await Promise.all(
1199
1216
  messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
@@ -1204,11 +1221,11 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1204
1221
  (message, index, self) => index === self.findIndex((m) => m.id === message.id)
1205
1222
  );
1206
1223
  const list = new agent.MessageList().add(uniqueMessages, "memory");
1207
- return list.get.all.v2();
1224
+ return { messages: list.get.all.db() };
1208
1225
  } catch (error$1) {
1209
1226
  throw new error.MastraError(
1210
1227
  {
1211
- id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_BY_ID_FAILED",
1228
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES_BY_ID", "FAILED"),
1212
1229
  domain: error.ErrorDomain.STORAGE,
1213
1230
  category: error.ErrorCategory.THIRD_PARTY,
1214
1231
  details: { messageIds: JSON.stringify(messageIds) }
@@ -1218,41 +1235,43 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1218
1235
  }
1219
1236
  }
1220
1237
  async listMessages(args) {
1221
- const { threadId, resourceId, include, filter, limit, offset = 0, orderBy } = args;
1222
- if (!threadId.trim()) {
1238
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
1239
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
1240
+ if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
1223
1241
  throw new error.MastraError(
1224
1242
  {
1225
- id: "STORAGE_DYNAMODB_LIST_MESSAGES_INVALID_THREAD_ID",
1243
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_THREAD_ID"),
1226
1244
  domain: error.ErrorDomain.STORAGE,
1227
1245
  category: error.ErrorCategory.THIRD_PARTY,
1228
- details: { threadId }
1246
+ details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
1229
1247
  },
1230
- new Error("threadId must be a non-empty string")
1248
+ new Error("threadId must be a non-empty string or array of non-empty strings")
1231
1249
  );
1232
1250
  }
1251
+ const perPage = storage.normalizePerPage(perPageInput, 40);
1252
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1233
1253
  try {
1234
- let perPage = 40;
1235
- if (limit !== void 0) {
1236
- if (limit === false) {
1237
- perPage = Number.MAX_SAFE_INTEGER;
1238
- } else if (limit === 0) {
1239
- perPage = 0;
1240
- } else if (typeof limit === "number" && limit > 0) {
1241
- perPage = limit;
1242
- }
1254
+ if (page < 0) {
1255
+ throw new error.MastraError(
1256
+ {
1257
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_PAGE"),
1258
+ domain: error.ErrorDomain.STORAGE,
1259
+ category: error.ErrorCategory.USER,
1260
+ details: { page }
1261
+ },
1262
+ new Error("page must be >= 0")
1263
+ );
1243
1264
  }
1244
- const page = perPage === 0 ? 0 : Math.floor(offset / perPage);
1245
- const sortField = orderBy?.field || "createdAt";
1246
- const sortDirection = orderBy?.direction || "DESC";
1265
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
1247
1266
  this.logger.debug("Getting messages with listMessages", {
1248
1267
  threadId,
1249
1268
  resourceId,
1250
- limit,
1269
+ perPageInput,
1251
1270
  offset,
1252
1271
  perPage,
1253
1272
  page,
1254
- sortField,
1255
- sortDirection
1273
+ field,
1274
+ direction
1256
1275
  });
1257
1276
  const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1258
1277
  const results = await query.go();
@@ -1260,38 +1279,28 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1260
1279
  if (resourceId) {
1261
1280
  allThreadMessages = allThreadMessages.filter((msg) => msg.resourceId === resourceId);
1262
1281
  }
1263
- if (filter?.dateRange) {
1264
- const dateRange = filter.dateRange;
1265
- allThreadMessages = allThreadMessages.filter((msg) => {
1266
- const createdAt = new Date(msg.createdAt).getTime();
1267
- if (dateRange.start) {
1268
- const startTime = dateRange.start instanceof Date ? dateRange.start.getTime() : new Date(dateRange.start).getTime();
1269
- if (createdAt < startTime) return false;
1270
- }
1271
- if (dateRange.end) {
1272
- const endTime = dateRange.end instanceof Date ? dateRange.end.getTime() : new Date(dateRange.end).getTime();
1273
- if (createdAt > endTime) return false;
1274
- }
1275
- return true;
1276
- });
1277
- }
1282
+ allThreadMessages = storage.filterByDateRange(
1283
+ allThreadMessages,
1284
+ (msg) => new Date(msg.createdAt),
1285
+ filter?.dateRange
1286
+ );
1278
1287
  allThreadMessages.sort((a, b) => {
1279
- const aValue = sortField === "createdAt" ? new Date(a.createdAt).getTime() : a[sortField];
1280
- const bValue = sortField === "createdAt" ? new Date(b.createdAt).getTime() : b[sortField];
1288
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1289
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1281
1290
  if (aValue === bValue) {
1282
1291
  return a.id.localeCompare(b.id);
1283
1292
  }
1284
- return sortDirection === "ASC" ? aValue - bValue : bValue - aValue;
1293
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
1285
1294
  });
1286
1295
  const total = allThreadMessages.length;
1287
1296
  const paginatedMessages = allThreadMessages.slice(offset, offset + perPage);
1288
1297
  const paginatedCount = paginatedMessages.length;
1289
- if (total === 0 && paginatedCount === 0) {
1298
+ if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
1290
1299
  return {
1291
1300
  messages: [],
1292
1301
  total: 0,
1293
1302
  page,
1294
- perPage,
1303
+ perPage: perPageForResponse,
1295
1304
  hasMore: false
1296
1305
  };
1297
1306
  }
@@ -1299,7 +1308,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1299
1308
  let includeMessages = [];
1300
1309
  if (include && include.length > 0) {
1301
1310
  const selectBy = { include };
1302
- includeMessages = await this._getIncludedMessages(threadId, selectBy);
1311
+ includeMessages = await this._getIncludedMessages(selectBy);
1303
1312
  for (const includeMsg of includeMessages) {
1304
1313
  if (!messageIds.has(includeMsg.id)) {
1305
1314
  paginatedMessages.push(includeMsg);
@@ -1308,33 +1317,36 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1308
1317
  }
1309
1318
  }
1310
1319
  const list = new agent.MessageList().add(paginatedMessages, "memory");
1311
- let finalMessages = list.get.all.v2();
1320
+ let finalMessages = list.get.all.db();
1312
1321
  finalMessages = finalMessages.sort((a, b) => {
1313
- const aValue = sortField === "createdAt" ? new Date(a.createdAt).getTime() : a[sortField];
1314
- const bValue = sortField === "createdAt" ? new Date(b.createdAt).getTime() : b[sortField];
1322
+ const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
1323
+ const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
1315
1324
  if (aValue === bValue) {
1316
1325
  return a.id.localeCompare(b.id);
1317
1326
  }
1318
- return sortDirection === "ASC" ? aValue - bValue : bValue - aValue;
1327
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
1319
1328
  });
1320
1329
  const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
1321
1330
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
1322
- const hasMore = limit === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
1331
+ let hasMore = false;
1332
+ if (perPageInput !== false && !allThreadMessagesReturned) {
1333
+ hasMore = offset + paginatedCount < total;
1334
+ }
1323
1335
  return {
1324
1336
  messages: finalMessages,
1325
1337
  total,
1326
1338
  page,
1327
- perPage,
1339
+ perPage: perPageForResponse,
1328
1340
  hasMore
1329
1341
  };
1330
1342
  } catch (error$1) {
1331
1343
  const mastraError = new error.MastraError(
1332
1344
  {
1333
- id: "STORAGE_DYNAMODB_STORE_LIST_MESSAGES_FAILED",
1345
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "FAILED"),
1334
1346
  domain: error.ErrorDomain.STORAGE,
1335
1347
  category: error.ErrorCategory.THIRD_PARTY,
1336
1348
  details: {
1337
- threadId,
1349
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
1338
1350
  resourceId: resourceId ?? ""
1339
1351
  }
1340
1352
  },
@@ -1345,27 +1357,17 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1345
1357
  return {
1346
1358
  messages: [],
1347
1359
  total: 0,
1348
- page: Math.floor(offset / (limit === false ? Number.MAX_SAFE_INTEGER : limit || 40)),
1349
- perPage: limit === false ? Number.MAX_SAFE_INTEGER : limit || 40,
1360
+ page,
1361
+ perPage: perPageForResponse,
1350
1362
  hasMore: false
1351
1363
  };
1352
1364
  }
1353
1365
  }
1354
- /**
1355
- * @todo When migrating from getThreadsByResourceIdPaginated to this method,
1356
- * implement orderBy and sortDirection support for full sorting capabilities
1357
- */
1358
- async listThreadsByResourceId(args) {
1359
- const { resourceId, limit, offset } = args;
1360
- const page = Math.floor(offset / limit);
1361
- const perPage = limit;
1362
- return this.getThreadsByResourceIdPaginated({ resourceId, page, perPage });
1363
- }
1364
1366
  async saveMessages(args) {
1365
- const { messages, format = "v1" } = args;
1367
+ const { messages } = args;
1366
1368
  this.logger.debug("Saving messages", { count: messages.length });
1367
1369
  if (!messages.length) {
1368
- return [];
1370
+ return { messages: [] };
1369
1371
  }
1370
1372
  const threadId = messages[0]?.threadId;
1371
1373
  if (!threadId) {
@@ -1419,12 +1421,11 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1419
1421
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1420
1422
  }).go();
1421
1423
  const list = new agent.MessageList().add(messages, "memory");
1422
- if (format === `v1`) return list.get.all.v1();
1423
- return list.get.all.v2();
1424
+ return { messages: list.get.all.db() };
1424
1425
  } catch (error$1) {
1425
1426
  throw new error.MastraError(
1426
1427
  {
1427
- id: "STORAGE_DYNAMODB_STORE_SAVE_MESSAGES_FAILED",
1428
+ id: storage.createStorageErrorId("DYNAMODB", "SAVE_MESSAGES", "FAILED"),
1428
1429
  domain: error.ErrorDomain.STORAGE,
1429
1430
  category: error.ErrorCategory.THIRD_PARTY,
1430
1431
  details: { count: messages.length }
@@ -1433,37 +1434,48 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1433
1434
  );
1434
1435
  }
1435
1436
  }
1436
- async getThreadsByResourceIdPaginated(args) {
1437
- const { resourceId, page = 0, perPage = 100 } = args;
1438
- const orderBy = this.castThreadOrderBy(args.orderBy);
1439
- const sortDirection = this.castThreadSortDirection(args.sortDirection);
1437
+ async listThreadsByResourceId(args) {
1438
+ const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
1439
+ const perPage = storage.normalizePerPage(perPageInput, 100);
1440
+ if (page < 0) {
1441
+ throw new error.MastraError(
1442
+ {
1443
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
1444
+ domain: error.ErrorDomain.STORAGE,
1445
+ category: error.ErrorCategory.USER,
1446
+ details: { page }
1447
+ },
1448
+ new Error("page must be >= 0")
1449
+ );
1450
+ }
1451
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1452
+ const { field, direction } = this.parseOrderBy(orderBy);
1440
1453
  this.logger.debug("Getting threads by resource ID with pagination", {
1441
1454
  resourceId,
1442
1455
  page,
1443
1456
  perPage,
1444
- orderBy,
1445
- sortDirection
1457
+ field,
1458
+ direction
1446
1459
  });
1447
1460
  try {
1448
1461
  const query = this.service.entities.thread.query.byResource({ entity: "thread", resourceId });
1449
1462
  const results = await query.go();
1450
- const allThreads = this.transformAndSortThreads(results.data, orderBy, sortDirection);
1451
- const startIndex = page * perPage;
1452
- const endIndex = startIndex + perPage;
1453
- const paginatedThreads = allThreads.slice(startIndex, endIndex);
1463
+ const allThreads = this.transformAndSortThreads(results.data, field, direction);
1464
+ const endIndex = offset + perPage;
1465
+ const paginatedThreads = allThreads.slice(offset, endIndex);
1454
1466
  const total = allThreads.length;
1455
- const hasMore = endIndex < total;
1467
+ const hasMore = offset + perPage < total;
1456
1468
  return {
1457
1469
  threads: paginatedThreads,
1458
1470
  total,
1459
1471
  page,
1460
- perPage,
1472
+ perPage: perPageForResponse,
1461
1473
  hasMore
1462
1474
  };
1463
1475
  } catch (error$1) {
1464
1476
  throw new error.MastraError(
1465
1477
  {
1466
- id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
1478
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
1467
1479
  domain: error.ErrorDomain.STORAGE,
1468
1480
  category: error.ErrorCategory.THIRD_PARTY,
1469
1481
  details: { resourceId, page, perPage }
@@ -1472,98 +1484,24 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1472
1484
  );
1473
1485
  }
1474
1486
  }
1475
- async getMessagesPaginated(args) {
1476
- const { threadId, resourceId, selectBy, format = "v1" } = args;
1477
- const { page = 0, perPage = 40, dateRange } = selectBy?.pagination || {};
1478
- const fromDate = dateRange?.start;
1479
- const toDate = dateRange?.end;
1480
- const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
1481
- this.logger.debug("Getting messages with pagination", { threadId, page, perPage, fromDate, toDate, limit });
1482
- try {
1483
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1484
- let messages = [];
1485
- if (selectBy?.include?.length) {
1486
- const includeMessages = await this._getIncludedMessages(threadId, selectBy);
1487
- if (includeMessages) {
1488
- messages.push(...includeMessages);
1489
- }
1490
- }
1491
- if (limit !== 0) {
1492
- const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
1493
- let results;
1494
- if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
1495
- results = await query.go({ limit, order: "desc" });
1496
- results.data = results.data.reverse();
1497
- } else {
1498
- results = await query.go();
1499
- }
1500
- let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
1501
- allThreadMessages.sort((a, b) => {
1502
- const timeA = a.createdAt.getTime();
1503
- const timeB = b.createdAt.getTime();
1504
- if (timeA === timeB) {
1505
- return a.id.localeCompare(b.id);
1506
- }
1507
- return timeA - timeB;
1508
- });
1509
- const excludeIds = messages.map((m) => m.id);
1510
- if (excludeIds.length > 0) {
1511
- allThreadMessages = allThreadMessages.filter((msg) => !excludeIds.includes(msg.id));
1512
- }
1513
- messages.push(...allThreadMessages);
1514
- }
1515
- messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1516
- if (fromDate || toDate) {
1517
- messages = messages.filter((msg) => {
1518
- const createdAt = new Date(msg.createdAt).getTime();
1519
- if (fromDate && createdAt < new Date(fromDate).getTime()) return false;
1520
- if (toDate && createdAt > new Date(toDate).getTime()) return false;
1521
- return true;
1522
- });
1523
- }
1524
- const total = messages.length;
1525
- const start = page * perPage;
1526
- const end = start + perPage;
1527
- const paginatedMessages = messages.slice(start, end);
1528
- const hasMore = end < total;
1529
- const list = new agent.MessageList({ threadId, resourceId }).add(paginatedMessages, "memory");
1530
- const finalMessages = format === "v2" ? list.get.all.v2() : list.get.all.v1();
1531
- return {
1532
- messages: finalMessages,
1533
- total,
1534
- page,
1535
- perPage,
1536
- hasMore
1537
- };
1538
- } catch (error$1) {
1539
- const mastraError = new error.MastraError(
1540
- {
1541
- id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
1542
- domain: error.ErrorDomain.STORAGE,
1543
- category: error.ErrorCategory.THIRD_PARTY,
1544
- details: { threadId, resourceId: resourceId ?? "" }
1545
- },
1546
- error$1
1547
- );
1548
- this.logger?.trackException?.(mastraError);
1549
- this.logger?.error?.(mastraError.toString());
1550
- return { messages: [], total: 0, page, perPage, hasMore: false };
1551
- }
1552
- }
1553
1487
  // Helper method to get included messages with context
1554
- async _getIncludedMessages(threadId, selectBy) {
1555
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
1488
+ async _getIncludedMessages(selectBy) {
1556
1489
  if (!selectBy?.include?.length) {
1557
1490
  return [];
1558
1491
  }
1559
1492
  const includeMessages = [];
1560
1493
  for (const includeItem of selectBy.include) {
1561
1494
  try {
1562
- const { id, threadId: targetThreadId, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1563
- const searchThreadId = targetThreadId || threadId;
1495
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
1496
+ const targetResult = await this.service.entities.message.get({ entity: "message", id }).go();
1497
+ if (!targetResult.data) {
1498
+ this.logger.warn("Target message not found", { id });
1499
+ continue;
1500
+ }
1501
+ const targetMessageData = targetResult.data;
1502
+ const searchThreadId = targetMessageData.threadId;
1564
1503
  this.logger.debug("Getting included messages for", {
1565
1504
  id,
1566
- targetThreadId,
1567
1505
  searchThreadId,
1568
1506
  withPreviousMessages,
1569
1507
  withNextMessages
@@ -1586,7 +1524,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1586
1524
  });
1587
1525
  const targetIndex = allMessages.findIndex((msg) => msg.id === id);
1588
1526
  if (targetIndex === -1) {
1589
- this.logger.warn("Target message not found", { id, threadId: searchThreadId });
1527
+ this.logger.warn("Target message not found in thread", { id, threadId: searchThreadId });
1590
1528
  continue;
1591
1529
  }
1592
1530
  this.logger.debug("Found target message at index", { id, targetIndex, totalMessages: allMessages.length });
@@ -1671,7 +1609,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1671
1609
  } catch (error$1) {
1672
1610
  throw new error.MastraError(
1673
1611
  {
1674
- id: "STORAGE_DYNAMODB_STORE_UPDATE_MESSAGES_FAILED",
1612
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_MESSAGES", "FAILED"),
1675
1613
  domain: error.ErrorDomain.STORAGE,
1676
1614
  category: error.ErrorCategory.THIRD_PARTY,
1677
1615
  details: { count: messages.length }
@@ -1700,7 +1638,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1700
1638
  } catch (error$1) {
1701
1639
  throw new error.MastraError(
1702
1640
  {
1703
- id: "STORAGE_DYNAMODB_STORE_GET_RESOURCE_BY_ID_FAILED",
1641
+ id: storage.createStorageErrorId("DYNAMODB", "GET_RESOURCE_BY_ID", "FAILED"),
1704
1642
  domain: error.ErrorDomain.STORAGE,
1705
1643
  category: error.ErrorCategory.THIRD_PARTY,
1706
1644
  details: { resourceId }
@@ -1732,7 +1670,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1732
1670
  } catch (error$1) {
1733
1671
  throw new error.MastraError(
1734
1672
  {
1735
- id: "STORAGE_DYNAMODB_STORE_SAVE_RESOURCE_FAILED",
1673
+ id: storage.createStorageErrorId("DYNAMODB", "SAVE_RESOURCE", "FAILED"),
1736
1674
  domain: error.ErrorDomain.STORAGE,
1737
1675
  category: error.ErrorCategory.THIRD_PARTY,
1738
1676
  details: { resourceId: resource.id }
@@ -1781,7 +1719,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1781
1719
  } catch (error$1) {
1782
1720
  throw new error.MastraError(
1783
1721
  {
1784
- id: "STORAGE_DYNAMODB_STORE_UPDATE_RESOURCE_FAILED",
1722
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_RESOURCE", "FAILED"),
1785
1723
  domain: error.ErrorDomain.STORAGE,
1786
1724
  category: error.ErrorCategory.THIRD_PARTY,
1787
1725
  details: { resourceId }
@@ -1791,342 +1729,37 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
1791
1729
  }
1792
1730
  }
1793
1731
  };
1794
- var StoreOperationsDynamoDB = class extends storage.StoreOperations {
1795
- client;
1796
- tableName;
1732
+ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
1797
1733
  service;
1798
- constructor({
1799
- service,
1800
- tableName,
1801
- client
1802
- }) {
1734
+ constructor(config) {
1803
1735
  super();
1804
- this.service = service;
1805
- this.client = client;
1806
- this.tableName = tableName;
1807
- }
1808
- async hasColumn() {
1809
- return true;
1810
- }
1811
- async dropTable() {
1736
+ this.service = resolveDynamoDBConfig(config);
1812
1737
  }
1813
- // Helper methods for entity/table mapping
1814
- getEntityNameForTable(tableName) {
1815
- const mapping = {
1816
- [storage.TABLE_THREADS]: "thread",
1817
- [storage.TABLE_MESSAGES]: "message",
1818
- [storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
1819
- [storage.TABLE_SCORERS]: "score",
1820
- [storage.TABLE_TRACES]: "trace",
1821
- [storage.TABLE_RESOURCES]: "resource",
1822
- [storage.TABLE_AI_SPANS]: "ai_span"
1823
- };
1824
- return mapping[tableName] || null;
1825
- }
1826
- /**
1827
- * Pre-processes a record to ensure Date objects are converted to ISO strings
1828
- * This is necessary because ElectroDB validation happens before setters are applied
1829
- */
1830
- preprocessRecord(record) {
1831
- const processed = { ...record };
1832
- if (processed.createdAt instanceof Date) {
1833
- processed.createdAt = processed.createdAt.toISOString();
1834
- }
1835
- if (processed.updatedAt instanceof Date) {
1836
- processed.updatedAt = processed.updatedAt.toISOString();
1837
- }
1838
- if (processed.created_at instanceof Date) {
1839
- processed.created_at = processed.created_at.toISOString();
1840
- }
1841
- if (processed.result && typeof processed.result === "object") {
1842
- processed.result = JSON.stringify(processed.result);
1843
- }
1844
- if (processed.test_info && typeof processed.test_info === "object") {
1845
- processed.test_info = JSON.stringify(processed.test_info);
1846
- } else if (processed.test_info === void 0 || processed.test_info === null) {
1847
- delete processed.test_info;
1848
- }
1849
- if (processed.snapshot && typeof processed.snapshot === "object") {
1850
- processed.snapshot = JSON.stringify(processed.snapshot);
1851
- }
1852
- if (processed.attributes && typeof processed.attributes === "object") {
1853
- processed.attributes = JSON.stringify(processed.attributes);
1854
- }
1855
- if (processed.status && typeof processed.status === "object") {
1856
- processed.status = JSON.stringify(processed.status);
1857
- }
1858
- if (processed.events && typeof processed.events === "object") {
1859
- processed.events = JSON.stringify(processed.events);
1860
- }
1861
- if (processed.links && typeof processed.links === "object") {
1862
- processed.links = JSON.stringify(processed.links);
1863
- }
1864
- return processed;
1738
+ async dangerouslyClearAll() {
1739
+ await deleteTableData(this.service, storage.TABLE_SCORERS);
1865
1740
  }
1866
1741
  /**
1867
- * Validates that the required DynamoDB table exists and is accessible.
1868
- * This does not check the table structure - it assumes the table
1869
- * was created with the correct structure via CDK/CloudFormation.
1870
- */
1871
- async validateTableExists() {
1872
- try {
1873
- const command = new clientDynamodb.DescribeTableCommand({
1874
- TableName: this.tableName
1875
- });
1876
- await this.client.send(command);
1877
- return true;
1878
- } catch (error$1) {
1879
- if (error$1.name === "ResourceNotFoundException") {
1880
- return false;
1881
- }
1882
- throw new error.MastraError(
1883
- {
1884
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
1885
- domain: error.ErrorDomain.STORAGE,
1886
- category: error.ErrorCategory.THIRD_PARTY,
1887
- details: { tableName: this.tableName }
1888
- },
1889
- error$1
1890
- );
1891
- }
1892
- }
1893
- /**
1894
- * This method is modified for DynamoDB with ElectroDB single-table design.
1895
- * It assumes the table is created and managed externally via CDK/CloudFormation.
1742
+ * DynamoDB-specific score row transformation.
1896
1743
  *
1897
- * This implementation only validates that the required table exists and is accessible.
1898
- * No table creation is attempted - we simply check if we can access the table.
1744
+ * Note: This implementation does NOT use coreTransformScoreRow because:
1745
+ * 1. ElectroDB already parses JSON fields via its entity getters
1746
+ * 2. DynamoDB stores empty strings for null values (which need special handling)
1747
+ * 3. 'entity' is a reserved ElectroDB key, so we use 'entityData' column
1899
1748
  */
1900
- async createTable({ tableName }) {
1901
- this.logger.debug("Validating access to externally managed table", { tableName, physicalTable: this.tableName });
1902
- try {
1903
- const tableExists = await this.validateTableExists();
1904
- if (!tableExists) {
1905
- this.logger.error(
1906
- `Table ${this.tableName} does not exist or is not accessible. It should be created via CDK/CloudFormation.`
1907
- );
1908
- throw new Error(
1909
- `Table ${this.tableName} does not exist or is not accessible. Ensure it's created via CDK/CloudFormation before using this store.`
1910
- );
1911
- }
1912
- this.logger.debug(`Table ${this.tableName} exists and is accessible`);
1913
- } catch (error$1) {
1914
- this.logger.error("Error validating table access", { tableName: this.tableName, error: error$1 });
1915
- throw new error.MastraError(
1916
- {
1917
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_ACCESS_FAILED",
1918
- domain: error.ErrorDomain.STORAGE,
1919
- category: error.ErrorCategory.THIRD_PARTY,
1920
- details: { tableName: this.tableName }
1921
- },
1922
- error$1
1923
- );
1924
- }
1925
- }
1926
- async insert({ tableName, record }) {
1927
- this.logger.debug("DynamoDB insert called", { tableName });
1928
- const entityName = this.getEntityNameForTable(tableName);
1929
- if (!entityName || !this.service.entities[entityName]) {
1930
- throw new error.MastraError({
1931
- id: "STORAGE_DYNAMODB_STORE_INSERT_INVALID_ARGS",
1932
- domain: error.ErrorDomain.STORAGE,
1933
- category: error.ErrorCategory.USER,
1934
- text: "No entity defined for tableName",
1935
- details: { tableName }
1936
- });
1937
- }
1938
- try {
1939
- const dataToSave = { entity: entityName, ...this.preprocessRecord(record) };
1940
- await this.service.entities[entityName].create(dataToSave).go();
1941
- } catch (error$1) {
1942
- throw new error.MastraError(
1943
- {
1944
- id: "STORAGE_DYNAMODB_STORE_INSERT_FAILED",
1945
- domain: error.ErrorDomain.STORAGE,
1946
- category: error.ErrorCategory.THIRD_PARTY,
1947
- details: { tableName }
1948
- },
1949
- error$1
1950
- );
1951
- }
1952
- }
1953
- async alterTable(_args) {
1954
- }
1955
- /**
1956
- * Clear all items from a logical "table" (entity type)
1957
- */
1958
- async clearTable({ tableName }) {
1959
- this.logger.debug("DynamoDB clearTable called", { tableName });
1960
- const entityName = this.getEntityNameForTable(tableName);
1961
- if (!entityName || !this.service.entities[entityName]) {
1962
- throw new error.MastraError({
1963
- id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_INVALID_ARGS",
1964
- domain: error.ErrorDomain.STORAGE,
1965
- category: error.ErrorCategory.USER,
1966
- text: "No entity defined for tableName",
1967
- details: { tableName }
1968
- });
1969
- }
1970
- try {
1971
- const result = await this.service.entities[entityName].scan.go({ pages: "all" });
1972
- if (!result.data.length) {
1973
- this.logger.debug(`No records found to clear for ${tableName}`);
1974
- return;
1975
- }
1976
- this.logger.debug(`Found ${result.data.length} records to delete for ${tableName}`);
1977
- const keysToDelete = result.data.map((item) => {
1978
- const key = { entity: entityName };
1979
- switch (entityName) {
1980
- case "thread":
1981
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'thread'`);
1982
- key.id = item.id;
1983
- break;
1984
- case "message":
1985
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'message'`);
1986
- key.id = item.id;
1987
- break;
1988
- case "workflow_snapshot":
1989
- if (!item.workflow_name)
1990
- throw new Error(`Missing required key 'workflow_name' for entity 'workflow_snapshot'`);
1991
- if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'workflow_snapshot'`);
1992
- key.workflow_name = item.workflow_name;
1993
- key.run_id = item.run_id;
1994
- break;
1995
- case "eval":
1996
- if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'eval'`);
1997
- key.run_id = item.run_id;
1998
- break;
1999
- case "trace":
2000
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'trace'`);
2001
- key.id = item.id;
2002
- break;
2003
- case "score":
2004
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
2005
- key.id = item.id;
2006
- break;
2007
- case "resource":
2008
- if (!item.id) throw new Error(`Missing required key 'id' for entity 'resource'`);
2009
- key.id = item.id;
2010
- break;
2011
- default:
2012
- this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
2013
- throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
2014
- }
2015
- return key;
2016
- });
2017
- const batchSize = 25;
2018
- for (let i = 0; i < keysToDelete.length; i += batchSize) {
2019
- const batchKeys = keysToDelete.slice(i, i + batchSize);
2020
- await this.service.entities[entityName].delete(batchKeys).go();
2021
- }
2022
- this.logger.debug(`Successfully cleared all records for ${tableName}`);
2023
- } catch (error$1) {
2024
- throw new error.MastraError(
2025
- {
2026
- id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_FAILED",
2027
- domain: error.ErrorDomain.STORAGE,
2028
- category: error.ErrorCategory.THIRD_PARTY,
2029
- details: { tableName }
2030
- },
2031
- error$1
2032
- );
2033
- }
2034
- }
2035
- /**
2036
- * Insert multiple records as a batch
2037
- */
2038
- async batchInsert({ tableName, records }) {
2039
- this.logger.debug("DynamoDB batchInsert called", { tableName, count: records.length });
2040
- const entityName = this.getEntityNameForTable(tableName);
2041
- if (!entityName || !this.service.entities[entityName]) {
2042
- throw new error.MastraError({
2043
- id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_INVALID_ARGS",
2044
- domain: error.ErrorDomain.STORAGE,
2045
- category: error.ErrorCategory.USER,
2046
- text: "No entity defined for tableName",
2047
- details: { tableName }
2048
- });
2049
- }
2050
- const recordsToSave = records.map((rec) => ({ entity: entityName, ...this.preprocessRecord(rec) }));
2051
- const batchSize = 25;
2052
- const batches = [];
2053
- for (let i = 0; i < recordsToSave.length; i += batchSize) {
2054
- const batch = recordsToSave.slice(i, i + batchSize);
2055
- batches.push(batch);
2056
- }
2057
- try {
2058
- for (const batch of batches) {
2059
- for (const recordData of batch) {
2060
- if (!recordData.entity) {
2061
- this.logger.error("Missing entity property in record data for batchInsert", { recordData, tableName });
2062
- throw new Error(`Internal error: Missing entity property during batchInsert for ${tableName}`);
2063
- }
2064
- this.logger.debug("Attempting to create record in batchInsert:", { entityName, recordData });
2065
- await this.service.entities[entityName].create(recordData).go();
2066
- }
2067
- }
2068
- } catch (error$1) {
2069
- throw new error.MastraError(
2070
- {
2071
- id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_FAILED",
2072
- domain: error.ErrorDomain.STORAGE,
2073
- category: error.ErrorCategory.THIRD_PARTY,
2074
- details: { tableName }
2075
- },
2076
- error$1
2077
- );
2078
- }
2079
- }
2080
- /**
2081
- * Load a record by its keys
2082
- */
2083
- async load({ tableName, keys }) {
2084
- this.logger.debug("DynamoDB load called", { tableName, keys });
2085
- const entityName = this.getEntityNameForTable(tableName);
2086
- if (!entityName || !this.service.entities[entityName]) {
2087
- throw new error.MastraError({
2088
- id: "STORAGE_DYNAMODB_STORE_LOAD_INVALID_ARGS",
2089
- domain: error.ErrorDomain.STORAGE,
2090
- category: error.ErrorCategory.USER,
2091
- text: "No entity defined for tableName",
2092
- details: { tableName }
2093
- });
2094
- }
2095
- try {
2096
- const keyObject = { entity: entityName, ...keys };
2097
- const result = await this.service.entities[entityName].get(keyObject).go();
2098
- if (!result.data) {
2099
- return null;
1749
+ parseScoreData(data) {
1750
+ const result = {};
1751
+ for (const key of Object.keys(storage.SCORERS_SCHEMA)) {
1752
+ if (["traceId", "resourceId", "threadId", "spanId"].includes(key)) {
1753
+ result[key] = data[key] === "" ? null : data[key];
1754
+ continue;
2100
1755
  }
2101
- let data = result.data;
2102
- return data;
2103
- } catch (error$1) {
2104
- throw new error.MastraError(
2105
- {
2106
- id: "STORAGE_DYNAMODB_STORE_LOAD_FAILED",
2107
- domain: error.ErrorDomain.STORAGE,
2108
- category: error.ErrorCategory.THIRD_PARTY,
2109
- details: { tableName }
2110
- },
2111
- error$1
2112
- );
1756
+ result[key] = data[key];
2113
1757
  }
2114
- }
2115
- };
2116
- var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2117
- service;
2118
- constructor({ service }) {
2119
- super();
2120
- this.service = service;
2121
- }
2122
- // Helper function to parse score data (handle JSON fields)
2123
- parseScoreData(data) {
1758
+ result.entity = data.entityData ?? null;
2124
1759
  return {
2125
- ...data,
2126
- // Convert date strings back to Date objects for consistency
1760
+ ...result,
2127
1761
  createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
2128
1762
  updatedAt: data.updatedAt ? new Date(data.updatedAt) : /* @__PURE__ */ new Date()
2129
- // JSON fields are already transformed by the entity's getters
2130
1763
  };
2131
1764
  }
2132
1765
  async getScoreById({ id }) {
@@ -2140,7 +1773,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2140
1773
  } catch (error$1) {
2141
1774
  throw new error.MastraError(
2142
1775
  {
2143
- id: "STORAGE_DYNAMODB_STORE_GET_SCORE_BY_ID_FAILED",
1776
+ id: storage.createStorageErrorId("DYNAMODB", "GET_SCORE_BY_ID", "FAILED"),
2144
1777
  domain: error.ErrorDomain.STORAGE,
2145
1778
  category: error.ErrorCategory.THIRD_PARTY,
2146
1779
  details: { id }
@@ -2152,61 +1785,67 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2152
1785
  async saveScore(score) {
2153
1786
  let validatedScore;
2154
1787
  try {
2155
- validatedScore = scores.saveScorePayloadSchema.parse(score);
1788
+ validatedScore = evals.saveScorePayloadSchema.parse(score);
2156
1789
  } catch (error$1) {
2157
1790
  throw new error.MastraError(
2158
1791
  {
2159
- id: "STORAGE_DYNAMODB_STORE_SAVE_SCORE_FAILED",
1792
+ id: storage.createStorageErrorId("DYNAMODB", "SAVE_SCORE", "VALIDATION_FAILED"),
2160
1793
  domain: error.ErrorDomain.STORAGE,
2161
- category: error.ErrorCategory.THIRD_PARTY
1794
+ category: error.ErrorCategory.USER,
1795
+ details: {
1796
+ scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
1797
+ entityId: score.entityId ?? "unknown",
1798
+ entityType: score.entityType ?? "unknown",
1799
+ traceId: score.traceId ?? "",
1800
+ spanId: score.spanId ?? ""
1801
+ }
2162
1802
  },
2163
1803
  error$1
2164
1804
  );
2165
1805
  }
2166
1806
  const now = /* @__PURE__ */ new Date();
2167
- const scoreId = `score-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
2168
- const scoreData = {
2169
- entity: "score",
2170
- id: scoreId,
2171
- scorerId: validatedScore.scorerId,
2172
- traceId: validatedScore.traceId || "",
2173
- spanId: validatedScore.spanId || "",
2174
- runId: validatedScore.runId,
2175
- scorer: typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer),
2176
- preprocessStepResult: typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult),
2177
- analyzeStepResult: typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult),
2178
- score: validatedScore.score,
2179
- reason: validatedScore.reason,
2180
- preprocessPrompt: validatedScore.preprocessPrompt,
2181
- generateScorePrompt: validatedScore.generateScorePrompt,
2182
- generateReasonPrompt: validatedScore.generateReasonPrompt,
2183
- analyzePrompt: validatedScore.analyzePrompt,
2184
- input: typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input),
2185
- output: typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output),
2186
- additionalContext: typeof validatedScore.additionalContext === "string" ? validatedScore.additionalContext : JSON.stringify(validatedScore.additionalContext),
2187
- requestContext: typeof validatedScore.requestContext === "string" ? validatedScore.requestContext : JSON.stringify(validatedScore.requestContext),
2188
- entityType: validatedScore.entityType,
2189
- entityData: typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity),
2190
- entityId: validatedScore.entityId,
2191
- source: validatedScore.source,
2192
- resourceId: validatedScore.resourceId || "",
2193
- threadId: validatedScore.threadId || "",
2194
- createdAt: now.toISOString(),
2195
- updatedAt: now.toISOString()
2196
- };
1807
+ const scoreId = crypto.randomUUID();
1808
+ const scorer = typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer);
1809
+ const preprocessStepResult = typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult);
1810
+ const analyzeStepResult = typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult);
1811
+ const input = typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input);
1812
+ const output = typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output);
1813
+ const requestContext = typeof validatedScore.requestContext === "string" ? validatedScore.requestContext : JSON.stringify(validatedScore.requestContext);
1814
+ const entity = typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity);
1815
+ const scoreData = Object.fromEntries(
1816
+ Object.entries({
1817
+ ...validatedScore,
1818
+ entity: "score",
1819
+ id: scoreId,
1820
+ scorer,
1821
+ preprocessStepResult,
1822
+ analyzeStepResult,
1823
+ input,
1824
+ output,
1825
+ requestContext,
1826
+ entityData: entity,
1827
+ traceId: validatedScore.traceId || "",
1828
+ resourceId: validatedScore.resourceId || "",
1829
+ threadId: validatedScore.threadId || "",
1830
+ spanId: validatedScore.spanId || "",
1831
+ createdAt: now.toISOString(),
1832
+ updatedAt: now.toISOString()
1833
+ }).filter(([_, value]) => value !== void 0 && value !== null)
1834
+ );
2197
1835
  try {
2198
1836
  await this.service.entities.score.upsert(scoreData).go();
2199
- const savedScore = {
2200
- ...score,
2201
- id: scoreId,
2202
- createdAt: now,
2203
- updatedAt: now
1837
+ return {
1838
+ score: {
1839
+ ...validatedScore,
1840
+ id: scoreId,
1841
+ createdAt: now,
1842
+ updatedAt: now
1843
+ }
2204
1844
  };
2205
- return { score: savedScore };
2206
1845
  } catch (error$1) {
2207
1846
  throw new error.MastraError(
2208
1847
  {
2209
- id: "STORAGE_DYNAMODB_STORE_SAVE_SCORE_FAILED",
1848
+ id: storage.createStorageErrorId("DYNAMODB", "SAVE_SCORE", "FAILED"),
2210
1849
  domain: error.ErrorDomain.STORAGE,
2211
1850
  category: error.ErrorCategory.THIRD_PARTY,
2212
1851
  details: { scorerId: score.scorerId, runId: score.runId }
@@ -2215,7 +1854,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2215
1854
  );
2216
1855
  }
2217
1856
  }
2218
- async getScoresByScorerId({
1857
+ async listScoresByScorerId({
2219
1858
  scorerId,
2220
1859
  pagination,
2221
1860
  entityId,
@@ -2236,24 +1875,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2236
1875
  allScores = allScores.filter((score) => score.source === source);
2237
1876
  }
2238
1877
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2239
- const startIndex = pagination.page * pagination.perPage;
2240
- const endIndex = startIndex + pagination.perPage;
2241
- const paginatedScores = allScores.slice(startIndex, endIndex);
1878
+ const { page, perPage: perPageInput } = pagination;
1879
+ const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
1880
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2242
1881
  const total = allScores.length;
2243
- const hasMore = endIndex < total;
1882
+ const end = perPageInput === false ? allScores.length : start + perPage;
1883
+ const paginatedScores = allScores.slice(start, end);
2244
1884
  return {
2245
1885
  scores: paginatedScores,
2246
1886
  pagination: {
2247
1887
  total,
2248
- page: pagination.page,
2249
- perPage: pagination.perPage,
2250
- hasMore
1888
+ page,
1889
+ perPage: perPageForResponse,
1890
+ hasMore: end < total
2251
1891
  }
2252
1892
  };
2253
1893
  } catch (error$1) {
2254
1894
  throw new error.MastraError(
2255
1895
  {
2256
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_SCORER_ID_FAILED",
1896
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
2257
1897
  domain: error.ErrorDomain.STORAGE,
2258
1898
  category: error.ErrorCategory.THIRD_PARTY,
2259
1899
  details: {
@@ -2269,7 +1909,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2269
1909
  );
2270
1910
  }
2271
1911
  }
2272
- async getScoresByRunId({
1912
+ async listScoresByRunId({
2273
1913
  runId,
2274
1914
  pagination
2275
1915
  }) {
@@ -2279,24 +1919,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2279
1919
  const results = await query.go();
2280
1920
  const allScores = results.data.map((data) => this.parseScoreData(data));
2281
1921
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2282
- const startIndex = pagination.page * pagination.perPage;
2283
- const endIndex = startIndex + pagination.perPage;
2284
- const paginatedScores = allScores.slice(startIndex, endIndex);
1922
+ const { page, perPage: perPageInput } = pagination;
1923
+ const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
1924
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2285
1925
  const total = allScores.length;
2286
- const hasMore = endIndex < total;
1926
+ const end = perPageInput === false ? allScores.length : start + perPage;
1927
+ const paginatedScores = allScores.slice(start, end);
2287
1928
  return {
2288
1929
  scores: paginatedScores,
2289
1930
  pagination: {
2290
1931
  total,
2291
- page: pagination.page,
2292
- perPage: pagination.perPage,
2293
- hasMore
1932
+ page,
1933
+ perPage: perPageForResponse,
1934
+ hasMore: end < total
2294
1935
  }
2295
1936
  };
2296
1937
  } catch (error$1) {
2297
1938
  throw new error.MastraError(
2298
1939
  {
2299
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_RUN_ID_FAILED",
1940
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_RUN_ID", "FAILED"),
2300
1941
  domain: error.ErrorDomain.STORAGE,
2301
1942
  category: error.ErrorCategory.THIRD_PARTY,
2302
1943
  details: { runId, page: pagination.page, perPage: pagination.perPage }
@@ -2305,7 +1946,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2305
1946
  );
2306
1947
  }
2307
1948
  }
2308
- async getScoresByEntityId({
1949
+ async listScoresByEntityId({
2309
1950
  entityId,
2310
1951
  entityType,
2311
1952
  pagination
@@ -2317,24 +1958,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2317
1958
  let allScores = results.data.map((data) => this.parseScoreData(data));
2318
1959
  allScores = allScores.filter((score) => score.entityType === entityType);
2319
1960
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2320
- const startIndex = pagination.page * pagination.perPage;
2321
- const endIndex = startIndex + pagination.perPage;
2322
- const paginatedScores = allScores.slice(startIndex, endIndex);
1961
+ const { page, perPage: perPageInput } = pagination;
1962
+ const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
1963
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2323
1964
  const total = allScores.length;
2324
- const hasMore = endIndex < total;
1965
+ const end = perPageInput === false ? allScores.length : start + perPage;
1966
+ const paginatedScores = allScores.slice(start, end);
2325
1967
  return {
2326
1968
  scores: paginatedScores,
2327
1969
  pagination: {
2328
1970
  total,
2329
- page: pagination.page,
2330
- perPage: pagination.perPage,
2331
- hasMore
1971
+ page,
1972
+ perPage: perPageForResponse,
1973
+ hasMore: end < total
2332
1974
  }
2333
1975
  };
2334
1976
  } catch (error$1) {
2335
1977
  throw new error.MastraError(
2336
1978
  {
2337
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_ENTITY_ID_FAILED",
1979
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
2338
1980
  domain: error.ErrorDomain.STORAGE,
2339
1981
  category: error.ErrorCategory.THIRD_PARTY,
2340
1982
  details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
@@ -2343,7 +1985,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2343
1985
  );
2344
1986
  }
2345
1987
  }
2346
- async getScoresBySpan({
1988
+ async listScoresBySpan({
2347
1989
  traceId,
2348
1990
  spanId,
2349
1991
  pagination
@@ -2354,24 +1996,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
2354
1996
  const results = await query.go();
2355
1997
  const allScores = results.data.map((data) => this.parseScoreData(data));
2356
1998
  allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
2357
- const startIndex = pagination.page * pagination.perPage;
2358
- const endIndex = startIndex + pagination.perPage;
2359
- const paginatedScores = allScores.slice(startIndex, endIndex);
1999
+ const { page, perPage: perPageInput } = pagination;
2000
+ const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
2001
+ const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
2360
2002
  const total = allScores.length;
2361
- const hasMore = endIndex < total;
2003
+ const end = perPageInput === false ? allScores.length : start + perPage;
2004
+ const paginatedScores = allScores.slice(start, end);
2362
2005
  return {
2363
2006
  scores: paginatedScores,
2364
2007
  pagination: {
2365
2008
  total,
2366
- page: pagination.page,
2367
- perPage: pagination.perPage,
2368
- hasMore
2009
+ page,
2010
+ perPage: perPageForResponse,
2011
+ hasMore: end < total
2369
2012
  }
2370
2013
  };
2371
2014
  } catch (error$1) {
2372
2015
  throw new error.MastraError(
2373
2016
  {
2374
- id: "STORAGE_DYNAMODB_STORE_GET_SCORES_BY_SPAN_FAILED",
2017
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SPAN", "FAILED"),
2375
2018
  domain: error.ErrorDomain.STORAGE,
2376
2019
  category: error.ErrorCategory.THIRD_PARTY,
2377
2020
  details: { traceId, spanId, page: pagination.page, perPage: pagination.perPage }
@@ -2393,52 +2036,111 @@ function formatWorkflowRun(snapshotData) {
2393
2036
  }
2394
2037
  var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2395
2038
  service;
2396
- constructor({ service }) {
2039
+ constructor(config) {
2397
2040
  super();
2398
- this.service = service;
2041
+ this.service = resolveDynamoDBConfig(config);
2042
+ }
2043
+ async dangerouslyClearAll() {
2044
+ await deleteTableData(this.service, storage.TABLE_WORKFLOW_SNAPSHOT);
2399
2045
  }
2400
- updateWorkflowResults({
2401
- // workflowName,
2402
- // runId,
2403
- // stepId,
2404
- // result,
2405
- // requestContext,
2046
+ async updateWorkflowResults({
2047
+ workflowName,
2048
+ runId,
2049
+ stepId,
2050
+ result,
2051
+ requestContext
2406
2052
  }) {
2407
- throw new Error("Method not implemented.");
2053
+ try {
2054
+ const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
2055
+ let snapshot;
2056
+ if (!existingSnapshot) {
2057
+ snapshot = {
2058
+ context: {},
2059
+ activePaths: [],
2060
+ timestamp: Date.now(),
2061
+ suspendedPaths: {},
2062
+ activeStepsPath: {},
2063
+ resumeLabels: {},
2064
+ serializedStepGraph: [],
2065
+ status: "pending",
2066
+ value: {},
2067
+ waitingPaths: {},
2068
+ runId,
2069
+ requestContext: {}
2070
+ };
2071
+ } else {
2072
+ snapshot = existingSnapshot;
2073
+ }
2074
+ snapshot.context[stepId] = result;
2075
+ snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
2076
+ await this.persistWorkflowSnapshot({ workflowName, runId, snapshot });
2077
+ return snapshot.context;
2078
+ } catch (error$1) {
2079
+ if (error$1 instanceof error.MastraError) throw error$1;
2080
+ throw new error.MastraError(
2081
+ {
2082
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
2083
+ domain: error.ErrorDomain.STORAGE,
2084
+ category: error.ErrorCategory.THIRD_PARTY,
2085
+ details: { workflowName, runId, stepId }
2086
+ },
2087
+ error$1
2088
+ );
2089
+ }
2408
2090
  }
2409
- updateWorkflowState({
2410
- // workflowName,
2411
- // runId,
2412
- // opts,
2091
+ async updateWorkflowState({
2092
+ workflowName,
2093
+ runId,
2094
+ opts
2413
2095
  }) {
2414
- throw new Error("Method not implemented.");
2096
+ try {
2097
+ const existingSnapshot = await this.loadWorkflowSnapshot({ workflowName, runId });
2098
+ if (!existingSnapshot || !existingSnapshot.context) {
2099
+ return void 0;
2100
+ }
2101
+ const updatedSnapshot = { ...existingSnapshot, ...opts };
2102
+ await this.persistWorkflowSnapshot({ workflowName, runId, snapshot: updatedSnapshot });
2103
+ return updatedSnapshot;
2104
+ } catch (error$1) {
2105
+ if (error$1 instanceof error.MastraError) throw error$1;
2106
+ throw new error.MastraError(
2107
+ {
2108
+ id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
2109
+ domain: error.ErrorDomain.STORAGE,
2110
+ category: error.ErrorCategory.THIRD_PARTY,
2111
+ details: { workflowName, runId }
2112
+ },
2113
+ error$1
2114
+ );
2115
+ }
2415
2116
  }
2416
2117
  // Workflow operations
2417
2118
  async persistWorkflowSnapshot({
2418
2119
  workflowName,
2419
2120
  runId,
2420
2121
  resourceId,
2421
- snapshot
2122
+ snapshot,
2123
+ createdAt,
2124
+ updatedAt
2422
2125
  }) {
2423
2126
  this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
2424
2127
  try {
2425
- const now = (/* @__PURE__ */ new Date()).toISOString();
2128
+ const now = /* @__PURE__ */ new Date();
2426
2129
  const data = {
2427
2130
  entity: "workflow_snapshot",
2428
2131
  // Add entity type
2429
2132
  workflow_name: workflowName,
2430
2133
  run_id: runId,
2431
2134
  snapshot: JSON.stringify(snapshot),
2432
- // Stringify the snapshot object
2433
- createdAt: now,
2434
- updatedAt: now,
2135
+ createdAt: (createdAt ?? now).toISOString(),
2136
+ updatedAt: (updatedAt ?? now).toISOString(),
2435
2137
  resourceId
2436
2138
  };
2437
2139
  await this.service.entities.workflow_snapshot.upsert(data).go();
2438
2140
  } catch (error$1) {
2439
2141
  throw new error.MastraError(
2440
2142
  {
2441
- id: "STORAGE_DYNAMODB_STORE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
2143
+ id: storage.createStorageErrorId("DYNAMODB", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
2442
2144
  domain: error.ErrorDomain.STORAGE,
2443
2145
  category: error.ErrorCategory.THIRD_PARTY,
2444
2146
  details: { workflowName, runId }
@@ -2466,7 +2168,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2466
2168
  } catch (error$1) {
2467
2169
  throw new error.MastraError(
2468
2170
  {
2469
- id: "STORAGE_DYNAMODB_STORE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
2171
+ id: storage.createStorageErrorId("DYNAMODB", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
2470
2172
  domain: error.ErrorDomain.STORAGE,
2471
2173
  category: error.ErrorCategory.THIRD_PARTY,
2472
2174
  details: { workflowName, runId }
@@ -2478,8 +2180,21 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2478
2180
  async listWorkflowRuns(args) {
2479
2181
  this.logger.debug("Getting workflow runs", { args });
2480
2182
  try {
2481
- const limit = args?.limit || 10;
2482
- const offset = args?.offset || 0;
2183
+ const perPage = args?.perPage !== void 0 ? args.perPage : 10;
2184
+ const page = args?.page !== void 0 ? args.page : 0;
2185
+ if (page < 0) {
2186
+ throw new error.MastraError(
2187
+ {
2188
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "INVALID_PAGE"),
2189
+ domain: error.ErrorDomain.STORAGE,
2190
+ category: error.ErrorCategory.USER,
2191
+ details: { page }
2192
+ },
2193
+ new Error("page must be >= 0")
2194
+ );
2195
+ }
2196
+ const normalizedPerPage = storage.normalizePerPage(perPage, 10);
2197
+ const offset = page * normalizedPerPage;
2483
2198
  let query;
2484
2199
  if (args?.workflowName) {
2485
2200
  query = this.service.entities.workflow_snapshot.query.primary({
@@ -2501,6 +2216,11 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2501
2216
  });
2502
2217
  if (pageResults.data && pageResults.data.length > 0) {
2503
2218
  let pageFilteredData = pageResults.data;
2219
+ if (args?.status) {
2220
+ pageFilteredData = pageFilteredData.filter((snapshot) => {
2221
+ return snapshot.snapshot.status === args.status;
2222
+ });
2223
+ }
2504
2224
  if (args?.fromDate || args?.toDate) {
2505
2225
  pageFilteredData = pageFilteredData.filter((snapshot) => {
2506
2226
  const createdAt = new Date(snapshot.createdAt);
@@ -2526,7 +2246,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2526
2246
  return { runs: [], total: 0 };
2527
2247
  }
2528
2248
  const total = allMatchingSnapshots.length;
2529
- const paginatedData = allMatchingSnapshots.slice(offset, offset + limit);
2249
+ const paginatedData = allMatchingSnapshots.slice(offset, offset + normalizedPerPage);
2530
2250
  const runs = paginatedData.map((snapshot) => formatWorkflowRun(snapshot));
2531
2251
  return {
2532
2252
  runs,
@@ -2535,7 +2255,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2535
2255
  } catch (error$1) {
2536
2256
  throw new error.MastraError(
2537
2257
  {
2538
- id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUNS_FAILED",
2258
+ id: storage.createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "FAILED"),
2539
2259
  domain: error.ErrorDomain.STORAGE,
2540
2260
  category: error.ErrorCategory.THIRD_PARTY,
2541
2261
  details: { workflowName: args?.workflowName || "", resourceId: args?.resourceId || "" }
@@ -2589,7 +2309,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2589
2309
  } catch (error$1) {
2590
2310
  throw new error.MastraError(
2591
2311
  {
2592
- id: "STORAGE_DYNAMODB_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2312
+ id: storage.createStorageErrorId("DYNAMODB", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
2593
2313
  domain: error.ErrorDomain.STORAGE,
2594
2314
  category: error.ErrorCategory.THIRD_PARTY,
2595
2315
  details: { runId, workflowName: args?.workflowName || "" }
@@ -2598,9 +2318,32 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
2598
2318
  );
2599
2319
  }
2600
2320
  }
2321
+ async deleteWorkflowRunById({ runId, workflowName }) {
2322
+ this.logger.debug("Deleting workflow run by ID", { runId, workflowName });
2323
+ try {
2324
+ await this.service.entities.workflow_snapshot.delete({
2325
+ entity: "workflow_snapshot",
2326
+ workflow_name: workflowName,
2327
+ run_id: runId
2328
+ }).go();
2329
+ } catch (error$1) {
2330
+ throw new error.MastraError(
2331
+ {
2332
+ id: storage.createStorageErrorId("DYNAMODB", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
2333
+ domain: error.ErrorDomain.STORAGE,
2334
+ category: error.ErrorCategory.THIRD_PARTY,
2335
+ details: { runId, workflowName }
2336
+ },
2337
+ error$1
2338
+ );
2339
+ }
2340
+ }
2601
2341
  };
2602
2342
 
2603
2343
  // src/storage/index.ts
2344
+ var isClientConfig = (config) => {
2345
+ return "client" in config;
2346
+ };
2604
2347
  var DynamoDBStore = class extends storage.MastraStorage {
2605
2348
  tableName;
2606
2349
  client;
@@ -2608,7 +2351,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2608
2351
  hasInitialized = null;
2609
2352
  stores;
2610
2353
  constructor({ name, config }) {
2611
- super({ name });
2354
+ super({ id: config.id, name, disableInit: config.disableInit });
2612
2355
  try {
2613
2356
  if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
2614
2357
  throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
@@ -2618,24 +2361,23 @@ var DynamoDBStore = class extends storage.MastraStorage {
2618
2361
  `DynamoDBStore: config.tableName "${config.tableName}" contains invalid characters or is not between 3 and 255 characters long.`
2619
2362
  );
2620
2363
  }
2621
- const dynamoClient = new clientDynamodb.DynamoDBClient({
2622
- region: config.region || "us-east-1",
2623
- endpoint: config.endpoint,
2624
- credentials: config.credentials
2625
- });
2626
2364
  this.tableName = config.tableName;
2627
- this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
2365
+ if (isClientConfig(config)) {
2366
+ this.client = config.client;
2367
+ } else {
2368
+ const dynamoClient = new clientDynamodb.DynamoDBClient({
2369
+ region: config.region || "us-east-1",
2370
+ endpoint: config.endpoint,
2371
+ credentials: config.credentials
2372
+ });
2373
+ this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
2374
+ }
2628
2375
  this.service = getElectroDbService(this.client, this.tableName);
2629
- const operations = new StoreOperationsDynamoDB({
2630
- service: this.service,
2631
- tableName: this.tableName,
2632
- client: this.client
2633
- });
2634
- const workflows = new WorkflowStorageDynamoDB({ service: this.service });
2635
- const memory = new MemoryStorageDynamoDB({ service: this.service });
2636
- const scores = new ScoresStorageDynamoDB({ service: this.service });
2376
+ const domainConfig = { service: this.service };
2377
+ const workflows = new WorkflowStorageDynamoDB(domainConfig);
2378
+ const memory = new MemoryStorageDynamoDB(domainConfig);
2379
+ const scores = new ScoresStorageDynamoDB(domainConfig);
2637
2380
  this.stores = {
2638
- operations,
2639
2381
  workflows,
2640
2382
  memory,
2641
2383
  scores
@@ -2643,7 +2385,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2643
2385
  } catch (error$1) {
2644
2386
  throw new error.MastraError(
2645
2387
  {
2646
- id: "STORAGE_DYNAMODB_STORE_CONSTRUCTOR_FAILED",
2388
+ id: storage.createStorageErrorId("DYNAMODB", "CONSTRUCTOR", "FAILED"),
2647
2389
  domain: error.ErrorDomain.STORAGE,
2648
2390
  category: error.ErrorCategory.USER
2649
2391
  },
@@ -2651,16 +2393,6 @@ var DynamoDBStore = class extends storage.MastraStorage {
2651
2393
  );
2652
2394
  }
2653
2395
  }
2654
- get supports() {
2655
- return {
2656
- selectByIncludeResourceScope: true,
2657
- resourceWorkingMemory: true,
2658
- hasColumn: false,
2659
- createTable: false,
2660
- deleteMessages: false,
2661
- getScoresBySpan: true
2662
- };
2663
- }
2664
2396
  /**
2665
2397
  * Validates that the required DynamoDB table exists and is accessible.
2666
2398
  * This does not check the table structure - it assumes the table
@@ -2679,7 +2411,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2679
2411
  }
2680
2412
  throw new error.MastraError(
2681
2413
  {
2682
- id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
2414
+ id: storage.createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_EXISTS", "FAILED"),
2683
2415
  domain: error.ErrorDomain.STORAGE,
2684
2416
  category: error.ErrorCategory.THIRD_PARTY,
2685
2417
  details: { tableName: this.tableName }
@@ -2702,7 +2434,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2702
2434
  } catch (error$1) {
2703
2435
  throw new error.MastraError(
2704
2436
  {
2705
- id: "STORAGE_DYNAMODB_STORE_INIT_FAILED",
2437
+ id: storage.createStorageErrorId("DYNAMODB", "INIT", "FAILED"),
2706
2438
  domain: error.ErrorDomain.STORAGE,
2707
2439
  category: error.ErrorCategory.THIRD_PARTY,
2708
2440
  details: { tableName: this.tableName }
@@ -2728,120 +2460,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
2728
2460
  throw err;
2729
2461
  });
2730
2462
  }
2731
- async createTable({ tableName, schema }) {
2732
- return this.stores.operations.createTable({ tableName, schema });
2733
- }
2734
- async alterTable(_args) {
2735
- return this.stores.operations.alterTable(_args);
2736
- }
2737
- async clearTable({ tableName }) {
2738
- return this.stores.operations.clearTable({ tableName });
2739
- }
2740
- async dropTable({ tableName }) {
2741
- return this.stores.operations.dropTable({ tableName });
2742
- }
2743
- async insert({ tableName, record }) {
2744
- return this.stores.operations.insert({ tableName, record });
2745
- }
2746
- async batchInsert({ tableName, records }) {
2747
- return this.stores.operations.batchInsert({ tableName, records });
2748
- }
2749
- async load({ tableName, keys }) {
2750
- return this.stores.operations.load({ tableName, keys });
2751
- }
2752
- // Thread operations
2753
- async getThreadById({ threadId }) {
2754
- return this.stores.memory.getThreadById({ threadId });
2755
- }
2756
- async getThreadsByResourceId(args) {
2757
- return this.stores.memory.getThreadsByResourceId(args);
2758
- }
2759
- async saveThread({ thread }) {
2760
- return this.stores.memory.saveThread({ thread });
2761
- }
2762
- async updateThread({
2763
- id,
2764
- title,
2765
- metadata
2766
- }) {
2767
- return this.stores.memory.updateThread({ id, title, metadata });
2768
- }
2769
- async deleteThread({ threadId }) {
2770
- return this.stores.memory.deleteThread({ threadId });
2771
- }
2772
- async getMessages({
2773
- threadId,
2774
- resourceId,
2775
- selectBy,
2776
- format
2777
- }) {
2778
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
2779
- }
2780
- async saveMessages(args) {
2781
- return this.stores.memory.saveMessages(args);
2782
- }
2783
- async getThreadsByResourceIdPaginated(args) {
2784
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
2785
- }
2786
- async getMessagesPaginated(args) {
2787
- return this.stores.memory.getMessagesPaginated(args);
2788
- }
2789
- async updateMessages(_args) {
2790
- return this.stores.memory.updateMessages(_args);
2791
- }
2792
- // Workflow operations
2793
- async updateWorkflowResults({
2794
- workflowName,
2795
- runId,
2796
- stepId,
2797
- result,
2798
- requestContext
2799
- }) {
2800
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
2801
- }
2802
- async updateWorkflowState({
2803
- workflowName,
2804
- runId,
2805
- opts
2806
- }) {
2807
- return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
2808
- }
2809
- async persistWorkflowSnapshot({
2810
- workflowName,
2811
- runId,
2812
- resourceId,
2813
- snapshot
2814
- }) {
2815
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
2816
- }
2817
- async loadWorkflowSnapshot({
2818
- workflowName,
2819
- runId
2820
- }) {
2821
- return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2822
- }
2823
- async listWorkflowRuns(args) {
2824
- return this.stores.workflows.listWorkflowRuns(args);
2825
- }
2826
- async getWorkflowRunById(args) {
2827
- return this.stores.workflows.getWorkflowRunById(args);
2828
- }
2829
- async getResourceById({ resourceId }) {
2830
- return this.stores.memory.getResourceById({ resourceId });
2831
- }
2832
- async saveResource({ resource }) {
2833
- return this.stores.memory.saveResource({ resource });
2834
- }
2835
- async updateResource({
2836
- resourceId,
2837
- workingMemory,
2838
- metadata
2839
- }) {
2840
- return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
2841
- }
2842
2463
  /**
2843
2464
  * Closes the DynamoDB client connection and cleans up resources.
2844
- * Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
2465
+ *
2466
+ * This will close the DynamoDB client, including pre-configured clients.
2845
2467
  */
2846
2468
  async close() {
2847
2469
  this.logger.debug("Closing DynamoDB client for store:", { name: this.name });
@@ -2851,7 +2473,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
2851
2473
  } catch (error$1) {
2852
2474
  throw new error.MastraError(
2853
2475
  {
2854
- id: "STORAGE_DYNAMODB_STORE_CLOSE_FAILED",
2476
+ id: storage.createStorageErrorId("DYNAMODB", "CLOSE", "FAILED"),
2855
2477
  domain: error.ErrorDomain.STORAGE,
2856
2478
  category: error.ErrorCategory.THIRD_PARTY
2857
2479
  },
@@ -2859,50 +2481,11 @@ var DynamoDBStore = class extends storage.MastraStorage {
2859
2481
  );
2860
2482
  }
2861
2483
  }
2862
- /**
2863
- * SCORERS - Not implemented
2864
- */
2865
- async getScoreById({ id: _id }) {
2866
- return this.stores.scores.getScoreById({ id: _id });
2867
- }
2868
- async saveScore(_score) {
2869
- return this.stores.scores.saveScore(_score);
2870
- }
2871
- async getScoresByRunId({
2872
- runId: _runId,
2873
- pagination: _pagination
2874
- }) {
2875
- return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
2876
- }
2877
- async getScoresByEntityId({
2878
- entityId: _entityId,
2879
- entityType: _entityType,
2880
- pagination: _pagination
2881
- }) {
2882
- return this.stores.scores.getScoresByEntityId({
2883
- entityId: _entityId,
2884
- entityType: _entityType,
2885
- pagination: _pagination
2886
- });
2887
- }
2888
- async getScoresByScorerId({
2889
- scorerId,
2890
- source,
2891
- entityId,
2892
- entityType,
2893
- pagination
2894
- }) {
2895
- return this.stores.scores.getScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
2896
- }
2897
- async getScoresBySpan({
2898
- traceId,
2899
- spanId,
2900
- pagination
2901
- }) {
2902
- return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
2903
- }
2904
2484
  };
2905
2485
 
2906
2486
  exports.DynamoDBStore = DynamoDBStore;
2487
+ exports.MemoryStorageDynamoDB = MemoryStorageDynamoDB;
2488
+ exports.ScoresStorageDynamoDB = ScoresStorageDynamoDB;
2489
+ exports.WorkflowStorageDynamoDB = WorkflowStorageDynamoDB;
2907
2490
  //# sourceMappingURL=index.cjs.map
2908
2491
  //# sourceMappingURL=index.cjs.map