@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.js
CHANGED
|
@@ -941,6 +941,7 @@ var PostgresStore = class extends MastraStorage {
|
|
|
941
941
|
const parsedSchemaName = this.schema ? parseSqlIdentifier(this.schema, "schema name") : void 0;
|
|
942
942
|
return parsedSchemaName ? `${parsedSchemaName}."${parsedIndexName}"` : `"${parsedIndexName}"`;
|
|
943
943
|
}
|
|
944
|
+
/** @deprecated use getEvals instead */
|
|
944
945
|
async getEvalsByAgentName(agentName, type) {
|
|
945
946
|
try {
|
|
946
947
|
const baseQuery = `SELECT * FROM ${this.getTableName(TABLE_EVALS)} WHERE agent_name = $1`;
|
|
@@ -991,76 +992,77 @@ var PostgresStore = class extends MastraStorage {
|
|
|
991
992
|
throw error;
|
|
992
993
|
}
|
|
993
994
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
995
|
+
/**
|
|
996
|
+
* @deprecated use getTracesPaginated instead
|
|
997
|
+
*/
|
|
998
|
+
async getTraces(args) {
|
|
999
|
+
if (args.fromDate || args.toDate) {
|
|
1000
|
+
args.dateRange = {
|
|
1001
|
+
start: args.fromDate,
|
|
1002
|
+
end: args.toDate
|
|
1003
|
+
};
|
|
1004
|
+
}
|
|
1005
|
+
const result = await this.getTracesPaginated(args);
|
|
1006
|
+
return result.traces;
|
|
1007
|
+
}
|
|
1008
|
+
async getTracesPaginated(args) {
|
|
1009
|
+
const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
|
|
1010
|
+
const fromDate = dateRange?.start;
|
|
1011
|
+
const toDate = dateRange?.end;
|
|
1012
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 100;
|
|
1013
|
+
const currentOffset = page * perPage;
|
|
1014
|
+
const queryParams = [];
|
|
1008
1015
|
const conditions = [];
|
|
1016
|
+
let paramIndex = 1;
|
|
1009
1017
|
if (name) {
|
|
1010
|
-
conditions.push(`name LIKE
|
|
1018
|
+
conditions.push(`name LIKE $${paramIndex++}`);
|
|
1019
|
+
queryParams.push(`${name}%`);
|
|
1011
1020
|
}
|
|
1012
1021
|
if (scope) {
|
|
1013
|
-
conditions.push(`scope = $${
|
|
1022
|
+
conditions.push(`scope = $${paramIndex++}`);
|
|
1023
|
+
queryParams.push(scope);
|
|
1014
1024
|
}
|
|
1015
1025
|
if (attributes) {
|
|
1016
|
-
Object.
|
|
1026
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
1017
1027
|
const parsedKey = parseSqlIdentifier(key, "attribute key");
|
|
1018
|
-
conditions.push(`attributes->>'${parsedKey}' = $${
|
|
1028
|
+
conditions.push(`attributes->>'${parsedKey}' = $${paramIndex++}`);
|
|
1029
|
+
queryParams.push(value);
|
|
1019
1030
|
});
|
|
1020
1031
|
}
|
|
1021
1032
|
if (filters) {
|
|
1022
|
-
Object.entries(filters).forEach(([key]) => {
|
|
1033
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
1023
1034
|
const parsedKey = parseSqlIdentifier(key, "filter key");
|
|
1024
|
-
conditions.push(
|
|
1035
|
+
conditions.push(`"${parsedKey}" = $${paramIndex++}`);
|
|
1036
|
+
queryParams.push(value);
|
|
1025
1037
|
});
|
|
1026
1038
|
}
|
|
1027
1039
|
if (fromDate) {
|
|
1028
|
-
conditions.push(`createdAt >= $${
|
|
1040
|
+
conditions.push(`"createdAt" >= $${paramIndex++}`);
|
|
1041
|
+
queryParams.push(fromDate);
|
|
1029
1042
|
}
|
|
1030
1043
|
if (toDate) {
|
|
1031
|
-
conditions.push(`createdAt <= $${
|
|
1044
|
+
conditions.push(`"createdAt" <= $${paramIndex++}`);
|
|
1045
|
+
queryParams.push(toDate);
|
|
1032
1046
|
}
|
|
1033
1047
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
if (
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
if (filters) {
|
|
1046
|
-
for (const [, value] of Object.entries(filters)) {
|
|
1047
|
-
args.push(value);
|
|
1048
|
-
}
|
|
1049
|
-
}
|
|
1050
|
-
if (fromDate) {
|
|
1051
|
-
args.push(fromDate.toISOString());
|
|
1052
|
-
}
|
|
1053
|
-
if (toDate) {
|
|
1054
|
-
args.push(toDate.toISOString());
|
|
1055
|
-
}
|
|
1056
|
-
const result = await this.db.manyOrNone(
|
|
1057
|
-
`SELECT * FROM ${this.getTableName(TABLE_TRACES)} ${whereClause} ORDER BY "createdAt" DESC LIMIT ${limit} OFFSET ${offset}`,
|
|
1058
|
-
args
|
|
1059
|
-
);
|
|
1060
|
-
if (!result) {
|
|
1061
|
-
return [];
|
|
1048
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_TRACES)} ${whereClause}`;
|
|
1049
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1050
|
+
const total = parseInt(countResult.count, 10);
|
|
1051
|
+
if (total === 0) {
|
|
1052
|
+
return {
|
|
1053
|
+
traces: [],
|
|
1054
|
+
total: 0,
|
|
1055
|
+
page,
|
|
1056
|
+
perPage,
|
|
1057
|
+
hasMore: false
|
|
1058
|
+
};
|
|
1062
1059
|
}
|
|
1063
|
-
|
|
1060
|
+
const dataQuery = `SELECT * FROM ${this.getTableName(
|
|
1061
|
+
TABLE_TRACES
|
|
1062
|
+
)} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1063
|
+
const finalQueryParams = [...queryParams, perPage, currentOffset];
|
|
1064
|
+
const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
|
|
1065
|
+
const traces = rows.map((row) => ({
|
|
1064
1066
|
id: row.id,
|
|
1065
1067
|
parentSpanId: row.parentSpanId,
|
|
1066
1068
|
traceId: row.traceId,
|
|
@@ -1076,6 +1078,13 @@ var PostgresStore = class extends MastraStorage {
|
|
|
1076
1078
|
other: row.other,
|
|
1077
1079
|
createdAt: row.createdAt
|
|
1078
1080
|
}));
|
|
1081
|
+
return {
|
|
1082
|
+
traces,
|
|
1083
|
+
total,
|
|
1084
|
+
page,
|
|
1085
|
+
perPage,
|
|
1086
|
+
hasMore: currentOffset + traces.length < total
|
|
1087
|
+
};
|
|
1079
1088
|
}
|
|
1080
1089
|
async setupSchema() {
|
|
1081
1090
|
if (!this.schema || this.schemaSetupComplete) {
|
|
@@ -1154,6 +1163,48 @@ var PostgresStore = class extends MastraStorage {
|
|
|
1154
1163
|
throw error;
|
|
1155
1164
|
}
|
|
1156
1165
|
}
|
|
1166
|
+
getDefaultValue(type) {
|
|
1167
|
+
switch (type) {
|
|
1168
|
+
case "timestamp":
|
|
1169
|
+
return "DEFAULT NOW()";
|
|
1170
|
+
case "jsonb":
|
|
1171
|
+
return "DEFAULT '{}'::jsonb";
|
|
1172
|
+
default:
|
|
1173
|
+
return super.getDefaultValue(type);
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
/**
|
|
1177
|
+
* Alters table schema to add columns if they don't exist
|
|
1178
|
+
* @param tableName Name of the table
|
|
1179
|
+
* @param schema Schema of the table
|
|
1180
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
1181
|
+
*/
|
|
1182
|
+
async alterTable({
|
|
1183
|
+
tableName,
|
|
1184
|
+
schema,
|
|
1185
|
+
ifNotExists
|
|
1186
|
+
}) {
|
|
1187
|
+
const fullTableName = this.getTableName(tableName);
|
|
1188
|
+
try {
|
|
1189
|
+
for (const columnName of ifNotExists) {
|
|
1190
|
+
if (schema[columnName]) {
|
|
1191
|
+
const columnDef = schema[columnName];
|
|
1192
|
+
const sqlType = this.getSqlType(columnDef.type);
|
|
1193
|
+
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
1194
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
1195
|
+
const parsedColumnName = parseSqlIdentifier(columnName, "column name");
|
|
1196
|
+
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
1197
|
+
await this.db.none(alterSql);
|
|
1198
|
+
this.logger?.debug?.(`Ensured column ${parsedColumnName} exists in table ${fullTableName}`);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
} catch (error) {
|
|
1202
|
+
this.logger?.error?.(
|
|
1203
|
+
`Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
|
|
1204
|
+
);
|
|
1205
|
+
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1157
1208
|
async clearTable({ tableName }) {
|
|
1158
1209
|
try {
|
|
1159
1210
|
await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
|
|
@@ -1229,29 +1280,65 @@ var PostgresStore = class extends MastraStorage {
|
|
|
1229
1280
|
throw error;
|
|
1230
1281
|
}
|
|
1231
1282
|
}
|
|
1232
|
-
|
|
1283
|
+
/**
|
|
1284
|
+
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
1285
|
+
*/
|
|
1286
|
+
async getThreadsByResourceId(args) {
|
|
1287
|
+
const { resourceId } = args;
|
|
1233
1288
|
try {
|
|
1234
|
-
const
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
metadata,
|
|
1240
|
-
"createdAt",
|
|
1241
|
-
"updatedAt"
|
|
1242
|
-
FROM ${this.getTableName(TABLE_THREADS)}
|
|
1243
|
-
WHERE "resourceId" = $1`,
|
|
1244
|
-
[resourceId]
|
|
1245
|
-
);
|
|
1246
|
-
return threads.map((thread) => ({
|
|
1289
|
+
const baseQuery = `FROM ${this.getTableName(TABLE_THREADS)} WHERE "resourceId" = $1`;
|
|
1290
|
+
const queryParams = [resourceId];
|
|
1291
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC`;
|
|
1292
|
+
const rows = await this.db.manyOrNone(dataQuery, queryParams);
|
|
1293
|
+
return (rows || []).map((thread) => ({
|
|
1247
1294
|
...thread,
|
|
1248
1295
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1249
1296
|
createdAt: thread.createdAt,
|
|
1250
1297
|
updatedAt: thread.updatedAt
|
|
1251
1298
|
}));
|
|
1252
1299
|
} catch (error) {
|
|
1253
|
-
|
|
1254
|
-
|
|
1300
|
+
this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
|
|
1301
|
+
return [];
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
1305
|
+
const { resourceId, page = 0, perPage: perPageInput } = args;
|
|
1306
|
+
try {
|
|
1307
|
+
const baseQuery = `FROM ${this.getTableName(TABLE_THREADS)} WHERE "resourceId" = $1`;
|
|
1308
|
+
const queryParams = [resourceId];
|
|
1309
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 100;
|
|
1310
|
+
const currentOffset = page * perPage;
|
|
1311
|
+
const countQuery = `SELECT COUNT(*) ${baseQuery}`;
|
|
1312
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1313
|
+
const total = parseInt(countResult.count, 10);
|
|
1314
|
+
if (total === 0) {
|
|
1315
|
+
return {
|
|
1316
|
+
threads: [],
|
|
1317
|
+
total: 0,
|
|
1318
|
+
page,
|
|
1319
|
+
perPage,
|
|
1320
|
+
hasMore: false
|
|
1321
|
+
};
|
|
1322
|
+
}
|
|
1323
|
+
const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC LIMIT $2 OFFSET $3`;
|
|
1324
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1325
|
+
const threads = (rows || []).map((thread) => ({
|
|
1326
|
+
...thread,
|
|
1327
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
1328
|
+
createdAt: thread.createdAt,
|
|
1329
|
+
// Assuming already Date objects or ISO strings
|
|
1330
|
+
updatedAt: thread.updatedAt
|
|
1331
|
+
}));
|
|
1332
|
+
return {
|
|
1333
|
+
threads,
|
|
1334
|
+
total,
|
|
1335
|
+
page,
|
|
1336
|
+
perPage,
|
|
1337
|
+
hasMore: currentOffset + threads.length < total
|
|
1338
|
+
};
|
|
1339
|
+
} catch (error) {
|
|
1340
|
+
this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
|
|
1341
|
+
return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
|
|
1255
1342
|
}
|
|
1256
1343
|
}
|
|
1257
1344
|
async saveThread({ thread }) {
|
|
@@ -1331,84 +1418,140 @@ var PostgresStore = class extends MastraStorage {
|
|
|
1331
1418
|
throw error;
|
|
1332
1419
|
}
|
|
1333
1420
|
}
|
|
1334
|
-
async getMessages(
|
|
1421
|
+
async getMessages(args) {
|
|
1422
|
+
const { threadId, format, selectBy } = args;
|
|
1423
|
+
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1424
|
+
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1335
1425
|
try {
|
|
1336
|
-
|
|
1337
|
-
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1426
|
+
let rows = [];
|
|
1338
1427
|
const include = selectBy?.include || [];
|
|
1339
1428
|
if (include.length) {
|
|
1340
|
-
|
|
1429
|
+
rows = await this.db.manyOrNone(
|
|
1341
1430
|
`
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
)
|
|
1349
|
-
SELECT
|
|
1350
|
-
m.id,
|
|
1351
|
-
m.content,
|
|
1352
|
-
m.role,
|
|
1353
|
-
m.type,
|
|
1354
|
-
m."createdAt",
|
|
1355
|
-
m.thread_id AS "threadId"
|
|
1356
|
-
FROM ordered_messages m
|
|
1357
|
-
WHERE m.id = ANY($2)
|
|
1358
|
-
OR EXISTS (
|
|
1359
|
-
SELECT 1 FROM ordered_messages target
|
|
1360
|
-
WHERE target.id = ANY($2)
|
|
1361
|
-
AND (
|
|
1362
|
-
-- Get previous messages based on the max withPreviousMessages
|
|
1363
|
-
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
1364
|
-
OR
|
|
1365
|
-
-- Get next messages based on the max withNextMessages
|
|
1366
|
-
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
1431
|
+
WITH ordered_messages AS (
|
|
1432
|
+
SELECT
|
|
1433
|
+
*,
|
|
1434
|
+
ROW_NUMBER() OVER (${orderByStatement}) as row_num
|
|
1435
|
+
FROM ${this.getTableName(TABLE_MESSAGES)}
|
|
1436
|
+
WHERE thread_id = $1
|
|
1367
1437
|
)
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1438
|
+
SELECT
|
|
1439
|
+
m.id,
|
|
1440
|
+
m.content,
|
|
1441
|
+
m.role,
|
|
1442
|
+
m.type,
|
|
1443
|
+
m."createdAt",
|
|
1444
|
+
m.thread_id AS "threadId"
|
|
1445
|
+
FROM ordered_messages m
|
|
1446
|
+
WHERE m.id = ANY($2)
|
|
1447
|
+
OR EXISTS (
|
|
1448
|
+
SELECT 1 FROM ordered_messages target
|
|
1449
|
+
WHERE target.id = ANY($2)
|
|
1450
|
+
AND (
|
|
1451
|
+
-- Get previous messages based on the max withPreviousMessages
|
|
1452
|
+
(m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
|
|
1453
|
+
OR
|
|
1454
|
+
-- Get next messages based on the max withNextMessages
|
|
1455
|
+
(m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
|
|
1456
|
+
)
|
|
1457
|
+
)
|
|
1458
|
+
ORDER BY m."createdAt" ASC
|
|
1459
|
+
`,
|
|
1460
|
+
// Keep ASC for final sorting after fetching context
|
|
1371
1461
|
[
|
|
1372
1462
|
threadId,
|
|
1373
1463
|
include.map((i) => i.id),
|
|
1374
|
-
Math.max(...include.map((i) => i.withPreviousMessages || 0)),
|
|
1375
|
-
|
|
1464
|
+
Math.max(0, ...include.map((i) => i.withPreviousMessages || 0)),
|
|
1465
|
+
// Ensure non-negative
|
|
1466
|
+
Math.max(0, ...include.map((i) => i.withNextMessages || 0))
|
|
1467
|
+
// Ensure non-negative
|
|
1376
1468
|
]
|
|
1377
1469
|
);
|
|
1378
|
-
|
|
1470
|
+
} else {
|
|
1471
|
+
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
1472
|
+
if (limit === 0 && selectBy?.last !== false) ; else {
|
|
1473
|
+
let query = `${selectStatement} FROM ${this.getTableName(
|
|
1474
|
+
TABLE_MESSAGES
|
|
1475
|
+
)} WHERE thread_id = $1 ${orderByStatement}`;
|
|
1476
|
+
const queryParams = [threadId];
|
|
1477
|
+
if (limit !== void 0 && selectBy?.last !== false) {
|
|
1478
|
+
query += ` LIMIT $2`;
|
|
1479
|
+
queryParams.push(limit);
|
|
1480
|
+
}
|
|
1481
|
+
rows = await this.db.manyOrNone(query, queryParams);
|
|
1482
|
+
}
|
|
1379
1483
|
}
|
|
1380
|
-
const
|
|
1381
|
-
`
|
|
1382
|
-
SELECT
|
|
1383
|
-
id,
|
|
1384
|
-
content,
|
|
1385
|
-
role,
|
|
1386
|
-
type,
|
|
1387
|
-
"createdAt",
|
|
1388
|
-
thread_id AS "threadId"
|
|
1389
|
-
FROM ${this.getTableName(TABLE_MESSAGES)}
|
|
1390
|
-
WHERE thread_id = $1
|
|
1391
|
-
AND id != ALL($2)
|
|
1392
|
-
ORDER BY "createdAt" DESC
|
|
1393
|
-
LIMIT $3
|
|
1394
|
-
`,
|
|
1395
|
-
[threadId, messages.map((m) => m.id), limit]
|
|
1396
|
-
);
|
|
1397
|
-
messages.push(...result);
|
|
1398
|
-
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1399
|
-
messages.forEach((message) => {
|
|
1484
|
+
const fetchedMessages = (rows || []).map((message) => {
|
|
1400
1485
|
if (typeof message.content === "string") {
|
|
1401
1486
|
try {
|
|
1402
1487
|
message.content = JSON.parse(message.content);
|
|
1403
1488
|
} catch {
|
|
1404
1489
|
}
|
|
1405
1490
|
}
|
|
1406
|
-
if (message.type ===
|
|
1491
|
+
if (message.type === "v2") delete message.type;
|
|
1492
|
+
return message;
|
|
1407
1493
|
});
|
|
1408
|
-
|
|
1494
|
+
const sortedMessages = fetchedMessages.sort(
|
|
1495
|
+
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
1496
|
+
);
|
|
1497
|
+
return format === "v2" ? sortedMessages.map(
|
|
1498
|
+
(m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
|
|
1499
|
+
) : sortedMessages;
|
|
1409
1500
|
} catch (error) {
|
|
1410
|
-
|
|
1411
|
-
|
|
1501
|
+
this.logger.error("Error getting messages:", error);
|
|
1502
|
+
return [];
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
async getMessagesPaginated(args) {
|
|
1506
|
+
const { threadId, format, selectBy } = args;
|
|
1507
|
+
const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
|
|
1508
|
+
const fromDate = dateRange?.start;
|
|
1509
|
+
const toDate = dateRange?.end;
|
|
1510
|
+
const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
|
|
1511
|
+
const orderByStatement = `ORDER BY "createdAt" DESC`;
|
|
1512
|
+
try {
|
|
1513
|
+
const perPage = perPageInput !== void 0 ? perPageInput : 40;
|
|
1514
|
+
const currentOffset = page * perPage;
|
|
1515
|
+
const conditions = [`thread_id = $1`];
|
|
1516
|
+
const queryParams = [threadId];
|
|
1517
|
+
let paramIndex = 2;
|
|
1518
|
+
if (fromDate) {
|
|
1519
|
+
conditions.push(`"createdAt" >= $${paramIndex++}`);
|
|
1520
|
+
queryParams.push(fromDate);
|
|
1521
|
+
}
|
|
1522
|
+
if (toDate) {
|
|
1523
|
+
conditions.push(`"createdAt" <= $${paramIndex++}`);
|
|
1524
|
+
queryParams.push(toDate);
|
|
1525
|
+
}
|
|
1526
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1527
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_MESSAGES)} ${whereClause}`;
|
|
1528
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1529
|
+
const total = parseInt(countResult.count, 10);
|
|
1530
|
+
if (total === 0) {
|
|
1531
|
+
return {
|
|
1532
|
+
messages: [],
|
|
1533
|
+
total: 0,
|
|
1534
|
+
page,
|
|
1535
|
+
perPage,
|
|
1536
|
+
hasMore: false
|
|
1537
|
+
};
|
|
1538
|
+
}
|
|
1539
|
+
const dataQuery = `${selectStatement} FROM ${this.getTableName(
|
|
1540
|
+
TABLE_MESSAGES
|
|
1541
|
+
)} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1542
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1543
|
+
const list = new MessageList().add(rows || [], "memory");
|
|
1544
|
+
const messagesToReturn = format === `v2` ? list.get.all.v2() : list.get.all.v1();
|
|
1545
|
+
return {
|
|
1546
|
+
messages: messagesToReturn,
|
|
1547
|
+
total,
|
|
1548
|
+
page,
|
|
1549
|
+
perPage,
|
|
1550
|
+
hasMore: currentOffset + rows.length < total
|
|
1551
|
+
};
|
|
1552
|
+
} catch (error) {
|
|
1553
|
+
this.logger.error("Error getting messages:", error);
|
|
1554
|
+
return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
|
|
1412
1555
|
}
|
|
1413
1556
|
}
|
|
1414
1557
|
async saveMessages({
|
|
@@ -1621,6 +1764,56 @@ var PostgresStore = class extends MastraStorage {
|
|
|
1621
1764
|
async close() {
|
|
1622
1765
|
this.pgp.end();
|
|
1623
1766
|
}
|
|
1767
|
+
async getEvals(options = {}) {
|
|
1768
|
+
const { agentName, type, page = 0, perPage = 100, dateRange } = options;
|
|
1769
|
+
const fromDate = dateRange?.start;
|
|
1770
|
+
const toDate = dateRange?.end;
|
|
1771
|
+
const conditions = [];
|
|
1772
|
+
const queryParams = [];
|
|
1773
|
+
let paramIndex = 1;
|
|
1774
|
+
if (agentName) {
|
|
1775
|
+
conditions.push(`agent_name = $${paramIndex++}`);
|
|
1776
|
+
queryParams.push(agentName);
|
|
1777
|
+
}
|
|
1778
|
+
if (type === "test") {
|
|
1779
|
+
conditions.push(`(test_info IS NOT NULL AND test_info->>'testPath' IS NOT NULL)`);
|
|
1780
|
+
} else if (type === "live") {
|
|
1781
|
+
conditions.push(`(test_info IS NULL OR test_info->>'testPath' IS NULL)`);
|
|
1782
|
+
}
|
|
1783
|
+
if (fromDate) {
|
|
1784
|
+
conditions.push(`created_at >= $${paramIndex++}`);
|
|
1785
|
+
queryParams.push(fromDate);
|
|
1786
|
+
}
|
|
1787
|
+
if (toDate) {
|
|
1788
|
+
conditions.push(`created_at <= $${paramIndex++}`);
|
|
1789
|
+
queryParams.push(toDate);
|
|
1790
|
+
}
|
|
1791
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
1792
|
+
const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_EVALS)} ${whereClause}`;
|
|
1793
|
+
const countResult = await this.db.one(countQuery, queryParams);
|
|
1794
|
+
const total = parseInt(countResult.count, 10);
|
|
1795
|
+
const currentOffset = page * perPage;
|
|
1796
|
+
if (total === 0) {
|
|
1797
|
+
return {
|
|
1798
|
+
evals: [],
|
|
1799
|
+
total: 0,
|
|
1800
|
+
page,
|
|
1801
|
+
perPage,
|
|
1802
|
+
hasMore: false
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
const dataQuery = `SELECT * FROM ${this.getTableName(
|
|
1806
|
+
TABLE_EVALS
|
|
1807
|
+
)} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
|
|
1808
|
+
const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
|
|
1809
|
+
return {
|
|
1810
|
+
evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
|
|
1811
|
+
total,
|
|
1812
|
+
page,
|
|
1813
|
+
perPage,
|
|
1814
|
+
hasMore: currentOffset + (rows?.length ?? 0) < total
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1624
1817
|
};
|
|
1625
1818
|
|
|
1626
1819
|
// src/vector/prompt.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/pg",
|
|
3
|
-
"version": "0.10.1",
|
|
3
|
+
"version": "0.10.2-alpha.1",
|
|
4
4
|
"description": "Postgres provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,20 +21,21 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"async-mutex": "^0.5.0",
|
|
24
|
-
"pg": "^8.
|
|
25
|
-
"pg-promise": "^11.
|
|
24
|
+
"pg": "^8.16.0",
|
|
25
|
+
"pg-promise": "^11.13.0",
|
|
26
26
|
"xxhash-wasm": "^1.1.0"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@microsoft/api-extractor": "^7.52.
|
|
30
|
-
"@types/node": "^20.17.
|
|
31
|
-
"@types/pg": "^8.
|
|
32
|
-
"eslint": "^9.
|
|
33
|
-
"tsup": "^8.
|
|
29
|
+
"@microsoft/api-extractor": "^7.52.8",
|
|
30
|
+
"@types/node": "^20.17.57",
|
|
31
|
+
"@types/pg": "^8.15.4",
|
|
32
|
+
"eslint": "^9.28.0",
|
|
33
|
+
"tsup": "^8.5.0",
|
|
34
34
|
"typescript": "^5.8.2",
|
|
35
|
-
"vitest": "^3.
|
|
36
|
-
"@internal/lint": "0.0.
|
|
37
|
-
"@
|
|
35
|
+
"vitest": "^3.2.2",
|
|
36
|
+
"@internal/lint": "0.0.10",
|
|
37
|
+
"@internal/storage-test-utils": "0.0.6",
|
|
38
|
+
"@mastra/core": "0.10.4-alpha.1"
|
|
38
39
|
},
|
|
39
40
|
"peerDependencies": {
|
|
40
41
|
"@mastra/core": "^0.10.2-alpha.0"
|