@mastra/libsql 1.6.4-alpha.0 → 1.7.0-alpha.0

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.cjs CHANGED
@@ -1320,6 +1320,8 @@ var LibSQLDB = class extends base.MastraBase {
1320
1320
  maxRetries;
1321
1321
  initialBackoffMs;
1322
1322
  executeWriteOperationWithRetry;
1323
+ /** Cache of actual table columns: tableName -> Promise<Set<columnName>> (stores in-flight promise to coalesce concurrent calls) */
1324
+ tableColumnsCache = /* @__PURE__ */ new Map();
1323
1325
  constructor({
1324
1326
  client,
1325
1327
  maxRetries,
@@ -1338,6 +1340,47 @@ var LibSQLDB = class extends base.MastraBase {
1338
1340
  initialBackoffMs: this.initialBackoffMs
1339
1341
  });
1340
1342
  }
1343
+ /**
1344
+ * Gets the set of column names that actually exist in the database table.
1345
+ * Results are cached; the cache is invalidated when alterTable() adds new columns.
1346
+ */
1347
+ async getTableColumns(tableName) {
1348
+ const cached = this.tableColumnsCache.get(tableName);
1349
+ if (cached) return cached;
1350
+ const promise = (async () => {
1351
+ try {
1352
+ const sanitizedTable = utils.parseSqlIdentifier(tableName, "table name");
1353
+ const result = await this.client.execute({
1354
+ sql: `PRAGMA table_info("${sanitizedTable}")`
1355
+ });
1356
+ const columns = new Set((result.rows || []).map((row) => row.name));
1357
+ if (columns.size === 0) {
1358
+ this.tableColumnsCache.delete(tableName);
1359
+ }
1360
+ return columns;
1361
+ } catch (error) {
1362
+ this.tableColumnsCache.delete(tableName);
1363
+ throw error;
1364
+ }
1365
+ })();
1366
+ this.tableColumnsCache.set(tableName, promise);
1367
+ return promise;
1368
+ }
1369
+ /**
1370
+ * Filters a record to only include columns that exist in the actual database table.
1371
+ * Unknown columns are silently dropped to ensure forward compatibility.
1372
+ */
1373
+ async filterRecordToKnownColumns(tableName, record) {
1374
+ const knownColumns = await this.getTableColumns(tableName);
1375
+ if (knownColumns.size === 0) return record;
1376
+ const filtered = {};
1377
+ for (const [key, value] of Object.entries(record)) {
1378
+ if (knownColumns.has(key)) {
1379
+ filtered[key] = value;
1380
+ }
1381
+ }
1382
+ return filtered;
1383
+ }
1341
1384
  /**
1342
1385
  * Checks if a column exists in the specified table.
1343
1386
  *
@@ -1359,10 +1402,12 @@ var LibSQLDB = class extends base.MastraBase {
1359
1402
  tableName,
1360
1403
  record
1361
1404
  }) {
1405
+ const filteredRecord = await this.filterRecordToKnownColumns(tableName, record);
1406
+ if (Object.keys(filteredRecord).length === 0) return;
1362
1407
  await this.client.execute(
1363
1408
  prepareStatement({
1364
1409
  tableName,
1365
- record
1410
+ record: filteredRecord
1366
1411
  })
1367
1412
  );
1368
1413
  }
@@ -1384,7 +1429,9 @@ var LibSQLDB = class extends base.MastraBase {
1384
1429
  keys,
1385
1430
  data
1386
1431
  }) {
1387
- await this.client.execute(prepareUpdateStatement({ tableName, updates: data, keys }));
1432
+ const filteredData = await this.filterRecordToKnownColumns(tableName, data);
1433
+ if (Object.keys(filteredData).length === 0) return;
1434
+ await this.client.execute(prepareUpdateStatement({ tableName, updates: filteredData, keys }));
1388
1435
  }
1389
1436
  /**
1390
1437
  * Updates a record in the specified table with automatic retry on lock errors.
@@ -1405,7 +1452,10 @@ var LibSQLDB = class extends base.MastraBase {
1405
1452
  records
1406
1453
  }) {
1407
1454
  if (records.length === 0) return;
1408
- const batchStatements = records.map((r) => prepareStatement({ tableName, record: r }));
1455
+ const filteredRecords = await Promise.all(records.map((r) => this.filterRecordToKnownColumns(tableName, r)));
1456
+ const nonEmptyRecords = filteredRecords.filter((r) => Object.keys(r).length > 0);
1457
+ if (nonEmptyRecords.length === 0) return;
1458
+ const batchStatements = nonEmptyRecords.map((r) => prepareStatement({ tableName, record: r }));
1409
1459
  await this.client.batch(batchStatements, "write");
1410
1460
  }
1411
1461
  /**
@@ -1443,7 +1493,15 @@ var LibSQLDB = class extends base.MastraBase {
1443
1493
  updates
1444
1494
  }) {
1445
1495
  if (updates.length === 0) return;
1446
- const batchStatements = updates.map(
1496
+ const filteredUpdates = [];
1497
+ for (const { keys, data } of updates) {
1498
+ const filteredData = await this.filterRecordToKnownColumns(tableName, data);
1499
+ if (Object.keys(filteredData).length > 0) {
1500
+ filteredUpdates.push({ keys, data: filteredData });
1501
+ }
1502
+ }
1503
+ if (filteredUpdates.length === 0) return;
1504
+ const batchStatements = filteredUpdates.map(
1447
1505
  ({ keys, data }) => prepareUpdateStatement({
1448
1506
  tableName,
1449
1507
  updates: data,
@@ -1753,6 +1811,8 @@ var LibSQLDB = class extends base.MastraBase {
1753
1811
  },
1754
1812
  error$1
1755
1813
  );
1814
+ } finally {
1815
+ this.tableColumnsCache.delete(tableName);
1756
1816
  }
1757
1817
  }
1758
1818
  /**
@@ -2032,6 +2092,8 @@ Note: This migration may take some time for large tables.
2032
2092
  },
2033
2093
  error$1
2034
2094
  );
2095
+ } finally {
2096
+ this.tableColumnsCache.delete(tableName);
2035
2097
  }
2036
2098
  }
2037
2099
  /**
@@ -2924,6 +2986,8 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2924
2986
  await this.#db.createTable({ tableName: storage.TABLE_DATASETS, schema: storage.DATASETS_SCHEMA });
2925
2987
  await this.#db.createTable({ tableName: storage.TABLE_DATASET_ITEMS, schema: storage.DATASET_ITEMS_SCHEMA });
2926
2988
  await this.#db.createTable({ tableName: storage.TABLE_DATASET_VERSIONS, schema: storage.DATASET_VERSIONS_SCHEMA });
2989
+ await this.#addColumnIfNotExists(storage.TABLE_DATASETS, "requestContextSchema", "TEXT");
2990
+ await this.#addColumnIfNotExists(storage.TABLE_DATASET_ITEMS, "requestContext", "TEXT");
2927
2991
  await this.#client.execute({
2928
2992
  sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto ON "${storage.TABLE_DATASET_ITEMS}" ("datasetId", "validTo")`,
2929
2993
  args: []
@@ -2945,6 +3009,12 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2945
3009
  args: []
2946
3010
  });
2947
3011
  }
3012
+ async #addColumnIfNotExists(table, column, sqlType) {
3013
+ const exists = await this.#db.hasColumn(table, column);
3014
+ if (!exists) {
3015
+ await this.#client.execute({ sql: `ALTER TABLE "${table}" ADD COLUMN "${column}" ${sqlType}`, args: [] });
3016
+ }
3017
+ }
2948
3018
  async dangerouslyClearAll() {
2949
3019
  await this.#db.deleteData({ tableName: storage.TABLE_DATASET_VERSIONS });
2950
3020
  await this.#db.deleteData({ tableName: storage.TABLE_DATASET_ITEMS });
@@ -2959,6 +3029,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2959
3029
  metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2960
3030
  inputSchema: row.inputSchema ? storage.safelyParseJSON(row.inputSchema) : void 0,
2961
3031
  groundTruthSchema: row.groundTruthSchema ? storage.safelyParseJSON(row.groundTruthSchema) : void 0,
3032
+ requestContextSchema: row.requestContextSchema ? storage.safelyParseJSON(row.requestContextSchema) : void 0,
2962
3033
  version: row.version,
2963
3034
  createdAt: storage.ensureDate(row.createdAt),
2964
3035
  updatedAt: storage.ensureDate(row.updatedAt)
@@ -2971,6 +3042,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2971
3042
  datasetVersion: row.datasetVersion,
2972
3043
  input: storage.safelyParseJSON(row.input),
2973
3044
  groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
3045
+ requestContext: row.requestContext ? storage.safelyParseJSON(row.requestContext) : void 0,
2974
3046
  metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2975
3047
  createdAt: storage.ensureDate(row.createdAt),
2976
3048
  updatedAt: storage.ensureDate(row.updatedAt)
@@ -2985,6 +3057,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
2985
3057
  isDeleted: Boolean(row.isDeleted),
2986
3058
  input: storage.safelyParseJSON(row.input),
2987
3059
  groundTruth: row.groundTruth ? storage.safelyParseJSON(row.groundTruth) : void 0,
3060
+ requestContext: row.requestContext ? storage.safelyParseJSON(row.requestContext) : void 0,
2988
3061
  metadata: row.metadata ? storage.safelyParseJSON(row.metadata) : void 0,
2989
3062
  createdAt: storage.ensureDate(row.createdAt),
2990
3063
  updatedAt: storage.ensureDate(row.updatedAt)
@@ -3013,6 +3086,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3013
3086
  metadata: input.metadata,
3014
3087
  inputSchema: input.inputSchema ?? null,
3015
3088
  groundTruthSchema: input.groundTruthSchema ?? null,
3089
+ requestContextSchema: input.requestContextSchema ?? null,
3016
3090
  version: 0,
3017
3091
  createdAt: nowIso,
3018
3092
  updatedAt: nowIso
@@ -3025,6 +3099,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3025
3099
  metadata: input.metadata,
3026
3100
  inputSchema: input.inputSchema ?? void 0,
3027
3101
  groundTruthSchema: input.groundTruthSchema ?? void 0,
3102
+ requestContextSchema: input.requestContextSchema ?? void 0,
3028
3103
  version: 0,
3029
3104
  createdAt: now,
3030
3105
  updatedAt: now
@@ -3092,6 +3167,10 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3092
3167
  updates.push("groundTruthSchema = ?");
3093
3168
  values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
3094
3169
  }
3170
+ if (args.requestContextSchema !== void 0) {
3171
+ updates.push("requestContextSchema = ?");
3172
+ values.push(args.requestContextSchema === null ? null : JSON.stringify(args.requestContextSchema));
3173
+ }
3095
3174
  values.push(args.id);
3096
3175
  await this.#client.execute({
3097
3176
  sql: `UPDATE ${storage.TABLE_DATASETS} SET ${updates.join(", ")} WHERE id = ?`,
@@ -3104,6 +3183,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3104
3183
  metadata: args.metadata ?? existing.metadata,
3105
3184
  inputSchema: (args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema) ?? void 0,
3106
3185
  groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
3186
+ requestContextSchema: (args.requestContextSchema !== void 0 ? args.requestContextSchema : existing.requestContextSchema) ?? void 0,
3107
3187
  updatedAt: new Date(now)
3108
3188
  };
3109
3189
  } catch (error$1) {
@@ -3209,13 +3289,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3209
3289
  args: [args.datasetId]
3210
3290
  },
3211
3291
  {
3212
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3292
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3213
3293
  args: [
3214
3294
  id,
3215
3295
  args.datasetId,
3216
3296
  args.datasetId,
3217
3297
  jsonbArg(args.input),
3218
3298
  jsonbArg(args.groundTruth),
3299
+ jsonbArg(args.requestContext),
3219
3300
  jsonbArg(args.metadata),
3220
3301
  nowIso,
3221
3302
  nowIso
@@ -3235,6 +3316,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3235
3316
  datasetVersion: newVersion,
3236
3317
  input: args.input,
3237
3318
  groundTruth: args.groundTruth,
3319
+ requestContext: args.requestContext,
3238
3320
  metadata: args.metadata,
3239
3321
  createdAt: now,
3240
3322
  updatedAt: now
@@ -3275,6 +3357,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3275
3357
  const nowIso = now.toISOString();
3276
3358
  const mergedInput = args.input ?? existing.input;
3277
3359
  const mergedGroundTruth = args.groundTruth ?? existing.groundTruth;
3360
+ const mergedRequestContext = args.requestContext ?? existing.requestContext;
3278
3361
  const mergedMetadata = args.metadata ?? existing.metadata;
3279
3362
  const results = await this.#client.batch(
3280
3363
  [
@@ -3287,13 +3370,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3287
3370
  args: [args.datasetId, args.id]
3288
3371
  },
3289
3372
  {
3290
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3373
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3291
3374
  args: [
3292
3375
  args.id,
3293
3376
  args.datasetId,
3294
3377
  args.datasetId,
3295
3378
  jsonbArg(mergedInput),
3296
3379
  jsonbArg(mergedGroundTruth),
3380
+ jsonbArg(mergedRequestContext),
3297
3381
  jsonbArg(mergedMetadata),
3298
3382
  existing.createdAt.toISOString(),
3299
3383
  nowIso
@@ -3312,6 +3396,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3312
3396
  datasetVersion: newVersion,
3313
3397
  input: mergedInput,
3314
3398
  groundTruth: mergedGroundTruth,
3399
+ requestContext: mergedRequestContext,
3315
3400
  metadata: mergedMetadata,
3316
3401
  updatedAt: now
3317
3402
  };
@@ -3352,13 +3437,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3352
3437
  args: [datasetId, id]
3353
3438
  },
3354
3439
  {
3355
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3440
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3356
3441
  args: [
3357
3442
  id,
3358
3443
  datasetId,
3359
3444
  datasetId,
3360
3445
  jsonbArg(existing.input),
3361
3446
  jsonbArg(existing.groundTruth),
3447
+ jsonbArg(existing.requestContext),
3362
3448
  jsonbArg(existing.metadata),
3363
3449
  existing.createdAt.toISOString(),
3364
3450
  nowIso
@@ -3639,13 +3725,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3639
3725
  const id = crypto.randomUUID();
3640
3726
  items.push({ id, input: itemInput });
3641
3727
  statements.push({
3642
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3728
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3643
3729
  args: [
3644
3730
  id,
3645
3731
  input.datasetId,
3646
3732
  input.datasetId,
3647
3733
  jsonbArg(itemInput.input),
3648
3734
  jsonbArg(itemInput.groundTruth),
3735
+ jsonbArg(itemInput.requestContext),
3649
3736
  jsonbArg(itemInput.metadata),
3650
3737
  nowIso,
3651
3738
  nowIso
@@ -3664,6 +3751,7 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3664
3751
  datasetVersion: newVersion,
3665
3752
  input: itemInput.input,
3666
3753
  groundTruth: itemInput.groundTruth,
3754
+ requestContext: itemInput.requestContext,
3667
3755
  metadata: itemInput.metadata,
3668
3756
  createdAt: now,
3669
3757
  updatedAt: now
@@ -3713,13 +3801,14 @@ var DatasetsLibSQL = class extends storage.DatasetsStorage {
3713
3801
  args: [input.datasetId, item.id]
3714
3802
  });
3715
3803
  statements.push({
3716
- sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3804
+ sql: `INSERT INTO ${storage.TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${storage.TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3717
3805
  args: [
3718
3806
  item.id,
3719
3807
  input.datasetId,
3720
3808
  input.datasetId,
3721
3809
  jsonbArg(item.input),
3722
3810
  jsonbArg(item.groundTruth),
3811
+ jsonbArg(item.requestContext),
3723
3812
  jsonbArg(item.metadata),
3724
3813
  item.createdAt.toISOString(),
3725
3814
  nowIso
@@ -5214,41 +5303,64 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5214
5303
  if (row.type && row.type !== `v2`) result.type = row.type;
5215
5304
  return result;
5216
5305
  }
5306
+ _sortMessages(messages, field, direction) {
5307
+ return messages.sort((a, b) => {
5308
+ const isDateField = field === "createdAt" || field === "updatedAt";
5309
+ const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5310
+ const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5311
+ if (typeof aValue === "number" && typeof bValue === "number") {
5312
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
5313
+ }
5314
+ return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5315
+ });
5316
+ }
5217
5317
  async _getIncludedMessages({ include }) {
5218
5318
  if (!include || include.length === 0) return null;
5319
+ const targetIds = include.map((inc) => inc.id).filter(Boolean);
5320
+ if (targetIds.length === 0) return null;
5321
+ const idPlaceholders = targetIds.map(() => "?").join(", ");
5322
+ const targetResult = await this.#client.execute({
5323
+ sql: `SELECT id, thread_id, "createdAt" FROM "${storage.TABLE_MESSAGES}" WHERE id IN (${idPlaceholders})`,
5324
+ args: targetIds
5325
+ });
5326
+ if (!targetResult.rows || targetResult.rows.length === 0) return null;
5327
+ const targetMap = new Map(
5328
+ targetResult.rows.map((r) => [r.id, { threadId: r.thread_id, createdAt: r.createdAt }])
5329
+ );
5219
5330
  const unionQueries = [];
5220
5331
  const params = [];
5221
5332
  for (const inc of include) {
5222
5333
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
5223
- unionQueries.push(
5224
- `
5225
- SELECT * FROM (
5226
- WITH target_thread AS (
5227
- SELECT thread_id FROM "${storage.TABLE_MESSAGES}" WHERE id = ?
5228
- ),
5229
- numbered_messages AS (
5230
- SELECT
5231
- id, content, role, type, "createdAt", thread_id, "resourceId",
5232
- ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
5233
- FROM "${storage.TABLE_MESSAGES}"
5234
- WHERE thread_id = (SELECT thread_id FROM target_thread)
5235
- ),
5236
- target_positions AS (
5237
- SELECT row_num as target_pos
5238
- FROM numbered_messages
5239
- WHERE id = ?
5240
- )
5241
- SELECT DISTINCT m.*
5242
- FROM numbered_messages m
5243
- CROSS JOIN target_positions t
5244
- WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)
5245
- )
5246
- `
5247
- // Keep ASC for final sorting after fetching context
5248
- );
5249
- params.push(id, id, withPreviousMessages, withNextMessages);
5250
- }
5251
- const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
5334
+ const target = targetMap.get(id);
5335
+ if (!target) continue;
5336
+ unionQueries.push(`SELECT * FROM (
5337
+ SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
5338
+ FROM "${storage.TABLE_MESSAGES}"
5339
+ WHERE thread_id = ?
5340
+ AND "createdAt" <= ?
5341
+ ORDER BY "createdAt" DESC, id DESC
5342
+ LIMIT ?
5343
+ )`);
5344
+ params.push(target.threadId, target.createdAt, withPreviousMessages + 1);
5345
+ if (withNextMessages > 0) {
5346
+ unionQueries.push(`SELECT * FROM (
5347
+ SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
5348
+ FROM "${storage.TABLE_MESSAGES}"
5349
+ WHERE thread_id = ?
5350
+ AND "createdAt" > ?
5351
+ ORDER BY "createdAt" ASC, id ASC
5352
+ LIMIT ?
5353
+ )`);
5354
+ params.push(target.threadId, target.createdAt, withNextMessages);
5355
+ }
5356
+ }
5357
+ if (unionQueries.length === 0) return null;
5358
+ let finalQuery;
5359
+ if (unionQueries.length === 1) {
5360
+ finalQuery = unionQueries[0];
5361
+ } else {
5362
+ finalQuery = `${unionQueries.join(" UNION ALL ")} ORDER BY "createdAt" ASC, id ASC`;
5363
+ }
5252
5364
  const includedResult = await this.#client.execute({ sql: finalQuery, args: params });
5253
5365
  const includedRows = includedResult.rows?.map((row) => this.parseRow(row));
5254
5366
  const seen = /* @__PURE__ */ new Set();
@@ -5343,6 +5455,23 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5343
5455
  );
