@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.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { createClient } from '@libsql/client';
2
2
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
- import { createVectorErrorId, AgentsStorage, AGENTS_SCHEMA, TABLE_AGENTS, AGENT_VERSIONS_SCHEMA, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BlobStore, TABLE_SKILL_BLOBS, SKILL_BLOBS_SCHEMA, DatasetsStorage, DATASETS_SCHEMA, TABLE_DATASETS, DATASET_ITEMS_SCHEMA, TABLE_DATASET_ITEMS, DATASET_VERSIONS_SCHEMA, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, ExperimentsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, MCPClientsStorage, MCP_CLIENTS_SCHEMA, TABLE_MCP_CLIENTS, MCP_CLIENT_VERSIONS_SCHEMA, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, MCP_SERVERS_SCHEMA, TABLE_MCP_SERVERS, MCP_SERVER_VERSIONS_SCHEMA, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, SPAN_SCHEMA, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, PROMPT_BLOCKS_SCHEMA, TABLE_PROMPT_BLOCKS, PROMPT_BLOCK_VERSIONS_SCHEMA, TABLE_PROMPT_BLOCK_VERSIONS, ScorerDefinitionsStorage, SCORER_DEFINITIONS_SCHEMA, TABLE_SCORER_DEFINITIONS, SCORER_DEFINITION_VERSIONS_SCHEMA, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, transformScoreRow, SkillsStorage, SKILLS_SCHEMA, TABLE_SKILLS, SKILL_VERSIONS_SCHEMA, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, WORKSPACES_SCHEMA, TABLE_WORKSPACES, WORKSPACE_VERSIONS_SCHEMA, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, TraceStatus, getSqlType } from '@mastra/core/storage';
3
+ import { createVectorErrorId, AgentsStorage, AGENTS_SCHEMA, TABLE_AGENTS, AGENT_VERSIONS_SCHEMA, TABLE_AGENT_VERSIONS, createStorageErrorId, normalizePerPage, calculatePagination, BlobStore, TABLE_SKILL_BLOBS, SKILL_BLOBS_SCHEMA, DatasetsStorage, DATASETS_SCHEMA, TABLE_DATASETS, DATASET_ITEMS_SCHEMA, TABLE_DATASET_ITEMS, DATASET_VERSIONS_SCHEMA, TABLE_DATASET_VERSIONS, ensureDate, safelyParseJSON, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, ExperimentsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, MCPClientsStorage, MCP_CLIENTS_SCHEMA, TABLE_MCP_CLIENTS, MCP_CLIENT_VERSIONS_SCHEMA, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, MCP_SERVERS_SCHEMA, TABLE_MCP_SERVERS, MCP_SERVER_VERSIONS_SCHEMA, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_SCHEMAS, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, SPAN_SCHEMA, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, PROMPT_BLOCKS_SCHEMA, TABLE_PROMPT_BLOCKS, PROMPT_BLOCK_VERSIONS_SCHEMA, TABLE_PROMPT_BLOCK_VERSIONS, ScorerDefinitionsStorage, SCORER_DEFINITIONS_SCHEMA, TABLE_SCORER_DEFINITIONS, SCORER_DEFINITION_VERSIONS_SCHEMA, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, SCORERS_SCHEMA, TABLE_SCORERS, transformScoreRow, SkillsStorage, SKILLS_SCHEMA, TABLE_SKILLS, SKILL_VERSIONS_SCHEMA, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, WORKSPACES_SCHEMA, TABLE_WORKSPACES, WORKSPACE_VERSIONS_SCHEMA, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, getSqlType, TraceStatus } from '@mastra/core/storage';
4
4
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
5
5
  import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
