@mastra/pg 0.10.1 → 0.10.2-alpha.1
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +28 -0
- package/dist/_tsup-dts-rollup.d.cts +58 -5
- package/dist/_tsup-dts-rollup.d.ts +58 -5
- package/dist/index.cjs +319 -126
- package/dist/index.js +319 -126
- package/package.json +12 -11
- package/src/storage/index.test.ts +558 -120
- package/src/storage/index.ts +405 -160
package/dist/index.cjs
CHANGED
|
@@ -949,6 +949,7 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
949
949
|
const parsedSchemaName = this.schema ? utils.parseSqlIdentifier(this.schema, "schema name") : void 0;
|
|
950
950
|
return parsedSchemaName ? `${parsedSchemaName}."${parsedIndexName}"` : `"${parsedIndexName}"`;
|
|
951
951
|
}
|
|
952
|
+
/** @deprecated use getEvals instead */
|
|
952
953
|
async getEvalsByAgentName(agentName, type) {
|
|
953
954
|
try {
|
|
954
955
|
const baseQuery = `SELECT * FROM ${this.getTableName(storage.TABLE_EVALS)} WHERE agent_name = $1`;
|
|
@@ -999,76 +1000,77 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
999
1000
|
throw error;
|
|
1000
1001
|
}
|
|
1001
1002
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1003
|
+
/**
|
|
1004
|
+
* @deprecated use getTracesPaginated instead
|
|
1005
|
+
*/
|
|
1006
|
+
async getTraces(args) {
|
|
1007
|
+
if (args.fromDate || args.toDate) {
|
|
1008
|
+
args.dateRange = {
|
|
1009
|
+
start: args.fromDate,
|
|
1010
|
+
end: args.toDate
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
const result = await this.getTracesPaginated(args);
|
|
1014
|
+
return result.traces;
|
|
1015
|
+
}
|
|
1016
|
+
async getTracesPaginated(args) {
|
|
1017
|
+
const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
|
|
1018
|
+
const fromDate = dateRange?.start;
|
|
1019
|
+
const toDate = dateRange?.end;
|
|
1020
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 100;
|
|
1021
|
+
const currentOffset = page * perPage;
|
|
1022
|
+
const queryParams = [];
|
|
1016
1023
|
const conditions = [];
|
|
1024
|
+
let paramIndex = 1;
|
|
1017
1025
|
if (name) {
|
|
1018
|
-
conditions.push(`name LIKE
|
|
1026
|
+
conditions.push(`name LIKE $${paramIndex++}`);
|
|
1027
|
+
queryParams.push(`${name}%`);
|
|
1019
1028
|
}
|
|
1020
1029
|
if (scope) {
|
|
1021
|
-
conditions.push(`scope = $${
|
|
1030
|
+
conditions.push(`scope = $${paramIndex++}`);
|
|
1031
|
+
queryParams.push(scope);
|
|
1022
1032
|
}
|
|
1023
1033
|
if (attributes) {
|
|
1024
|
-
Object.
|
|
1034
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
1025
1035
|
const parsedKey = utils.parseSqlIdentifier(key, "attribute key");
|
|
1026
|
-
conditions.push(`attributes->>'${parsedKey}' = $${
|
|
1036
|
+
conditions.push(`attributes->>'${parsedKey}' = $${paramIndex++}`);
|
|
1037
|
+
queryParams.push(value);
|
|
1027
1038
|
});
|
|
1028
1039
|
}
|
|
1029
1040
|
if (filters) {
|
|
1030
|
-
Object.entries(filters).forEach(([key]) => {
|
|
1041
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
1031
1042
|
const parsedKey = utils.parseSqlIdentifier(key, "filter key");
|
|
1032
|
-
conditions.push(
|
|
1043
|
+
conditions.push(`"${parsedKey}" = $${paramIndex++}`);
|
|
1044
|
+
queryParams.push(value);
|
|
1033
1045
|
});
|
|
1034
1046
|
}
|
|
1035
1047
|
if (fromDate) {
|
|
1036
|
-
conditions.push(`createdAt >= $${
|
|
1048
|
+
conditions.push(`"createdAt" >= $${paramIndex++}`);
|
|
1049
|
+
queryParams.push(fromDate);
|
|
1037
1050
|
}
|
|
1038
1051
|
if (toDate) {
|
|
1039
|
-
conditions.push(`createdAt <= $${
|
|
1052
|
+
conditions.push(`"createdAt" <= $${paramIndex++}`);
|
|
1053
|
+
queryParams.push(toDate);
|
|
1040
1054
|
}
|
|
1041
1055
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (filters) {
|
|
1054
|
-
for (const [, value] of Object.entries(filters)) {
|
|
1055
|
-
args.push(value);
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
if (fromDate) {
|
|
1059
|
-
args.push(fromDate.toISOString());
|
|
1060
|
-
}
|
|
1061
|
-
if (toDate) {
|
|
1062
|
-
args.push(toDate.toISOString());
|
|
1063
|
-
}
|
|
1064
|
-
const result = await this.db.manyOrNone(
|
|
1065
|
-
`SELECT * FROM ${this.getTableName(storage.TABLE_TRACES)} ${whereClause} ORDER BY "createdAt" DESC LIMIT ${limit} OFFSET ${offset}`,
|
|
1066
|
-
args
|
|
1067
|
-
);
|
|
1068
|
-
if (!result) {
|
|
1069
|
-
return [];
|
|
1056
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(storage.TABLE_TRACES)} ${whereClause}`;
|
|
1057
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1058
|
+
const total = parseInt(countResult.count, 10);
|
|
1059
|
+
if (total === 0) {
|
|
1060
|
+
return {
|
|
1061
|
+
traces: [],
|
|
1062
|
+
total: 0,
|
|
1063
|
+
page,
|
|
1064
|
+
perPage,
|
|
1065
|
+
hasMore: false
|
|
1066
|
+
};
|
|
1070
1067
|
}
|
|
1071
|
-
|
|
1068
|
+
const dataQuery = `SELECT * FROM ${this.getTableName(
|
|
1069
|
+
storage.TABLE_TRACES
|
|
1070
|
+
)} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1071
|
+
const finalQueryParams = [...queryParams, perPage, currentOffset];
|
|
1072
|
+
const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
|
|
1073
|
+
const traces = rows.map((row) => ({
|
|
1072
1074
|
id: row.id,
|
|
1073
1075
|
parentSpanId: row.parentSpanId,
|
|
1074
1076
|
traceId: row.traceId,
|
|
@@ -1084,6 +1086,13 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1084
1086
|
other: row.other,
|
|
1085
1087
|
createdAt: row.createdAt
|
|
1086
1088
|
}));
|
|
1089
|
+
return {
|
|
1090
|
+
traces,
|
|
1091
|
+
total,
|
|
1092
|
+
page,
|
|
1093
|
+
perPage,
|
|
1094
|
+
hasMore: currentOffset + traces.length < total
|
|
1095
|
+
};
|
|
1087
1096
|
}
|
|
1088
1097
|
async setupSchema() {
|
|
1089
1098
|
if (!this.schema || this.schemaSetupComplete) {
|
|
@@ -1162,6 +1171,48 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1162
1171
|
throw error;
|
|
1163
1172
|
}
|
|
1164
1173
|
}
|
|
1174
|
+
getDefaultValue(type) {
|
|
1175
|
+
switch (type) {
|
|
1176
|
+
case "timestamp":
|
|
1177
|
+
return "DEFAULT NOW()";
|
|
1178
|
+
case "jsonb":
|
|
1179
|
+
return "DEFAULT '{}'::jsonb";
|
|
1180
|
+
default:
|
|
1181
|
+
return super.getDefaultValue(type);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
/**
|
|
1185
|
+
* Alters table schema to add columns if they don't exist
|
|
1186
|
+
* @param tableName Name of the table
|
|
1187
|
+
* @param schema Schema of the table
|
|
1188
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
1189
|
+
*/
|
|
1190
|
+
async alterTable({
|
|
1191
|
+
tableName,
|
|
1192
|
+
schema,
|
|
1193
|
+
ifNotExists
|
|
1194
|
+
}) {
|
|
1195
|
+
const fullTableName = this.getTableName(tableName);
|
|
1196
|
+
try {
|
|
1197
|
+
for (const columnName of ifNotExists) {
|
|
1198
|
+
if (schema[columnName]) {
|
|
1199
|
+
const columnDef = schema[columnName];
|
|
1200
|
+
const sqlType = this.getSqlType(columnDef.type);
|
|
1201
|
+
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
1202
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
1203
|
+
const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
|
|
1204
|
+
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
1205
|
+
await this.db.none(alterSql);
|
|
1206
|
+
this.logger?.debug?.(`Ensured column ${parsedColumnName} exists in table ${fullTableName}`);
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
} catch (error) {
|
|
1210
|
+
this.logger?.error?.(
|
|
1211
|
+
`Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
|
|
1212
|
+
);
|
|
1213
|
+
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1165
1216
|
async clearTable({ tableName }) {
|
|
1166
1217
|
try {
|
|
1167
1218
|
await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
|
|
@@ -1237,29 +1288,65 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1237
1288
|
throw error;
|
|
1238
1289
|
}
|
|
1239
1290
|
}
|
|
1240
|
-
|
|
1291
|
+
/**
|
|
1292
|
+
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
1293
|
+
*/
|
|
1294
|
+
async getThreadsByResourceId(args) {
|
|
1295
|
+
const { resourceId } = args;
|
|
1241
1296
|
try {
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
metadata,
|
|
1248
|
-
"createdAt",
|
|
1249
|
-
"updatedAt"
|
|
1250
|
-
FROM ${this.getTableName(storage.TABLE_THREADS)}
|
|
1251
|
-
WHERE "resourceId" = $1`,
|
|
1252
|
-
[resourceId]
|
|
1253
|
-
);
|
|
1254
|
-
return threads.map((thread) => ({
|
|
1297
|
+
const baseQuery = `FROM ${this.getTableName(storage.TABLE_THREADS)} WHERE "resourceId" = $1`;
|
|
1298
|
+
const queryParams = [resourceId];
|
|
1299
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC`;
|
|
1300
|
+
const rows = await this.db.manyOrNone(dataQuery, queryParams);
|
|
1301
|
+
return (rows || []).map((thread) => ({
|
|
1255
1302
|
...thread,
|
|
1256
1303
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1257
1304
|
createdAt: thread.createdAt,
|
|
1258
1305
|
updatedAt: thread.updatedAt
|
|
1259
1306
|
}));
|
|
1260
1307
|
} catch (error) {
|
|
1261
|
-
|
|
1262
|
-
|
|
1308
|
+
this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
|
|
1309
|
+
return [];
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
1313
|
+
const { resourceId, page = 0, perPage: perPageInput } = args;
|
|
1314
|
+
try {
|
|
1315
|
+
const baseQuery = `FROM ${this.getTableName(storage.TABLE_THREADS)} WHERE "resourceId" = $1`;
|
|
1316
|
+
const queryParams = [resourceId];
|
|
1317
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 100;
|
|
1318
|
+
const currentOffset = page * perPage;
|
|
1319
|
+
const countQuery = `SELECT COUNT(*) ${baseQuery}`;
|
|
1320
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1321
|
+
const total = parseInt(countResult.count, 10);
|
|
1322
|
+
if (total === 0) {
|
|
1323
|
+
return {
|
|
1324
|
+
threads: [],
|
|
1325
|
+
total: 0,
|
|
1326
|
+
page,
|
|
1327
|
+
perPage,
|
|
1328
|
+
hasMore: false
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC LIMIT $2 OFFSET $3`;
|
|
1332
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1333
|
+
const threads = (rows || []).map((thread) => ({
|
|
1334
|
+
...thread,
|
|
1335
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1336
|
+
createdAt: thread.createdAt,
|
|
1337
|
+
// Assuming already Date objects or ISO strings
|
|
1338
|
+
updatedAt: thread.updatedAt
|
|
1339
|
+
}));
|
|
1340
|
+
return {
|
|
1341
|
+
threads,
|
|
1342
|
+
total,
|
|
1343
|
+
page,
|
|
1344
|
+
perPage,
|
|
1345
|
+
hasMore: currentOffset + threads.length < total
|
|
1346
|
+
};
|
|
1347
|
+
} catch (error) {
|
|
1348
|
+
this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
|
|
1349
|
+
return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
|
|
1263
1350
|
}
|
|
1264
1351
|
}
|
|
1265
1352
|
async saveThread({ thread }) {
|
|
@@ -1339,84 +1426,140 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1339
1426
|
throw error;
|
|
1340
1427
|
}
|
|
1341
1428
|
}
|
|
1342
|
-
async getMessages(
|
|
1429
|
+
async getMessages(args) {
|
|
1430
|
+
const { threadId, format, selectBy } = args;
|
|
1431
|
+
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1432
|
+
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1343
1433
|
try {
|
|
1344
|
-
|
|
1345
|
-
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1434
|
+
let rows = [];
|
|
1346
1435
|
const include = selectBy?.include || [];
|
|
1347
1436
|
if (include.length) {
|
|
1348
|
-
|
|
1437
|
+
rows = await this.db.manyOrNone(
|
|
1349
1438
|
`
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
)
|
|
1357
|
-
SELECT
|
|
1358
|
-
m.id,
|
|
1359
|
-
m.content,
|
|
1360
|
-
m.role,
|
|
1361
|
-
m.type,
|
|
1362
|
-
m."createdAt",
|
|
1363
|
-
m.thread_id AS "threadId"
|
|
1364
|
-
FROM ordered_messages m
|
|
1365
|
-
WHERE m.id = ANY($2)
|
|
1366
|
-
OR EXISTS (
|
|
1367
|
-
SELECT 1 FROM ordered_messages target
|
|
1368
|
-
WHERE target.id = ANY($2)
|
|
1369
|
-
AND (
|
|
1370
|
-
-- Get previous messages based on the max withPreviousMessages
|
|
1371
|
-
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
1372
|
-
OR
|
|
1373
|
-
-- Get next messages based on the max withNextMessages
|
|
1374
|
-
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
1439
|
+
WITH ordered_messages AS (
|
|
1440
|
+
SELECT
|
|
1441
|
+
*,
|
|
1442
|
+
ROW_NUMBER() OVER (${orderByStatement}) as row_num
|
|
1443
|
+
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
1444
|
+
WHERE thread_id = $1
|
|
1375
1445
|
)
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1446
|
+
SELECT
|
|
1447
|
+
m.id,
|
|
1448
|
+
m.content,
|
|
1449
|
+
m.role,
|
|
1450
|
+
m.type,
|
|
1451
|
+
m."createdAt",
|
|
1452
|
+
m.thread_id AS "threadId"
|
|
1453
|
+
FROM ordered_messages m
|
|
1454
|
+
WHERE m.id = ANY($2)
|
|
1455
|
+
OR EXISTS (
|
|
1456
|
+
SELECT 1 FROM ordered_messages target
|
|
1457
|
+
WHERE target.id = ANY($2)
|
|
1458
|
+
AND (
|
|
1459
|
+
-- Get previous messages based on the max withPreviousMessages
|
|
1460
|
+
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
1461
|
+
OR
|
|
1462
|
+
-- Get next messages based on the max withNextMessages
|
|
1463
|
+
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
1464
|
+
)
|
|
1465
|
+
)
|
|
1466
|
+
ORDER BY m."createdAt" ASC
|
|
1467
|
+
`,
|
|
1468
|
+
// Keep ASC for final sorting after fetching context
|
|
1379
1469
|
[
|
|
1380
1470
|
threadId,
|
|
1381
1471
|
include.map((i) => i.id),
|
|
1382
|
-
Math.max(...include.map((i) => i.withPreviousMessages || 0)),
|
|
1383
|
-
|
|
1472
|
+
Math.max(0, ...include.map((i) => i.withPreviousMessages || 0)),
|
|
1473
|
+
// Ensure non-negative
|
|
1474
|
+
Math.max(0, ...include.map((i) => i.withNextMessages || 0))
|
|
1475
|
+
// Ensure non-negative
|
|
1384
1476
|
]
|
|
1385
1477
|
);
|
|
1386
|
-
|
|
1478
|
+
} else {
|
|
1479
|
+
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1480
|
+
if (limit === 0 && selectBy?.last !== false) ; else {
|
|
1481
|
+
let query = `${selectStatement} FROM ${this.getTableName(
|
|
1482
|
+
storage.TABLE_MESSAGES
|
|
1483
|
+
)} WHERE thread_id = $1 ${orderByStatement}`;
|
|
1484
|
+
const queryParams = [threadId];
|
|
1485
|
+
if (limit !== void 0 && selectBy?.last !== false) {
|
|
1486
|
+
query += ` LIMIT $2`;
|
|
1487
|
+
queryParams.push(limit);
|
|
1488
|
+
}
|
|
1489
|
+
rows = await this.db.manyOrNone(query, queryParams);
|
|
1490
|
+
}
|
|
1387
1491
|
}
|
|
1388
|
-
const
|
|
1389
|
-
`
|
|
1390
|
-
SELECT
|
|
1391
|
-
id,
|
|
1392
|
-
content,
|
|
1393
|
-
role,
|
|
1394
|
-
type,
|
|
1395
|
-
"createdAt",
|
|
1396
|
-
thread_id AS "threadId"
|
|
1397
|
-
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
1398
|
-
WHERE thread_id = $1
|
|
1399
|
-
AND id != ALL($2)
|
|
1400
|
-
ORDER BY "createdAt" DESC
|
|
1401
|
-
LIMIT $3
|
|
1402
|
-
`,
|
|
1403
|
-
[threadId, messages.map((m) => m.id), limit]
|
|
1404
|
-
);
|
|
1405
|
-
messages.push(...result);
|
|
1406
|
-
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1407
|
-
messages.forEach((message) => {
|
|
1492
|
+
const fetchedMessages = (rows || []).map((message) => {
|
|
1408
1493
|
if (typeof message.content === "string") {
|
|
1409
1494
|
try {
|
|
1410
1495
|
message.content = JSON.parse(message.content);
|
|
1411
1496
|
} catch {
|
|
1412
1497
|
}
|
|
1413
1498
|
}
|
|
1414
|
-
if (message.type ===
|
|
1499
|
+
if (message.type === "v2") delete message.type;
|
|
1500
|
+
return message;
|
|
1415
1501
|
});
|
|
1416
|
-
|
|
1502
|
+
const sortedMessages = fetchedMessages.sort(
|
|
1503
|
+
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
1504
|
+
);
|
|
1505
|
+
return format === "v2" ? sortedMessages.map(
|
|
1506
|
+
(m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
|
|
1507
|
+
) : sortedMessages;
|
|
1417
1508
|
} catch (error) {
|
|
1418
|
-
|
|
1419
|
-
|
|
1509
|
+
this.logger.error("Error getting messages:", error);
|
|
1510
|
+
return [];
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
async getMessagesPaginated(args) {
|
|
1514
|
+
const { threadId, format, selectBy } = args;
|
|
1515
|
+
const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
|
|
1516
|
+
const fromDate = dateRange?.start;
|
|
1517
|
+
const toDate = dateRange?.end;
|
|
1518
|
+
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1519
|
+
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1520
|
+
try {
|
|
1521
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 40;
|
|
1522
|
+
const currentOffset = page * perPage;
|
|
1523
|
+
const conditions = [`thread_id = $1`];
|
|
1524
|
+
const queryParams = [threadId];
|
|
1525
|
+
let paramIndex = 2;
|
|
1526
|
+
if (fromDate) {
|
|
1527
|
+
conditions.push(`"createdAt" >= $${paramIndex++}`);
|
|
1528
|
+
queryParams.push(fromDate);
|
|
1529
|
+
}
|
|
1530
|
+
if (toDate) {
|
|
1531
|
+
conditions.push(`"createdAt" <= $${paramIndex++}`);
|
|
1532
|
+
queryParams.push(toDate);
|
|
1533
|
+
}
|
|
1534
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1535
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(storage.TABLE_MESSAGES)} ${whereClause}`;
|
|
1536
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1537
|
+
const total = parseInt(countResult.count, 10);
|
|
1538
|
+
if (total === 0) {
|
|
1539
|
+
return {
|
|
1540
|
+
messages: [],
|
|
1541
|
+
total: 0,
|
|
1542
|
+
page,
|
|
1543
|
+
perPage,
|
|
1544
|
+
hasMore: false
|
|
1545
|
+
};
|
|
1546
|
+
}
|
|
1547
|
+
const dataQuery = `${selectStatement} FROM ${this.getTableName(
|
|
1548
|
+
storage.TABLE_MESSAGES
|
|
1549
|
+
)} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1550
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1551
|
+
const list = new agent.MessageList().add(rows || [], "memory");
|
|
1552
|
+
const messagesToReturn = format === `v2` ? list.get.all.v2() : list.get.all.v1();
|
|
1553
|
+
return {
|
|
1554
|
+
messages: messagesToReturn,
|
|
1555
|
+
total,
|
|
1556
|
+
page,
|
|
1557
|
+
perPage,
|
|
1558
|
+
hasMore: currentOffset + rows.length < total
|
|
1559
|
+
};
|
|
1560
|
+
} catch (error) {
|
|
1561
|
+
this.logger.error("Error getting messages:", error);
|
|
1562
|
+
return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
|
|
1420
1563
|
}
|
|
1421
1564
|
}
|
|
1422
1565
|
async saveMessages({
|
|
@@ -1629,6 +1772,56 @@ var PostgresStore = class extends storage.MastraStorage {
|
|
|
1629
1772
|
async close() {
|
|
1630
1773
|
this.pgp.end();
|
|
1631
1774
|
}
|
|
1775
|
+
async getEvals(options = {}) {
|
|
1776
|
+
const { agentName, type, page = 0, perPage = 100, dateRange } = options;
|
|
1777
|
+
const fromDate = dateRange?.start;
|
|
1778
|
+
const toDate = dateRange?.end;
|
|
1779
|
+
const conditions = [];
|
|
1780
|
+
const queryParams = [];
|
|
1781
|
+
let paramIndex = 1;
|
|
1782
|
+
if (agentName) {
|
|
1783
|
+
conditions.push(`agent_name = $${paramIndex++}`);
|
|
1784
|
+
queryParams.push(agentName);
|
|
1785
|
+
}
|
|
1786
|
+
if (type === "test") {
|
|
1787
|
+
conditions.push(`(test_info IS NOT NULL AND test_info->>'testPath' IS NOT NULL)`);
|
|
1788
|
+
} else if (type === "live") {
|
|
1789
|
+
conditions.push(`(test_info IS NULL OR test_info->>'testPath' IS NULL)`);
|
|
1790
|
+
}
|
|
1791
|
+
if (fromDate) {
|
|
1792
|
+
conditions.push(`created_at >= $${paramIndex++}`);
|
|
1793
|
+
queryParams.push(fromDate);
|
|
1794
|
+
}
|
|
1795
|
+
if (toDate) {
|
|
1796
|
+
conditions.push(`created_at <= $${paramIndex++}`);
|
|
1797
|
+
queryParams.push(toDate);
|
|
1798
|
+
}
|
|
1799
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1800
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(storage.TABLE_EVALS)} ${whereClause}`;
|
|
1801
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1802
|
+
const total = parseInt(countResult.count, 10);
|
|
1803
|
+
const currentOffset = page * perPage;
|
|
1804
|
+
if (total === 0) {
|
|
1805
|
+
return {
|
|
1806
|
+
evals: [],
|
|
1807
|
+
total: 0,
|
|
1808
|
+
page,
|
|
1809
|
+
perPage,
|
|
1810
|
+
hasMore: false
|
|
1811
|
+
};
|
|
1812
|
+
}
|
|
1813
|
+
const dataQuery = `SELECT * FROM ${this.getTableName(
|
|
1814
|
+
storage.TABLE_EVALS
|
|
1815
|
+
)} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1816
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1817
|
+
return {
|
|
1818
|
+
evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
|
|
1819
|
+
total,
|
|
1820
|
+
page,
|
|
1821
|
+
perPage,
|
|
1822
|
+
hasMore: currentOffset + (rows?.length ?? 0) < total
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1632
1825
|
};
|
|
1633
1826
|
|
|
1634
1827
|
// src/vector/prompt.ts
|