5344
5456
  }
5345
5457
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5458
+ if (perPage === 0 && (!include || include.length === 0)) {
5459
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5460
+ }
5461
+ if (perPage === 0 && include && include.length > 0) {
5462
+ const includeMessages = await this._getIncludedMessages({ include });
5463
+ if (!includeMessages || includeMessages.length === 0) {
5464
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5465
+ }
5466
+ const list2 = new agent.MessageList().add(includeMessages, "memory");
5467
+ return {
5468
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
5469
+ total: 0,
5470
+ page,
5471
+ perPage: perPageForResponse,
5472
+ hasMore: false
5473
+ };
5474
+ }
5346
5475
  const countResult = await this.#client.execute({
5347
5476
  sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_MESSAGES} ${whereClause}`,
5348
5477
  args: queryParams
@@ -5376,16 +5505,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5376
5505
  }
5377
5506
  }
5378
5507
  const list = new agent.MessageList().add(messages, "memory");
5379
- let finalMessages = list.get.all.db();
5380
- finalMessages = finalMessages.sort((a, b) => {
5381
- const isDateField = field === "createdAt" || field === "updatedAt";
5382
- const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5383
- const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5384
- if (typeof aValue === "number" && typeof bValue === "number") {
5385
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
5386
- }
5387
- return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5388
- });
5508
+ const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
5389
5509
  const threadIdSet = new Set(threadIds);
5390
5510
  const returnedThreadMessageIds = new Set(
5391
5511
  finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
@@ -5471,6 +5591,23 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5471
5591
  );
5472
5592
  }
5473
5593
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
5594
+ if (perPage === 0 && (!include || include.length === 0)) {
5595
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5596
+ }
5597
+ if (perPage === 0 && include && include.length > 0) {
5598
+ const includeMessages = await this._getIncludedMessages({ include });
5599
+ if (!includeMessages || includeMessages.length === 0) {
5600
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5601
+ }
5602
+ const list2 = new agent.MessageList().add(includeMessages, "memory");
5603
+ return {
5604
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
5605
+ total: 0,
5606
+ page,
5607
+ perPage: perPageForResponse,
5608
+ hasMore: false
5609
+ };
5610
+ }
5474
5611
  const countResult = await this.#client.execute({
5475
5612
  sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_MESSAGES} ${whereClause}`,