6
6
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
@@ -1318,6 +1318,8 @@ var LibSQLDB = class extends MastraBase {
1318
1318
  maxRetries;
1319
1319
  initialBackoffMs;
1320
1320
  executeWriteOperationWithRetry;
1321
+ /** Cache of actual table columns: tableName -> Promise<Set<columnName>> (stores in-flight promise to coalesce concurrent calls) */
1322
+ tableColumnsCache = /* @__PURE__ */ new Map();
1321
1323
  constructor({
1322
1324
  client,
1323
1325
  maxRetries,
@@ -1336,6 +1338,47 @@ var LibSQLDB = class extends MastraBase {
1336
1338
  initialBackoffMs: this.initialBackoffMs
1337
1339
  });
1338
1340
  }
1341
+ /**
1342
+ * Gets the set of column names that actually exist in the database table.
1343
+ * Results are cached; the cache is invalidated when alterTable() adds new columns.
1344
+ */
1345
+ async getTableColumns(tableName) {
1346
+ const cached = this.tableColumnsCache.get(tableName);
1347
+ if (cached) return cached;
1348
+ const promise = (async () => {
1349
+ try {
1350
+ const sanitizedTable = parseSqlIdentifier(tableName, "table name");
1351
+ const result = await this.client.execute({
1352
+ sql: `PRAGMA table_info("${sanitizedTable}")`
1353
+ });
1354
+ const columns = new Set((result.rows || []).map((row) => row.name));
1355
+ if (columns.size === 0) {
1356
+ this.tableColumnsCache.delete(tableName);
1357
+ }
1358
+ return columns;
1359
+ } catch (error) {
1360
+ this.tableColumnsCache.delete(tableName);
1361
+ throw error;
1362
+ }
1363
+ })();
1364
+ this.tableColumnsCache.set(tableName, promise);
1365
+ return promise;
1366
+ }
1367
+ /**
1368
+ * Filters a record to only include columns that exist in the actual database table.
1369
+ * Unknown columns are silently dropped to ensure forward compatibility.
1370
+ */
1371
+ async filterRecordToKnownColumns(tableName, record) {
1372
+ const knownColumns = await this.getTableColumns(tableName);
1373
+ if (knownColumns.size === 0) return record;
1374
+ const filtered = {};
1375
+ for (const [key, value] of Object.entries(record)) {
1376
+ if (knownColumns.has(key)) {
1377
+ filtered[key] = value;
1378
+ }
1379
+ }
1380
+ return filtered;
1381
+ }
1339
1382
  /**
1340
1383
  * Checks if a column exists in the specified table.
1341
1384
  *
@@ -1357,10 +1400,12 @@ var LibSQLDB = class extends MastraBase {
1357
1400
  tableName,
1358
1401
  record
1359
1402
  }) {
1403
+ const filteredRecord = await this.filterRecordToKnownColumns(tableName, record);
1404
+ if (Object.keys(filteredRecord).length === 0) return;
1360
1405
  await this.client.execute(
1361
1406
  prepareStatement({
1362
1407
  tableName,
1363
- record
1408
+ record: filteredRecord
1364
1409
  })
1365
1410
  );
1366
1411
  }
@@ -1382,7 +1427,9 @@ var LibSQLDB = class extends MastraBase {
1382
1427
  keys,
1383
1428
  data
1384
1429
  }) {
1385
- await this.client.execute(prepareUpdateStatement({ tableName, updates: data, keys }));
1430
+ const filteredData = await this.filterRecordToKnownColumns(tableName, data);
1431
+ if (Object.keys(filteredData).length === 0) return;
1432
+ await this.client.execute(prepareUpdateStatement({ tableName, updates: filteredData, keys }));
1386
1433
  }
1387
1434
  /**
1388
1435
  * Updates a record in the specified table with automatic retry on lock errors.
@@ -1403,7 +1450,10 @@ var LibSQLDB = class extends MastraBase {
1403
1450
  records
1404
1451
  }) {
1405
1452
  if (records.length === 0) return;
1406
- const batchStatements = records.map((r) => prepareStatement({ tableName, record: r }));
1453
+ const filteredRecords = await Promise.all(records.map((r) => this.filterRecordToKnownColumns(tableName, r)));
1454
+ const nonEmptyRecords = filteredRecords.filter((r) => Object.keys(r).length > 0);
1455
+ if (nonEmptyRecords.length === 0) return;
1456
+ const batchStatements = nonEmptyRecords.map((r) => prepareStatement({ tableName, record: r }));
1407
1457
  await this.client.batch(batchStatements, "write");
1408
1458
  }
1409
1459
  /**
@@ -1441,7 +1491,15 @@ var LibSQLDB = class extends MastraBase {
1441
1491
  updates
1442
1492
  }) {
1443
1493
  if (updates.length === 0) return;
1444
- const batchStatements = updates.map(
1494
+ const filteredUpdates = [];
1495
+ for (const { keys, data } of updates) {
1496
+ const filteredData = await this.filterRecordToKnownColumns(tableName, data);
1497
+ if (Object.keys(filteredData).length > 0) {
1498
+ filteredUpdates.push({ keys, data: filteredData });
1499
+ }
1500
+ }
1501
+ if (filteredUpdates.length === 0) return;
1502
+ const batchStatements = filteredUpdates.map(
1445
1503
  ({ keys, data }) => prepareUpdateStatement({
1446
1504
  tableName,
1447
1505
  updates: data,
@@ -1751,6 +1809,8 @@ var LibSQLDB = class extends MastraBase {
1751
1809
  },
1752
1810
  error
1753
1811
  );
1812
+ } finally {
1813
+ this.tableColumnsCache.delete(tableName);
1754
1814
  }
1755
1815
  }
1756
1816
  /**
@@ -2030,6 +2090,8 @@ Note: This migration may take some time for large tables.
2030
2090
  },
2031
2091
  error
2032
2092
  );
2093
+ } finally {
2094
+ this.tableColumnsCache.delete(tableName);
2033
2095
  }
2034
2096
  }
2035
2097
  /**
@@ -2922,6 +2984,8 @@ var DatasetsLibSQL = class extends DatasetsStorage {
2922
2984
  await this.#db.createTable({ tableName: TABLE_DATASETS, schema: DATASETS_SCHEMA });
2923
2985
  await this.#db.createTable({ tableName: TABLE_DATASET_ITEMS, schema: DATASET_ITEMS_SCHEMA });
2924
2986
  await this.#db.createTable({ tableName: TABLE_DATASET_VERSIONS, schema: DATASET_VERSIONS_SCHEMA });
2987
+ await this.#addColumnIfNotExists(TABLE_DATASETS, "requestContextSchema", "TEXT");
2988
+ await this.#addColumnIfNotExists(TABLE_DATASET_ITEMS, "requestContext", "TEXT");
2925
2989
  await this.#client.execute({
2926
2990
  sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto ON "${TABLE_DATASET_ITEMS}" ("datasetId", "validTo")`,
2927
2991
  args: []
@@ -2943,6 +3007,12 @@ var DatasetsLibSQL = class extends DatasetsStorage {
2943
3007
  args: []
2944
3008
  });
2945
3009
  }
3010
+ async #addColumnIfNotExists(table, column, sqlType) {
3011
+ const exists = await this.#db.hasColumn(table, column);
3012
+ if (!exists) {
3013
+ await this.#client.execute({ sql: `ALTER TABLE "${table}" ADD COLUMN "${column}" ${sqlType}`, args: [] });
3014
+ }
3015
+ }
2946
3016
  async dangerouslyClearAll() {
2947
3017
  await this.#db.deleteData({ tableName: TABLE_DATASET_VERSIONS });
2948
3018
  await this.#db.deleteData({ tableName: TABLE_DATASET_ITEMS });
@@ -2957,6 +3027,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
2957
3027
  metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
2958
3028
  inputSchema: row.inputSchema ? safelyParseJSON(row.inputSchema) : void 0,
2959
3029
  groundTruthSchema: row.groundTruthSchema ? safelyParseJSON(row.groundTruthSchema) : void 0,
3030
+ requestContextSchema: row.requestContextSchema ? safelyParseJSON(row.requestContextSchema) : void 0,
2960
3031
  version: row.version,
2961
3032
  createdAt: ensureDate(row.createdAt),
2962
3033
  updatedAt: ensureDate(row.updatedAt)
@@ -2969,6 +3040,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
2969
3040
  datasetVersion: row.datasetVersion,
2970
3041
  input: safelyParseJSON(row.input),
2971
3042
  groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : void 0,
3043
+ requestContext: row.requestContext ? safelyParseJSON(row.requestContext) : void 0,
2972
3044
  metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
2973
3045
  createdAt: ensureDate(row.createdAt),
2974
3046
  updatedAt: ensureDate(row.updatedAt)
@@ -2983,6 +3055,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
2983
3055
  isDeleted: Boolean(row.isDeleted),
2984
3056
  input: safelyParseJSON(row.input),
2985
3057
  groundTruth: row.groundTruth ? safelyParseJSON(row.groundTruth) : void 0,
3058
+ requestContext: row.requestContext ? safelyParseJSON(row.requestContext) : void 0,
2986
3059
  metadata: row.metadata ? safelyParseJSON(row.metadata) : void 0,
2987
3060
  createdAt: ensureDate(row.createdAt),
2988
3061
  updatedAt: ensureDate(row.updatedAt)
@@ -3011,6 +3084,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3011
3084
  metadata: input.metadata,
3012
3085
  inputSchema: input.inputSchema ?? null,
3013
3086
  groundTruthSchema: input.groundTruthSchema ?? null,
3087
+ requestContextSchema: input.requestContextSchema ?? null,
3014
3088
  version: 0,
3015
3089
  createdAt: nowIso,
3016
3090
  updatedAt: nowIso
@@ -3023,6 +3097,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3023
3097
  metadata: input.metadata,
3024
3098
  inputSchema: input.inputSchema ?? void 0,
3025
3099
  groundTruthSchema: input.groundTruthSchema ?? void 0,
3100
+ requestContextSchema: input.requestContextSchema ?? void 0,
3026
3101
  version: 0,
3027
3102
  createdAt: now,
3028
3103
  updatedAt: now
@@ -3090,6 +3165,10 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3090
3165
  updates.push("groundTruthSchema = ?");
3091
3166
  values.push(args.groundTruthSchema === null ? null : JSON.stringify(args.groundTruthSchema));
3092
3167
  }
3168
+ if (args.requestContextSchema !== void 0) {
3169
+ updates.push("requestContextSchema = ?");
3170
+ values.push(args.requestContextSchema === null ? null : JSON.stringify(args.requestContextSchema));
3171
+ }
3093
3172
  values.push(args.id);
3094
3173
  await this.#client.execute({
3095
3174
  sql: `UPDATE ${TABLE_DATASETS} SET ${updates.join(", ")} WHERE id = ?`,
@@ -3102,6 +3181,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3102
3181
  metadata: args.metadata ?? existing.metadata,
3103
3182
  inputSchema: (args.inputSchema !== void 0 ? args.inputSchema : existing.inputSchema) ?? void 0,
3104
3183
  groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
3184
+ requestContextSchema: (args.requestContextSchema !== void 0 ? args.requestContextSchema : existing.requestContextSchema) ?? void 0,
3105
3185
  updatedAt: new Date(now)
3106
3186
  };
3107
3187
  } catch (error) {
@@ -3207,13 +3287,14 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3207
3287
  args: [args.datasetId]
3208
3288
  },
3209
3289
  {
3210
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3290
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3211
3291
  args: [
3212
3292
  id,
3213
3293
  args.datasetId,
3214
3294
  args.datasetId,
3215
3295
  jsonbArg(args.input),
3216
3296
  jsonbArg(args.groundTruth),
3297
+ jsonbArg(args.requestContext),
3217
3298
  jsonbArg(args.metadata),
3218
3299
  nowIso,
3219
3300
  nowIso
@@ -3233,6 +3314,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3233
3314
  datasetVersion: newVersion,
3234
3315
  input: args.input,
3235
3316
  groundTruth: args.groundTruth,
3317
+ requestContext: args.requestContext,
3236
3318
  metadata: args.metadata,
3237
3319
  createdAt: now,
3238
3320
  updatedAt: now
@@ -3273,6 +3355,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3273
3355
  const nowIso = now.toISOString();
3274
3356
  const mergedInput = args.input ?? existing.input;
3275
3357
  const mergedGroundTruth = args.groundTruth ?? existing.groundTruth;
3358
+ const mergedRequestContext = args.requestContext ?? existing.requestContext;
3276
3359
  const mergedMetadata = args.metadata ?? existing.metadata;
3277
3360
  const results = await this.#client.batch(
3278
3361
  [
@@ -3285,13 +3368,14 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3285
3368
  args: [args.datasetId, args.id]
3286
3369
  },
3287
3370
  {
3288
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3371
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3289
3372
  args: [
3290
3373
  args.id,
3291
3374
  args.datasetId,
3292
3375
  args.datasetId,
3293
3376
  jsonbArg(mergedInput),
3294
3377
  jsonbArg(mergedGroundTruth),
3378
+ jsonbArg(mergedRequestContext),
3295
3379
  jsonbArg(mergedMetadata),
3296
3380
  existing.createdAt.toISOString(),
3297
3381
  nowIso
@@ -3310,6 +3394,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3310
3394
  datasetVersion: newVersion,
3311
3395
  input: mergedInput,
3312
3396
  groundTruth: mergedGroundTruth,
3397
+ requestContext: mergedRequestContext,
3313
3398
  metadata: mergedMetadata,
3314
3399
  updatedAt: now
3315
3400
  };
@@ -3350,13 +3435,14 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3350
3435
  args: [datasetId, id]
3351
3436
  },
3352
3437
  {
3353
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3438
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3354
3439
  args: [
3355
3440
  id,
3356
3441
  datasetId,
3357
3442
  datasetId,
3358
3443
  jsonbArg(existing.input),
3359
3444
  jsonbArg(existing.groundTruth),
3445
+ jsonbArg(existing.requestContext),
3360
3446
  jsonbArg(existing.metadata),
3361
3447
  existing.createdAt.toISOString(),
3362
3448
  nowIso
@@ -3637,13 +3723,14 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3637
3723
  const id = crypto.randomUUID();
3638
3724
  items.push({ id, input: itemInput });
3639
3725
  statements.push({
3640
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3726
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 0, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3641
3727
  args: [
3642
3728
  id,
3643
3729
  input.datasetId,
3644
3730
  input.datasetId,
3645
3731
  jsonbArg(itemInput.input),
3646
3732
  jsonbArg(itemInput.groundTruth),
3733
+ jsonbArg(itemInput.requestContext),
3647
3734
  jsonbArg(itemInput.metadata),
3648
3735
  nowIso,
3649
3736
  nowIso
@@ -3662,6 +3749,7 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3662
3749
  datasetVersion: newVersion,
3663
3750
  input: itemInput.input,
3664
3751
  groundTruth: itemInput.groundTruth,
3752
+ requestContext: itemInput.requestContext,
3665
3753
  metadata: itemInput.metadata,
3666
3754
  createdAt: now,
3667
3755
  updatedAt: now
@@ -3711,13 +3799,14 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3711
3799
  args: [input.datasetId, item.id]
3712
3800
  });
3713
3801
  statements.push({
3714
- sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3802
+ sql: `INSERT INTO ${TABLE_DATASET_ITEMS} (id, datasetId, datasetVersion, validTo, isDeleted, input, groundTruth, requestContext, metadata, createdAt, updatedAt) VALUES (?, ?, (SELECT version FROM ${TABLE_DATASETS} WHERE id = ?), NULL, 1, jsonb(?), jsonb(?), jsonb(?), jsonb(?), ?, ?)`,
3715
3803
  args: [
3716
3804
  item.id,
3717
3805
  input.datasetId,
3718
3806
  input.datasetId,
3719
3807
  jsonbArg(item.input),
3720
3808
  jsonbArg(item.groundTruth),
3809
+ jsonbArg(item.requestContext),
3721
3810
  jsonbArg(item.metadata),
3722
3811
  item.createdAt.toISOString(),
3723
3812
  nowIso
@@ -5212,41 +5301,64 @@ var MemoryLibSQL = class extends MemoryStorage {
5212
5301
  if (row.type && row.type !== `v2`) result.type = row.type;
5213
5302
  return result;
5214
5303
  }
5304
+ _sortMessages(messages, field, direction) {
5305
+ return messages.sort((a, b) => {
5306
+ const isDateField = field === "createdAt" || field === "updatedAt";
5307
+ const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5308
+ const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5309
+ if (typeof aValue === "number" && typeof bValue === "number") {
5310
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
5311
+ }
5312
+ return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5313
+ });
5314
+ }
5215
5315
  async _getIncludedMessages({ include }) {
5216
5316
  if (!include || include.length === 0) return null;
5317
+ const targetIds = include.map((inc) => inc.id).filter(Boolean);
5318
+ if (targetIds.length === 0) return null;
5319
+ const idPlaceholders = targetIds.map(() => "?").join(", ");
5320
+ const targetResult = await this.#client.execute({
5321
+ sql: `SELECT id, thread_id, "createdAt" FROM "${TABLE_MESSAGES}" WHERE id IN (${idPlaceholders})`,
5322
+ args: targetIds
5323
+ });
5324
+ if (!targetResult.rows || targetResult.rows.length === 0) return null;
5325
+ const targetMap = new Map(
5326
+ targetResult.rows.map((r) => [r.id, { threadId: r.thread_id, createdAt: r.createdAt }])
5327
+ );
5217
5328
  const unionQueries = [];
5218
5329
  const params = [];
5219
5330
  for (const inc of include) {
5220
5331
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
5221
- unionQueries.push(
5222
- `
5223
- SELECT * FROM (
5224
- WITH target_thread AS (
5225
- SELECT thread_id FROM "${TABLE_MESSAGES}" WHERE id = ?
5226
- ),
5227
- numbered_messages AS (
5228
- SELECT
5229
- id, content, role, type, "createdAt", thread_id, "resourceId",
5230
- ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
5231
- FROM "${TABLE_MESSAGES}"
5232
- WHERE thread_id = (SELECT thread_id FROM target_thread)
5233
- ),
5234
- target_positions AS (
5235
- SELECT row_num as target_pos
5236
- FROM numbered_messages
5237
- WHERE id = ?
5238
- )
5239
- SELECT DISTINCT m.*
5240
- FROM numbered_messages m
5241
- CROSS JOIN target_positions t
5242
- WHERE m.row_num BETWEEN (t.target_pos - ?) AND (t.target_pos + ?)
5243
- )
5244
- `
5245
- // Keep ASC for final sorting after fetching context
5246
- );
5247
- params.push(id, id, withPreviousMessages, withNextMessages);
5248
- }
5249
- const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
5332
+ const target = targetMap.get(id);
5333
+ if (!target) continue;
5334
+ unionQueries.push(`SELECT * FROM (
5335
+ SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
5336
+ FROM "${TABLE_MESSAGES}"
5337
+ WHERE thread_id = ?
5338
+ AND "createdAt" <= ?
5339
+ ORDER BY "createdAt" DESC, id DESC
5340
+ LIMIT ?
5341
+ )`);
5342
+ params.push(target.threadId, target.createdAt, withPreviousMessages + 1);
5343
+ if (withNextMessages > 0) {
5344
+ unionQueries.push(`SELECT * FROM (
5345
+ SELECT id, content, role, type, "createdAt", thread_id, "resourceId"
5346
+ FROM "${TABLE_MESSAGES}"
5347
+ WHERE thread_id = ?
5348
+ AND "createdAt" > ?
5349
+ ORDER BY "createdAt" ASC, id ASC
5350
+ LIMIT ?
5351
+ )`);
5352
+ params.push(target.threadId, target.createdAt, withNextMessages);
5353
+ }
5354
+ }
5355
+ if (unionQueries.length === 0) return null;
5356
+ let finalQuery;
5357
+ if (unionQueries.length === 1) {
5358
+ finalQuery = unionQueries[0];
5359
+ } else {
5360
+ finalQuery = `${unionQueries.join(" UNION ALL ")} ORDER BY "createdAt" ASC, id ASC`;
5361
+ }
5250
5362
  const includedResult = await this.#client.execute({ sql: finalQuery, args: params });
5251
5363
  const includedRows = includedResult.rows?.map((row) => this.parseRow(row));
5252
5364
  const seen = /* @__PURE__ */ new Set();
@@ -5341,6 +5453,23 @@ var MemoryLibSQL = class extends MemoryStorage {
5341
5453
  );
5342
5454
  }
