@mastra/pg 0.10.2-alpha.0 → 0.10.2-alpha.2

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/dist/index.js CHANGED
@@ -936,6 +936,11 @@ var PostgresStore = class extends MastraStorage {
936
936
  }
937
937
  );
938
938
  }
939
+ get supports() {
940
+ return {
941
+ selectByIncludeResourceScope: true
942
+ };
943
+ }
939
944
  getTableName(indexName) {
940
945
  const parsedIndexName = parseSqlIdentifier(indexName, "table name");
941
946
  const parsedSchemaName = this.schema ? parseSqlIdentifier(this.schema, "schema name") : void 0;
@@ -992,18 +997,23 @@ var PostgresStore = class extends MastraStorage {
992
997
  throw error;
993
998
  }
994
999
  }
1000
+ /**
1001
+ * @deprecated use getTracesPaginated instead
1002
+ */
995
1003
  async getTraces(args) {
996
- const {
997
- name,
998
- scope,
999
- page,
1000
- perPage: perPageInput,
1001
- attributes,
1002
- filters,
1003
- fromDate,
1004
- toDate,
1005
- returnPaginationResults
1006
- } = args;
1004
+ if (args.fromDate || args.toDate) {
1005
+ args.dateRange = {
1006
+ start: args.fromDate,
1007
+ end: args.toDate
1008
+ };
1009
+ }
1010
+ const result = await this.getTracesPaginated(args);
1011
+ return result.traces;
1012
+ }
1013
+ async getTracesPaginated(args) {
1014
+ const { name, scope, page = 0, perPage: perPageInput, attributes, filters, dateRange } = args;
1015
+ const fromDate = dateRange?.start;
1016
+ const toDate = dateRange?.end;
1007
1017
  const perPage = perPageInput !== void 0 ? perPageInput : 100;
1008
1018
  const currentOffset = page * perPage;
1009
1019
  const queryParams = [];
@@ -1043,7 +1053,7 @@ var PostgresStore = class extends MastraStorage {
1043
1053
  const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_TRACES)} ${whereClause}`;
1044
1054
  const countResult = await this.db.one(countQuery, queryParams);
1045
1055
  const total = parseInt(countResult.count, 10);
1046
- if (total === 0 && returnPaginationResults) {
1056
+ if (total === 0) {
1047
1057
  return {
1048
1058
  traces: [],
1049
1059
  total: 0,
@@ -1051,10 +1061,10 @@ var PostgresStore = class extends MastraStorage {
1051
1061
  perPage,
1052
1062
  hasMore: false
1053
1063
  };
1054
- } else if (total === 0) {
1055
- return [];
1056
1064
  }
1057
- const dataQuery = `SELECT * FROM ${this.getTableName(TABLE_TRACES)} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1065
+ const dataQuery = `SELECT * FROM ${this.getTableName(
1066
+ TABLE_TRACES
1067
+ )} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1058
1068
  const finalQueryParams = [...queryParams, perPage, currentOffset];
1059
1069
  const rows = await this.db.manyOrNone(dataQuery, finalQueryParams);
1060
1070
  const traces = rows.map((row) => ({
@@ -1073,17 +1083,13 @@ var PostgresStore = class extends MastraStorage {
1073
1083
  other: row.other,
1074
1084
  createdAt: row.createdAt
1075
1085
  }));
1076
- if (returnPaginationResults) {
1077
- return {
1078
- traces,
1079
- total,
1080
- page,
1081
- perPage,
1082
- hasMore: currentOffset + traces.length < total
1083
- };
1084
- } else {
1085
- return traces;
1086
- }
1086
+ return {
1087
+ traces,
1088
+ total,
1089
+ page,
1090
+ perPage,
1091
+ hasMore: currentOffset + traces.length < total
1092
+ };
1087
1093
  }
1088
1094
  async setupSchema() {
1089
1095
  if (!this.schema || this.schemaSetupComplete) {
@@ -1162,6 +1168,48 @@ var PostgresStore = class extends MastraStorage {
1162
1168
  throw error;
1163
1169
  }
1164
1170
  }
1171
+ getDefaultValue(type) {
1172
+ switch (type) {
1173
+ case "timestamp":
1174
+ return "DEFAULT NOW()";
1175
+ case "jsonb":
1176
+ return "DEFAULT '{}'::jsonb";
1177
+ default:
1178
+ return super.getDefaultValue(type);
1179
+ }
1180
+ }
1181
+ /**
1182
+ * Alters table schema to add columns if they don't exist
1183
+ * @param tableName Name of the table
1184
+ * @param schema Schema of the table
1185
+ * @param ifNotExists Array of column names to add if they don't exist
1186
+ */
1187
+ async alterTable({
1188
+ tableName,
1189
+ schema,
1190
+ ifNotExists
1191
+ }) {
1192
+ const fullTableName = this.getTableName(tableName);
1193
+ try {
1194
+ for (const columnName of ifNotExists) {
1195
+ if (schema[columnName]) {
1196
+ const columnDef = schema[columnName];
1197
+ const sqlType = this.getSqlType(columnDef.type);
1198
+ const nullable = columnDef.nullable === false ? "NOT NULL" : "";
1199
+ const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
1200
+ const parsedColumnName = parseSqlIdentifier(columnName, "column name");
1201
+ const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN IF NOT EXISTS "${parsedColumnName}" ${sqlType} ${nullable} ${defaultValue}`.trim();
1202
+ await this.db.none(alterSql);
1203
+ this.logger?.debug?.(`Ensured column ${parsedColumnName} exists in table ${fullTableName}`);
1204
+ }
1205
+ }
1206
+ } catch (error) {
1207
+ this.logger?.error?.(
1208
+ `Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
1209
+ );
1210
+ throw new Error(`Failed to alter table ${tableName}: ${error}`);
1211
+ }
1212
+ }
1165
1213
  async clearTable({ tableName }) {
1166
1214
  try {
1167
1215
  await this.db.none(`TRUNCATE TABLE ${this.getTableName(tableName)} CASCADE`);
@@ -1237,58 +1285,65 @@ var PostgresStore = class extends MastraStorage {
1237
1285
  throw error;
1238
1286
  }
1239
1287
  }
1288
+ /**
1289
+ * @deprecated use getThreadsByResourceIdPaginated instead
1290
+ */
1240
1291
  async getThreadsByResourceId(args) {
1241
- const { resourceId, page, perPage: perPageInput } = args;
1292
+ const { resourceId } = args;
1242
1293
  try {
1243
1294
  const baseQuery = `FROM ${this.getTableName(TABLE_THREADS)} WHERE "resourceId" = $1`;
1244
1295
  const queryParams = [resourceId];
1245
- if (page !== void 0) {
1246
- const perPage = perPageInput !== void 0 ? perPageInput : 100;
1247
- const currentOffset = page * perPage;
1248
- const countQuery = `SELECT COUNT(*) ${baseQuery}`;
1249
- const countResult = await this.db.one(countQuery, queryParams);
1250
- const total = parseInt(countResult.count, 10);
1251
- if (total === 0) {
1252
- return {
1253
- threads: [],
1254
- total: 0,
1255
- page,
1256
- perPage,
1257
- hasMore: false
1258
- };
1259
- }
1260
- const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC LIMIT $2 OFFSET $3`;
1261
- const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1262
- const threads = (rows || []).map((thread) => ({
1263
- ...thread,
1264
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1265
- createdAt: thread.createdAt,
1266
- // Assuming already Date objects or ISO strings
1267
- updatedAt: thread.updatedAt
1268
- }));
1296
+ const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC`;
1297
+ const rows = await this.db.manyOrNone(dataQuery, queryParams);
1298
+ return (rows || []).map((thread) => ({
1299
+ ...thread,
1300
+ metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1301
+ createdAt: thread.createdAt,
1302
+ updatedAt: thread.updatedAt
1303
+ }));
1304
+ } catch (error) {
1305
+ this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
1306
+ return [];
1307
+ }
1308
+ }
1309
+ async getThreadsByResourceIdPaginated(args) {
1310
+ const { resourceId, page = 0, perPage: perPageInput } = args;
1311
+ try {
1312
+ const baseQuery = `FROM ${this.getTableName(TABLE_THREADS)} WHERE "resourceId" = $1`;
1313
+ const queryParams = [resourceId];
1314
+ const perPage = perPageInput !== void 0 ? perPageInput : 100;
1315
+ const currentOffset = page * perPage;
1316
+ const countQuery = `SELECT COUNT(*) ${baseQuery}`;
1317
+ const countResult = await this.db.one(countQuery, queryParams);
1318
+ const total = parseInt(countResult.count, 10);
1319
+ if (total === 0) {
1269
1320
  return {
1270
- threads,
1271
- total,
1321
+ threads: [],
1322
+ total: 0,
1272
1323
  page,
1273
1324
  perPage,
1274
- hasMore: currentOffset + threads.length < total
1325
+ hasMore: false
1275
1326
  };
1276
- } else {
1277
- const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC`;
1278
- const rows = await this.db.manyOrNone(dataQuery, queryParams);
1279
- return (rows || []).map((thread) => ({
1280
- ...thread,
1281
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1282
- createdAt: thread.createdAt,
1283
- updatedAt: thread.updatedAt
1284
- }));
1285
1327
  }
1328
+ const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "updatedAt" ${baseQuery} ORDER BY "createdAt" DESC LIMIT $2 OFFSET $3`;
1329
+ const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1330
+ const threads = (rows || []).map((thread) => ({
1331
+ ...thread,
1332
+ metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
1333
+ createdAt: thread.createdAt,
1334
+ // Assuming already Date objects or ISO strings
1335
+ updatedAt: thread.updatedAt
1336
+ }));
1337
+ return {
1338
+ threads,
1339
+ total,
1340
+ page,
1341
+ perPage,
1342
+ hasMore: currentOffset + threads.length < total
1343
+ };
1286
1344
  } catch (error) {
1287
1345
  this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
1288
- if (page !== void 0) {
1289
- return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
1290
- }
1291
- return [];
1346
+ return { threads: [], total: 0, page, perPage: perPageInput || 100, hasMore: false };
1292
1347
  }
1293
1348
  }
1294
1349
  async saveThread({ thread }) {
@@ -1369,144 +1424,156 @@ var PostgresStore = class extends MastraStorage {
1369
1424
  }
1370
1425
  }
1371
1426
  async getMessages(args) {
1372
- const { threadId, format, page, perPage: perPageInput, fromDate, toDate, selectBy } = args;
1427
+ const { threadId, format, selectBy } = args;
1373
1428
  const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
1374
1429
  const orderByStatement = `ORDER BY "createdAt" DESC`;
1375
1430
  try {
1376
- if (page !== void 0) {
1377
- const perPage = perPageInput !== void 0 ? perPageInput : 40;
1378
- const currentOffset = page * perPage;
1379
- const conditions = [`thread_id = $1`];
1380
- const queryParams = [threadId];
1381
- let paramIndex = 2;
1382
- if (fromDate) {
1383
- conditions.push(`"createdAt" >= $${paramIndex++}`);
1384
- queryParams.push(fromDate);
1385
- }
1386
- if (toDate) {
1387
- conditions.push(`"createdAt" <= $${paramIndex++}`);
1388
- queryParams.push(toDate);
1389
- }
1390
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1391
- const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_MESSAGES)} ${whereClause}`;
1392
- const countResult = await this.db.one(countQuery, queryParams);
1393
- const total = parseInt(countResult.count, 10);
1394
- if (total === 0) {
1395
- return {
1396
- messages: [],
1397
- total: 0,
1398
- page,
1399
- perPage,
1400
- hasMore: false
1401
- };
1402
- }
1403
- const dataQuery = `${selectStatement} FROM ${this.getTableName(TABLE_MESSAGES)} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1404
- const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1405
- const fetchedMessages = (rows || []).map((message) => {
1406
- if (typeof message.content === "string") {
1407
- try {
1408
- message.content = JSON.parse(message.content);
1409
- } catch {
1410
- }
1411
- }
1412
- if (message.type === "v2") delete message.type;
1413
- return message;
1414
- });
1415
- const messagesToReturn = format === "v2" ? fetchedMessages.map(
1416
- (m) => ({
1417
- ...m,
1418
- content: m.content || { format: 2, parts: [{ type: "text", text: "" }] }
1419
- })
1420
- ) : fetchedMessages;
1421
- return {
1422
- messages: messagesToReturn,
1423
- total,
1424
- page,
1425
- perPage,
1426
- hasMore: currentOffset + fetchedMessages.length < total
1427
- };
1428
- } else {
1429
- let rows = [];
1430
- const include = selectBy?.include || [];
1431
- if (include.length) {
1432
- rows = await this.db.manyOrNone(
1431
+ let rows = [];
1432
+ const include = selectBy?.include || [];
1433
+ if (include.length) {
1434
+ const unionQueries = [];
1435
+ const params = [];
1436
+ let paramIdx = 1;
1437
+ for (const inc of include) {
1438
+ const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
1439
+ const searchId = inc.threadId || threadId;
1440
+ unionQueries.push(
1433
1441
  `
1434
- WITH ordered_messages AS (
1435
- SELECT
1436
- *,
1437
- ROW_NUMBER() OVER (${orderByStatement}) as row_num
1438
- FROM ${this.getTableName(TABLE_MESSAGES)}
1439
- WHERE thread_id = $1
1440
- )
1441
- SELECT
1442
- m.id,
1443
- m.content,
1444
- m.role,
1445
- m.type,
1446
- m."createdAt",
1447
- m.thread_id AS "threadId"
1448
- FROM ordered_messages m
1449
- WHERE m.id = ANY($2)
1450
- OR EXISTS (
1451
- SELECT 1 FROM ordered_messages target
1452
- WHERE target.id = ANY($2)
1453
- AND (
1454
- -- Get previous messages based on the max withPreviousMessages
1455
- (m.row_num <= target.row_num + $3 AND m.row_num > target.row_num)
1456
- OR
1457
- -- Get next messages based on the max withNextMessages
1458
- (m.row_num >= target.row_num - $4 AND m.row_num < target.row_num)
1442
+ SELECT * FROM (
1443
+ WITH ordered_messages AS (
1444
+ SELECT
1445
+ *,
1446
+ ROW_NUMBER() OVER (${orderByStatement}) as row_num
1447
+ FROM ${this.getTableName(TABLE_MESSAGES)}
1448
+ WHERE thread_id = $${paramIdx}
1459
1449
  )
1460
- )
1461
- ORDER BY m."createdAt" ASC
1462
- `,
1450
+ SELECT
1451
+ m.id,
1452
+ m.content,
1453
+ m.role,
1454
+ m.type,
1455
+ m."createdAt",
1456
+ m.thread_id AS "threadId",
1457
+ m."resourceId"
1458
+ FROM ordered_messages m
1459
+ WHERE m.id = $${paramIdx + 1}
1460
+ OR EXISTS (
1461
+ SELECT 1 FROM ordered_messages target
1462
+ WHERE target.id = $${paramIdx + 1}
1463
+ AND (
1464
+ -- Get previous messages based on the max withPreviousMessages
1465
+ (m.row_num <= target.row_num + $${paramIdx + 2} AND m.row_num > target.row_num)
1466
+ OR
1467
+ -- Get next messages based on the max withNextMessages
1468
+ (m.row_num >= target.row_num - $${paramIdx + 3} AND m.row_num < target.row_num)
1469
+ )
1470
+ )
1471
+ )
1472
+ `
1463
1473
  // Keep ASC for final sorting after fetching context
1464
- [
1465
- threadId,
1466
- include.map((i) => i.id),
1467
- Math.max(0, ...include.map((i) => i.withPreviousMessages || 0)),
1468
- // Ensure non-negative
1469
- Math.max(0, ...include.map((i) => i.withNextMessages || 0))
1470
- // Ensure non-negative
1471
- ]
1472
1474
  );
1473
- } else {
1474
- const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
1475
- if (limit === 0 && selectBy?.last !== false) ; else {
1476
- let query = `${selectStatement} FROM ${this.getTableName(TABLE_MESSAGES)} WHERE thread_id = $1 ${orderByStatement}`;
1477
- const queryParams = [threadId];
1478
- if (limit !== void 0 && selectBy?.last !== false) {
1479
- query += ` LIMIT $2`;
1480
- queryParams.push(limit);
1481
- }
1482
- rows = await this.db.manyOrNone(query, queryParams);
1483
- }
1475
+ params.push(searchId, id, withPreviousMessages, withNextMessages);
1476
+ paramIdx += 4;
1484
1477
  }
1485
- const fetchedMessages = (rows || []).map((message) => {
1486
- if (typeof message.content === "string") {
1487
- try {
1488
- message.content = JSON.parse(message.content);
1489
- } catch {
1490
- }
1491
- }
1492
- if (message.type === "v2") delete message.type;
1493
- return message;
1494
- });
1495
- const sortedMessages = fetchedMessages.sort(
1496
- (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
1478
+ const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
1479
+ const includedRows = await this.db.manyOrNone(finalQuery, params);
1480
+ const dedupedRows = Object.values(
1481
+ includedRows.reduce(
1482
+ (acc, row) => {
1483
+ acc[row.id] = row;
1484
+ return acc;
1485
+ },
1486
+ {}
1487
+ )
1497
1488
  );
1498
- return format === "v2" ? sortedMessages.map(
1499
- (m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
1500
- ) : sortedMessages;
1489
+ rows = dedupedRows;
1490
+ } else {
1491
+ const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
1492
+ if (limit === 0 && selectBy?.last !== false) ; else {
1493
+ let query = `${selectStatement} FROM ${this.getTableName(
1494
+ TABLE_MESSAGES
1495
+ )} WHERE thread_id = $1 ${orderByStatement}`;
1496
+ const queryParams = [threadId];
1497
+ if (limit !== void 0 && selectBy?.last !== false) {
1498
+ query += ` LIMIT $2`;
1499
+ queryParams.push(limit);
1500
+ }
1501
+ rows = await this.db.manyOrNone(query, queryParams);
1502
+ }
1501
1503
  }
1504
+ const fetchedMessages = (rows || []).map((message) => {
1505
+ if (typeof message.content === "string") {
1506
+ try {
1507
+ message.content = JSON.parse(message.content);
1508
+ } catch {
1509
+ }
1510
+ }
1511
+ if (message.type === "v2") delete message.type;
1512
+ return message;
1513
+ });
1514
+ const sortedMessages = fetchedMessages.sort(
1515
+ (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
1516
+ );
1517
+ return format === "v2" ? sortedMessages.map(
1518
+ (m) => ({ ...m, content: m.content || { format: 2, parts: [{ type: "text", text: "" }] } })
1519
+ ) : sortedMessages;
1502
1520
  } catch (error) {
1503
1521
  this.logger.error("Error getting messages:", error);
1504
- if (page !== void 0) {
1505
- return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
1506
- }
1507
1522
  return [];
1508
1523
  }
1509
1524
  }
1525
+ async getMessagesPaginated(args) {
1526
+ const { threadId, format, selectBy } = args;
1527
+ const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
1528
+ const fromDate = dateRange?.start;
1529
+ const toDate = dateRange?.end;
1530
+ const selectStatement = `SELECT id, content, role, type, "createdAt", thread_id AS "threadId"`;
1531
+ const orderByStatement = `ORDER BY "createdAt" DESC`;
1532
+ try {
1533
+ const perPage = perPageInput !== void 0 ? perPageInput : 40;
1534
+ const currentOffset = page * perPage;
1535
+ const conditions = [`thread_id = $1`];
1536
+ const queryParams = [threadId];
1537
+ let paramIndex = 2;
1538
+ if (fromDate) {
1539
+ conditions.push(`"createdAt" >= $${paramIndex++}`);
1540
+ queryParams.push(fromDate);
1541
+ }
1542
+ if (toDate) {
1543
+ conditions.push(`"createdAt" <= $${paramIndex++}`);
1544
+ queryParams.push(toDate);
1545
+ }
1546
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1547
+ const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_MESSAGES)} ${whereClause}`;
1548
+ const countResult = await this.db.one(countQuery, queryParams);
1549
+ const total = parseInt(countResult.count, 10);
1550
+ if (total === 0) {
1551
+ return {
1552
+ messages: [],
1553
+ total: 0,
1554
+ page,
1555
+ perPage,
1556
+ hasMore: false
1557
+ };
1558
+ }
1559
+ const dataQuery = `${selectStatement} FROM ${this.getTableName(
1560
+ TABLE_MESSAGES
1561
+ )} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1562
+ const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1563
+ const list = new MessageList().add(rows || [], "memory");
1564
+ const messagesToReturn = format === `v2` ? list.get.all.v2() : list.get.all.v1();
1565
+ return {
1566
+ messages: messagesToReturn,
1567
+ total,
1568
+ page,
1569
+ perPage,
1570
+ hasMore: currentOffset + rows.length < total
1571
+ };
1572
+ } catch (error) {
1573
+ this.logger.error("Error getting messages:", error);
1574
+ return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
1575
+ }
1576
+ }
1510
1577
  async saveMessages({
1511
1578
  messages,
1512
1579
  format
@@ -1523,16 +1590,27 @@ var PostgresStore = class extends MastraStorage {
1523
1590
  }
1524
1591
  await this.db.tx(async (t) => {
1525
1592
  for (const message of messages) {
1593
+ if (!message.threadId) {
1594
+ throw new Error(
1595
+ `Expected to find a threadId for message, but couldn't find one. An unexpected error has occurred.`
1596
+ );
1597
+ }
1598
+ if (!message.resourceId) {
1599
+ throw new Error(
1600
+ `Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`
1601
+ );
1602
+ }
1526
1603
  await t.none(
1527
- `INSERT INTO ${this.getTableName(TABLE_MESSAGES)} (id, thread_id, content, "createdAt", role, type)
1528
- VALUES ($1, $2, $3, $4, $5, $6)`,
1604
+ `INSERT INTO ${this.getTableName(TABLE_MESSAGES)} (id, thread_id, content, "createdAt", role, type, "resourceId")
1605
+ VALUES ($1, $2, $3, $4, $5, $6, $7)`,
1529
1606
  [
1530
1607
  message.id,
1531
- threadId,
1608
+ message.threadId,
1532
1609
  typeof message.content === "string" ? message.content : JSON.stringify(message.content),
1533
1610
  message.createdAt || (/* @__PURE__ */ new Date()).toISOString(),
1534
1611
  message.role,
1535
- message.type || "v2"
1612
+ message.type || "v2",
1613
+ message.resourceId
1536
1614
  ]
1537
1615
  );
1538
1616
  }
@@ -1717,8 +1795,10 @@ var PostgresStore = class extends MastraStorage {
1717
1795
  async close() {
1718
1796
  this.pgp.end();
1719
1797
  }
1720
- async getEvals(options) {
1721
- const { agentName, type, page, perPage, limit, offset, fromDate, toDate } = options || {};
1798
+ async getEvals(options = {}) {
1799
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
1800
+ const fromDate = dateRange?.start;
1801
+ const toDate = dateRange?.end;
1722
1802
  const conditions = [];
1723
1803
  const queryParams = [];
1724
1804
  let paramIndex = 1;
@@ -1743,45 +1823,26 @@ var PostgresStore = class extends MastraStorage {
1743
1823
  const countQuery = `SELECT COUNT(*) FROM ${this.getTableName(TABLE_EVALS)} ${whereClause}`;
1744
1824
  const countResult = await this.db.one(countQuery, queryParams);
1745
1825
  const total = parseInt(countResult.count, 10);
1746
- let currentLimit;
1747
- let currentOffset;
1748
- let currentPage = page;
1749
- let currentPerPage = perPage;
1750
- let hasMore = false;
1751
- if (limit !== void 0 && offset !== void 0) {
1752
- currentLimit = limit;
1753
- currentOffset = offset;
1754
- currentPage = void 0;
1755
- currentPerPage = void 0;
1756
- hasMore = currentOffset + currentLimit < total;
1757
- } else if (page !== void 0 && perPage !== void 0) {
1758
- currentLimit = perPage;
1759
- currentOffset = page * perPage;
1760
- hasMore = currentOffset + currentLimit < total;
1761
- } else {
1762
- currentLimit = perPage || 100;
1763
- currentOffset = (page || 0) * currentLimit;
1764
- if (page === void 0) currentPage = 0;
1765
- if (currentPerPage === void 0) currentPerPage = currentLimit;
1766
- hasMore = currentOffset + currentLimit < total;
1767
- }
1826
+ const currentOffset = page * perPage;
1768
1827
  if (total === 0) {
1769
1828
  return {
1770
1829
  evals: [],
1771
1830
  total: 0,
1772
- page: currentPage,
1773
- perPage: currentPerPage,
1831
+ page,
1832
+ perPage,
1774
1833
  hasMore: false
1775
1834
  };
1776
1835
  }
1777
- const dataQuery = `SELECT * FROM ${this.getTableName(TABLE_EVALS)} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1778
- const rows = await this.db.manyOrNone(dataQuery, [...queryParams, currentLimit, currentOffset]);
1836
+ const dataQuery = `SELECT * FROM ${this.getTableName(
1837
+ TABLE_EVALS
1838
+ )} ${whereClause} ORDER BY created_at DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
1839
+ const rows = await this.db.manyOrNone(dataQuery, [...queryParams, perPage, currentOffset]);
1779
1840
  return {
1780
1841
  evals: rows?.map((row) => this.transformEvalRow(row)) ?? [],
1781
1842
  total,
1782
- page: currentPage,
1783
- perPage: currentPerPage,
1784
- hasMore
1843
+ page,
1844
+ perPage,
1845
+ hasMore: currentOffset + (rows?.length ?? 0) < total
1785
1846
  };
1786
1847
  }
1787
1848
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/pg",
3
- "version": "0.10.2-alpha.0",
3
+ "version": "0.10.2-alpha.2",
4
4
  "description": "Postgres provider for Mastra - includes both vector and db storage capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,10 +32,10 @@
32
32
  "eslint": "^9.28.0",
33
33
  "tsup": "^8.5.0",
34
34
  "typescript": "^5.8.2",
35
- "vitest": "^3.1.2",
35
+ "vitest": "^3.2.2",
36
36
  "@internal/lint": "0.0.10",
37
- "@internal/storage-test-utils": "0.0.6",
38
- "@mastra/core": "0.10.4-alpha.0"
37
+ "@mastra/core": "0.10.4-alpha.2",
38
+ "@internal/storage-test-utils": "0.0.6"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@mastra/core": "^0.10.2-alpha.0"