5476
5613
  args: queryParams
@@ -5504,16 +5641,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
5504
5641
  }
5505
5642
  }
5506
5643
  const list = new agent.MessageList().add(messages, "memory");
5507
- let finalMessages = list.get.all.db();
5508
- finalMessages = finalMessages.sort((a, b) => {
5509
- const isDateField = field === "createdAt" || field === "updatedAt";
5510
- const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5511
- const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5512
- if (typeof aValue === "number" && typeof bValue === "number") {
5513
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
5514
- }
5515
- return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5516
- });
5644
+ const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
5517
5645
  const hasMore = perPageInput !== false && offset + perPage < total;
5518
5646
  return {
5519
5647
  messages: finalMessages,
@@ -7093,6 +7221,11 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
7093
7221
  }
7094
7222
  async init() {
7095
7223
  await this.#db.createTable({ tableName: storage.TABLE_SPANS, schema: storage.SPAN_SCHEMA });
7224
+ await this.#db.alterTable({
7225
+ tableName: storage.TABLE_SPANS,
7226
+ schema: storage.SPAN_SCHEMA,
7227
+ ifNotExists: ["requestContext"]
7228
+ });
7096
7229
  }
7097
7230
  async dangerouslyClearAll() {
7098
7231
  await this.#db.deleteData({ tableName: storage.TABLE_SPANS });
@@ -7264,7 +7397,8 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
7264
7397
  }
7265
7398
  async listTraces(args) {
7266
7399
  const { filters, pagination, orderBy } = storage.listTracesArgsSchema.parse(args);
7267
- const { page, perPage } = pagination;
7400
+ const page = pagination?.page ?? 0;
7401
+ const perPage = pagination?.perPage ?? 10;
7268
7402
  const tableName = utils.parseSqlIdentifier(storage.TABLE_SPANS, "table name");
7269
7403
  try {
7270
7404
  const conditions = ["parentSpanId IS NULL"];
@@ -7404,8 +7538,8 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
7404
7538
  }
7405
7539
  }
7406
7540
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
7407
- const sortField = orderBy.field;
7408
- const sortDirection = orderBy.direction;
7541
+ const sortField = orderBy?.field ?? "startedAt";
7542
+ const sortDirection = orderBy?.direction ?? "DESC";
7409
7543
  let orderByClause;
7410
7544
  if (sortField === "endedAt") {
7411
7545
  orderByClause = sortDirection === "DESC" ? `CASE WHEN ${sortField} IS NULL THEN 0 ELSE 1 END, ${sortField} DESC` : `CASE WHEN ${sortField} IS NULL THEN 1 ELSE 0 END, ${sortField} ASC`;