5343
5455
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5456
+ if (perPage === 0 && (!include || include.length === 0)) {
5457
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5458
+ }
5459
+ if (perPage === 0 && include && include.length > 0) {
5460
+ const includeMessages = await this._getIncludedMessages({ include });
5461
+ if (!includeMessages || includeMessages.length === 0) {
5462
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5463
+ }
5464
+ const list2 = new MessageList().add(includeMessages, "memory");
5465
+ return {
5466
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
5467
+ total: 0,
5468
+ page,
5469
+ perPage: perPageForResponse,
5470
+ hasMore: false
5471
+ };
5472
+ }
5344
5473
  const countResult = await this.#client.execute({
5345
5474
  sql: `SELECT COUNT(*) as count FROM ${TABLE_MESSAGES} ${whereClause}`,
5346
5475
  args: queryParams
@@ -5374,16 +5503,7 @@ var MemoryLibSQL = class extends MemoryStorage {
5374
5503
  }
5375
5504
  }
5376
5505
  const list = new MessageList().add(messages, "memory");
5377
- let finalMessages = list.get.all.db();
5378
- finalMessages = finalMessages.sort((a, b) => {
5379
- const isDateField = field === "createdAt" || field === "updatedAt";
5380
- const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5381
- const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5382
- if (typeof aValue === "number" && typeof bValue === "number") {
5383
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
5384
- }
5385
- return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5386
- });
5506
+ const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
5387
5507
  const threadIdSet = new Set(threadIds);
