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