@mastra/dynamodb 0.0.0-remove-unused-model-providers-api-20251030210744 → 0.0.0-safe-stringify-telemetry-20251205024938
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/CHANGELOG.md +45 -13
- package/dist/entities/index.d.ts +5 -1
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/score.d.ts +5 -1
- package/dist/entities/score.d.ts.map +1 -1
- package/dist/index.cjs +476 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +477 -162
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/legacy-evals/index.d.ts +19 -0
- package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +7 -8
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/operations/index.d.ts.map +1 -1
- package/dist/storage/domains/score/index.d.ts.map +1 -1
- package/dist/storage/domains/traces/index.d.ts +28 -0
- package/dist/storage/domains/traces/index.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +3 -3
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +34 -4
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +13 -6
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DynamoDBClient, DescribeTableCommand } from '@aws-sdk/client-dynamodb';
|
|
2
2
|
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb';
|
|
3
3
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
4
|
-
import { MastraStorage, StoreOperations, WorkflowsStorage, MemoryStorage, resolveMessageLimit, ScoresStorage, TABLE_AI_SPANS, TABLE_RESOURCES,
|
|
4
|
+
import { MastraStorage, StoreOperations, TracesStorage, TABLE_TRACES, WorkflowsStorage, MemoryStorage, resolveMessageLimit, ScoresStorage, SCORERS_SCHEMA, LegacyEvalsStorage, TABLE_AI_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_EVALS, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, TABLE_THREADS } from '@mastra/core/storage';
|
|
5
5
|
import { Entity, Service } from 'electrodb';
|
|
6
6
|
import { MessageList } from '@mastra/core/agent';
|
|
7
7
|
import { saveScorePayloadSchema } from '@mastra/core/scores';
|
|
@@ -423,6 +423,10 @@ var scoreEntity = new Entity({
|
|
|
423
423
|
return value;
|
|
424
424
|
}
|
|
425
425
|
},
|
|
426
|
+
preprocessPrompt: {
|
|
427
|
+
type: "string",
|
|
428
|
+
required: false
|
|
429
|
+
},
|
|
426
430
|
preprocessStepResult: {
|
|
427
431
|
type: "string",
|
|
428
432
|
required: false,
|
|
@@ -562,7 +566,7 @@ var scoreEntity = new Entity({
|
|
|
562
566
|
return value;
|
|
563
567
|
}
|
|
564
568
|
},
|
|
565
|
-
|
|
569
|
+
runtimeContext: {
|
|
566
570
|
type: "string",
|
|
567
571
|
required: false,
|
|
568
572
|
set: (value) => {
|
|
@@ -933,6 +937,187 @@ function getElectroDbService(client, tableName) {
|
|
|
933
937
|
}
|
|
934
938
|
);
|
|
935
939
|
}
|
|
940
|
+
var LegacyEvalsDynamoDB = class extends LegacyEvalsStorage {
|
|
941
|
+
service;
|
|
942
|
+
tableName;
|
|
943
|
+
constructor({ service, tableName }) {
|
|
944
|
+
super();
|
|
945
|
+
this.service = service;
|
|
946
|
+
this.tableName = tableName;
|
|
947
|
+
}
|
|
948
|
+
// Eval operations
|
|
949
|
+
async getEvalsByAgentName(agentName, type) {
|
|
950
|
+
this.logger.debug("Getting evals for agent", { agentName, type });
|
|
951
|
+
try {
|
|
952
|
+
const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
|
|
953
|
+
const results = await query.go({ order: "desc", limit: 100 });
|
|
954
|
+
if (!results.data.length) {
|
|
955
|
+
return [];
|
|
956
|
+
}
|
|
957
|
+
let filteredData = results.data;
|
|
958
|
+
if (type) {
|
|
959
|
+
filteredData = filteredData.filter((evalRecord) => {
|
|
960
|
+
try {
|
|
961
|
+
const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
|
|
962
|
+
if (type === "test" && !testInfo) {
|
|
963
|
+
return false;
|
|
964
|
+
}
|
|
965
|
+
if (type === "live" && testInfo) {
|
|
966
|
+
return false;
|
|
967
|
+
}
|
|
968
|
+
} catch (e) {
|
|
969
|
+
this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
|
|
970
|
+
}
|
|
971
|
+
return true;
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
return filteredData.map((evalRecord) => {
|
|
975
|
+
try {
|
|
976
|
+
return {
|
|
977
|
+
input: evalRecord.input,
|
|
978
|
+
output: evalRecord.output,
|
|
979
|
+
// Safely parse result and test_info
|
|
980
|
+
result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
|
|
981
|
+
agentName: evalRecord.agent_name,
|
|
982
|
+
createdAt: evalRecord.created_at,
|
|
983
|
+
// Keep as string from DDB?
|
|
984
|
+
metricName: evalRecord.metric_name,
|
|
985
|
+
instructions: evalRecord.instructions,
|
|
986
|
+
runId: evalRecord.run_id,
|
|
987
|
+
globalRunId: evalRecord.global_run_id,
|
|
988
|
+
testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
|
|
989
|
+
};
|
|
990
|
+
} catch (parseError) {
|
|
991
|
+
this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
|
|
992
|
+
return {
|
|
993
|
+
agentName: evalRecord.agent_name,
|
|
994
|
+
createdAt: evalRecord.created_at,
|
|
995
|
+
runId: evalRecord.run_id,
|
|
996
|
+
globalRunId: evalRecord.global_run_id
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
} catch (error) {
|
|
1001
|
+
throw new MastraError(
|
|
1002
|
+
{
|
|
1003
|
+
id: "STORAGE_DYNAMODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
|
|
1004
|
+
domain: ErrorDomain.STORAGE,
|
|
1005
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1006
|
+
details: { agentName }
|
|
1007
|
+
},
|
|
1008
|
+
error
|
|
1009
|
+
);
|
|
1010
|
+
}
|
|
1011
|
+
}
|
|
1012
|
+
async getEvals(options = {}) {
|
|
1013
|
+
const { agentName, type, page = 0, perPage = 100, dateRange } = options;
|
|
1014
|
+
this.logger.debug("Getting evals with pagination", { agentName, type, page, perPage, dateRange });
|
|
1015
|
+
try {
|
|
1016
|
+
let query;
|
|
1017
|
+
if (agentName) {
|
|
1018
|
+
query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
|
|
1019
|
+
} else {
|
|
1020
|
+
query = this.service.entities.eval.query.byEntity({ entity: "eval" });
|
|
1021
|
+
}
|
|
1022
|
+
const results = await query.go({
|
|
1023
|
+
order: "desc",
|
|
1024
|
+
pages: "all"
|
|
1025
|
+
// Get all pages to apply filtering and pagination
|
|
1026
|
+
});
|
|
1027
|
+
if (!results.data.length) {
|
|
1028
|
+
return {
|
|
1029
|
+
evals: [],
|
|
1030
|
+
total: 0,
|
|
1031
|
+
page,
|
|
1032
|
+
perPage,
|
|
1033
|
+
hasMore: false
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
let filteredData = results.data;
|
|
1037
|
+
if (type) {
|
|
1038
|
+
filteredData = filteredData.filter((evalRecord) => {
|
|
1039
|
+
try {
|
|
1040
|
+
const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
|
|
1041
|
+
if (type === "test" && !testInfo) {
|
|
1042
|
+
return false;
|
|
1043
|
+
}
|
|
1044
|
+
if (type === "live" && testInfo) {
|
|
1045
|
+
return false;
|
|
1046
|
+
}
|
|
1047
|
+
} catch (e) {
|
|
1048
|
+
this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
|
|
1049
|
+
}
|
|
1050
|
+
return true;
|
|
1051
|
+
});
|
|
1052
|
+
}
|
|
1053
|
+
if (dateRange) {
|
|
1054
|
+
const fromDate = dateRange.start;
|
|
1055
|
+
const toDate = dateRange.end;
|
|
1056
|
+
filteredData = filteredData.filter((evalRecord) => {
|
|
1057
|
+
const recordDate = new Date(evalRecord.created_at);
|
|
1058
|
+
if (fromDate && recordDate < fromDate) {
|
|
1059
|
+
return false;
|
|
1060
|
+
}
|
|
1061
|
+
if (toDate && recordDate > toDate) {
|
|
1062
|
+
return false;
|
|
1063
|
+
}
|
|
1064
|
+
return true;
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
const total = filteredData.length;
|
|
1068
|
+
const start = page * perPage;
|
|
1069
|
+
const end = start + perPage;
|
|
1070
|
+
const paginatedData = filteredData.slice(start, end);
|
|
1071
|
+
const evals = paginatedData.map((evalRecord) => {
|
|
1072
|
+
try {
|
|
1073
|
+
return {
|
|
1074
|
+
input: evalRecord.input,
|
|
1075
|
+
output: evalRecord.output,
|
|
1076
|
+
result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
|
|
1077
|
+
agentName: evalRecord.agent_name,
|
|
1078
|
+
createdAt: evalRecord.created_at,
|
|
1079
|
+
metricName: evalRecord.metric_name,
|
|
1080
|
+
instructions: evalRecord.instructions,
|
|
1081
|
+
runId: evalRecord.run_id,
|
|
1082
|
+
globalRunId: evalRecord.global_run_id,
|
|
1083
|
+
testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
|
|
1084
|
+
};
|
|
1085
|
+
} catch (parseError) {
|
|
1086
|
+
this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
|
|
1087
|
+
return {
|
|
1088
|
+
agentName: evalRecord.agent_name,
|
|
1089
|
+
createdAt: evalRecord.created_at,
|
|
1090
|
+
runId: evalRecord.run_id,
|
|
1091
|
+
globalRunId: evalRecord.global_run_id
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
const hasMore = end < total;
|
|
1096
|
+
return {
|
|
1097
|
+
evals,
|
|
1098
|
+
total,
|
|
1099
|
+
page,
|
|
1100
|
+
perPage,
|
|
1101
|
+
hasMore
|
|
1102
|
+
};
|
|
1103
|
+
} catch (error) {
|
|
1104
|
+
throw new MastraError(
|
|
1105
|
+
{
|
|
1106
|
+
id: "STORAGE_DYNAMODB_STORE_GET_EVALS_FAILED",
|
|
1107
|
+
domain: ErrorDomain.STORAGE,
|
|
1108
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1109
|
+
details: {
|
|
1110
|
+
agentName: agentName || "all",
|
|
1111
|
+
type: type || "all",
|
|
1112
|
+
page,
|
|
1113
|
+
perPage
|
|
1114
|
+
}
|
|
1115
|
+
},
|
|
1116
|
+
error
|
|
1117
|
+
);
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
936
1121
|
var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
937
1122
|
service;
|
|
938
1123
|
constructor({ service }) {
|
|
@@ -1037,7 +1222,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
|
1037
1222
|
resourceId: thread.resourceId,
|
|
1038
1223
|
title: threadData.title,
|
|
1039
1224
|
createdAt: thread.createdAt || now,
|
|
1040
|
-
updatedAt:
|
|
1225
|
+
updatedAt: now,
|
|
1041
1226
|
metadata: thread.metadata
|
|
1042
1227
|
};
|
|
1043
1228
|
} catch (error) {
|
|
@@ -1189,7 +1374,10 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
|
1189
1374
|
);
|
|
1190
1375
|
}
|
|
1191
1376
|
}
|
|
1192
|
-
async
|
|
1377
|
+
async getMessagesById({
|
|
1378
|
+
messageIds,
|
|
1379
|
+
format
|
|
1380
|
+
}) {
|
|
1193
1381
|
this.logger.debug("Getting messages by ID", { messageIds });
|
|
1194
1382
|
if (messageIds.length === 0) return [];
|
|
1195
1383
|
try {
|
|
@@ -1202,6 +1390,7 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
|
1202
1390
|
(message, index, self) => index === self.findIndex((m) => m.id === message.id)
|
|
1203
1391
|
);
|
|
1204
1392
|
const list = new MessageList().add(uniqueMessages, "memory");
|
|
1393
|
+
if (format === `v1`) return list.get.all.v1();
|
|
1205
1394
|
return list.get.all.v2();
|
|
1206
1395
|
} catch (error) {
|
|
1207
1396
|
throw new MastraError(
|
|
@@ -1215,150 +1404,6 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
|
1215
1404
|
);
|
|
1216
1405
|
}
|
|
1217
1406
|
}
|
|
1218
|
-
async listMessages(args) {
|
|
1219
|
-
const { threadId, resourceId, include, filter, limit, offset = 0, orderBy } = args;
|
|
1220
|
-
if (!threadId.trim()) {
|
|
1221
|
-
throw new MastraError(
|
|
1222
|
-
{
|
|
1223
|
-
id: "STORAGE_DYNAMODB_LIST_MESSAGES_INVALID_THREAD_ID",
|
|
1224
|
-
domain: ErrorDomain.STORAGE,
|
|
1225
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
1226
|
-
details: { threadId }
|
|
1227
|
-
},
|
|
1228
|
-
new Error("threadId must be a non-empty string")
|
|
1229
|
-
);
|
|
1230
|
-
}
|
|
1231
|
-
try {
|
|
1232
|
-
let perPage = 40;
|
|
1233
|
-
if (limit !== void 0) {
|
|
1234
|
-
if (limit === false) {
|
|
1235
|
-
perPage = Number.MAX_SAFE_INTEGER;
|
|
1236
|
-
} else if (limit === 0) {
|
|
1237
|
-
perPage = 0;
|
|
1238
|
-
} else if (typeof limit === "number" && limit > 0) {
|
|
1239
|
-
perPage = limit;
|
|
1240
|
-
}
|
|
1241
|
-
}
|
|
1242
|
-
const page = perPage === 0 ? 0 : Math.floor(offset / perPage);
|
|
1243
|
-
const sortField = orderBy?.field || "createdAt";
|
|
1244
|
-
const sortDirection = orderBy?.direction || "DESC";
|
|
1245
|
-
this.logger.debug("Getting messages with listMessages", {
|
|
1246
|
-
threadId,
|
|
1247
|
-
resourceId,
|
|
1248
|
-
limit,
|
|
1249
|
-
offset,
|
|
1250
|
-
perPage,
|
|
1251
|
-
page,
|
|
1252
|
-
sortField,
|
|
1253
|
-
sortDirection
|
|
1254
|
-
});
|
|
1255
|
-
const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
|
|
1256
|
-
const results = await query.go();
|
|
1257
|
-
let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
|
|
1258
|
-
if (resourceId) {
|
|
1259
|
-
allThreadMessages = allThreadMessages.filter((msg) => msg.resourceId === resourceId);
|
|
1260
|
-
}
|
|
1261
|
-
if (filter?.dateRange) {
|
|
1262
|
-
const dateRange = filter.dateRange;
|
|
1263
|
-
allThreadMessages = allThreadMessages.filter((msg) => {
|
|
1264
|
-
const createdAt = new Date(msg.createdAt).getTime();
|
|
1265
|
-
if (dateRange.start) {
|
|
1266
|
-
const startTime = dateRange.start instanceof Date ? dateRange.start.getTime() : new Date(dateRange.start).getTime();
|
|
1267
|
-
if (createdAt < startTime) return false;
|
|
1268
|
-
}
|
|
1269
|
-
if (dateRange.end) {
|
|
1270
|
-
const endTime = dateRange.end instanceof Date ? dateRange.end.getTime() : new Date(dateRange.end).getTime();
|
|
1271
|
-
if (createdAt > endTime) return false;
|
|
1272
|
-
}
|
|
1273
|
-
return true;
|
|
1274
|
-
});
|
|
1275
|
-
}
|
|
1276
|
-
allThreadMessages.sort((a, b) => {
|
|
1277
|
-
const aValue = sortField === "createdAt" ? new Date(a.createdAt).getTime() : a[sortField];
|
|
1278
|
-
const bValue = sortField === "createdAt" ? new Date(b.createdAt).getTime() : b[sortField];
|
|
1279
|
-
if (aValue === bValue) {
|
|
1280
|
-
return a.id.localeCompare(b.id);
|
|
1281
|
-
}
|
|
1282
|
-
return sortDirection === "ASC" ? aValue - bValue : bValue - aValue;
|
|
1283
|
-
});
|
|
1284
|
-
const total = allThreadMessages.length;
|
|
1285
|
-
const paginatedMessages = allThreadMessages.slice(offset, offset + perPage);
|
|
1286
|
-
const paginatedCount = paginatedMessages.length;
|
|
1287
|
-
if (total === 0 && paginatedCount === 0) {
|
|
1288
|
-
return {
|
|
1289
|
-
messages: [],
|
|
1290
|
-
total: 0,
|
|
1291
|
-
page,
|
|
1292
|
-
perPage,
|
|
1293
|
-
hasMore: false
|
|
1294
|
-
};
|
|
1295
|
-
}
|
|
1296
|
-
const messageIds = new Set(paginatedMessages.map((m) => m.id));
|
|
1297
|
-
let includeMessages = [];
|
|
1298
|
-
if (include && include.length > 0) {
|
|
1299
|
-
const selectBy = { include };
|
|
1300
|
-
includeMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
1301
|
-
for (const includeMsg of includeMessages) {
|
|
1302
|
-
if (!messageIds.has(includeMsg.id)) {
|
|
1303
|
-
paginatedMessages.push(includeMsg);
|
|
1304
|
-
messageIds.add(includeMsg.id);
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
}
|
|
1308
|
-
const list = new MessageList().add(paginatedMessages, "memory");
|
|
1309
|
-
let finalMessages = list.get.all.v2();
|
|
1310
|
-
finalMessages = finalMessages.sort((a, b) => {
|
|
1311
|
-
const aValue = sortField === "createdAt" ? new Date(a.createdAt).getTime() : a[sortField];
|
|
1312
|
-
const bValue = sortField === "createdAt" ? new Date(b.createdAt).getTime() : b[sortField];
|
|
1313
|
-
if (aValue === bValue) {
|
|
1314
|
-
return a.id.localeCompare(b.id);
|
|
1315
|
-
}
|
|
1316
|
-
return sortDirection === "ASC" ? aValue - bValue : bValue - aValue;
|
|
1317
|
-
});
|
|
1318
|
-
const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
|
|
1319
|
-
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
1320
|
-
const hasMore = limit === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
|
|
1321
|
-
return {
|
|
1322
|
-
messages: finalMessages,
|
|
1323
|
-
total,
|
|
1324
|
-
page,
|
|
1325
|
-
perPage,
|
|
1326
|
-
hasMore
|
|
1327
|
-
};
|
|
1328
|
-
} catch (error) {
|
|
1329
|
-
const mastraError = new MastraError(
|
|
1330
|
-
{
|
|
1331
|
-
id: "STORAGE_DYNAMODB_STORE_LIST_MESSAGES_FAILED",
|
|
1332
|
-
domain: ErrorDomain.STORAGE,
|
|
1333
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
1334
|
-
details: {
|
|
1335
|
-
threadId,
|
|
1336
|
-
resourceId: resourceId ?? ""
|
|
1337
|
-
}
|
|
1338
|
-
},
|
|
1339
|
-
error
|
|
1340
|
-
);
|
|
1341
|
-
this.logger?.error?.(mastraError.toString());
|
|
1342
|
-
this.logger?.trackException?.(mastraError);
|
|
1343
|
-
return {
|
|
1344
|
-
messages: [],
|
|
1345
|
-
total: 0,
|
|
1346
|
-
page: Math.floor(offset / (limit === false ? Number.MAX_SAFE_INTEGER : limit || 40)),
|
|
1347
|
-
perPage: limit === false ? Number.MAX_SAFE_INTEGER : limit || 40,
|
|
1348
|
-
hasMore: false
|
|
1349
|
-
};
|
|
1350
|
-
}
|
|
1351
|
-
}
|
|
1352
|
-
/**
|
|
1353
|
-
* @todo When migrating from getThreadsByResourceIdPaginated to this method,
|
|
1354
|
-
* implement orderBy and sortDirection support for full sorting capabilities
|
|
1355
|
-
*/
|
|
1356
|
-
async listThreadsByResourceId(args) {
|
|
1357
|
-
const { resourceId, limit, offset } = args;
|
|
1358
|
-
const page = Math.floor(offset / limit);
|
|
1359
|
-
const perPage = limit;
|
|
1360
|
-
return this.getThreadsByResourceIdPaginated({ resourceId, page, perPage });
|
|
1361
|
-
}
|
|
1362
1407
|
async saveMessages(args) {
|
|
1363
1408
|
const { messages, format = "v1" } = args;
|
|
1364
1409
|
this.logger.debug("Saving messages", { count: messages.length });
|
|
@@ -1525,7 +1570,8 @@ var MemoryStorageDynamoDB = class extends MemoryStorage {
|
|
|
1525
1570
|
const paginatedMessages = messages.slice(start, end);
|
|
1526
1571
|
const hasMore = end < total;
|
|
1527
1572
|
const list = new MessageList({ threadId, resourceId }).add(paginatedMessages, "memory");
|
|
1528
|
-
|
|
1573
|
+
let finalMessages = format === "v2" ? list.get.all.v2() : list.get.all.v1();
|
|
1574
|
+
finalMessages = finalMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1529
1575
|
return {
|
|
1530
1576
|
messages: finalMessages,
|
|
1531
1577
|
total,
|
|
@@ -1814,6 +1860,7 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
|
|
|
1814
1860
|
[TABLE_THREADS]: "thread",
|
|
1815
1861
|
[TABLE_MESSAGES]: "message",
|
|
1816
1862
|
[TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
|
|
1863
|
+
[TABLE_EVALS]: "eval",
|
|
1817
1864
|
[TABLE_SCORERS]: "score",
|
|
1818
1865
|
[TABLE_TRACES]: "trace",
|
|
1819
1866
|
[TABLE_RESOURCES]: "resource",
|
|
@@ -2002,10 +2049,6 @@ var StoreOperationsDynamoDB = class extends StoreOperations {
|
|
|
2002
2049
|
if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
|
|
2003
2050
|
key.id = item.id;
|
|
2004
2051
|
break;
|
|
2005
|
-
case "resource":
|
|
2006
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'resource'`);
|
|
2007
|
-
key.id = item.id;
|
|
2008
|
-
break;
|
|
2009
2052
|
default:
|
|
2010
2053
|
this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
|
|
2011
2054
|
throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
|
|
@@ -2119,8 +2162,17 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
|
|
|
2119
2162
|
}
|
|
2120
2163
|
// Helper function to parse score data (handle JSON fields)
|
|
2121
2164
|
parseScoreData(data) {
|
|
2165
|
+
const result = {};
|
|
2166
|
+
for (const key of Object.keys(SCORERS_SCHEMA)) {
|
|
2167
|
+
if (["traceId", "resourceId", "threadId", "spanId"].includes(key)) {
|
|
2168
|
+
result[key] = data[key] === "" ? null : data[key];
|
|
2169
|
+
continue;
|
|
2170
|
+
}
|
|
2171
|
+
result[key] = data[key];
|
|
2172
|
+
}
|
|
2173
|
+
result.entity = data.entityData ? data.entityData : null;
|
|
2122
2174
|
return {
|
|
2123
|
-
...
|
|
2175
|
+
...result,
|
|
2124
2176
|
// Convert date strings back to Date objects for consistency
|
|
2125
2177
|
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
2126
2178
|
updatedAt: data.updatedAt ? new Date(data.updatedAt) : /* @__PURE__ */ new Date()
|
|
@@ -2182,7 +2234,7 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
|
|
|
2182
2234
|
input: typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input),
|
|
2183
2235
|
output: typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output),
|
|
2184
2236
|
additionalContext: typeof validatedScore.additionalContext === "string" ? validatedScore.additionalContext : JSON.stringify(validatedScore.additionalContext),
|
|
2185
|
-
|
|
2237
|
+
runtimeContext: typeof validatedScore.runtimeContext === "string" ? validatedScore.runtimeContext : JSON.stringify(validatedScore.runtimeContext),
|
|
2186
2238
|
entityType: validatedScore.entityType,
|
|
2187
2239
|
entityData: typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity),
|
|
2188
2240
|
entityId: validatedScore.entityId,
|
|
@@ -2379,6 +2431,239 @@ var ScoresStorageDynamoDB = class extends ScoresStorage {
|
|
|
2379
2431
|
}
|
|
2380
2432
|
}
|
|
2381
2433
|
};
|
|
2434
|
+
var TracesStorageDynamoDB = class extends TracesStorage {
|
|
2435
|
+
service;
|
|
2436
|
+
operations;
|
|
2437
|
+
constructor({ service, operations }) {
|
|
2438
|
+
super();
|
|
2439
|
+
this.service = service;
|
|
2440
|
+
this.operations = operations;
|
|
2441
|
+
}
|
|
2442
|
+
// Trace operations
|
|
2443
|
+
async getTraces(args) {
|
|
2444
|
+
const { name, scope, page, perPage } = args;
|
|
2445
|
+
this.logger.debug("Getting traces", { name, scope, page, perPage });
|
|
2446
|
+
try {
|
|
2447
|
+
let query;
|
|
2448
|
+
if (name) {
|
|
2449
|
+
query = this.service.entities.trace.query.byName({ entity: "trace", name });
|
|
2450
|
+
} else if (scope) {
|
|
2451
|
+
query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
|
|
2452
|
+
} else {
|
|
2453
|
+
this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
|
|
2454
|
+
query = this.service.entities.trace.scan;
|
|
2455
|
+
}
|
|
2456
|
+
let items = [];
|
|
2457
|
+
let cursor = null;
|
|
2458
|
+
let pagesFetched = 0;
|
|
2459
|
+
const startPage = page > 0 ? page : 1;
|
|
2460
|
+
do {
|
|
2461
|
+
const results = await query.go({ cursor, limit: perPage });
|
|
2462
|
+
pagesFetched++;
|
|
2463
|
+
if (pagesFetched === startPage) {
|
|
2464
|
+
items = results.data;
|
|
2465
|
+
break;
|
|
2466
|
+
}
|
|
2467
|
+
cursor = results.cursor;
|
|
2468
|
+
if (!cursor && results.data.length > 0 && pagesFetched < startPage) {
|
|
2469
|
+
break;
|
|
2470
|
+
}
|
|
2471
|
+
} while (cursor && pagesFetched < startPage);
|
|
2472
|
+
return items;
|
|
2473
|
+
} catch (error) {
|
|
2474
|
+
throw new MastraError(
|
|
2475
|
+
{
|
|
2476
|
+
id: "STORAGE_DYNAMODB_STORE_GET_TRACES_FAILED",
|
|
2477
|
+
domain: ErrorDomain.STORAGE,
|
|
2478
|
+
category: ErrorCategory.THIRD_PARTY
|
|
2479
|
+
},
|
|
2480
|
+
error
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
}
|
|
2484
|
+
async batchTraceInsert({ records }) {
|
|
2485
|
+
this.logger.debug("Batch inserting traces", { count: records.length });
|
|
2486
|
+
if (!records.length) {
|
|
2487
|
+
return;
|
|
2488
|
+
}
|
|
2489
|
+
try {
|
|
2490
|
+
const recordsToSave = records.map((rec) => ({ entity: "trace", ...rec }));
|
|
2491
|
+
await this.operations.batchInsert({
|
|
2492
|
+
tableName: TABLE_TRACES,
|
|
2493
|
+
records: recordsToSave
|
|
2494
|
+
// Pass records with 'entity' included
|
|
2495
|
+
});
|
|
2496
|
+
} catch (error) {
|
|
2497
|
+
throw new MastraError(
|
|
2498
|
+
{
|
|
2499
|
+
id: "STORAGE_DYNAMODB_STORE_BATCH_TRACE_INSERT_FAILED",
|
|
2500
|
+
domain: ErrorDomain.STORAGE,
|
|
2501
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2502
|
+
details: { count: records.length }
|
|
2503
|
+
},
|
|
2504
|
+
error
|
|
2505
|
+
);
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
async getTracesPaginated(args) {
|
|
2509
|
+
const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
|
|
2510
|
+
this.logger.debug("Getting traces with pagination", { name, scope, page, perPage, attributes, filters, dateRange });
|
|
2511
|
+
try {
|
|
2512
|
+
let query;
|
|
2513
|
+
if (name) {
|
|
2514
|
+
query = this.service.entities.trace.query.byName({ entity: "trace", name });
|
|
2515
|
+
} else if (scope) {
|
|
2516
|
+
query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
|
|
2517
|
+
} else {
|
|
2518
|
+
this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
|
|
2519
|
+
query = this.service.entities.trace.scan;
|
|
2520
|
+
}
|
|
2521
|
+
const results = await query.go({
|
|
2522
|
+
order: "desc",
|
|
2523
|
+
pages: "all"
|
|
2524
|
+
// Get all pages to apply filtering and pagination
|
|
2525
|
+
});
|
|
2526
|
+
if (!results.data.length) {
|
|
2527
|
+
return {
|
|
2528
|
+
traces: [],
|
|
2529
|
+
total: 0,
|
|
2530
|
+
page,
|
|
2531
|
+
perPage,
|
|
2532
|
+
hasMore: false
|
|
2533
|
+
};
|
|
2534
|
+
}
|
|
2535
|
+
let filteredData = results.data;
|
|
2536
|
+
if (attributes) {
|
|
2537
|
+
filteredData = filteredData.filter((item) => {
|
|
2538
|
+
try {
|
|
2539
|
+
let itemAttributes = {};
|
|
2540
|
+
if (item.attributes) {
|
|
2541
|
+
if (typeof item.attributes === "string") {
|
|
2542
|
+
if (item.attributes === "[object Object]") {
|
|
2543
|
+
itemAttributes = {};
|
|
2544
|
+
} else {
|
|
2545
|
+
try {
|
|
2546
|
+
itemAttributes = JSON.parse(item.attributes);
|
|
2547
|
+
} catch {
|
|
2548
|
+
itemAttributes = {};
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
} else if (typeof item.attributes === "object") {
|
|
2552
|
+
itemAttributes = item.attributes;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
return Object.entries(attributes).every(([key, value]) => itemAttributes[key] === value);
|
|
2556
|
+
} catch (e) {
|
|
2557
|
+
this.logger.warn("Failed to parse attributes during filtering", { item, error: e });
|
|
2558
|
+
return false;
|
|
2559
|
+
}
|
|
2560
|
+
});
|
|
2561
|
+
}
|
|
2562
|
+
if (dateRange?.start) {
|
|
2563
|
+
filteredData = filteredData.filter((item) => {
|
|
2564
|
+
const itemDate = new Date(item.createdAt);
|
|
2565
|
+
return itemDate >= dateRange.start;
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
if (dateRange?.end) {
|
|
2569
|
+
filteredData = filteredData.filter((item) => {
|
|
2570
|
+
const itemDate = new Date(item.createdAt);
|
|
2571
|
+
return itemDate <= dateRange.end;
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2574
|
+
const total = filteredData.length;
|
|
2575
|
+
const start = page * perPage;
|
|
2576
|
+
const end = start + perPage;
|
|
2577
|
+
const paginatedData = filteredData.slice(start, end);
|
|
2578
|
+
const traces = paginatedData.map((item) => {
|
|
2579
|
+
let attributes2;
|
|
2580
|
+
if (item.attributes) {
|
|
2581
|
+
if (typeof item.attributes === "string") {
|
|
2582
|
+
if (item.attributes === "[object Object]") {
|
|
2583
|
+
attributes2 = void 0;
|
|
2584
|
+
} else {
|
|
2585
|
+
try {
|
|
2586
|
+
attributes2 = JSON.parse(item.attributes);
|
|
2587
|
+
} catch {
|
|
2588
|
+
attributes2 = void 0;
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
} else if (typeof item.attributes === "object") {
|
|
2592
|
+
attributes2 = item.attributes;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
let status;
|
|
2596
|
+
if (item.status) {
|
|
2597
|
+
if (typeof item.status === "string") {
|
|
2598
|
+
try {
|
|
2599
|
+
status = JSON.parse(item.status);
|
|
2600
|
+
} catch {
|
|
2601
|
+
status = void 0;
|
|
2602
|
+
}
|
|
2603
|
+
} else if (typeof item.status === "object") {
|
|
2604
|
+
status = item.status;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
let events;
|
|
2608
|
+
if (item.events) {
|
|
2609
|
+
if (typeof item.events === "string") {
|
|
2610
|
+
try {
|
|
2611
|
+
events = JSON.parse(item.events);
|
|
2612
|
+
} catch {
|
|
2613
|
+
events = void 0;
|
|
2614
|
+
}
|
|
2615
|
+
} else if (Array.isArray(item.events)) {
|
|
2616
|
+
events = item.events;
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
let links;
|
|
2620
|
+
if (item.links) {
|
|
2621
|
+
if (typeof item.links === "string") {
|
|
2622
|
+
try {
|
|
2623
|
+
links = JSON.parse(item.links);
|
|
2624
|
+
} catch {
|
|
2625
|
+
links = void 0;
|
|
2626
|
+
}
|
|
2627
|
+
} else if (Array.isArray(item.links)) {
|
|
2628
|
+
links = item.links;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
return {
|
|
2632
|
+
id: item.id,
|
|
2633
|
+
parentSpanId: item.parentSpanId,
|
|
2634
|
+
name: item.name,
|
|
2635
|
+
traceId: item.traceId,
|
|
2636
|
+
scope: item.scope,
|
|
2637
|
+
kind: item.kind,
|
|
2638
|
+
attributes: attributes2,
|
|
2639
|
+
status,
|
|
2640
|
+
events,
|
|
2641
|
+
links,
|
|
2642
|
+
other: item.other,
|
|
2643
|
+
startTime: item.startTime,
|
|
2644
|
+
endTime: item.endTime,
|
|
2645
|
+
createdAt: item.createdAt
|
|
2646
|
+
};
|
|
2647
|
+
});
|
|
2648
|
+
return {
|
|
2649
|
+
traces,
|
|
2650
|
+
total,
|
|
2651
|
+
page,
|
|
2652
|
+
perPage,
|
|
2653
|
+
hasMore: end < total
|
|
2654
|
+
};
|
|
2655
|
+
} catch (error) {
|
|
2656
|
+
throw new MastraError(
|
|
2657
|
+
{
|
|
2658
|
+
id: "STORAGE_DYNAMODB_STORE_GET_TRACES_PAGINATED_FAILED",
|
|
2659
|
+
domain: ErrorDomain.STORAGE,
|
|
2660
|
+
category: ErrorCategory.THIRD_PARTY
|
|
2661
|
+
},
|
|
2662
|
+
error
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
};
|
|
2382
2667
|
function formatWorkflowRun(snapshotData) {
|
|
2383
2668
|
return {
|
|
2384
2669
|
workflowName: snapshotData.workflow_name,
|
|
@@ -2400,7 +2685,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
|
|
|
2400
2685
|
// runId,
|
|
2401
2686
|
// stepId,
|
|
2402
2687
|
// result,
|
|
2403
|
-
//
|
|
2688
|
+
// runtimeContext,
|
|
2404
2689
|
}) {
|
|
2405
2690
|
throw new Error("Method not implemented.");
|
|
2406
2691
|
}
|
|
@@ -2427,7 +2712,6 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
|
|
|
2427
2712
|
workflow_name: workflowName,
|
|
2428
2713
|
run_id: runId,
|
|
2429
2714
|
snapshot: JSON.stringify(snapshot),
|
|
2430
|
-
// Stringify the snapshot object
|
|
2431
2715
|
createdAt: now,
|
|
2432
2716
|
updatedAt: now,
|
|
2433
2717
|
resourceId
|
|
@@ -2473,7 +2757,7 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
|
|
|
2473
2757
|
);
|
|
2474
2758
|
}
|
|
2475
2759
|
}
|
|
2476
|
-
async
|
|
2760
|
+
async getWorkflowRuns(args) {
|
|
2477
2761
|
this.logger.debug("Getting workflow runs", { args });
|
|
2478
2762
|
try {
|
|
2479
2763
|
const limit = args?.limit || 10;
|
|
@@ -2499,6 +2783,11 @@ var WorkflowStorageDynamoDB = class extends WorkflowsStorage {
|
|
|
2499
2783
|
});
|
|
2500
2784
|
if (pageResults.data && pageResults.data.length > 0) {
|
|
2501
2785
|
let pageFilteredData = pageResults.data;
|
|
2786
|
+
if (args?.status) {
|
|
2787
|
+
pageFilteredData = pageFilteredData.filter((snapshot) => {
|
|
2788
|
+
return snapshot.snapshot.status === args.status;
|
|
2789
|
+
});
|
|
2790
|
+
}
|
|
2502
2791
|
if (args?.fromDate || args?.toDate) {
|
|
2503
2792
|
pageFilteredData = pageFilteredData.filter((snapshot) => {
|
|
2504
2793
|
const createdAt = new Date(snapshot.createdAt);
|
|
@@ -2629,11 +2918,14 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
2629
2918
|
tableName: this.tableName,
|
|
2630
2919
|
client: this.client
|
|
2631
2920
|
});
|
|
2921
|
+
const traces = new TracesStorageDynamoDB({ service: this.service, operations });
|
|
2632
2922
|
const workflows = new WorkflowStorageDynamoDB({ service: this.service });
|
|
2633
2923
|
const memory = new MemoryStorageDynamoDB({ service: this.service });
|
|
2634
2924
|
const scores = new ScoresStorageDynamoDB({ service: this.service });
|
|
2635
2925
|
this.stores = {
|
|
2636
2926
|
operations,
|
|
2927
|
+
legacyEvals: new LegacyEvalsDynamoDB({ service: this.service, tableName: this.tableName }),
|
|
2928
|
+
traces,
|
|
2637
2929
|
workflows,
|
|
2638
2930
|
memory,
|
|
2639
2931
|
scores
|
|
@@ -2775,6 +3067,12 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
2775
3067
|
}) {
|
|
2776
3068
|
return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
|
|
2777
3069
|
}
|
|
3070
|
+
async getMessagesById({
|
|
3071
|
+
messageIds,
|
|
3072
|
+
format
|
|
3073
|
+
}) {
|
|
3074
|
+
return this.stores.memory.getMessagesById({ messageIds, format });
|
|
3075
|
+
}
|
|
2778
3076
|
async saveMessages(args) {
|
|
2779
3077
|
return this.stores.memory.saveMessages(args);
|
|
2780
3078
|
}
|
|
@@ -2787,15 +3085,25 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
2787
3085
|
async updateMessages(_args) {
|
|
2788
3086
|
return this.stores.memory.updateMessages(_args);
|
|
2789
3087
|
}
|
|
3088
|
+
// Trace operations
|
|
3089
|
+
async getTraces(args) {
|
|
3090
|
+
return this.stores.traces.getTraces(args);
|
|
3091
|
+
}
|
|
3092
|
+
async batchTraceInsert({ records }) {
|
|
3093
|
+
return this.stores.traces.batchTraceInsert({ records });
|
|
3094
|
+
}
|
|
3095
|
+
async getTracesPaginated(_args) {
|
|
3096
|
+
return this.stores.traces.getTracesPaginated(_args);
|
|
3097
|
+
}
|
|
2790
3098
|
// Workflow operations
|
|
2791
3099
|
async updateWorkflowResults({
|
|
2792
3100
|
workflowName,
|
|
2793
3101
|
runId,
|
|
2794
3102
|
stepId,
|
|
2795
3103
|
result,
|
|
2796
|
-
|
|
3104
|
+
runtimeContext
|
|
2797
3105
|
}) {
|
|
2798
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result,
|
|
3106
|
+
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
|
|
2799
3107
|
}
|
|
2800
3108
|
async updateWorkflowState({
|
|
2801
3109
|
workflowName,
|
|
@@ -2818,8 +3126,8 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
2818
3126
|
}) {
|
|
2819
3127
|
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
2820
3128
|
}
|
|
2821
|
-
async
|
|
2822
|
-
return this.stores.workflows.
|
|
3129
|
+
async getWorkflowRuns(args) {
|
|
3130
|
+
return this.stores.workflows.getWorkflowRuns(args);
|
|
2823
3131
|
}
|
|
2824
3132
|
async getWorkflowRunById(args) {
|
|
2825
3133
|
return this.stores.workflows.getWorkflowRunById(args);
|
|
@@ -2837,6 +3145,13 @@ var DynamoDBStore = class extends MastraStorage {
|
|
|
2837
3145
|
}) {
|
|
2838
3146
|
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
2839
3147
|
}
|
|
3148
|
+
// Eval operations
|
|
3149
|
+
async getEvalsByAgentName(agentName, type) {
|
|
3150
|
+
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
3151
|
+
}
|
|
3152
|
+
async getEvals(options) {
|
|
3153
|
+
return this.stores.legacyEvals.getEvals(options);
|
|
3154
|
+
}
|
|
2840
3155
|
/**
|
|
2841
3156
|
* Closes the DynamoDB client connection and cleans up resources.
|
|
2842
3157
|
* Should be called when the store is no longer needed, e.g., at the end of tests or application shutdown.
|