5388
5508
  const returnedThreadMessageIds = new Set(
5389
5509
  finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
@@ -5469,6 +5589,23 @@ var MemoryLibSQL = class extends MemoryStorage {
5469
5589
  );
5470
5590
  }
5471
5591
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
5592
+ if (perPage === 0 && (!include || include.length === 0)) {
5593
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5594
+ }
5595
+ if (perPage === 0 && include && include.length > 0) {
5596
+ const includeMessages = await this._getIncludedMessages({ include });
5597
+ if (!includeMessages || includeMessages.length === 0) {
5598
+ return { messages: [], total: 0, page, perPage: perPageForResponse, hasMore: false };
5599
+ }
5600
+ const list2 = new MessageList().add(includeMessages, "memory");
5601
+ return {
5602
+ messages: this._sortMessages(list2.get.all.db(), field, direction),
5603
+ total: 0,
5604
+ page,
5605
+ perPage: perPageForResponse,
5606
+ hasMore: false
5607
+ };
5608
+ }
5472
5609
  const countResult = await this.#client.execute({
5473
5610
  sql: `SELECT COUNT(*) as count FROM ${TABLE_MESSAGES} ${whereClause}`,
5474
5611
  args: queryParams
@@ -5502,16 +5639,7 @@ var MemoryLibSQL = class extends MemoryStorage {
5502
5639
  }
