@mastra/dynamodb 0.0.0-error-handler-fix-20251020202607 → 0.0.0-execa-dynamic-import-20260304221256
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 +1442 -3
- package/LICENSE.md +15 -0
- package/README.md +1 -2
- package/dist/docs/SKILL.md +22 -0
- package/dist/docs/assets/SOURCE_MAP.json +6 -0
- package/dist/docs/references/reference-storage-dynamodb.md +282 -0
- package/dist/entities/eval.d.ts +8 -0
- package/dist/entities/eval.d.ts.map +1 -1
- package/dist/entities/index.d.ts +66 -5
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/message.d.ts +8 -0
- package/dist/entities/message.d.ts.map +1 -1
- package/dist/entities/resource.d.ts +8 -0
- package/dist/entities/resource.d.ts.map +1 -1
- package/dist/entities/score.d.ts +18 -5
- package/dist/entities/score.d.ts.map +1 -1
- package/dist/entities/thread.d.ts +8 -0
- package/dist/entities/thread.d.ts.map +1 -1
- package/dist/entities/trace.d.ts +8 -0
- package/dist/entities/trace.d.ts.map +1 -1
- package/dist/entities/utils.d.ts +90 -0
- package/dist/entities/utils.d.ts.map +1 -1
- package/dist/entities/workflow-snapshot.d.ts +8 -0
- package/dist/entities/workflow-snapshot.d.ts.map +1 -1
- package/dist/index.cjs +786 -1269
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +780 -1270
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +48 -0
- package/dist/storage/db/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +18 -45
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +47 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -0
- package/dist/storage/domains/utils.d.ts +7 -0
- package/dist/storage/domains/utils.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +26 -24
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +177 -221
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/ttl.d.ts +52 -0
- package/dist/storage/ttl.d.ts.map +1 -0
- package/package.json +17 -16
- package/dist/storage/domains/legacy-evals/index.d.ts +0 -19
- package/dist/storage/domains/legacy-evals/index.d.ts.map +0 -1
- package/dist/storage/domains/operations/index.d.ts +0 -69
- package/dist/storage/domains/operations/index.d.ts.map +0 -1
- package/dist/storage/domains/score/index.d.ts +0 -51
- package/dist/storage/domains/score/index.d.ts.map +0 -1
- package/dist/storage/domains/traces/index.d.ts +0 -28
- package/dist/storage/domains/traces/index.d.ts.map +0 -1
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
|
|
9
|
+
var evals = require('@mastra/core/evals');
|
|
10
10
|
|
|
11
11
|
// src/storage/index.ts
|
|
12
12
|
|
|
@@ -60,6 +60,25 @@ var baseAttributes = {
|
|
|
60
60
|
}
|
|
61
61
|
return value;
|
|
62
62
|
}
|
|
63
|
+
},
|
|
64
|
+
/**
|
|
65
|
+
* TTL attribute for DynamoDB automatic item expiration.
|
|
66
|
+
* This is a Unix timestamp (epoch seconds) that indicates when the item should be deleted.
|
|
67
|
+
*
|
|
68
|
+
* Note: For TTL to work, you must enable TTL on your DynamoDB table
|
|
69
|
+
* specifying this attribute name (default: 'ttl').
|
|
70
|
+
*/
|
|
71
|
+
ttl: {
|
|
72
|
+
type: "number",
|
|
73
|
+
required: false
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Alternative TTL attribute with configurable name.
|
|
77
|
+
* Use this if you've configured TTL on your DynamoDB table with 'expiresAt' as the attribute name.
|
|
78
|
+
*/
|
|
79
|
+
expiresAt: {
|
|
80
|
+
type: "number",
|
|
81
|
+
required: false
|
|
63
82
|
}
|
|
64
83
|
};
|
|
65
84
|
|
|
@@ -425,6 +444,10 @@ var scoreEntity = new electrodb.Entity({
|
|
|
425
444
|
return value;
|
|
426
445
|
}
|
|
427
446
|
},
|
|
447
|
+
preprocessPrompt: {
|
|
448
|
+
type: "string",
|
|
449
|
+
required: false
|
|
450
|
+
},
|
|
428
451
|
preprocessStepResult: {
|
|
429
452
|
type: "string",
|
|
430
453
|
required: false,
|
|
@@ -564,7 +587,29 @@ var scoreEntity = new electrodb.Entity({
|
|
|
564
587
|
return value;
|
|
565
588
|
}
|
|
566
589
|
},
|
|
567
|
-
|
|
590
|
+
metadata: {
|
|
591
|
+
type: "string",
|
|
592
|
+
required: false,
|
|
593
|
+
set: (value) => {
|
|
594
|
+
if (value && typeof value !== "string") {
|
|
595
|
+
return JSON.stringify(value);
|
|
596
|
+
}
|
|
597
|
+
return value;
|
|
598
|
+
},
|
|
599
|
+
get: (value) => {
|
|
600
|
+
if (value && typeof value === "string") {
|
|
601
|
+
try {
|
|
602
|
+
if (value.startsWith("{") || value.startsWith("[")) {
|
|
603
|
+
return JSON.parse(value);
|
|
604
|
+
}
|
|
605
|
+
} catch {
|
|
606
|
+
return value;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
return value;
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
requestContext: {
|
|
568
613
|
type: "string",
|
|
569
614
|
required: false,
|
|
570
615
|
set: (value) => {
|
|
@@ -935,193 +980,146 @@ function getElectroDbService(client, tableName) {
|
|
|
935
980
|
}
|
|
936
981
|
);
|
|
937
982
|
}
|
|
938
|
-
|
|
983
|
+
function resolveDynamoDBConfig(config) {
|
|
984
|
+
if ("service" in config) {
|
|
985
|
+
return { service: config.service, ttl: config.ttl };
|
|
986
|
+
}
|
|
987
|
+
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
988
|
+
region: config.region || "us-east-1",
|
|
989
|
+
endpoint: config.endpoint,
|
|
990
|
+
credentials: config.credentials
|
|
991
|
+
});
|
|
992
|
+
const client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
|
|
993
|
+
return {
|
|
994
|
+
service: getElectroDbService(client, config.tableName),
|
|
995
|
+
ttl: config.ttl
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// src/storage/ttl.ts
|
|
1000
|
+
function calculateTtl(entityName, ttlConfig, customTtlSeconds) {
|
|
1001
|
+
const entityConfig = ttlConfig?.[entityName];
|
|
1002
|
+
if (!entityConfig?.enabled) {
|
|
1003
|
+
return void 0;
|
|
1004
|
+
}
|
|
1005
|
+
const ttlSeconds = customTtlSeconds ?? entityConfig.defaultTtlSeconds;
|
|
1006
|
+
if (ttlSeconds === void 0 || ttlSeconds <= 0) {
|
|
1007
|
+
return void 0;
|
|
1008
|
+
}
|
|
1009
|
+
return Math.floor(Date.now() / 1e3) + ttlSeconds;
|
|
1010
|
+
}
|
|
1011
|
+
function getTtlAttributeName(entityName, ttlConfig) {
|
|
1012
|
+
const entityConfig = ttlConfig?.[entityName];
|
|
1013
|
+
return entityConfig?.attributeName ?? "ttl";
|
|
1014
|
+
}
|
|
1015
|
+
function isTtlEnabled(entityName, ttlConfig) {
|
|
1016
|
+
return ttlConfig?.[entityName]?.enabled === true;
|
|
1017
|
+
}
|
|
1018
|
+
function getTtlProps(entityName, ttlConfig, customTtlSeconds) {
|
|
1019
|
+
const ttlValue = calculateTtl(entityName, ttlConfig, customTtlSeconds);
|
|
1020
|
+
if (ttlValue === void 0) return {};
|
|
1021
|
+
const attributeName = getTtlAttributeName(entityName, ttlConfig);
|
|
1022
|
+
return { [attributeName]: ttlValue };
|
|
1023
|
+
}
|
|
1024
|
+
var ENTITY_MAP = {
|
|
1025
|
+
[storage.TABLE_THREADS]: "thread",
|
|
1026
|
+
[storage.TABLE_MESSAGES]: "message",
|
|
1027
|
+
[storage.TABLE_RESOURCES]: "resource",
|
|
1028
|
+
[storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
|
|
1029
|
+
[storage.TABLE_SCORERS]: "score"
|
|
1030
|
+
};
|
|
1031
|
+
function getDeleteKey(entityName, item) {
|
|
1032
|
+
const key = { entity: entityName };
|
|
1033
|
+
switch (entityName) {
|
|
1034
|
+
case "thread":
|
|
1035
|
+
case "message":
|
|
1036
|
+
case "resource":
|
|
1037
|
+
case "score":
|
|
1038
|
+
key.id = item.id;
|
|
1039
|
+
break;
|
|
1040
|
+
case "workflow_snapshot":
|
|
1041
|
+
key.workflow_name = item.workflow_name;
|
|
1042
|
+
key.run_id = item.run_id;
|
|
1043
|
+
break;
|
|
1044
|
+
default:
|
|
1045
|
+
key.id = item.id;
|
|
1046
|
+
}
|
|
1047
|
+
return key;
|
|
1048
|
+
}
|
|
1049
|
+
async function deleteTableData(service, tableName) {
|
|
1050
|
+
const entityName = ENTITY_MAP[tableName];
|
|
1051
|
+
if (!entityName || !service.entities[entityName]) {
|
|
1052
|
+
throw new Error(`No entity mapping found for table: ${tableName}`);
|
|
1053
|
+
}
|
|
1054
|
+
const entity = service.entities[entityName];
|
|
1055
|
+
const result = await entity.scan.go({ pages: "all" });
|
|
1056
|
+
if (!result.data.length) {
|
|
1057
|
+
return;
|
|
1058
|
+
}
|
|
1059
|
+
const batchSize = 25;
|
|
1060
|
+
for (let i = 0; i < result.data.length; i += batchSize) {
|
|
1061
|
+
const batch = result.data.slice(i, i + batchSize);
|
|
1062
|
+
const keysToDelete = batch.map((item) => getDeleteKey(entityName, item));
|
|
1063
|
+
await entity.delete(keysToDelete).go();
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
// src/storage/domains/memory/index.ts
|
|
1068
|
+
var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
939
1069
|
service;
|
|
940
|
-
|
|
941
|
-
constructor(
|
|
1070
|
+
ttlConfig;
|
|
1071
|
+
constructor(config) {
|
|
942
1072
|
super();
|
|
943
|
-
|
|
944
|
-
this.
|
|
1073
|
+
const resolved = resolveDynamoDBConfig(config);
|
|
1074
|
+
this.service = resolved.service;
|
|
1075
|
+
this.ttlConfig = resolved.ttl;
|
|
945
1076
|
}
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
this.
|
|
949
|
-
|
|
950
|
-
const query = this.service.entities.eval.query.byAgent({ entity: "eval", agent_name: agentName });
|
|
951
|
-
const results = await query.go({ order: "desc", limit: 100 });
|
|
952
|
-
if (!results.data.length) {
|
|
953
|
-
return [];
|
|
954
|
-
}
|
|
955
|
-
let filteredData = results.data;
|
|
956
|
-
if (type) {
|
|
957
|
-
filteredData = filteredData.filter((evalRecord) => {
|
|
958
|
-
try {
|
|
959
|
-
const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
|
|
960
|
-
if (type === "test" && !testInfo) {
|
|
961
|
-
return false;
|
|
962
|
-
}
|
|
963
|
-
if (type === "live" && testInfo) {
|
|
964
|
-
return false;
|
|
965
|
-
}
|
|
966
|
-
} catch (e) {
|
|
967
|
-
this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
|
|
968
|
-
}
|
|
969
|
-
return true;
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
return filteredData.map((evalRecord) => {
|
|
973
|
-
try {
|
|
974
|
-
return {
|
|
975
|
-
input: evalRecord.input,
|
|
976
|
-
output: evalRecord.output,
|
|
977
|
-
// Safely parse result and test_info
|
|
978
|
-
result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
|
|
979
|
-
agentName: evalRecord.agent_name,
|
|
980
|
-
createdAt: evalRecord.created_at,
|
|
981
|
-
// Keep as string from DDB?
|
|
982
|
-
metricName: evalRecord.metric_name,
|
|
983
|
-
instructions: evalRecord.instructions,
|
|
984
|
-
runId: evalRecord.run_id,
|
|
985
|
-
globalRunId: evalRecord.global_run_id,
|
|
986
|
-
testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
|
|
987
|
-
};
|
|
988
|
-
} catch (parseError) {
|
|
989
|
-
this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
|
|
990
|
-
return {
|
|
991
|
-
agentName: evalRecord.agent_name,
|
|
992
|
-
createdAt: evalRecord.created_at,
|
|
993
|
-
runId: evalRecord.run_id,
|
|
994
|
-
globalRunId: evalRecord.global_run_id
|
|
995
|
-
};
|
|
996
|
-
}
|
|
997
|
-
});
|
|
998
|
-
} catch (error$1) {
|
|
999
|
-
throw new error.MastraError(
|
|
1000
|
-
{
|
|
1001
|
-
id: "STORAGE_DYNAMODB_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
|
|
1002
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1003
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1004
|
-
details: { agentName }
|
|
1005
|
-
},
|
|
1006
|
-
error$1
|
|
1007
|
-
);
|
|
1008
|
-
}
|
|
1077
|
+
async dangerouslyClearAll() {
|
|
1078
|
+
await deleteTableData(this.service, storage.TABLE_THREADS);
|
|
1079
|
+
await deleteTableData(this.service, storage.TABLE_MESSAGES);
|
|
1080
|
+
await deleteTableData(this.service, storage.TABLE_RESOURCES);
|
|
1009
1081
|
}
|
|
1010
|
-
async
|
|
1011
|
-
|
|
1012
|
-
|
|
1082
|
+
async deleteMessages(messageIds) {
|
|
1083
|
+
if (!messageIds || messageIds.length === 0) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
this.logger.debug("Deleting messages", { count: messageIds.length });
|
|
1013
1087
|
try {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
total: 0,
|
|
1029
|
-
page,
|
|
1030
|
-
perPage,
|
|
1031
|
-
hasMore: false
|
|
1032
|
-
};
|
|
1033
|
-
}
|
|
1034
|
-
let filteredData = results.data;
|
|
1035
|
-
if (type) {
|
|
1036
|
-
filteredData = filteredData.filter((evalRecord) => {
|
|
1037
|
-
try {
|
|
1038
|
-
const testInfo = evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0;
|
|
1039
|
-
if (type === "test" && !testInfo) {
|
|
1040
|
-
return false;
|
|
1041
|
-
}
|
|
1042
|
-
if (type === "live" && testInfo) {
|
|
1043
|
-
return false;
|
|
1088
|
+
const threadIds = /* @__PURE__ */ new Set();
|
|
1089
|
+
const batchSize = 25;
|
|
1090
|
+
for (let i = 0; i < messageIds.length; i += batchSize) {
|
|
1091
|
+
const batch = messageIds.slice(i, i + batchSize);
|
|
1092
|
+
const messagesToDelete = await Promise.all(
|
|
1093
|
+
batch.map(async (id) => {
|
|
1094
|
+
const result = await this.service.entities.message.get({ entity: "message", id }).go();
|
|
1095
|
+
return result.data;
|
|
1096
|
+
})
|
|
1097
|
+
);
|
|
1098
|
+
for (const message of messagesToDelete) {
|
|
1099
|
+
if (message) {
|
|
1100
|
+
if (message.threadId) {
|
|
1101
|
+
threadIds.add(message.threadId);
|
|
1044
1102
|
}
|
|
1045
|
-
|
|
1046
|
-
this.logger.warn("Failed to parse test_info during filtering", { record: evalRecord, error: e });
|
|
1103
|
+
await this.service.entities.message.delete({ entity: "message", id: message.id }).go();
|
|
1047
1104
|
}
|
|
1048
|
-
|
|
1049
|
-
});
|
|
1105
|
+
}
|
|
1050
1106
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
filteredData = filteredData.filter((evalRecord) => {
|
|
1055
|
-
const recordDate = new Date(evalRecord.created_at);
|
|
1056
|
-
if (fromDate && recordDate < fromDate) {
|
|
1057
|
-
return false;
|
|
1058
|
-
}
|
|
1059
|
-
if (toDate && recordDate > toDate) {
|
|
1060
|
-
return false;
|
|
1061
|
-
}
|
|
1062
|
-
return true;
|
|
1063
|
-
});
|
|
1107
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1108
|
+
for (const threadId of threadIds) {
|
|
1109
|
+
await this.service.entities.thread.update({ entity: "thread", id: threadId }).set({ updatedAt: now }).go();
|
|
1064
1110
|
}
|
|
1065
|
-
const total = filteredData.length;
|
|
1066
|
-
const start = page * perPage;
|
|
1067
|
-
const end = start + perPage;
|
|
1068
|
-
const paginatedData = filteredData.slice(start, end);
|
|
1069
|
-
const evals = paginatedData.map((evalRecord) => {
|
|
1070
|
-
try {
|
|
1071
|
-
return {
|
|
1072
|
-
input: evalRecord.input,
|
|
1073
|
-
output: evalRecord.output,
|
|
1074
|
-
result: evalRecord.result && typeof evalRecord.result === "string" ? JSON.parse(evalRecord.result) : void 0,
|
|
1075
|
-
agentName: evalRecord.agent_name,
|
|
1076
|
-
createdAt: evalRecord.created_at,
|
|
1077
|
-
metricName: evalRecord.metric_name,
|
|
1078
|
-
instructions: evalRecord.instructions,
|
|
1079
|
-
runId: evalRecord.run_id,
|
|
1080
|
-
globalRunId: evalRecord.global_run_id,
|
|
1081
|
-
testInfo: evalRecord.test_info && typeof evalRecord.test_info === "string" ? JSON.parse(evalRecord.test_info) : void 0
|
|
1082
|
-
};
|
|
1083
|
-
} catch (parseError) {
|
|
1084
|
-
this.logger.error("Failed to parse eval record", { record: evalRecord, error: parseError });
|
|
1085
|
-
return {
|
|
1086
|
-
agentName: evalRecord.agent_name,
|
|
1087
|
-
createdAt: evalRecord.created_at,
|
|
1088
|
-
runId: evalRecord.run_id,
|
|
1089
|
-
globalRunId: evalRecord.global_run_id
|
|
1090
|
-
};
|
|
1091
|
-
}
|
|
1092
|
-
});
|
|
1093
|
-
const hasMore = end < total;
|
|
1094
|
-
return {
|
|
1095
|
-
evals,
|
|
1096
|
-
total,
|
|
1097
|
-
page,
|
|
1098
|
-
perPage,
|
|
1099
|
-
hasMore
|
|
1100
|
-
};
|
|
1101
1111
|
} catch (error$1) {
|
|
1102
1112
|
throw new error.MastraError(
|
|
1103
1113
|
{
|
|
1104
|
-
id: "
|
|
1114
|
+
id: storage.createStorageErrorId("DYNAMODB", "DELETE_MESSAGES", "FAILED"),
|
|
1105
1115
|
domain: error.ErrorDomain.STORAGE,
|
|
1106
1116
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1107
|
-
details: {
|
|
1108
|
-
agentName: agentName || "all",
|
|
1109
|
-
type: type || "all",
|
|
1110
|
-
page,
|
|
1111
|
-
perPage
|
|
1112
|
-
}
|
|
1117
|
+
details: { count: messageIds.length }
|
|
1113
1118
|
},
|
|
1114
1119
|
error$1
|
|
1115
1120
|
);
|
|
1116
1121
|
}
|
|
1117
1122
|
}
|
|
1118
|
-
};
|
|
1119
|
-
var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
1120
|
-
service;
|
|
1121
|
-
constructor({ service }) {
|
|
1122
|
-
super();
|
|
1123
|
-
this.service = service;
|
|
1124
|
-
}
|
|
1125
1123
|
// Helper function to parse message data (handle JSON fields)
|
|
1126
1124
|
parseMessageData(data) {
|
|
1127
1125
|
return {
|
|
@@ -1134,17 +1132,17 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1134
1132
|
};
|
|
1135
1133
|
}
|
|
1136
1134
|
// Helper function to transform and sort threads
|
|
1137
|
-
transformAndSortThreads(rawThreads,
|
|
1135
|
+
transformAndSortThreads(rawThreads, field, direction) {
|
|
1138
1136
|
return rawThreads.map((data) => ({
|
|
1139
1137
|
...data,
|
|
1140
1138
|
// Convert date strings back to Date objects for consistency
|
|
1141
1139
|
createdAt: typeof data.createdAt === "string" ? new Date(data.createdAt) : data.createdAt,
|
|
1142
1140
|
updatedAt: typeof data.updatedAt === "string" ? new Date(data.updatedAt) : data.updatedAt
|
|
1143
1141
|
})).sort((a, b) => {
|
|
1144
|
-
const fieldA =
|
|
1145
|
-
const fieldB =
|
|
1142
|
+
const fieldA = field === "createdAt" ? a.createdAt : a.updatedAt;
|
|
1143
|
+
const fieldB = field === "createdAt" ? b.createdAt : b.updatedAt;
|
|
1146
1144
|
const comparison = fieldA.getTime() - fieldB.getTime();
|
|
1147
|
-
return
|
|
1145
|
+
return direction === "DESC" ? -comparison : comparison;
|
|
1148
1146
|
});
|
|
1149
1147
|
}
|
|
1150
1148
|
async getThreadById({ threadId }) {
|
|
@@ -1166,7 +1164,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1166
1164
|
} catch (error$1) {
|
|
1167
1165
|
throw new error.MastraError(
|
|
1168
1166
|
{
|
|
1169
|
-
id: "
|
|
1167
|
+
id: storage.createStorageErrorId("DYNAMODB", "GET_THREAD_BY_ID", "FAILED"),
|
|
1170
1168
|
domain: error.ErrorDomain.STORAGE,
|
|
1171
1169
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1172
1170
|
details: { threadId }
|
|
@@ -1175,32 +1173,6 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1175
1173
|
);
|
|
1176
1174
|
}
|
|
1177
1175
|
}
|
|
1178
|
-
/**
|
|
1179
|
-
* @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
|
|
1180
|
-
*/
|
|
1181
|
-
async getThreadsByResourceId(args) {
|
|
1182
|
-
const resourceId = args.resourceId;
|
|
1183
|
-
const orderBy = this.castThreadOrderBy(args.orderBy);
|
|
1184
|
-
const sortDirection = this.castThreadSortDirection(args.sortDirection);
|
|
1185
|
-
this.logger.debug("Getting threads by resource ID", { resourceId, orderBy, sortDirection });
|
|
1186
|
-
try {
|
|
1187
|
-
const result = await this.service.entities.thread.query.byResource({ entity: "thread", resourceId }).go();
|
|
1188
|
-
if (!result.data.length) {
|
|
1189
|
-
return [];
|
|
1190
|
-
}
|
|
1191
|
-
return this.transformAndSortThreads(result.data, orderBy, sortDirection);
|
|
1192
|
-
} catch (error$1) {
|
|
1193
|
-
throw new error.MastraError(
|
|
1194
|
-
{
|
|
1195
|
-
id: "STORAGE_DYNAMODB_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
|
|
1196
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1197
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1198
|
-
details: { resourceId }
|
|
1199
|
-
},
|
|
1200
|
-
error$1
|
|
1201
|
-
);
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
1176
|
async saveThread({ thread }) {
|
|
1205
1177
|
this.logger.debug("Saving thread", { threadId: thread.id });
|
|
1206
1178
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1211,7 +1183,8 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1211
1183
|
title: thread.title || `Thread ${thread.id}`,
|
|
1212
1184
|
createdAt: thread.createdAt?.toISOString() || now.toISOString(),
|
|
1213
1185
|
updatedAt: thread.updatedAt?.toISOString() || now.toISOString(),
|
|
1214
|
-
metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0
|
|
1186
|
+
metadata: thread.metadata ? JSON.stringify(thread.metadata) : void 0,
|
|
1187
|
+
...getTtlProps("thread", this.ttlConfig)
|
|
1215
1188
|
};
|
|
1216
1189
|
try {
|
|
1217
1190
|
await this.service.entities.thread.upsert(threadData).go();
|
|
@@ -1220,13 +1193,13 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1220
1193
|
resourceId: thread.resourceId,
|
|
1221
1194
|
title: threadData.title,
|
|
1222
1195
|
createdAt: thread.createdAt || now,
|
|
1223
|
-
updatedAt: now,
|
|
1196
|
+
updatedAt: thread.updatedAt || now,
|
|
1224
1197
|
metadata: thread.metadata
|
|
1225
1198
|
};
|
|
1226
1199
|
} catch (error$1) {
|
|
1227
1200
|
throw new error.MastraError(
|
|
1228
1201
|
{
|
|
1229
|
-
id: "
|
|
1202
|
+
id: storage.createStorageErrorId("DYNAMODB", "SAVE_THREAD", "FAILED"),
|
|
1230
1203
|
domain: error.ErrorDomain.STORAGE,
|
|
1231
1204
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1232
1205
|
details: { threadId: thread.id }
|
|
@@ -1268,7 +1241,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1268
1241
|
} catch (error$1) {
|
|
1269
1242
|
throw new error.MastraError(
|
|
1270
1243
|
{
|
|
1271
|
-
id: "
|
|
1244
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_THREAD", "FAILED"),
|
|
1272
1245
|
domain: error.ErrorDomain.STORAGE,
|
|
1273
1246
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1274
1247
|
details: { threadId: id }
|
|
@@ -1280,7 +1253,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1280
1253
|
async deleteThread({ threadId }) {
|
|
1281
1254
|
this.logger.debug("Deleting thread", { threadId });
|
|
1282
1255
|
try {
|
|
1283
|
-
const messages = await this.
|
|
1256
|
+
const { messages } = await this.listMessages({ threadId, perPage: false });
|
|
1284
1257
|
if (messages.length > 0) {
|
|
1285
1258
|
const batchSize = 25;
|
|
1286
1259
|
for (let i = 0; i < messages.length; i += batchSize) {
|
|
@@ -1300,7 +1273,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1300
1273
|
} catch (error$1) {
|
|
1301
1274
|
throw new error.MastraError(
|
|
1302
1275
|
{
|
|
1303
|
-
id: "
|
|
1276
|
+
id: storage.createStorageErrorId("DYNAMODB", "DELETE_THREAD", "FAILED"),
|
|
1304
1277
|
domain: error.ErrorDomain.STORAGE,
|
|
1305
1278
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1306
1279
|
details: { threadId }
|
|
@@ -1309,104 +1282,166 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1309
1282
|
);
|
|
1310
1283
|
}
|
|
1311
1284
|
}
|
|
1312
|
-
async
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
selectBy,
|
|
1316
|
-
format
|
|
1317
|
-
}) {
|
|
1318
|
-
this.logger.debug("Getting messages", { threadId, selectBy });
|
|
1285
|
+
async listMessagesById({ messageIds }) {
|
|
1286
|
+
this.logger.debug("Getting messages by ID", { messageIds });
|
|
1287
|
+
if (messageIds.length === 0) return { messages: [] };
|
|
1319
1288
|
try {
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
messages.push(...includeMessages);
|
|
1327
|
-
}
|
|
1328
|
-
}
|
|
1329
|
-
if (limit !== 0) {
|
|
1330
|
-
const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
|
|
1331
|
-
let results;
|
|
1332
|
-
if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
|
|
1333
|
-
results = await query.go({ limit, order: "desc" });
|
|
1334
|
-
results.data = results.data.reverse();
|
|
1335
|
-
} else {
|
|
1336
|
-
results = await query.go();
|
|
1337
|
-
}
|
|
1338
|
-
let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg);
|
|
1339
|
-
allThreadMessages.sort((a, b) => {
|
|
1340
|
-
const timeA = a.createdAt.getTime();
|
|
1341
|
-
const timeB = b.createdAt.getTime();
|
|
1342
|
-
if (timeA === timeB) {
|
|
1343
|
-
return a.id.localeCompare(b.id);
|
|
1344
|
-
}
|
|
1345
|
-
return timeA - timeB;
|
|
1346
|
-
});
|
|
1347
|
-
messages.push(...allThreadMessages);
|
|
1348
|
-
}
|
|
1349
|
-
messages.sort((a, b) => {
|
|
1350
|
-
const timeA = a.createdAt.getTime();
|
|
1351
|
-
const timeB = b.createdAt.getTime();
|
|
1352
|
-
if (timeA === timeB) {
|
|
1353
|
-
return a.id.localeCompare(b.id);
|
|
1354
|
-
}
|
|
1355
|
-
return timeA - timeB;
|
|
1356
|
-
});
|
|
1357
|
-
const uniqueMessages = messages.filter(
|
|
1289
|
+
const results = await Promise.all(
|
|
1290
|
+
messageIds.map((id) => this.service.entities.message.query.primary({ entity: "message", id }).go())
|
|
1291
|
+
);
|
|
1292
|
+
const data = results.map((result) => result.data).flat(1);
|
|
1293
|
+
let parsedMessages = data.map((data2) => this.parseMessageData(data2)).filter((msg) => "content" in msg);
|
|
1294
|
+
const uniqueMessages = parsedMessages.filter(
|
|
1358
1295
|
(message, index, self) => index === self.findIndex((m) => m.id === message.id)
|
|
1359
1296
|
);
|
|
1360
|
-
const list = new agent.MessageList(
|
|
1361
|
-
|
|
1362
|
-
return list.get.all.v1();
|
|
1297
|
+
const list = new agent.MessageList().add(uniqueMessages, "memory");
|
|
1298
|
+
return { messages: list.get.all.db() };
|
|
1363
1299
|
} catch (error$1) {
|
|
1364
1300
|
throw new error.MastraError(
|
|
1365
1301
|
{
|
|
1366
|
-
id: "
|
|
1302
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES_BY_ID", "FAILED"),
|
|
1367
1303
|
domain: error.ErrorDomain.STORAGE,
|
|
1368
1304
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1369
|
-
details: {
|
|
1305
|
+
details: { messageIds: JSON.stringify(messageIds) }
|
|
1370
1306
|
},
|
|
1371
1307
|
error$1
|
|
1372
1308
|
);
|
|
1373
1309
|
}
|
|
1374
1310
|
}
|
|
1375
|
-
async
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1311
|
+
async listMessages(args) {
|
|
1312
|
+
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
1313
|
+
const threadIds = Array.isArray(threadId) ? threadId : [threadId];
|
|
1314
|
+
if (threadIds.length === 0 || threadIds.some((id) => !id.trim())) {
|
|
1315
|
+
throw new error.MastraError(
|
|
1316
|
+
{
|
|
1317
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_THREAD_ID"),
|
|
1318
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1319
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1320
|
+
details: { threadId: Array.isArray(threadId) ? threadId.join(",") : threadId }
|
|
1321
|
+
},
|
|
1322
|
+
new Error("threadId must be a non-empty string or array of non-empty strings")
|
|
1384
1323
|
);
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1324
|
+
}
|
|
1325
|
+
const perPage = storage.normalizePerPage(perPageInput, 40);
|
|
1326
|
+
const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
1327
|
+
try {
|
|
1328
|
+
if (page < 0) {
|
|
1329
|
+
throw new error.MastraError(
|
|
1330
|
+
{
|
|
1331
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "INVALID_PAGE"),
|
|
1332
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1333
|
+
category: error.ErrorCategory.USER,
|
|
1334
|
+
details: { page }
|
|
1335
|
+
},
|
|
1336
|
+
new Error("page must be >= 0")
|
|
1337
|
+
);
|
|
1338
|
+
}
|
|
1339
|
+
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
1340
|
+
this.logger.debug("Getting messages with listMessages", {
|
|
1341
|
+
threadId,
|
|
1342
|
+
resourceId,
|
|
1343
|
+
perPageInput,
|
|
1344
|
+
offset,
|
|
1345
|
+
perPage,
|
|
1346
|
+
page,
|
|
1347
|
+
field,
|
|
1348
|
+
direction
|
|
1349
|
+
});
|
|
1350
|
+
const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
|
|
1351
|
+
const results = await query.go();
|
|
1352
|
+
let allThreadMessages = results.data.map((data) => this.parseMessageData(data)).filter((msg) => "content" in msg && typeof msg.content === "object");
|
|
1353
|
+
if (resourceId) {
|
|
1354
|
+
allThreadMessages = allThreadMessages.filter((msg) => msg.resourceId === resourceId);
|
|
1355
|
+
}
|
|
1356
|
+
allThreadMessages = storage.filterByDateRange(
|
|
1357
|
+
allThreadMessages,
|
|
1358
|
+
(msg) => new Date(msg.createdAt),
|
|
1359
|
+
filter?.dateRange
|
|
1389
1360
|
);
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1361
|
+
allThreadMessages.sort((a, b) => {
|
|
1362
|
+
const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
1363
|
+
const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
1364
|
+
if (aValue === bValue) {
|
|
1365
|
+
return a.id.localeCompare(b.id);
|
|
1366
|
+
}
|
|
1367
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
1368
|
+
});
|
|
1369
|
+
const total = allThreadMessages.length;
|
|
1370
|
+
const paginatedMessages = allThreadMessages.slice(offset, offset + perPage);
|
|
1371
|
+
const paginatedCount = paginatedMessages.length;
|
|
1372
|
+
if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
|
|
1373
|
+
return {
|
|
1374
|
+
messages: [],
|
|
1375
|
+
total: 0,
|
|
1376
|
+
page,
|
|
1377
|
+
perPage: perPageForResponse,
|
|
1378
|
+
hasMore: false
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
const messageIds = new Set(paginatedMessages.map((m) => m.id));
|
|
1382
|
+
let includeMessages = [];
|
|
1383
|
+
if (include && include.length > 0) {
|
|
1384
|
+
const selectBy = { include };
|
|
1385
|
+
includeMessages = await this._getIncludedMessages(selectBy);
|
|
1386
|
+
for (const includeMsg of includeMessages) {
|
|
1387
|
+
if (!messageIds.has(includeMsg.id)) {
|
|
1388
|
+
paginatedMessages.push(includeMsg);
|
|
1389
|
+
messageIds.add(includeMsg.id);
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
const list = new agent.MessageList().add(paginatedMessages, "memory");
|
|
1394
|
+
let finalMessages = list.get.all.db();
|
|
1395
|
+
finalMessages = finalMessages.sort((a, b) => {
|
|
1396
|
+
const aValue = field === "createdAt" ? new Date(a.createdAt).getTime() : a[field];
|
|
1397
|
+
const bValue = field === "createdAt" ? new Date(b.createdAt).getTime() : b[field];
|
|
1398
|
+
if (aValue === bValue) {
|
|
1399
|
+
return a.id.localeCompare(b.id);
|
|
1400
|
+
}
|
|
1401
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
1402
|
+
});
|
|
1403
|
+
const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
|
|
1404
|
+
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
1405
|
+
let hasMore = false;
|
|
1406
|
+
if (perPageInput !== false && !allThreadMessagesReturned) {
|
|
1407
|
+
hasMore = offset + paginatedCount < total;
|
|
1408
|
+
}
|
|
1409
|
+
return {
|
|
1410
|
+
messages: finalMessages,
|
|
1411
|
+
total,
|
|
1412
|
+
page,
|
|
1413
|
+
perPage: perPageForResponse,
|
|
1414
|
+
hasMore
|
|
1415
|
+
};
|
|
1393
1416
|
} catch (error$1) {
|
|
1394
|
-
|
|
1417
|
+
const mastraError = new error.MastraError(
|
|
1395
1418
|
{
|
|
1396
|
-
id: "
|
|
1419
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_MESSAGES", "FAILED"),
|
|
1397
1420
|
domain: error.ErrorDomain.STORAGE,
|
|
1398
1421
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1399
|
-
details: {
|
|
1422
|
+
details: {
|
|
1423
|
+
threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
|
|
1424
|
+
resourceId: resourceId ?? ""
|
|
1425
|
+
}
|
|
1400
1426
|
},
|
|
1401
1427
|
error$1
|
|
1402
1428
|
);
|
|
1429
|
+
this.logger?.error?.(mastraError.toString());
|
|
1430
|
+
this.logger?.trackException?.(mastraError);
|
|
1431
|
+
return {
|
|
1432
|
+
messages: [],
|
|
1433
|
+
total: 0,
|
|
1434
|
+
page,
|
|
1435
|
+
perPage: perPageForResponse,
|
|
1436
|
+
hasMore: false
|
|
1437
|
+
};
|
|
1403
1438
|
}
|
|
1404
1439
|
}
|
|
1405
1440
|
async saveMessages(args) {
|
|
1406
|
-
const { messages
|
|
1441
|
+
const { messages } = args;
|
|
1407
1442
|
this.logger.debug("Saving messages", { count: messages.length });
|
|
1408
1443
|
if (!messages.length) {
|
|
1409
|
-
return [];
|
|
1444
|
+
return { messages: [] };
|
|
1410
1445
|
}
|
|
1411
1446
|
const threadId = messages[0]?.threadId;
|
|
1412
1447
|
if (!threadId) {
|
|
@@ -1416,20 +1451,18 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1416
1451
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1417
1452
|
return {
|
|
1418
1453
|
entity: "message",
|
|
1419
|
-
// Add entity type
|
|
1420
1454
|
id: msg.id,
|
|
1421
1455
|
threadId: msg.threadId,
|
|
1422
1456
|
role: msg.role,
|
|
1423
1457
|
type: msg.type,
|
|
1424
1458
|
resourceId: msg.resourceId,
|
|
1425
|
-
// Ensure complex fields are stringified if not handled by attribute setters
|
|
1426
1459
|
content: typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content),
|
|
1427
1460
|
toolCallArgs: `toolCallArgs` in msg && msg.toolCallArgs ? JSON.stringify(msg.toolCallArgs) : void 0,
|
|
1428
1461
|
toolCallIds: `toolCallIds` in msg && msg.toolCallIds ? JSON.stringify(msg.toolCallIds) : void 0,
|
|
1429
1462
|
toolNames: `toolNames` in msg && msg.toolNames ? JSON.stringify(msg.toolNames) : void 0,
|
|
1430
1463
|
createdAt: msg.createdAt instanceof Date ? msg.createdAt.toISOString() : msg.createdAt || now,
|
|
1431
|
-
updatedAt: now
|
|
1432
|
-
|
|
1464
|
+
updatedAt: now,
|
|
1465
|
+
...getTtlProps("message", this.ttlConfig)
|
|
1433
1466
|
};
|
|
1434
1467
|
});
|
|
1435
1468
|
try {
|
|
@@ -1460,12 +1493,11 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1460
1493
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1461
1494
|
}).go();
|
|
1462
1495
|
const list = new agent.MessageList().add(messages, "memory");
|
|
1463
|
-
|
|
1464
|
-
return list.get.all.v2();
|
|
1496
|
+
return { messages: list.get.all.db() };
|
|
1465
1497
|
} catch (error$1) {
|
|
1466
1498
|
throw new error.MastraError(
|
|
1467
1499
|
{
|
|
1468
|
-
id: "
|
|
1500
|
+
id: storage.createStorageErrorId("DYNAMODB", "SAVE_MESSAGES", "FAILED"),
|
|
1469
1501
|
domain: error.ErrorDomain.STORAGE,
|
|
1470
1502
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1471
1503
|
details: { count: messages.length }
|
|
@@ -1474,137 +1506,103 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1474
1506
|
);
|
|
1475
1507
|
}
|
|
1476
1508
|
}
|
|
1477
|
-
async
|
|
1478
|
-
const {
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1509
|
+
async listThreads(args) {
|
|
1510
|
+
const { page = 0, perPage: perPageInput, orderBy, filter } = args;
|
|
1511
|
+
try {
|
|
1512
|
+
this.validatePaginationInput(page, perPageInput ?? 100);
|
|
1513
|
+
} catch (error$1) {
|
|
1514
|
+
throw new error.MastraError(
|
|
1515
|
+
{
|
|
1516
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS", "INVALID_PAGE"),
|
|
1517
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1518
|
+
category: error.ErrorCategory.USER,
|
|
1519
|
+
details: {
|
|
1520
|
+
page,
|
|
1521
|
+
...perPageInput !== void 0 && { perPage: perPageInput }
|
|
1522
|
+
}
|
|
1523
|
+
},
|
|
1524
|
+
error$1 instanceof Error ? error$1 : new Error("Invalid pagination parameters")
|
|
1525
|
+
);
|
|
1526
|
+
}
|
|
1527
|
+
const perPage = storage.normalizePerPage(perPageInput, 100);
|
|
1528
|
+
const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
1529
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
1530
|
+
this.logger.debug("Listing threads with filters", {
|
|
1531
|
+
resourceId: filter?.resourceId,
|
|
1532
|
+
metadataKeys: filter?.metadata ? Object.keys(filter.metadata) : [],
|
|
1483
1533
|
page,
|
|
1484
1534
|
perPage,
|
|
1485
|
-
|
|
1486
|
-
|
|
1535
|
+
field,
|
|
1536
|
+
direction
|
|
1487
1537
|
});
|
|
1488
1538
|
try {
|
|
1489
|
-
const
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1539
|
+
const rawThreads = filter?.resourceId ? (await this.service.entities.thread.query.byResource({
|
|
1540
|
+
entity: "thread",
|
|
1541
|
+
resourceId: filter.resourceId
|
|
1542
|
+
}).go({ pages: "all" })).data : (await this.service.entities.thread.scan.go({ pages: "all" })).data;
|
|
1543
|
+
let allThreads = this.transformAndSortThreads(rawThreads, field, direction);
|
|
1544
|
+
if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
|
|
1545
|
+
allThreads = allThreads.filter((thread) => {
|
|
1546
|
+
let threadMeta = null;
|
|
1547
|
+
if (typeof thread.metadata === "string") {
|
|
1548
|
+
try {
|
|
1549
|
+
threadMeta = JSON.parse(thread.metadata);
|
|
1550
|
+
} catch {
|
|
1551
|
+
return false;
|
|
1552
|
+
}
|
|
1553
|
+
} else if (thread.metadata && typeof thread.metadata === "object") {
|
|
1554
|
+
threadMeta = thread.metadata;
|
|
1555
|
+
}
|
|
1556
|
+
if (!threadMeta) return false;
|
|
1557
|
+
return Object.entries(filter.metadata).every(([key, value]) => threadMeta[key] === value);
|
|
1558
|
+
});
|
|
1559
|
+
}
|
|
1560
|
+
const endIndex = offset + perPage;
|
|
1561
|
+
const paginatedThreads = allThreads.slice(offset, endIndex);
|
|
1495
1562
|
const total = allThreads.length;
|
|
1496
|
-
const hasMore =
|
|
1563
|
+
const hasMore = offset + perPage < total;
|
|
1497
1564
|
return {
|
|
1498
1565
|
threads: paginatedThreads,
|
|
1499
1566
|
total,
|
|
1500
1567
|
page,
|
|
1501
|
-
perPage,
|
|
1568
|
+
perPage: perPageForResponse,
|
|
1502
1569
|
hasMore
|
|
1503
1570
|
};
|
|
1504
1571
|
} catch (error$1) {
|
|
1505
1572
|
throw new error.MastraError(
|
|
1506
1573
|
{
|
|
1507
|
-
id: "
|
|
1574
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_THREADS", "FAILED"),
|
|
1508
1575
|
domain: error.ErrorDomain.STORAGE,
|
|
1509
1576
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1510
|
-
details: {
|
|
1577
|
+
details: {
|
|
1578
|
+
...filter?.resourceId && { resourceId: filter.resourceId },
|
|
1579
|
+
hasMetadataFilter: !!(filter?.metadata && Object.keys(filter.metadata).length),
|
|
1580
|
+
page,
|
|
1581
|
+
perPage: perPageForResponse
|
|
1582
|
+
}
|
|
1511
1583
|
},
|
|
1512
1584
|
error$1
|
|
1513
1585
|
);
|
|
1514
1586
|
}
|
|
1515
1587
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
const
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
messages.push(...includeMessages);
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
if (limit !== 0) {
|
|
1533
|
-
const query = this.service.entities.message.query.byThread({ entity: "message", threadId });
|
|
1534
|
-
let results;
|
|
1535
|
-
if (limit !== Number.MAX_SAFE_INTEGER && limit > 0) {
|
|
1536
|
-
results = await query.go({ limit, order: "desc" });
|
|
1537
|
-
results.data = results.data.reverse();
|
|
1538
|
-
} else {
|
|
1539
|
-
results = await query.go();
|
|
1588
|
+
// Helper method to get included messages with context
|
|
1589
|
+
async _getIncludedMessages(selectBy) {
|
|
1590
|
+
if (!selectBy?.include?.length) {
|
|
1591
|
+
return [];
|
|
1592
|
+
}
|
|
1593
|
+
const includeMessages = [];
|
|
1594
|
+
for (const includeItem of selectBy.include) {
|
|
1595
|
+
try {
|
|
1596
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
|
|
1597
|
+
const targetResult = await this.service.entities.message.get({ entity: "message", id }).go();
|
|
1598
|
+
if (!targetResult.data) {
|
|
1599
|
+
this.logger.warn("Target message not found", { id });
|
|
1600
|
+
continue;
|
|
1540
1601
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
const timeA = a.createdAt.getTime();
|
|
1544
|
-
const timeB = b.createdAt.getTime();
|
|
1545
|
-
if (timeA === timeB) {
|
|
1546
|
-
return a.id.localeCompare(b.id);
|
|
1547
|
-
}
|
|
1548
|
-
return timeA - timeB;
|
|
1549
|
-
});
|
|
1550
|
-
const excludeIds = messages.map((m) => m.id);
|
|
1551
|
-
if (excludeIds.length > 0) {
|
|
1552
|
-
allThreadMessages = allThreadMessages.filter((msg) => !excludeIds.includes(msg.id));
|
|
1553
|
-
}
|
|
1554
|
-
messages.push(...allThreadMessages);
|
|
1555
|
-
}
|
|
1556
|
-
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1557
|
-
if (fromDate || toDate) {
|
|
1558
|
-
messages = messages.filter((msg) => {
|
|
1559
|
-
const createdAt = new Date(msg.createdAt).getTime();
|
|
1560
|
-
if (fromDate && createdAt < new Date(fromDate).getTime()) return false;
|
|
1561
|
-
if (toDate && createdAt > new Date(toDate).getTime()) return false;
|
|
1562
|
-
return true;
|
|
1563
|
-
});
|
|
1564
|
-
}
|
|
1565
|
-
const total = messages.length;
|
|
1566
|
-
const start = page * perPage;
|
|
1567
|
-
const end = start + perPage;
|
|
1568
|
-
const paginatedMessages = messages.slice(start, end);
|
|
1569
|
-
const hasMore = end < total;
|
|
1570
|
-
const list = new agent.MessageList({ threadId, resourceId }).add(paginatedMessages, "memory");
|
|
1571
|
-
const finalMessages = format === "v2" ? list.get.all.v2() : list.get.all.v1();
|
|
1572
|
-
return {
|
|
1573
|
-
messages: finalMessages,
|
|
1574
|
-
total,
|
|
1575
|
-
page,
|
|
1576
|
-
perPage,
|
|
1577
|
-
hasMore
|
|
1578
|
-
};
|
|
1579
|
-
} catch (error$1) {
|
|
1580
|
-
const mastraError = new error.MastraError(
|
|
1581
|
-
{
|
|
1582
|
-
id: "STORAGE_DYNAMODB_STORE_GET_MESSAGES_PAGINATED_FAILED",
|
|
1583
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1584
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1585
|
-
details: { threadId, resourceId: resourceId ?? "" }
|
|
1586
|
-
},
|
|
1587
|
-
error$1
|
|
1588
|
-
);
|
|
1589
|
-
this.logger?.trackException?.(mastraError);
|
|
1590
|
-
this.logger?.error?.(mastraError.toString());
|
|
1591
|
-
return { messages: [], total: 0, page, perPage, hasMore: false };
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
1594
|
-
// Helper method to get included messages with context
|
|
1595
|
-
async _getIncludedMessages(threadId, selectBy) {
|
|
1596
|
-
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
1597
|
-
if (!selectBy?.include?.length) {
|
|
1598
|
-
return [];
|
|
1599
|
-
}
|
|
1600
|
-
const includeMessages = [];
|
|
1601
|
-
for (const includeItem of selectBy.include) {
|
|
1602
|
-
try {
|
|
1603
|
-
const { id, threadId: targetThreadId, withPreviousMessages = 0, withNextMessages = 0 } = includeItem;
|
|
1604
|
-
const searchThreadId = targetThreadId || threadId;
|
|
1602
|
+
const targetMessageData = targetResult.data;
|
|
1603
|
+
const searchThreadId = targetMessageData.threadId;
|
|
1605
1604
|
this.logger.debug("Getting included messages for", {
|
|
1606
1605
|
id,
|
|
1607
|
-
targetThreadId,
|
|
1608
1606
|
searchThreadId,
|
|
1609
1607
|
withPreviousMessages,
|
|
1610
1608
|
withNextMessages
|
|
@@ -1627,7 +1625,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1627
1625
|
});
|
|
1628
1626
|
const targetIndex = allMessages.findIndex((msg) => msg.id === id);
|
|
1629
1627
|
if (targetIndex === -1) {
|
|
1630
|
-
this.logger.warn("Target message not found", { id, threadId: searchThreadId });
|
|
1628
|
+
this.logger.warn("Target message not found in thread", { id, threadId: searchThreadId });
|
|
1631
1629
|
continue;
|
|
1632
1630
|
}
|
|
1633
1631
|
this.logger.debug("Found target message at index", { id, targetIndex, totalMessages: allMessages.length });
|
|
@@ -1712,7 +1710,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1712
1710
|
} catch (error$1) {
|
|
1713
1711
|
throw new error.MastraError(
|
|
1714
1712
|
{
|
|
1715
|
-
id: "
|
|
1713
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_MESSAGES", "FAILED"),
|
|
1716
1714
|
domain: error.ErrorDomain.STORAGE,
|
|
1717
1715
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1718
1716
|
details: { count: messages.length }
|
|
@@ -1741,7 +1739,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1741
1739
|
} catch (error$1) {
|
|
1742
1740
|
throw new error.MastraError(
|
|
1743
1741
|
{
|
|
1744
|
-
id: "
|
|
1742
|
+
id: storage.createStorageErrorId("DYNAMODB", "GET_RESOURCE_BY_ID", "FAILED"),
|
|
1745
1743
|
domain: error.ErrorDomain.STORAGE,
|
|
1746
1744
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1747
1745
|
details: { resourceId }
|
|
@@ -1759,7 +1757,8 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1759
1757
|
workingMemory: resource.workingMemory,
|
|
1760
1758
|
metadata: resource.metadata ? JSON.stringify(resource.metadata) : void 0,
|
|
1761
1759
|
createdAt: resource.createdAt?.toISOString() || now.toISOString(),
|
|
1762
|
-
updatedAt: now.toISOString()
|
|
1760
|
+
updatedAt: now.toISOString(),
|
|
1761
|
+
...getTtlProps("resource", this.ttlConfig)
|
|
1763
1762
|
};
|
|
1764
1763
|
try {
|
|
1765
1764
|
await this.service.entities.resource.upsert(resourceData).go();
|
|
@@ -1773,7 +1772,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1773
1772
|
} catch (error$1) {
|
|
1774
1773
|
throw new error.MastraError(
|
|
1775
1774
|
{
|
|
1776
|
-
id: "
|
|
1775
|
+
id: storage.createStorageErrorId("DYNAMODB", "SAVE_RESOURCE", "FAILED"),
|
|
1777
1776
|
domain: error.ErrorDomain.STORAGE,
|
|
1778
1777
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1779
1778
|
details: { resourceId: resource.id }
|
|
@@ -1822,7 +1821,7 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1822
1821
|
} catch (error$1) {
|
|
1823
1822
|
throw new error.MastraError(
|
|
1824
1823
|
{
|
|
1825
|
-
id: "
|
|
1824
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_RESOURCE", "FAILED"),
|
|
1826
1825
|
domain: error.ErrorDomain.STORAGE,
|
|
1827
1826
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1828
1827
|
details: { resourceId }
|
|
@@ -1832,339 +1831,40 @@ var MemoryStorageDynamoDB = class extends storage.MemoryStorage {
|
|
|
1832
1831
|
}
|
|
1833
1832
|
}
|
|
1834
1833
|
};
|
|
1835
|
-
var
|
|
1836
|
-
client;
|
|
1837
|
-
tableName;
|
|
1834
|
+
var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
1838
1835
|
service;
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
tableName,
|
|
1842
|
-
client
|
|
1843
|
-
}) {
|
|
1836
|
+
ttlConfig;
|
|
1837
|
+
constructor(config) {
|
|
1844
1838
|
super();
|
|
1845
|
-
|
|
1846
|
-
this.
|
|
1847
|
-
this.
|
|
1848
|
-
}
|
|
1849
|
-
async hasColumn() {
|
|
1850
|
-
return true;
|
|
1839
|
+
const resolved = resolveDynamoDBConfig(config);
|
|
1840
|
+
this.service = resolved.service;
|
|
1841
|
+
this.ttlConfig = resolved.ttl;
|
|
1851
1842
|
}
|
|
1852
|
-
async
|
|
1853
|
-
|
|
1854
|
-
// Helper methods for entity/table mapping
|
|
1855
|
-
getEntityNameForTable(tableName) {
|
|
1856
|
-
const mapping = {
|
|
1857
|
-
[storage.TABLE_THREADS]: "thread",
|
|
1858
|
-
[storage.TABLE_MESSAGES]: "message",
|
|
1859
|
-
[storage.TABLE_WORKFLOW_SNAPSHOT]: "workflow_snapshot",
|
|
1860
|
-
[storage.TABLE_EVALS]: "eval",
|
|
1861
|
-
[storage.TABLE_SCORERS]: "score",
|
|
1862
|
-
[storage.TABLE_TRACES]: "trace",
|
|
1863
|
-
[storage.TABLE_RESOURCES]: "resource",
|
|
1864
|
-
[storage.TABLE_AI_SPANS]: "ai_span"
|
|
1865
|
-
};
|
|
1866
|
-
return mapping[tableName] || null;
|
|
1843
|
+
async dangerouslyClearAll() {
|
|
1844
|
+
await deleteTableData(this.service, storage.TABLE_SCORERS);
|
|
1867
1845
|
}
|
|
1868
1846
|
/**
|
|
1869
|
-
*
|
|
1870
|
-
* This is necessary because ElectroDB validation happens before setters are applied
|
|
1871
|
-
*/
|
|
1872
|
-
preprocessRecord(record) {
|
|
1873
|
-
const processed = { ...record };
|
|
1874
|
-
if (processed.createdAt instanceof Date) {
|
|
1875
|
-
processed.createdAt = processed.createdAt.toISOString();
|
|
1876
|
-
}
|
|
1877
|
-
if (processed.updatedAt instanceof Date) {
|
|
1878
|
-
processed.updatedAt = processed.updatedAt.toISOString();
|
|
1879
|
-
}
|
|
1880
|
-
if (processed.created_at instanceof Date) {
|
|
1881
|
-
processed.created_at = processed.created_at.toISOString();
|
|
1882
|
-
}
|
|
1883
|
-
if (processed.result && typeof processed.result === "object") {
|
|
1884
|
-
processed.result = JSON.stringify(processed.result);
|
|
1885
|
-
}
|
|
1886
|
-
if (processed.test_info && typeof processed.test_info === "object") {
|
|
1887
|
-
processed.test_info = JSON.stringify(processed.test_info);
|
|
1888
|
-
} else if (processed.test_info === void 0 || processed.test_info === null) {
|
|
1889
|
-
delete processed.test_info;
|
|
1890
|
-
}
|
|
1891
|
-
if (processed.snapshot && typeof processed.snapshot === "object") {
|
|
1892
|
-
processed.snapshot = JSON.stringify(processed.snapshot);
|
|
1893
|
-
}
|
|
1894
|
-
if (processed.attributes && typeof processed.attributes === "object") {
|
|
1895
|
-
processed.attributes = JSON.stringify(processed.attributes);
|
|
1896
|
-
}
|
|
1897
|
-
if (processed.status && typeof processed.status === "object") {
|
|
1898
|
-
processed.status = JSON.stringify(processed.status);
|
|
1899
|
-
}
|
|
1900
|
-
if (processed.events && typeof processed.events === "object") {
|
|
1901
|
-
processed.events = JSON.stringify(processed.events);
|
|
1902
|
-
}
|
|
1903
|
-
if (processed.links && typeof processed.links === "object") {
|
|
1904
|
-
processed.links = JSON.stringify(processed.links);
|
|
1905
|
-
}
|
|
1906
|
-
return processed;
|
|
1907
|
-
}
|
|
1908
|
-
/**
|
|
1909
|
-
* Validates that the required DynamoDB table exists and is accessible.
|
|
1910
|
-
* This does not check the table structure - it assumes the table
|
|
1911
|
-
* was created with the correct structure via CDK/CloudFormation.
|
|
1912
|
-
*/
|
|
1913
|
-
async validateTableExists() {
|
|
1914
|
-
try {
|
|
1915
|
-
const command = new clientDynamodb.DescribeTableCommand({
|
|
1916
|
-
TableName: this.tableName
|
|
1917
|
-
});
|
|
1918
|
-
await this.client.send(command);
|
|
1919
|
-
return true;
|
|
1920
|
-
} catch (error$1) {
|
|
1921
|
-
if (error$1.name === "ResourceNotFoundException") {
|
|
1922
|
-
return false;
|
|
1923
|
-
}
|
|
1924
|
-
throw new error.MastraError(
|
|
1925
|
-
{
|
|
1926
|
-
id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_EXISTS_FAILED",
|
|
1927
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1928
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1929
|
-
details: { tableName: this.tableName }
|
|
1930
|
-
},
|
|
1931
|
-
error$1
|
|
1932
|
-
);
|
|
1933
|
-
}
|
|
1934
|
-
}
|
|
1935
|
-
/**
|
|
1936
|
-
* This method is modified for DynamoDB with ElectroDB single-table design.
|
|
1937
|
-
* It assumes the table is created and managed externally via CDK/CloudFormation.
|
|
1847
|
+
* DynamoDB-specific score row transformation.
|
|
1938
1848
|
*
|
|
1939
|
-
* This implementation
|
|
1940
|
-
*
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
this.logger.debug("Validating access to externally managed table", { tableName, physicalTable: this.tableName });
|
|
1944
|
-
try {
|
|
1945
|
-
const tableExists = await this.validateTableExists();
|
|
1946
|
-
if (!tableExists) {
|
|
1947
|
-
this.logger.error(
|
|
1948
|
-
`Table ${this.tableName} does not exist or is not accessible. It should be created via CDK/CloudFormation.`
|
|
1949
|
-
);
|
|
1950
|
-
throw new Error(
|
|
1951
|
-
`Table ${this.tableName} does not exist or is not accessible. Ensure it's created via CDK/CloudFormation before using this store.`
|
|
1952
|
-
);
|
|
1953
|
-
}
|
|
1954
|
-
this.logger.debug(`Table ${this.tableName} exists and is accessible`);
|
|
1955
|
-
} catch (error$1) {
|
|
1956
|
-
this.logger.error("Error validating table access", { tableName: this.tableName, error: error$1 });
|
|
1957
|
-
throw new error.MastraError(
|
|
1958
|
-
{
|
|
1959
|
-
id: "STORAGE_DYNAMODB_STORE_VALIDATE_TABLE_ACCESS_FAILED",
|
|
1960
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1961
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1962
|
-
details: { tableName: this.tableName }
|
|
1963
|
-
},
|
|
1964
|
-
error$1
|
|
1965
|
-
);
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
async insert({ tableName, record }) {
|
|
1969
|
-
this.logger.debug("DynamoDB insert called", { tableName });
|
|
1970
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
1971
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
1972
|
-
throw new error.MastraError({
|
|
1973
|
-
id: "STORAGE_DYNAMODB_STORE_INSERT_INVALID_ARGS",
|
|
1974
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1975
|
-
category: error.ErrorCategory.USER,
|
|
1976
|
-
text: "No entity defined for tableName",
|
|
1977
|
-
details: { tableName }
|
|
1978
|
-
});
|
|
1979
|
-
}
|
|
1980
|
-
try {
|
|
1981
|
-
const dataToSave = { entity: entityName, ...this.preprocessRecord(record) };
|
|
1982
|
-
await this.service.entities[entityName].create(dataToSave).go();
|
|
1983
|
-
} catch (error$1) {
|
|
1984
|
-
throw new error.MastraError(
|
|
1985
|
-
{
|
|
1986
|
-
id: "STORAGE_DYNAMODB_STORE_INSERT_FAILED",
|
|
1987
|
-
domain: error.ErrorDomain.STORAGE,
|
|
1988
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
1989
|
-
details: { tableName }
|
|
1990
|
-
},
|
|
1991
|
-
error$1
|
|
1992
|
-
);
|
|
1993
|
-
}
|
|
1994
|
-
}
|
|
1995
|
-
async alterTable(_args) {
|
|
1996
|
-
}
|
|
1997
|
-
/**
|
|
1998
|
-
* Clear all items from a logical "table" (entity type)
|
|
1849
|
+
* Note: This implementation does NOT use coreTransformScoreRow because:
|
|
1850
|
+
* 1. ElectroDB already parses JSON fields via its entity getters
|
|
1851
|
+
* 2. DynamoDB stores empty strings for null values (which need special handling)
|
|
1852
|
+
* 3. 'entity' is a reserved ElectroDB key, so we use 'entityData' column
|
|
1999
1853
|
*/
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
const
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2007
|
-
category: error.ErrorCategory.USER,
|
|
2008
|
-
text: "No entity defined for tableName",
|
|
2009
|
-
details: { tableName }
|
|
2010
|
-
});
|
|
2011
|
-
}
|
|
2012
|
-
try {
|
|
2013
|
-
const result = await this.service.entities[entityName].scan.go({ pages: "all" });
|
|
2014
|
-
if (!result.data.length) {
|
|
2015
|
-
this.logger.debug(`No records found to clear for ${tableName}`);
|
|
2016
|
-
return;
|
|
2017
|
-
}
|
|
2018
|
-
this.logger.debug(`Found ${result.data.length} records to delete for ${tableName}`);
|
|
2019
|
-
const keysToDelete = result.data.map((item) => {
|
|
2020
|
-
const key = { entity: entityName };
|
|
2021
|
-
switch (entityName) {
|
|
2022
|
-
case "thread":
|
|
2023
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'thread'`);
|
|
2024
|
-
key.id = item.id;
|
|
2025
|
-
break;
|
|
2026
|
-
case "message":
|
|
2027
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'message'`);
|
|
2028
|
-
key.id = item.id;
|
|
2029
|
-
break;
|
|
2030
|
-
case "workflow_snapshot":
|
|
2031
|
-
if (!item.workflow_name)
|
|
2032
|
-
throw new Error(`Missing required key 'workflow_name' for entity 'workflow_snapshot'`);
|
|
2033
|
-
if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'workflow_snapshot'`);
|
|
2034
|
-
key.workflow_name = item.workflow_name;
|
|
2035
|
-
key.run_id = item.run_id;
|
|
2036
|
-
break;
|
|
2037
|
-
case "eval":
|
|
2038
|
-
if (!item.run_id) throw new Error(`Missing required key 'run_id' for entity 'eval'`);
|
|
2039
|
-
key.run_id = item.run_id;
|
|
2040
|
-
break;
|
|
2041
|
-
case "trace":
|
|
2042
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'trace'`);
|
|
2043
|
-
key.id = item.id;
|
|
2044
|
-
break;
|
|
2045
|
-
case "score":
|
|
2046
|
-
if (!item.id) throw new Error(`Missing required key 'id' for entity 'score'`);
|
|
2047
|
-
key.id = item.id;
|
|
2048
|
-
break;
|
|
2049
|
-
default:
|
|
2050
|
-
this.logger.warn(`Unknown entity type encountered during clearTable: ${entityName}`);
|
|
2051
|
-
throw new Error(`Cannot construct delete key for unknown entity type: ${entityName}`);
|
|
2052
|
-
}
|
|
2053
|
-
return key;
|
|
2054
|
-
});
|
|
2055
|
-
const batchSize = 25;
|
|
2056
|
-
for (let i = 0; i < keysToDelete.length; i += batchSize) {
|
|
2057
|
-
const batchKeys = keysToDelete.slice(i, i + batchSize);
|
|
2058
|
-
await this.service.entities[entityName].delete(batchKeys).go();
|
|
2059
|
-
}
|
|
2060
|
-
this.logger.debug(`Successfully cleared all records for ${tableName}`);
|
|
2061
|
-
} catch (error$1) {
|
|
2062
|
-
throw new error.MastraError(
|
|
2063
|
-
{
|
|
2064
|
-
id: "STORAGE_DYNAMODB_STORE_CLEAR_TABLE_FAILED",
|
|
2065
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2066
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
2067
|
-
details: { tableName }
|
|
2068
|
-
},
|
|
2069
|
-
error$1
|
|
2070
|
-
);
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
/**
|
|
2074
|
-
* Insert multiple records as a batch
|
|
2075
|
-
*/
|
|
2076
|
-
async batchInsert({ tableName, records }) {
|
|
2077
|
-
this.logger.debug("DynamoDB batchInsert called", { tableName, count: records.length });
|
|
2078
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
2079
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
2080
|
-
throw new error.MastraError({
|
|
2081
|
-
id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_INVALID_ARGS",
|
|
2082
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2083
|
-
category: error.ErrorCategory.USER,
|
|
2084
|
-
text: "No entity defined for tableName",
|
|
2085
|
-
details: { tableName }
|
|
2086
|
-
});
|
|
2087
|
-
}
|
|
2088
|
-
const recordsToSave = records.map((rec) => ({ entity: entityName, ...this.preprocessRecord(rec) }));
|
|
2089
|
-
const batchSize = 25;
|
|
2090
|
-
const batches = [];
|
|
2091
|
-
for (let i = 0; i < recordsToSave.length; i += batchSize) {
|
|
2092
|
-
const batch = recordsToSave.slice(i, i + batchSize);
|
|
2093
|
-
batches.push(batch);
|
|
2094
|
-
}
|
|
2095
|
-
try {
|
|
2096
|
-
for (const batch of batches) {
|
|
2097
|
-
for (const recordData of batch) {
|
|
2098
|
-
if (!recordData.entity) {
|
|
2099
|
-
this.logger.error("Missing entity property in record data for batchInsert", { recordData, tableName });
|
|
2100
|
-
throw new Error(`Internal error: Missing entity property during batchInsert for ${tableName}`);
|
|
2101
|
-
}
|
|
2102
|
-
this.logger.debug("Attempting to create record in batchInsert:", { entityName, recordData });
|
|
2103
|
-
await this.service.entities[entityName].create(recordData).go();
|
|
2104
|
-
}
|
|
2105
|
-
}
|
|
2106
|
-
} catch (error$1) {
|
|
2107
|
-
throw new error.MastraError(
|
|
2108
|
-
{
|
|
2109
|
-
id: "STORAGE_DYNAMODB_STORE_BATCH_INSERT_FAILED",
|
|
2110
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2111
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
2112
|
-
details: { tableName }
|
|
2113
|
-
},
|
|
2114
|
-
error$1
|
|
2115
|
-
);
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
/**
|
|
2119
|
-
* Load a record by its keys
|
|
2120
|
-
*/
|
|
2121
|
-
async load({ tableName, keys }) {
|
|
2122
|
-
this.logger.debug("DynamoDB load called", { tableName, keys });
|
|
2123
|
-
const entityName = this.getEntityNameForTable(tableName);
|
|
2124
|
-
if (!entityName || !this.service.entities[entityName]) {
|
|
2125
|
-
throw new error.MastraError({
|
|
2126
|
-
id: "STORAGE_DYNAMODB_STORE_LOAD_INVALID_ARGS",
|
|
2127
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2128
|
-
category: error.ErrorCategory.USER,
|
|
2129
|
-
text: "No entity defined for tableName",
|
|
2130
|
-
details: { tableName }
|
|
2131
|
-
});
|
|
2132
|
-
}
|
|
2133
|
-
try {
|
|
2134
|
-
const keyObject = { entity: entityName, ...keys };
|
|
2135
|
-
const result = await this.service.entities[entityName].get(keyObject).go();
|
|
2136
|
-
if (!result.data) {
|
|
2137
|
-
return null;
|
|
1854
|
+
parseScoreData(data) {
|
|
1855
|
+
const result = {};
|
|
1856
|
+
for (const key of Object.keys(storage.SCORERS_SCHEMA)) {
|
|
1857
|
+
if (["traceId", "resourceId", "threadId", "spanId"].includes(key)) {
|
|
1858
|
+
result[key] = data[key] === "" ? null : data[key];
|
|
1859
|
+
continue;
|
|
2138
1860
|
}
|
|
2139
|
-
|
|
2140
|
-
return data;
|
|
2141
|
-
} catch (error$1) {
|
|
2142
|
-
throw new error.MastraError(
|
|
2143
|
-
{
|
|
2144
|
-
id: "STORAGE_DYNAMODB_STORE_LOAD_FAILED",
|
|
2145
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2146
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
2147
|
-
details: { tableName }
|
|
2148
|
-
},
|
|
2149
|
-
error$1
|
|
2150
|
-
);
|
|
1861
|
+
result[key] = data[key];
|
|
2151
1862
|
}
|
|
2152
|
-
|
|
2153
|
-
};
|
|
2154
|
-
var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
2155
|
-
service;
|
|
2156
|
-
constructor({ service }) {
|
|
2157
|
-
super();
|
|
2158
|
-
this.service = service;
|
|
2159
|
-
}
|
|
2160
|
-
// Helper function to parse score data (handle JSON fields)
|
|
2161
|
-
parseScoreData(data) {
|
|
1863
|
+
result.entity = data.entityData ?? null;
|
|
2162
1864
|
return {
|
|
2163
|
-
...
|
|
2164
|
-
// Convert date strings back to Date objects for consistency
|
|
1865
|
+
...result,
|
|
2165
1866
|
createdAt: data.createdAt ? new Date(data.createdAt) : /* @__PURE__ */ new Date(),
|
|
2166
1867
|
updatedAt: data.updatedAt ? new Date(data.updatedAt) : /* @__PURE__ */ new Date()
|
|
2167
|
-
// JSON fields are already transformed by the entity's getters
|
|
2168
1868
|
};
|
|
2169
1869
|
}
|
|
2170
1870
|
async getScoreById({ id }) {
|
|
@@ -2178,7 +1878,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2178
1878
|
} catch (error$1) {
|
|
2179
1879
|
throw new error.MastraError(
|
|
2180
1880
|
{
|
|
2181
|
-
id: "
|
|
1881
|
+
id: storage.createStorageErrorId("DYNAMODB", "GET_SCORE_BY_ID", "FAILED"),
|
|
2182
1882
|
domain: error.ErrorDomain.STORAGE,
|
|
2183
1883
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2184
1884
|
details: { id }
|
|
@@ -2190,61 +1890,72 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2190
1890
|
async saveScore(score) {
|
|
2191
1891
|
let validatedScore;
|
|
2192
1892
|
try {
|
|
2193
|
-
validatedScore =
|
|
1893
|
+
validatedScore = evals.saveScorePayloadSchema.parse(score);
|
|
2194
1894
|
} catch (error$1) {
|
|
2195
1895
|
throw new error.MastraError(
|
|
2196
1896
|
{
|
|
2197
|
-
id: "
|
|
1897
|
+
id: storage.createStorageErrorId("DYNAMODB", "SAVE_SCORE", "VALIDATION_FAILED"),
|
|
2198
1898
|
domain: error.ErrorDomain.STORAGE,
|
|
2199
|
-
category: error.ErrorCategory.
|
|
1899
|
+
category: error.ErrorCategory.USER,
|
|
1900
|
+
details: {
|
|
1901
|
+
scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
|
|
1902
|
+
entityId: score.entityId ?? "unknown",
|
|
1903
|
+
entityType: score.entityType ?? "unknown",
|
|
1904
|
+
traceId: score.traceId ?? "",
|
|
1905
|
+
spanId: score.spanId ?? ""
|
|
1906
|
+
}
|
|
2200
1907
|
},
|
|
2201
1908
|
error$1
|
|
2202
1909
|
);
|
|
2203
1910
|
}
|
|
2204
1911
|
const now = /* @__PURE__ */ new Date();
|
|
2205
|
-
const scoreId =
|
|
2206
|
-
const
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
1912
|
+
const scoreId = crypto.randomUUID();
|
|
1913
|
+
const scorer = typeof validatedScore.scorer === "string" ? validatedScore.scorer : JSON.stringify(validatedScore.scorer);
|
|
1914
|
+
const preprocessStepResult = typeof validatedScore.preprocessStepResult === "string" ? validatedScore.preprocessStepResult : JSON.stringify(validatedScore.preprocessStepResult);
|
|
1915
|
+
const analyzeStepResult = typeof validatedScore.analyzeStepResult === "string" ? validatedScore.analyzeStepResult : JSON.stringify(validatedScore.analyzeStepResult);
|
|
1916
|
+
const input = typeof validatedScore.input === "string" ? validatedScore.input : JSON.stringify(validatedScore.input);
|
|
1917
|
+
const output = typeof validatedScore.output === "string" ? validatedScore.output : JSON.stringify(validatedScore.output);
|
|
1918
|
+
const requestContext = typeof validatedScore.requestContext === "string" ? validatedScore.requestContext : JSON.stringify(validatedScore.requestContext);
|
|
1919
|
+
const entity = typeof validatedScore.entity === "string" ? validatedScore.entity : JSON.stringify(validatedScore.entity);
|
|
1920
|
+
const metadata = typeof validatedScore.metadata === "string" ? validatedScore.metadata : validatedScore.metadata ? JSON.stringify(validatedScore.metadata) : void 0;
|
|
1921
|
+
const additionalContext = typeof validatedScore.additionalContext === "string" ? validatedScore.additionalContext : validatedScore.additionalContext ? JSON.stringify(validatedScore.additionalContext) : void 0;
|
|
1922
|
+
const scoreData = Object.fromEntries(
|
|
1923
|
+
Object.entries({
|
|
1924
|
+
...validatedScore,
|
|
1925
|
+
entity: "score",
|
|
1926
|
+
id: scoreId,
|
|
1927
|
+
scorer,
|
|
1928
|
+
preprocessStepResult,
|
|
1929
|
+
analyzeStepResult,
|
|
1930
|
+
input,
|
|
1931
|
+
output,
|
|
1932
|
+
requestContext,
|
|
1933
|
+
metadata,
|
|
1934
|
+
additionalContext,
|
|
1935
|
+
entityData: entity,
|
|
1936
|
+
traceId: validatedScore.traceId || "",
|
|
1937
|
+
resourceId: validatedScore.resourceId || "",
|
|
1938
|
+
threadId: validatedScore.threadId || "",
|
|
1939
|
+
spanId: validatedScore.spanId || "",
|
|
1940
|
+
createdAt: now.toISOString(),
|
|
1941
|
+
updatedAt: now.toISOString(),
|
|
1942
|
+
...getTtlProps("score", this.ttlConfig)
|
|
1943
|
+
}).filter(([_, value]) => value !== void 0 && value !== null)
|
|
1944
|
+
);
|
|
2235
1945
|
try {
|
|
2236
1946
|
await this.service.entities.score.upsert(scoreData).go();
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
1947
|
+
return {
|
|
1948
|
+
score: {
|
|
1949
|
+
...validatedScore,
|
|
1950
|
+
id: scoreId,
|
|
1951
|
+
createdAt: now,
|
|
1952
|
+
updatedAt: now
|
|
1953
|
+
}
|
|
2242
1954
|
};
|
|
2243
|
-
return { score: savedScore };
|
|
2244
1955
|
} catch (error$1) {
|
|
2245
1956
|
throw new error.MastraError(
|
|
2246
1957
|
{
|
|
2247
|
-
id: "
|
|
1958
|
+
id: storage.createStorageErrorId("DYNAMODB", "SAVE_SCORE", "FAILED"),
|
|
2248
1959
|
domain: error.ErrorDomain.STORAGE,
|
|
2249
1960
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2250
1961
|
details: { scorerId: score.scorerId, runId: score.runId }
|
|
@@ -2253,7 +1964,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2253
1964
|
);
|
|
2254
1965
|
}
|
|
2255
1966
|
}
|
|
2256
|
-
async
|
|
1967
|
+
async listScoresByScorerId({
|
|
2257
1968
|
scorerId,
|
|
2258
1969
|
pagination,
|
|
2259
1970
|
entityId,
|
|
@@ -2274,24 +1985,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2274
1985
|
allScores = allScores.filter((score) => score.source === source);
|
|
2275
1986
|
}
|
|
2276
1987
|
allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2277
|
-
const
|
|
2278
|
-
const
|
|
2279
|
-
const
|
|
1988
|
+
const { page, perPage: perPageInput } = pagination;
|
|
1989
|
+
const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
|
|
1990
|
+
const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
2280
1991
|
const total = allScores.length;
|
|
2281
|
-
const
|
|
1992
|
+
const end = perPageInput === false ? allScores.length : start + perPage;
|
|
1993
|
+
const paginatedScores = allScores.slice(start, end);
|
|
2282
1994
|
return {
|
|
2283
1995
|
scores: paginatedScores,
|
|
2284
1996
|
pagination: {
|
|
2285
1997
|
total,
|
|
2286
|
-
page
|
|
2287
|
-
perPage:
|
|
2288
|
-
hasMore
|
|
1998
|
+
page,
|
|
1999
|
+
perPage: perPageForResponse,
|
|
2000
|
+
hasMore: end < total
|
|
2289
2001
|
}
|
|
2290
2002
|
};
|
|
2291
2003
|
} catch (error$1) {
|
|
2292
2004
|
throw new error.MastraError(
|
|
2293
2005
|
{
|
|
2294
|
-
id: "
|
|
2006
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
|
|
2295
2007
|
domain: error.ErrorDomain.STORAGE,
|
|
2296
2008
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2297
2009
|
details: {
|
|
@@ -2307,7 +2019,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2307
2019
|
);
|
|
2308
2020
|
}
|
|
2309
2021
|
}
|
|
2310
|
-
async
|
|
2022
|
+
async listScoresByRunId({
|
|
2311
2023
|
runId,
|
|
2312
2024
|
pagination
|
|
2313
2025
|
}) {
|
|
@@ -2317,24 +2029,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2317
2029
|
const results = await query.go();
|
|
2318
2030
|
const allScores = results.data.map((data) => this.parseScoreData(data));
|
|
2319
2031
|
allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2320
|
-
const
|
|
2321
|
-
const
|
|
2322
|
-
const
|
|
2032
|
+
const { page, perPage: perPageInput } = pagination;
|
|
2033
|
+
const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
|
|
2034
|
+
const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
2323
2035
|
const total = allScores.length;
|
|
2324
|
-
const
|
|
2036
|
+
const end = perPageInput === false ? allScores.length : start + perPage;
|
|
2037
|
+
const paginatedScores = allScores.slice(start, end);
|
|
2325
2038
|
return {
|
|
2326
2039
|
scores: paginatedScores,
|
|
2327
2040
|
pagination: {
|
|
2328
2041
|
total,
|
|
2329
|
-
page
|
|
2330
|
-
perPage:
|
|
2331
|
-
hasMore
|
|
2042
|
+
page,
|
|
2043
|
+
perPage: perPageForResponse,
|
|
2044
|
+
hasMore: end < total
|
|
2332
2045
|
}
|
|
2333
2046
|
};
|
|
2334
2047
|
} catch (error$1) {
|
|
2335
2048
|
throw new error.MastraError(
|
|
2336
2049
|
{
|
|
2337
|
-
id: "
|
|
2050
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_RUN_ID", "FAILED"),
|
|
2338
2051
|
domain: error.ErrorDomain.STORAGE,
|
|
2339
2052
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2340
2053
|
details: { runId, page: pagination.page, perPage: pagination.perPage }
|
|
@@ -2343,7 +2056,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2343
2056
|
);
|
|
2344
2057
|
}
|
|
2345
2058
|
}
|
|
2346
|
-
async
|
|
2059
|
+
async listScoresByEntityId({
|
|
2347
2060
|
entityId,
|
|
2348
2061
|
entityType,
|
|
2349
2062
|
pagination
|
|
@@ -2355,24 +2068,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2355
2068
|
let allScores = results.data.map((data) => this.parseScoreData(data));
|
|
2356
2069
|
allScores = allScores.filter((score) => score.entityType === entityType);
|
|
2357
2070
|
allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2358
|
-
const
|
|
2359
|
-
const
|
|
2360
|
-
const
|
|
2071
|
+
const { page, perPage: perPageInput } = pagination;
|
|
2072
|
+
const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
|
|
2073
|
+
const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
2361
2074
|
const total = allScores.length;
|
|
2362
|
-
const
|
|
2075
|
+
const end = perPageInput === false ? allScores.length : start + perPage;
|
|
2076
|
+
const paginatedScores = allScores.slice(start, end);
|
|
2363
2077
|
return {
|
|
2364
2078
|
scores: paginatedScores,
|
|
2365
2079
|
pagination: {
|
|
2366
2080
|
total,
|
|
2367
|
-
page
|
|
2368
|
-
perPage:
|
|
2369
|
-
hasMore
|
|
2081
|
+
page,
|
|
2082
|
+
perPage: perPageForResponse,
|
|
2083
|
+
hasMore: end < total
|
|
2370
2084
|
}
|
|
2371
2085
|
};
|
|
2372
2086
|
} catch (error$1) {
|
|
2373
2087
|
throw new error.MastraError(
|
|
2374
2088
|
{
|
|
2375
|
-
id: "
|
|
2089
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
|
|
2376
2090
|
domain: error.ErrorDomain.STORAGE,
|
|
2377
2091
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2378
2092
|
details: { entityId, entityType, page: pagination.page, perPage: pagination.perPage }
|
|
@@ -2381,7 +2095,7 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2381
2095
|
);
|
|
2382
2096
|
}
|
|
2383
2097
|
}
|
|
2384
|
-
async
|
|
2098
|
+
async listScoresBySpan({
|
|
2385
2099
|
traceId,
|
|
2386
2100
|
spanId,
|
|
2387
2101
|
pagination
|
|
@@ -2392,24 +2106,25 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2392
2106
|
const results = await query.go();
|
|
2393
2107
|
const allScores = results.data.map((data) => this.parseScoreData(data));
|
|
2394
2108
|
allScores.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
2395
|
-
const
|
|
2396
|
-
const
|
|
2397
|
-
const
|
|
2109
|
+
const { page, perPage: perPageInput } = pagination;
|
|
2110
|
+
const perPage = storage.normalizePerPage(perPageInput, Number.MAX_SAFE_INTEGER);
|
|
2111
|
+
const { offset: start, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
|
|
2398
2112
|
const total = allScores.length;
|
|
2399
|
-
const
|
|
2113
|
+
const end = perPageInput === false ? allScores.length : start + perPage;
|
|
2114
|
+
const paginatedScores = allScores.slice(start, end);
|
|
2400
2115
|
return {
|
|
2401
2116
|
scores: paginatedScores,
|
|
2402
2117
|
pagination: {
|
|
2403
2118
|
total,
|
|
2404
|
-
page
|
|
2405
|
-
perPage:
|
|
2406
|
-
hasMore
|
|
2119
|
+
page,
|
|
2120
|
+
perPage: perPageForResponse,
|
|
2121
|
+
hasMore: end < total
|
|
2407
2122
|
}
|
|
2408
2123
|
};
|
|
2409
2124
|
} catch (error$1) {
|
|
2410
2125
|
throw new error.MastraError(
|
|
2411
2126
|
{
|
|
2412
|
-
id: "
|
|
2127
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_SCORES_BY_SPAN", "FAILED"),
|
|
2413
2128
|
domain: error.ErrorDomain.STORAGE,
|
|
2414
2129
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2415
2130
|
details: { traceId, spanId, page: pagination.page, perPage: pagination.perPage }
|
|
@@ -2419,239 +2134,6 @@ var ScoresStorageDynamoDB = class extends storage.ScoresStorage {
|
|
|
2419
2134
|
}
|
|
2420
2135
|
}
|
|
2421
2136
|
};
|
|
2422
|
-
var TracesStorageDynamoDB = class extends storage.TracesStorage {
|
|
2423
|
-
service;
|
|
2424
|
-
operations;
|
|
2425
|
-
constructor({ service, operations }) {
|
|
2426
|
-
super();
|
|
2427
|
-
this.service = service;
|
|
2428
|
-
this.operations = operations;
|
|
2429
|
-
}
|
|
2430
|
-
// Trace operations
|
|
2431
|
-
async getTraces(args) {
|
|
2432
|
-
const { name, scope, page, perPage } = args;
|
|
2433
|
-
this.logger.debug("Getting traces", { name, scope, page, perPage });
|
|
2434
|
-
try {
|
|
2435
|
-
let query;
|
|
2436
|
-
if (name) {
|
|
2437
|
-
query = this.service.entities.trace.query.byName({ entity: "trace", name });
|
|
2438
|
-
} else if (scope) {
|
|
2439
|
-
query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
|
|
2440
|
-
} else {
|
|
2441
|
-
this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
|
|
2442
|
-
query = this.service.entities.trace.scan;
|
|
2443
|
-
}
|
|
2444
|
-
let items = [];
|
|
2445
|
-
let cursor = null;
|
|
2446
|
-
let pagesFetched = 0;
|
|
2447
|
-
const startPage = page > 0 ? page : 1;
|
|
2448
|
-
do {
|
|
2449
|
-
const results = await query.go({ cursor, limit: perPage });
|
|
2450
|
-
pagesFetched++;
|
|
2451
|
-
if (pagesFetched === startPage) {
|
|
2452
|
-
items = results.data;
|
|
2453
|
-
break;
|
|
2454
|
-
}
|
|
2455
|
-
cursor = results.cursor;
|
|
2456
|
-
if (!cursor && results.data.length > 0 && pagesFetched < startPage) {
|
|
2457
|
-
break;
|
|
2458
|
-
}
|
|
2459
|
-
} while (cursor && pagesFetched < startPage);
|
|
2460
|
-
return items;
|
|
2461
|
-
} catch (error$1) {
|
|
2462
|
-
throw new error.MastraError(
|
|
2463
|
-
{
|
|
2464
|
-
id: "STORAGE_DYNAMODB_STORE_GET_TRACES_FAILED",
|
|
2465
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2466
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
2467
|
-
},
|
|
2468
|
-
error$1
|
|
2469
|
-
);
|
|
2470
|
-
}
|
|
2471
|
-
}
|
|
2472
|
-
async batchTraceInsert({ records }) {
|
|
2473
|
-
this.logger.debug("Batch inserting traces", { count: records.length });
|
|
2474
|
-
if (!records.length) {
|
|
2475
|
-
return;
|
|
2476
|
-
}
|
|
2477
|
-
try {
|
|
2478
|
-
const recordsToSave = records.map((rec) => ({ entity: "trace", ...rec }));
|
|
2479
|
-
await this.operations.batchInsert({
|
|
2480
|
-
tableName: storage.TABLE_TRACES,
|
|
2481
|
-
records: recordsToSave
|
|
2482
|
-
// Pass records with 'entity' included
|
|
2483
|
-
});
|
|
2484
|
-
} catch (error$1) {
|
|
2485
|
-
throw new error.MastraError(
|
|
2486
|
-
{
|
|
2487
|
-
id: "STORAGE_DYNAMODB_STORE_BATCH_TRACE_INSERT_FAILED",
|
|
2488
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2489
|
-
category: error.ErrorCategory.THIRD_PARTY,
|
|
2490
|
-
details: { count: records.length }
|
|
2491
|
-
},
|
|
2492
|
-
error$1
|
|
2493
|
-
);
|
|
2494
|
-
}
|
|
2495
|
-
}
|
|
2496
|
-
async getTracesPaginated(args) {
|
|
2497
|
-
const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
|
|
2498
|
-
this.logger.debug("Getting traces with pagination", { name, scope, page, perPage, attributes, filters, dateRange });
|
|
2499
|
-
try {
|
|
2500
|
-
let query;
|
|
2501
|
-
if (name) {
|
|
2502
|
-
query = this.service.entities.trace.query.byName({ entity: "trace", name });
|
|
2503
|
-
} else if (scope) {
|
|
2504
|
-
query = this.service.entities.trace.query.byScope({ entity: "trace", scope });
|
|
2505
|
-
} else {
|
|
2506
|
-
this.logger.warn("Performing a scan operation on traces - consider using a more specific query");
|
|
2507
|
-
query = this.service.entities.trace.scan;
|
|
2508
|
-
}
|
|
2509
|
-
const results = await query.go({
|
|
2510
|
-
order: "desc",
|
|
2511
|
-
pages: "all"
|
|
2512
|
-
// Get all pages to apply filtering and pagination
|
|
2513
|
-
});
|
|
2514
|
-
if (!results.data.length) {
|
|
2515
|
-
return {
|
|
2516
|
-
traces: [],
|
|
2517
|
-
total: 0,
|
|
2518
|
-
page,
|
|
2519
|
-
perPage,
|
|
2520
|
-
hasMore: false
|
|
2521
|
-
};
|
|
2522
|
-
}
|
|
2523
|
-
let filteredData = results.data;
|
|
2524
|
-
if (attributes) {
|
|
2525
|
-
filteredData = filteredData.filter((item) => {
|
|
2526
|
-
try {
|
|
2527
|
-
let itemAttributes = {};
|
|
2528
|
-
if (item.attributes) {
|
|
2529
|
-
if (typeof item.attributes === "string") {
|
|
2530
|
-
if (item.attributes === "[object Object]") {
|
|
2531
|
-
itemAttributes = {};
|
|
2532
|
-
} else {
|
|
2533
|
-
try {
|
|
2534
|
-
itemAttributes = JSON.parse(item.attributes);
|
|
2535
|
-
} catch {
|
|
2536
|
-
itemAttributes = {};
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
} else if (typeof item.attributes === "object") {
|
|
2540
|
-
itemAttributes = item.attributes;
|
|
2541
|
-
}
|
|
2542
|
-
}
|
|
2543
|
-
return Object.entries(attributes).every(([key, value]) => itemAttributes[key] === value);
|
|
2544
|
-
} catch (e) {
|
|
2545
|
-
this.logger.warn("Failed to parse attributes during filtering", { item, error: e });
|
|
2546
|
-
return false;
|
|
2547
|
-
}
|
|
2548
|
-
});
|
|
2549
|
-
}
|
|
2550
|
-
if (dateRange?.start) {
|
|
2551
|
-
filteredData = filteredData.filter((item) => {
|
|
2552
|
-
const itemDate = new Date(item.createdAt);
|
|
2553
|
-
return itemDate >= dateRange.start;
|
|
2554
|
-
});
|
|
2555
|
-
}
|
|
2556
|
-
if (dateRange?.end) {
|
|
2557
|
-
filteredData = filteredData.filter((item) => {
|
|
2558
|
-
const itemDate = new Date(item.createdAt);
|
|
2559
|
-
return itemDate <= dateRange.end;
|
|
2560
|
-
});
|
|
2561
|
-
}
|
|
2562
|
-
const total = filteredData.length;
|
|
2563
|
-
const start = page * perPage;
|
|
2564
|
-
const end = start + perPage;
|
|
2565
|
-
const paginatedData = filteredData.slice(start, end);
|
|
2566
|
-
const traces = paginatedData.map((item) => {
|
|
2567
|
-
let attributes2;
|
|
2568
|
-
if (item.attributes) {
|
|
2569
|
-
if (typeof item.attributes === "string") {
|
|
2570
|
-
if (item.attributes === "[object Object]") {
|
|
2571
|
-
attributes2 = void 0;
|
|
2572
|
-
} else {
|
|
2573
|
-
try {
|
|
2574
|
-
attributes2 = JSON.parse(item.attributes);
|
|
2575
|
-
} catch {
|
|
2576
|
-
attributes2 = void 0;
|
|
2577
|
-
}
|
|
2578
|
-
}
|
|
2579
|
-
} else if (typeof item.attributes === "object") {
|
|
2580
|
-
attributes2 = item.attributes;
|
|
2581
|
-
}
|
|
2582
|
-
}
|
|
2583
|
-
let status;
|
|
2584
|
-
if (item.status) {
|
|
2585
|
-
if (typeof item.status === "string") {
|
|
2586
|
-
try {
|
|
2587
|
-
status = JSON.parse(item.status);
|
|
2588
|
-
} catch {
|
|
2589
|
-
status = void 0;
|
|
2590
|
-
}
|
|
2591
|
-
} else if (typeof item.status === "object") {
|
|
2592
|
-
status = item.status;
|
|
2593
|
-
}
|
|
2594
|
-
}
|
|
2595
|
-
let events;
|
|
2596
|
-
if (item.events) {
|
|
2597
|
-
if (typeof item.events === "string") {
|
|
2598
|
-
try {
|
|
2599
|
-
events = JSON.parse(item.events);
|
|
2600
|
-
} catch {
|
|
2601
|
-
events = void 0;
|
|
2602
|
-
}
|
|
2603
|
-
} else if (Array.isArray(item.events)) {
|
|
2604
|
-
events = item.events;
|
|
2605
|
-
}
|
|
2606
|
-
}
|
|
2607
|
-
let links;
|
|
2608
|
-
if (item.links) {
|
|
2609
|
-
if (typeof item.links === "string") {
|
|
2610
|
-
try {
|
|
2611
|
-
links = JSON.parse(item.links);
|
|
2612
|
-
} catch {
|
|
2613
|
-
links = void 0;
|
|
2614
|
-
}
|
|
2615
|
-
} else if (Array.isArray(item.links)) {
|
|
2616
|
-
links = item.links;
|
|
2617
|
-
}
|
|
2618
|
-
}
|
|
2619
|
-
return {
|
|
2620
|
-
id: item.id,
|
|
2621
|
-
parentSpanId: item.parentSpanId,
|
|
2622
|
-
name: item.name,
|
|
2623
|
-
traceId: item.traceId,
|
|
2624
|
-
scope: item.scope,
|
|
2625
|
-
kind: item.kind,
|
|
2626
|
-
attributes: attributes2,
|
|
2627
|
-
status,
|
|
2628
|
-
events,
|
|
2629
|
-
links,
|
|
2630
|
-
other: item.other,
|
|
2631
|
-
startTime: item.startTime,
|
|
2632
|
-
endTime: item.endTime,
|
|
2633
|
-
createdAt: item.createdAt
|
|
2634
|
-
};
|
|
2635
|
-
});
|
|
2636
|
-
return {
|
|
2637
|
-
traces,
|
|
2638
|
-
total,
|
|
2639
|
-
page,
|
|
2640
|
-
perPage,
|
|
2641
|
-
hasMore: end < total
|
|
2642
|
-
};
|
|
2643
|
-
} catch (error$1) {
|
|
2644
|
-
throw new error.MastraError(
|
|
2645
|
-
{
|
|
2646
|
-
id: "STORAGE_DYNAMODB_STORE_GET_TRACES_PAGINATED_FAILED",
|
|
2647
|
-
domain: error.ErrorDomain.STORAGE,
|
|
2648
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
2649
|
-
},
|
|
2650
|
-
error$1
|
|
2651
|
-
);
|
|
2652
|
-
}
|
|
2653
|
-
}
|
|
2654
|
-
};
|
|
2655
2137
|
function formatWorkflowRun(snapshotData) {
|
|
2656
2138
|
return {
|
|
2657
2139
|
workflowName: snapshotData.workflow_name,
|
|
@@ -2662,54 +2144,228 @@ function formatWorkflowRun(snapshotData) {
|
|
|
2662
2144
|
resourceId: snapshotData.resourceId
|
|
2663
2145
|
};
|
|
2664
2146
|
}
|
|
2147
|
+
var MAX_RETRIES = 5;
|
|
2148
|
+
var BASE_DELAY_MS = 50;
|
|
2665
2149
|
var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
2666
2150
|
service;
|
|
2667
|
-
|
|
2151
|
+
ttlConfig;
|
|
2152
|
+
constructor(config) {
|
|
2668
2153
|
super();
|
|
2669
|
-
|
|
2154
|
+
const resolved = resolveDynamoDBConfig(config);
|
|
2155
|
+
this.service = resolved.service;
|
|
2156
|
+
this.ttlConfig = resolved.ttl;
|
|
2157
|
+
}
|
|
2158
|
+
supportsConcurrentUpdates() {
|
|
2159
|
+
return true;
|
|
2160
|
+
}
|
|
2161
|
+
async dangerouslyClearAll() {
|
|
2162
|
+
await deleteTableData(this.service, storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2163
|
+
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Helper to check if an error is a DynamoDB conditional check failure
|
|
2166
|
+
*/
|
|
2167
|
+
isConditionalCheckFailed(error) {
|
|
2168
|
+
if (error && typeof error === "object") {
|
|
2169
|
+
const err = error;
|
|
2170
|
+
if (err.name === "ConditionalCheckFailedException" || err.code === "ConditionalCheckFailedException" || (err.__type?.includes("ConditionalCheckFailedException") ?? false)) {
|
|
2171
|
+
return true;
|
|
2172
|
+
}
|
|
2173
|
+
if (err.message?.includes("conditional request failed")) {
|
|
2174
|
+
return true;
|
|
2175
|
+
}
|
|
2176
|
+
if (err.cause && typeof err.cause === "object") {
|
|
2177
|
+
const cause = err.cause;
|
|
2178
|
+
if (cause.name === "ConditionalCheckFailedException" || cause.code === "ConditionalCheckFailedException") {
|
|
2179
|
+
return true;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
return false;
|
|
2184
|
+
}
|
|
2185
|
+
/**
|
|
2186
|
+
* Helper to delay with exponential backoff and jitter
|
|
2187
|
+
*/
|
|
2188
|
+
async delay(attempt) {
|
|
2189
|
+
const backoff = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
2190
|
+
const jitter = Math.random() * backoff * 0.5;
|
|
2191
|
+
await new Promise((resolve) => setTimeout(resolve, backoff + jitter));
|
|
2670
2192
|
}
|
|
2671
|
-
updateWorkflowResults({
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2193
|
+
async updateWorkflowResults({
|
|
2194
|
+
workflowName,
|
|
2195
|
+
runId,
|
|
2196
|
+
stepId,
|
|
2197
|
+
result,
|
|
2198
|
+
requestContext
|
|
2677
2199
|
}) {
|
|
2678
|
-
|
|
2200
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
2201
|
+
try {
|
|
2202
|
+
const existingRecord = await this.service.entities.workflow_snapshot.get({
|
|
2203
|
+
entity: "workflow_snapshot",
|
|
2204
|
+
workflow_name: workflowName,
|
|
2205
|
+
run_id: runId
|
|
2206
|
+
}).go();
|
|
2207
|
+
const now = /* @__PURE__ */ new Date();
|
|
2208
|
+
let snapshot;
|
|
2209
|
+
let previousUpdatedAt;
|
|
2210
|
+
if (!existingRecord.data) {
|
|
2211
|
+
snapshot = {
|
|
2212
|
+
context: {},
|
|
2213
|
+
activePaths: [],
|
|
2214
|
+
timestamp: Date.now(),
|
|
2215
|
+
suspendedPaths: {},
|
|
2216
|
+
activeStepsPath: {},
|
|
2217
|
+
resumeLabels: {},
|
|
2218
|
+
serializedStepGraph: [],
|
|
2219
|
+
status: "pending",
|
|
2220
|
+
value: {},
|
|
2221
|
+
waitingPaths: {},
|
|
2222
|
+
runId,
|
|
2223
|
+
requestContext: {}
|
|
2224
|
+
};
|
|
2225
|
+
} else {
|
|
2226
|
+
snapshot = existingRecord.data.snapshot;
|
|
2227
|
+
previousUpdatedAt = existingRecord.data.updatedAt;
|
|
2228
|
+
}
|
|
2229
|
+
snapshot.context[stepId] = result;
|
|
2230
|
+
snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
|
|
2231
|
+
const data = {
|
|
2232
|
+
entity: "workflow_snapshot",
|
|
2233
|
+
workflow_name: workflowName,
|
|
2234
|
+
run_id: runId,
|
|
2235
|
+
snapshot: JSON.stringify(snapshot),
|
|
2236
|
+
createdAt: existingRecord.data?.createdAt ?? now.toISOString(),
|
|
2237
|
+
updatedAt: now.toISOString(),
|
|
2238
|
+
...getTtlProps("workflow_snapshot", this.ttlConfig)
|
|
2239
|
+
};
|
|
2240
|
+
if (previousUpdatedAt) {
|
|
2241
|
+
await this.service.entities.workflow_snapshot.upsert(data).where((attr, op) => op.eq(attr.updatedAt, previousUpdatedAt)).go();
|
|
2242
|
+
} else {
|
|
2243
|
+
await this.service.entities.workflow_snapshot.create(data).where((attr, op) => op.notExists(attr.run_id)).go();
|
|
2244
|
+
}
|
|
2245
|
+
return snapshot.context;
|
|
2246
|
+
} catch (error$1) {
|
|
2247
|
+
if (this.isConditionalCheckFailed(error$1)) {
|
|
2248
|
+
if (attempt < MAX_RETRIES - 1) {
|
|
2249
|
+
this.logger.debug(
|
|
2250
|
+
`Optimistic locking conflict in updateWorkflowResults, retrying (attempt ${attempt + 1})`
|
|
2251
|
+
);
|
|
2252
|
+
await this.delay(attempt);
|
|
2253
|
+
continue;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
if (error$1 instanceof error.MastraError) throw error$1;
|
|
2257
|
+
throw new error.MastraError(
|
|
2258
|
+
{
|
|
2259
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
|
|
2260
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2261
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2262
|
+
details: { workflowName, runId, stepId }
|
|
2263
|
+
},
|
|
2264
|
+
error$1
|
|
2265
|
+
);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
throw new error.MastraError(
|
|
2269
|
+
{
|
|
2270
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_RESULTS", "MAX_RETRIES_EXCEEDED"),
|
|
2271
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2272
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2273
|
+
details: { workflowName, runId, stepId }
|
|
2274
|
+
},
|
|
2275
|
+
new Error("Max retries exceeded for optimistic locking")
|
|
2276
|
+
);
|
|
2679
2277
|
}
|
|
2680
|
-
updateWorkflowState({
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2278
|
+
async updateWorkflowState({
|
|
2279
|
+
workflowName,
|
|
2280
|
+
runId,
|
|
2281
|
+
opts
|
|
2684
2282
|
}) {
|
|
2685
|
-
|
|
2283
|
+
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
2284
|
+
try {
|
|
2285
|
+
const existingRecord = await this.service.entities.workflow_snapshot.get({
|
|
2286
|
+
entity: "workflow_snapshot",
|
|
2287
|
+
workflow_name: workflowName,
|
|
2288
|
+
run_id: runId
|
|
2289
|
+
}).go();
|
|
2290
|
+
if (!existingRecord.data) {
|
|
2291
|
+
return void 0;
|
|
2292
|
+
}
|
|
2293
|
+
const existingSnapshot = existingRecord.data.snapshot;
|
|
2294
|
+
if (!existingSnapshot || !existingSnapshot.context) {
|
|
2295
|
+
return void 0;
|
|
2296
|
+
}
|
|
2297
|
+
const previousUpdatedAt = existingRecord.data.updatedAt;
|
|
2298
|
+
const updatedSnapshot = { ...existingSnapshot, ...opts };
|
|
2299
|
+
const now = /* @__PURE__ */ new Date();
|
|
2300
|
+
const data = {
|
|
2301
|
+
entity: "workflow_snapshot",
|
|
2302
|
+
workflow_name: workflowName,
|
|
2303
|
+
run_id: runId,
|
|
2304
|
+
snapshot: JSON.stringify(updatedSnapshot),
|
|
2305
|
+
createdAt: existingRecord.data.createdAt,
|
|
2306
|
+
updatedAt: now.toISOString(),
|
|
2307
|
+
resourceId: existingRecord.data.resourceId,
|
|
2308
|
+
...getTtlProps("workflow_snapshot", this.ttlConfig)
|
|
2309
|
+
};
|
|
2310
|
+
await this.service.entities.workflow_snapshot.upsert(data).where((attr, op) => op.eq(attr.updatedAt, previousUpdatedAt)).go();
|
|
2311
|
+
return updatedSnapshot;
|
|
2312
|
+
} catch (error$1) {
|
|
2313
|
+
if (this.isConditionalCheckFailed(error$1)) {
|
|
2314
|
+
if (attempt < MAX_RETRIES - 1) {
|
|
2315
|
+
this.logger.debug(`Optimistic locking conflict in updateWorkflowState, retrying (attempt ${attempt + 1})`);
|
|
2316
|
+
await this.delay(attempt);
|
|
2317
|
+
continue;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
if (error$1 instanceof error.MastraError) throw error$1;
|
|
2321
|
+
throw new error.MastraError(
|
|
2322
|
+
{
|
|
2323
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "FAILED"),
|
|
2324
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2325
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2326
|
+
details: { workflowName, runId }
|
|
2327
|
+
},
|
|
2328
|
+
error$1
|
|
2329
|
+
);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2332
|
+
throw new error.MastraError(
|
|
2333
|
+
{
|
|
2334
|
+
id: storage.createStorageErrorId("DYNAMODB", "UPDATE_WORKFLOW_STATE", "MAX_RETRIES_EXCEEDED"),
|
|
2335
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2336
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2337
|
+
details: { workflowName, runId }
|
|
2338
|
+
},
|
|
2339
|
+
new Error("Max retries exceeded for optimistic locking")
|
|
2340
|
+
);
|
|
2686
2341
|
}
|
|
2687
2342
|
// Workflow operations
|
|
2688
2343
|
async persistWorkflowSnapshot({
|
|
2689
2344
|
workflowName,
|
|
2690
2345
|
runId,
|
|
2691
2346
|
resourceId,
|
|
2692
|
-
snapshot
|
|
2347
|
+
snapshot,
|
|
2348
|
+
createdAt,
|
|
2349
|
+
updatedAt
|
|
2693
2350
|
}) {
|
|
2694
2351
|
this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
|
|
2695
2352
|
try {
|
|
2696
|
-
const now =
|
|
2353
|
+
const now = /* @__PURE__ */ new Date();
|
|
2697
2354
|
const data = {
|
|
2698
2355
|
entity: "workflow_snapshot",
|
|
2699
|
-
// Add entity type
|
|
2700
2356
|
workflow_name: workflowName,
|
|
2701
2357
|
run_id: runId,
|
|
2702
2358
|
snapshot: JSON.stringify(snapshot),
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2359
|
+
createdAt: (createdAt ?? now).toISOString(),
|
|
2360
|
+
updatedAt: (updatedAt ?? now).toISOString(),
|
|
2361
|
+
resourceId,
|
|
2362
|
+
...getTtlProps("workflow_snapshot", this.ttlConfig)
|
|
2707
2363
|
};
|
|
2708
2364
|
await this.service.entities.workflow_snapshot.upsert(data).go();
|
|
2709
2365
|
} catch (error$1) {
|
|
2710
2366
|
throw new error.MastraError(
|
|
2711
2367
|
{
|
|
2712
|
-
id: "
|
|
2368
|
+
id: storage.createStorageErrorId("DYNAMODB", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
|
|
2713
2369
|
domain: error.ErrorDomain.STORAGE,
|
|
2714
2370
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2715
2371
|
details: { workflowName, runId }
|
|
@@ -2737,7 +2393,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2737
2393
|
} catch (error$1) {
|
|
2738
2394
|
throw new error.MastraError(
|
|
2739
2395
|
{
|
|
2740
|
-
id: "
|
|
2396
|
+
id: storage.createStorageErrorId("DYNAMODB", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
|
|
2741
2397
|
domain: error.ErrorDomain.STORAGE,
|
|
2742
2398
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2743
2399
|
details: { workflowName, runId }
|
|
@@ -2746,11 +2402,24 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2746
2402
|
);
|
|
2747
2403
|
}
|
|
2748
2404
|
}
|
|
2749
|
-
async
|
|
2405
|
+
async listWorkflowRuns(args) {
|
|
2750
2406
|
this.logger.debug("Getting workflow runs", { args });
|
|
2751
2407
|
try {
|
|
2752
|
-
const
|
|
2753
|
-
const
|
|
2408
|
+
const perPage = args?.perPage !== void 0 ? args.perPage : 10;
|
|
2409
|
+
const page = args?.page !== void 0 ? args.page : 0;
|
|
2410
|
+
if (page < 0) {
|
|
2411
|
+
throw new error.MastraError(
|
|
2412
|
+
{
|
|
2413
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "INVALID_PAGE"),
|
|
2414
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2415
|
+
category: error.ErrorCategory.USER,
|
|
2416
|
+
details: { page }
|
|
2417
|
+
},
|
|
2418
|
+
new Error("page must be >= 0")
|
|
2419
|
+
);
|
|
2420
|
+
}
|
|
2421
|
+
const normalizedPerPage = storage.normalizePerPage(perPage, 10);
|
|
2422
|
+
const offset = page * normalizedPerPage;
|
|
2754
2423
|
let query;
|
|
2755
2424
|
if (args?.workflowName) {
|
|
2756
2425
|
query = this.service.entities.workflow_snapshot.query.primary({
|
|
@@ -2772,6 +2441,11 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2772
2441
|
});
|
|
2773
2442
|
if (pageResults.data && pageResults.data.length > 0) {
|
|
2774
2443
|
let pageFilteredData = pageResults.data;
|
|
2444
|
+
if (args?.status) {
|
|
2445
|
+
pageFilteredData = pageFilteredData.filter((snapshot) => {
|
|
2446
|
+
return snapshot.snapshot.status === args.status;
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2775
2449
|
if (args?.fromDate || args?.toDate) {
|
|
2776
2450
|
pageFilteredData = pageFilteredData.filter((snapshot) => {
|
|
2777
2451
|
const createdAt = new Date(snapshot.createdAt);
|
|
@@ -2797,7 +2471,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2797
2471
|
return { runs: [], total: 0 };
|
|
2798
2472
|
}
|
|
2799
2473
|
const total = allMatchingSnapshots.length;
|
|
2800
|
-
const paginatedData = allMatchingSnapshots.slice(offset, offset +
|
|
2474
|
+
const paginatedData = allMatchingSnapshots.slice(offset, offset + normalizedPerPage);
|
|
2801
2475
|
const runs = paginatedData.map((snapshot) => formatWorkflowRun(snapshot));
|
|
2802
2476
|
return {
|
|
2803
2477
|
runs,
|
|
@@ -2806,7 +2480,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2806
2480
|
} catch (error$1) {
|
|
2807
2481
|
throw new error.MastraError(
|
|
2808
2482
|
{
|
|
2809
|
-
id: "
|
|
2483
|
+
id: storage.createStorageErrorId("DYNAMODB", "LIST_WORKFLOW_RUNS", "FAILED"),
|
|
2810
2484
|
domain: error.ErrorDomain.STORAGE,
|
|
2811
2485
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2812
2486
|
details: { workflowName: args?.workflowName || "", resourceId: args?.resourceId || "" }
|
|
@@ -2860,7 +2534,7 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2860
2534
|
} catch (error$1) {
|
|
2861
2535
|
throw new error.MastraError(
|
|
2862
2536
|
{
|
|
2863
|
-
id: "
|
|
2537
|
+
id: storage.createStorageErrorId("DYNAMODB", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
|
|
2864
2538
|
domain: error.ErrorDomain.STORAGE,
|
|
2865
2539
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2866
2540
|
details: { runId, workflowName: args?.workflowName || "" }
|
|
@@ -2869,17 +2543,41 @@ var WorkflowStorageDynamoDB = class extends storage.WorkflowsStorage {
|
|
|
2869
2543
|
);
|
|
2870
2544
|
}
|
|
2871
2545
|
}
|
|
2546
|
+
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
2547
|
+
this.logger.debug("Deleting workflow run by ID", { runId, workflowName });
|
|
2548
|
+
try {
|
|
2549
|
+
await this.service.entities.workflow_snapshot.delete({
|
|
2550
|
+
entity: "workflow_snapshot",
|
|
2551
|
+
workflow_name: workflowName,
|
|
2552
|
+
run_id: runId
|
|
2553
|
+
}).go();
|
|
2554
|
+
} catch (error$1) {
|
|
2555
|
+
throw new error.MastraError(
|
|
2556
|
+
{
|
|
2557
|
+
id: storage.createStorageErrorId("DYNAMODB", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
|
|
2558
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2559
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2560
|
+
details: { runId, workflowName }
|
|
2561
|
+
},
|
|
2562
|
+
error$1
|
|
2563
|
+
);
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2872
2566
|
};
|
|
2873
2567
|
|
|
2874
2568
|
// src/storage/index.ts
|
|
2875
|
-
var
|
|
2569
|
+
var isClientConfig = (config) => {
|
|
2570
|
+
return "client" in config;
|
|
2571
|
+
};
|
|
2572
|
+
var DynamoDBStore = class extends storage.MastraCompositeStore {
|
|
2876
2573
|
tableName;
|
|
2877
2574
|
client;
|
|
2878
2575
|
service;
|
|
2576
|
+
ttlConfig;
|
|
2879
2577
|
hasInitialized = null;
|
|
2880
2578
|
stores;
|
|
2881
2579
|
constructor({ name, config }) {
|
|
2882
|
-
super({ name });
|
|
2580
|
+
super({ id: config.id, name, disableInit: config.disableInit });
|
|
2883
2581
|
try {
|
|
2884
2582
|
if (!config.tableName || typeof config.tableName !== "string" || config.tableName.trim() === "") {
|
|
2885
2583
|
throw new Error("DynamoDBStore: config.tableName must be provided and cannot be empty.");
|
|
@@ -2889,27 +2587,24 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2889
2587
|
`DynamoDBStore: config.tableName "${config.tableName}" contains invalid characters or is not between 3 and 255 characters long.`
|
|
2890
2588
|
);
|
|
2891
2589
|
}
|
|
2892
|
-
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
2893
|
-
region: config.region || "us-east-1",
|
|
2894
|
-
endpoint: config.endpoint,
|
|
2895
|
-
credentials: config.credentials
|
|
2896
|
-
});
|
|
2897
2590
|
this.tableName = config.tableName;
|
|
2898
|
-
this.
|
|
2591
|
+
this.ttlConfig = config.ttl;
|
|
2592
|
+
if (isClientConfig(config)) {
|
|
2593
|
+
this.client = config.client;
|
|
2594
|
+
} else {
|
|
2595
|
+
const dynamoClient = new clientDynamodb.DynamoDBClient({
|
|
2596
|
+
region: config.region || "us-east-1",
|
|
2597
|
+
endpoint: config.endpoint,
|
|
2598
|
+
credentials: config.credentials
|
|
2599
|
+
});
|
|
2600
|
+
this.client = libDynamodb.DynamoDBDocumentClient.from(dynamoClient);
|
|
2601
|
+
}
|
|
2899
2602
|
this.service = getElectroDbService(this.client, this.tableName);
|
|
2900
|
-
const
|
|
2901
|
-
|
|
2902
|
-
|
|
2903
|
-
|
|
2904
|
-
});
|
|
2905
|
-
const traces = new TracesStorageDynamoDB({ service: this.service, operations });
|
|
2906
|
-
const workflows = new WorkflowStorageDynamoDB({ service: this.service });
|
|
2907
|
-
const memory = new MemoryStorageDynamoDB({ service: this.service });
|
|
2908
|
-
const scores = new ScoresStorageDynamoDB({ service: this.service });
|
|
2603
|
+
const domainConfig = { service: this.service, ttl: this.ttlConfig };
|
|
2604
|
+
const workflows = new WorkflowStorageDynamoDB(domainConfig);
|
|
2605
|
+
const memory = new MemoryStorageDynamoDB(domainConfig);
|
|
2606
|
+
const scores = new ScoresStorageDynamoDB(domainConfig);
|
|
2909
2607
|
this.stores = {
|
|
2910
|
-
operations,
|
|
2911
|
-
legacyEvals: new LegacyEvalsDynamoDB({ service: this.service, tableName: this.tableName }),
|
|
2912
|
-
traces,
|
|
2913
2608
|
workflows,
|
|
2914
2609
|
memory,
|
|
2915
2610
|
scores
|
|
@@ -2917,7 +2612,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2917
2612
|
} catch (error$1) {
|
|
2918
2613
|
throw new error.MastraError(
|
|
2919
2614
|
{
|
|
2920
|
-
id: "
|
|
2615
|
+
id: storage.createStorageErrorId("DYNAMODB", "CONSTRUCTOR", "FAILED"),
|
|
2921
2616
|
domain: error.ErrorDomain.STORAGE,
|
|
2922
2617
|
category: error.ErrorCategory.USER
|
|
2923
2618
|
},
|
|
@@ -2925,16 +2620,6 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2925
2620
|
);
|
|
2926
2621
|
}
|
|
2927
2622
|
}
|
|
2928
|
-
get supports() {
|
|
2929
|
-
return {
|
|
2930
|
-
selectByIncludeResourceScope: true,
|
|
2931
|
-
resourceWorkingMemory: true,
|
|
2932
|
-
hasColumn: false,
|
|
2933
|
-
createTable: false,
|
|
2934
|
-
deleteMessages: false,
|
|
2935
|
-
getScoresBySpan: true
|
|
2936
|
-
};
|
|
2937
|
-
}
|
|
2938
2623
|
/**
|
|
2939
2624
|
* Validates that the required DynamoDB table exists and is accessible.
|
|
2940
2625
|
* This does not check the table structure - it assumes the table
|
|
@@ -2953,7 +2638,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2953
2638
|
}
|
|
2954
2639
|
throw new error.MastraError(
|
|
2955
2640
|
{
|
|
2956
|
-
id: "
|
|
2641
|
+
id: storage.createStorageErrorId("DYNAMODB", "VALIDATE_TABLE_EXISTS", "FAILED"),
|
|
2957
2642
|
domain: error.ErrorDomain.STORAGE,
|
|
2958
2643
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2959
2644
|
details: { tableName: this.tableName }
|
|
@@ -2976,7 +2661,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
2976
2661
|
} catch (error$1) {
|
|
2977
2662
|
throw new error.MastraError(
|
|
2978
2663
|
{
|
|
2979
|
-
id: "
|
|
2664
|
+
id: storage.createStorageErrorId("DYNAMODB", "INIT", "FAILED"),
|
|
2980
2665
|
domain: error.ErrorDomain.STORAGE,
|
|
2981
2666
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
2982
2667
|
details: { tableName: this.tableName }
|
|
@@ -3002,143 +2687,10 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
3002
2687
|
throw err;
|
|
3003
2688
|
});
|
|
3004
2689
|
}
|
|
3005
|
-
async createTable({ tableName, schema }) {
|
|
3006
|
-
return this.stores.operations.createTable({ tableName, schema });
|
|
3007
|
-
}
|
|
3008
|
-
async alterTable(_args) {
|
|
3009
|
-
return this.stores.operations.alterTable(_args);
|
|
3010
|
-
}
|
|
3011
|
-
async clearTable({ tableName }) {
|
|
3012
|
-
return this.stores.operations.clearTable({ tableName });
|
|
3013
|
-
}
|
|
3014
|
-
async dropTable({ tableName }) {
|
|
3015
|
-
return this.stores.operations.dropTable({ tableName });
|
|
3016
|
-
}
|
|
3017
|
-
async insert({ tableName, record }) {
|
|
3018
|
-
return this.stores.operations.insert({ tableName, record });
|
|
3019
|
-
}
|
|
3020
|
-
async batchInsert({ tableName, records }) {
|
|
3021
|
-
return this.stores.operations.batchInsert({ tableName, records });
|
|
3022
|
-
}
|
|
3023
|
-
async load({ tableName, keys }) {
|
|
3024
|
-
return this.stores.operations.load({ tableName, keys });
|
|
3025
|
-
}
|
|
3026
|
-
// Thread operations
|
|
3027
|
-
async getThreadById({ threadId }) {
|
|
3028
|
-
return this.stores.memory.getThreadById({ threadId });
|
|
3029
|
-
}
|
|
3030
|
-
async getThreadsByResourceId(args) {
|
|
3031
|
-
return this.stores.memory.getThreadsByResourceId(args);
|
|
3032
|
-
}
|
|
3033
|
-
async saveThread({ thread }) {
|
|
3034
|
-
return this.stores.memory.saveThread({ thread });
|
|
3035
|
-
}
|
|
3036
|
-
async updateThread({
|
|
3037
|
-
id,
|
|
3038
|
-
title,
|
|
3039
|
-
metadata
|
|
3040
|
-
}) {
|
|
3041
|
-
return this.stores.memory.updateThread({ id, title, metadata });
|
|
3042
|
-
}
|
|
3043
|
-
async deleteThread({ threadId }) {
|
|
3044
|
-
return this.stores.memory.deleteThread({ threadId });
|
|
3045
|
-
}
|
|
3046
|
-
async getMessages({
|
|
3047
|
-
threadId,
|
|
3048
|
-
resourceId,
|
|
3049
|
-
selectBy,
|
|
3050
|
-
format
|
|
3051
|
-
}) {
|
|
3052
|
-
return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
|
|
3053
|
-
}
|
|
3054
|
-
async getMessagesById({
|
|
3055
|
-
messageIds,
|
|
3056
|
-
format
|
|
3057
|
-
}) {
|
|
3058
|
-
return this.stores.memory.getMessagesById({ messageIds, format });
|
|
3059
|
-
}
|
|
3060
|
-
async saveMessages(args) {
|
|
3061
|
-
return this.stores.memory.saveMessages(args);
|
|
3062
|
-
}
|
|
3063
|
-
async getThreadsByResourceIdPaginated(args) {
|
|
3064
|
-
return this.stores.memory.getThreadsByResourceIdPaginated(args);
|
|
3065
|
-
}
|
|
3066
|
-
async getMessagesPaginated(args) {
|
|
3067
|
-
return this.stores.memory.getMessagesPaginated(args);
|
|
3068
|
-
}
|
|
3069
|
-
async updateMessages(_args) {
|
|
3070
|
-
return this.stores.memory.updateMessages(_args);
|
|
3071
|
-
}
|
|
3072
|
-
// Trace operations
|
|
3073
|
-
async getTraces(args) {
|
|
3074
|
-
return this.stores.traces.getTraces(args);
|
|
3075
|
-
}
|
|
3076
|
-
async batchTraceInsert({ records }) {
|
|
3077
|
-
return this.stores.traces.batchTraceInsert({ records });
|
|
3078
|
-
}
|
|
3079
|
-
async getTracesPaginated(_args) {
|
|
3080
|
-
return this.stores.traces.getTracesPaginated(_args);
|
|
3081
|
-
}
|
|
3082
|
-
// Workflow operations
|
|
3083
|
-
async updateWorkflowResults({
|
|
3084
|
-
workflowName,
|
|
3085
|
-
runId,
|
|
3086
|
-
stepId,
|
|
3087
|
-
result,
|
|
3088
|
-
runtimeContext
|
|
3089
|
-
}) {
|
|
3090
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
|
|
3091
|
-
}
|
|
3092
|
-
async updateWorkflowState({
|
|
3093
|
-
workflowName,
|
|
3094
|
-
runId,
|
|
3095
|
-
opts
|
|
3096
|
-
}) {
|
|
3097
|
-
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
3098
|
-
}
|
|
3099
|
-
async persistWorkflowSnapshot({
|
|
3100
|
-
workflowName,
|
|
3101
|
-
runId,
|
|
3102
|
-
resourceId,
|
|
3103
|
-
snapshot
|
|
3104
|
-
}) {
|
|
3105
|
-
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
3106
|
-
}
|
|
3107
|
-
async loadWorkflowSnapshot({
|
|
3108
|
-
workflowName,
|
|
3109
|
-
runId
|
|
3110
|
-
}) {
|
|
3111
|
-
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
3112
|
-
}
|
|
3113
|
-
async getWorkflowRuns(args) {
|
|
3114
|
-
return this.stores.workflows.getWorkflowRuns(args);
|
|
3115
|
-
}
|
|
3116
|
-
async getWorkflowRunById(args) {
|
|
3117
|
-
return this.stores.workflows.getWorkflowRunById(args);
|
|
3118
|
-
}
|
|
3119
|
-
async getResourceById({ resourceId }) {
|
|
3120
|
-
return this.stores.memory.getResourceById({ resourceId });
|
|
3121
|
-
}
|
|
3122
|
-
async saveResource({ resource }) {
|
|
3123
|
-
return this.stores.memory.saveResource({ resource });
|
|
3124
|
-
}
|
|
3125
|
-
async updateResource({
|
|
3126
|
-
resourceId,
|
|
3127
|
-
workingMemory,
|
|
3128
|
-
metadata
|
|
3129
|
-
}) {
|
|
3130
|
-
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
3131
|
-
}
|
|
3132
|
-
// Eval operations
|
|
3133
|
-
async getEvalsByAgentName(agentName, type) {
|
|
3134
|
-
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
3135
|
-
}
|
|
3136
|
-
async getEvals(options) {
|
|
3137
|
-
return this.stores.legacyEvals.getEvals(options);
|
|
3138
|
-
}
|
|
3139
2690
|
/**
|
|
3140
2691
|
* Closes the DynamoDB client connection and cleans up resources.
|
|
3141
|
-
*
|
|
2692
|
+
*
|
|
2693
|
+
* This will close the DynamoDB client, including pre-configured clients.
|
|
3142
2694
|
*/
|
|
3143
2695
|
async close() {
|
|
3144
2696
|
this.logger.debug("Closing DynamoDB client for store:", { name: this.name });
|
|
@@ -3148,7 +2700,7 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
3148
2700
|
} catch (error$1) {
|
|
3149
2701
|
throw new error.MastraError(
|
|
3150
2702
|
{
|
|
3151
|
-
id: "
|
|
2703
|
+
id: storage.createStorageErrorId("DYNAMODB", "CLOSE", "FAILED"),
|
|
3152
2704
|
domain: error.ErrorDomain.STORAGE,
|
|
3153
2705
|
category: error.ErrorCategory.THIRD_PARTY
|
|
3154
2706
|
},
|
|
@@ -3156,50 +2708,15 @@ var DynamoDBStore = class extends storage.MastraStorage {
|
|
|
3156
2708
|
);
|
|
3157
2709
|
}
|
|
3158
2710
|
}
|
|
3159
|
-
/**
|
|
3160
|
-
* SCORERS - Not implemented
|
|
3161
|
-
*/
|
|
3162
|
-
async getScoreById({ id: _id }) {
|
|
3163
|
-
return this.stores.scores.getScoreById({ id: _id });
|
|
3164
|
-
}
|
|
3165
|
-
async saveScore(_score) {
|
|
3166
|
-
return this.stores.scores.saveScore(_score);
|
|
3167
|
-
}
|
|
3168
|
-
async getScoresByRunId({
|
|
3169
|
-
runId: _runId,
|
|
3170
|
-
pagination: _pagination
|
|
3171
|
-
}) {
|
|
3172
|
-
return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
|
|
3173
|
-
}
|
|
3174
|
-
async getScoresByEntityId({
|
|
3175
|
-
entityId: _entityId,
|
|
3176
|
-
entityType: _entityType,
|
|
3177
|
-
pagination: _pagination
|
|
3178
|
-
}) {
|
|
3179
|
-
return this.stores.scores.getScoresByEntityId({
|
|
3180
|
-
entityId: _entityId,
|
|
3181
|
-
entityType: _entityType,
|
|
3182
|
-
pagination: _pagination
|
|
3183
|
-
});
|
|
3184
|
-
}
|
|
3185
|
-
async getScoresByScorerId({
|
|
3186
|
-
scorerId,
|
|
3187
|
-
source,
|
|
3188
|
-
entityId,
|
|
3189
|
-
entityType,
|
|
3190
|
-
pagination
|
|
3191
|
-
}) {
|
|
3192
|
-
return this.stores.scores.getScoresByScorerId({ scorerId, source, entityId, entityType, pagination });
|
|
3193
|
-
}
|
|
3194
|
-
async getScoresBySpan({
|
|
3195
|
-
traceId,
|
|
3196
|
-
spanId,
|
|
3197
|
-
pagination
|
|
3198
|
-
}) {
|
|
3199
|
-
return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
|
|
3200
|
-
}
|
|
3201
2711
|
};
|
|
3202
2712
|
|
|
3203
2713
|
exports.DynamoDBStore = DynamoDBStore;
|
|
2714
|
+
exports.MemoryStorageDynamoDB = MemoryStorageDynamoDB;
|
|
2715
|
+
exports.ScoresStorageDynamoDB = ScoresStorageDynamoDB;
|
|
2716
|
+
exports.WorkflowStorageDynamoDB = WorkflowStorageDynamoDB;
|
|
2717
|
+
exports.calculateTtl = calculateTtl;
|
|
2718
|
+
exports.getTtlAttributeName = getTtlAttributeName;
|
|
2719
|
+
exports.getTtlProps = getTtlProps;
|
|
2720
|
+
exports.isTtlEnabled = isTtlEnabled;
|
|
3204
2721
|
//# sourceMappingURL=index.cjs.map
|
|
3205
2722
|
//# sourceMappingURL=index.cjs.map
|