5503
5640
  }
5504
5641
  const list = new MessageList().add(messages, "memory");
5505
- let finalMessages = list.get.all.db();
5506
- finalMessages = finalMessages.sort((a, b) => {
5507
- const isDateField = field === "createdAt" || field === "updatedAt";
5508
- const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
5509
- const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
5510
- if (typeof aValue === "number" && typeof bValue === "number") {
5511
- return direction === "ASC" ? aValue - bValue : bValue - aValue;
5512
- }
5513
- return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
5514
- });
5642
+ const finalMessages = this._sortMessages(list.get.all.db(), field, direction);
5515
5643
  const hasMore = perPageInput !== false && offset + perPage < total;
5516
5644
  return {
5517
5645
  messages: finalMessages,
@@ -7091,6 +7219,11 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
7091
7219
  }
7092
7220
  async init() {
7093
7221
  await this.#db.createTable({ tableName: TABLE_SPANS, schema: SPAN_SCHEMA });
7222
+ await this.#db.alterTable({
7223
+ tableName: TABLE_SPANS,
7224
+ schema: SPAN_SCHEMA,
7225
+ ifNotExists: ["requestContext"]
7226
+ });
7094
7227
  }
7095
7228
  async dangerouslyClearAll() {
7096
7229
  await this.#db.deleteData({ tableName: TABLE_SPANS });
@@ -7262,7 +7395,8 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
7262
7395
  }
7263
7396
  async listTraces(args) {
7264
7397
  const { filters, pagination, orderBy } = listTracesArgsSchema.parse(args);
7265
- const { page, perPage } = pagination;
7398
+ const page = pagination?.page ?? 0;
7399
+ const perPage = pagination?.perPage ?? 10;
7266
7400
  const tableName = parseSqlIdentifier(TABLE_SPANS, "table name");
7267
7401
  try {
7268
7402
  const conditions = ["parentSpanId IS NULL"];
@@ -7402,8 +7536,8 @@ var ObservabilityLibSQL = class extends ObservabilityStorage {
7402
7536
  }
7403
7537
  }
7404
7538
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
7405
- const sortField = orderBy.field;
7406
- const sortDirection = orderBy.direction;
7539
+ const sortField = orderBy?.field ?? "startedAt";
7540
+ const sortDirection = orderBy?.direction ?? "DESC";
7407
7541
  let orderByClause;
7408
7542
  if (sortField === "endedAt") {
7409
7543
  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`;