@mastra/libsql 0.10.4-alpha.0 → 0.10.4-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
@@ -1,9 +1,10 @@
1
1
  import { createClient } from '@libsql/client';
2
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
3
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
3
4
  import { MastraVector } from '@mastra/core/vector';
4
5
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
5
6
  import { MessageList } from '@mastra/core/agent';
6
- import { MastraStorage, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS, TABLE_MESSAGES, TABLE_EVALS, TABLE_TRACES } from '@mastra/core/storage';
7
+ import { MastraStorage, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS, TABLE_MESSAGES, TABLE_EVALS, TABLE_TRACES, TABLE_RESOURCES } from '@mastra/core/storage';
7
8
 
8
9
  // src/vector/index.ts
9
10
  var LibSQLFilterTranslator = class extends BaseFilterTranslator {
@@ -406,7 +407,7 @@ function buildCondition(key, value, parentPath) {
406
407
  return handleOperator(key, value);
407
408
  }
408
409
  function handleLogicalOperator(key, value, parentPath) {
409
- if (!value || value.length === 0) {
410
+ if (!value || Array.isArray(value) && value.length === 0) {
410
411
  switch (key) {
411
412
  case "$and":
412
413
  case "$nor":
@@ -430,7 +431,7 @@ function handleLogicalOperator(key, value, parentPath) {
430
431
  const values = [];
431
432
  const joinOperator = key === "$or" || key === "$nor" ? "OR" : "AND";
432
433
  const conditions = Array.isArray(value) ? value.map((f) => {
433
- const entries = Object.entries(f);
434
+ const entries = !!f ? Object.entries(f) : [];
434
435
  return entries.map(([k, v]) => buildCondition(k, v));
435
436
  }) : [buildCondition(key, value)];
436
437
  const joined = conditions.flat().map((c) => {
@@ -554,6 +555,17 @@ var LibSQLVector = class extends MastraVector {
554
555
  if (!Array.isArray(queryVector) || !queryVector.every((x) => typeof x === "number" && Number.isFinite(x))) {
555
556
  throw new Error("queryVector must be an array of finite numbers");
556
557
  }
558
+ } catch (error) {
559
+ throw new MastraError(
560
+ {
561
+ id: "LIBSQL_VECTOR_QUERY_INVALID_ARGS",
562
+ domain: ErrorDomain.STORAGE,
563
+ category: ErrorCategory.USER
564
+ },
565
+ error
566
+ );
567
+ }
568
+ try {
557
569
  const parsedIndexName = parseSqlIdentifier(indexName, "index name");
558
570
  const vectorStr = `[${queryVector.join(",")}]`;
559
571
  const translatedFilter = this.transformFilter(filter);
@@ -585,11 +597,30 @@ var LibSQLVector = class extends MastraVector {
585
597
  metadata: JSON.parse(metadata ?? "{}"),
586
598
  ...includeVector && embedding && { vector: JSON.parse(embedding) }
587
599
  }));
588
- } finally {
600
+ } catch (error) {
601
+ throw new MastraError(
602
+ {
603
+ id: "LIBSQL_VECTOR_QUERY_FAILED",
604
+ domain: ErrorDomain.STORAGE,
605
+ category: ErrorCategory.THIRD_PARTY
606
+ },
607
+ error
608
+ );
589
609
  }
590
610
  }
591
611
  upsert(args) {
592
- return this.executeWriteOperationWithRetry(() => this.doUpsert(args), true);
612
+ try {
613
+ return this.executeWriteOperationWithRetry(() => this.doUpsert(args), true);
614
+ } catch (error) {
615
+ throw new MastraError(
616
+ {
617
+ id: "LIBSQL_VECTOR_UPSERT_FAILED",
618
+ domain: ErrorDomain.STORAGE,
619
+ category: ErrorCategory.THIRD_PARTY
620
+ },
621
+ error
622
+ );
623
+ }
593
624
  }
594
625
  async doUpsert({ indexName, vectors, metadata, ids }) {
595
626
  const tx = await this.turso.transaction("write");
@@ -632,7 +663,19 @@ var LibSQLVector = class extends MastraVector {
632
663
  }
633
664
  }
634
665
  createIndex(args) {
635
- return this.executeWriteOperationWithRetry(() => this.doCreateIndex(args));
666
+ try {
667
+ return this.executeWriteOperationWithRetry(() => this.doCreateIndex(args));
668
+ } catch (error) {
669
+ throw new MastraError(
670
+ {
671
+ id: "LIBSQL_VECTOR_CREATE_INDEX_FAILED",
672
+ domain: ErrorDomain.STORAGE,
673
+ category: ErrorCategory.THIRD_PARTY,
674
+ details: { indexName: args.indexName, dimension: args.dimension }
675
+ },
676
+ error
677
+ );
678
+ }
636
679
  }
637
680
  async doCreateIndex({ indexName, dimension }) {
638
681
  if (!Number.isInteger(dimension) || dimension <= 0) {
@@ -659,7 +702,19 @@ var LibSQLVector = class extends MastraVector {
659
702
  });
660
703
  }
661
704
  deleteIndex(args) {
662
- return this.executeWriteOperationWithRetry(() => this.doDeleteIndex(args));
705
+ try {
706
+ return this.executeWriteOperationWithRetry(() => this.doDeleteIndex(args));
707
+ } catch (error) {
708
+ throw new MastraError(
709
+ {
710
+ id: "LIBSQL_VECTOR_DELETE_INDEX_FAILED",
711
+ domain: ErrorDomain.STORAGE,
712
+ category: ErrorCategory.THIRD_PARTY,
713
+ details: { indexName: args.indexName }
714
+ },
715
+ error
716
+ );
717
+ }
663
718
  }
664
719
  async doDeleteIndex({ indexName }) {
665
720
  const parsedIndexName = parseSqlIdentifier(indexName, "index name");
@@ -681,7 +736,14 @@ var LibSQLVector = class extends MastraVector {
681
736
  });
682
737
  return result.rows.map((row) => row.name);
683
738
  } catch (error) {
684
- throw new Error(`Failed to list vector tables: ${error.message}`);
739
+ throw new MastraError(
740
+ {
741
+ id: "LIBSQL_VECTOR_LIST_INDEXES_FAILED",
742
+ domain: ErrorDomain.STORAGE,
743
+ category: ErrorCategory.THIRD_PARTY
744
+ },
745
+ error
746
+ );
685
747
  }
686
748
  }
687
749
  /**
@@ -722,7 +784,15 @@ var LibSQLVector = class extends MastraVector {
722
784
  metric
723
785
  };
724
786
  } catch (e) {
725
- throw new Error(`Failed to describe vector table: ${e.message}`);
787
+ throw new MastraError(
788
+ {
789
+ id: "LIBSQL_VECTOR_DESCRIBE_INDEX_FAILED",
790
+ domain: ErrorDomain.STORAGE,
791
+ category: ErrorCategory.THIRD_PARTY,
792
+ details: { indexName }
793
+ },
794
+ e
795
+ );
726
796
  }
727
797
  }
728
798
  /**
@@ -752,7 +822,13 @@ var LibSQLVector = class extends MastraVector {
752
822
  args.push(JSON.stringify(update.metadata));
753
823
  }
754
824
  if (updates.length === 0) {
755
- throw new Error("No updates provided");
825
+ throw new MastraError({
826
+ id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
827
+ domain: ErrorDomain.STORAGE,
828
+ category: ErrorCategory.USER,
829
+ details: { indexName, id },
830
+ text: "No updates provided"
831
+ });
756
832
  }
757
833
  args.push(id);
758
834
  const query = `
@@ -760,10 +836,22 @@ var LibSQLVector = class extends MastraVector {
760
836
  SET ${updates.join(", ")}
761
837
  WHERE vector_id = ?;
762
838
  `;
763
- await this.turso.execute({
764
- sql: query,
765
- args
766
- });
839
+ try {
840
+ await this.turso.execute({
841
+ sql: query,
842
+ args
843
+ });
844
+ } catch (error) {
845
+ throw new MastraError(
846
+ {
847
+ id: "LIBSQL_VECTOR_UPDATE_VECTOR_FAILED",
848
+ domain: ErrorDomain.STORAGE,
849
+ category: ErrorCategory.THIRD_PARTY,
850
+ details: { indexName, id }
851
+ },
852
+ error
853
+ );
854
+ }
767
855
  }
768
856
  /**
769
857
  * Deletes a vector by its ID.
@@ -773,7 +861,19 @@ var LibSQLVector = class extends MastraVector {
773
861
  * @throws Will throw an error if the deletion operation fails.
774
862
  */
775
863
  deleteVector(args) {
776
- return this.executeWriteOperationWithRetry(() => this.doDeleteVector(args));
864
+ try {
865
+ return this.executeWriteOperationWithRetry(() => this.doDeleteVector(args));
866
+ } catch (error) {
867
+ throw new MastraError(
868
+ {
869
+ id: "LIBSQL_VECTOR_DELETE_VECTOR_FAILED",
870
+ domain: ErrorDomain.STORAGE,
871
+ category: ErrorCategory.THIRD_PARTY,
872
+ details: { indexName: args.indexName, id: args.id }
873
+ },
874
+ error
875
+ );
876
+ }
777
877
  }
778
878
  async doDeleteVector({ indexName, id }) {
779
879
  const parsedIndexName = parseSqlIdentifier(indexName, "index name");
@@ -783,7 +883,19 @@ var LibSQLVector = class extends MastraVector {
783
883
  });
784
884
  }
785
885
  truncateIndex(args) {
786
- return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
886
+ try {
887
+ return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
888
+ } catch (error) {
889
+ throw new MastraError(
890
+ {
891
+ id: "LIBSQL_VECTOR_TRUNCATE_INDEX_FAILED",
892
+ domain: ErrorDomain.STORAGE,
893
+ category: ErrorCategory.THIRD_PARTY,
894
+ details: { indexName: args.indexName }
895
+ },
896
+ error
897
+ );
898
+ }
787
899
  }
788
900
  async _doTruncateIndex({ indexName }) {
789
901
  await this.turso.execute({
@@ -818,7 +930,8 @@ var LibSQLStore = class extends MastraStorage {
818
930
  }
819
931
  get supports() {
820
932
  return {
821
- selectByIncludeResourceScope: true
933
+ selectByIncludeResourceScope: true,
934
+ resourceWorkingMemory: true
822
935
  };
823
936
  }
824
937
  getCreateTableSQL(tableName, schema) {
@@ -850,8 +963,17 @@ var LibSQLStore = class extends MastraStorage {
850
963
  const sql = this.getCreateTableSQL(tableName, schema);
851
964
  await this.client.execute(sql);
852
965
  } catch (error) {
853
- this.logger.error(`Error creating table ${tableName}: ${error}`);
854
- throw error;
966
+ throw new MastraError(
967
+ {
968
+ id: "LIBSQL_STORE_CREATE_TABLE_FAILED",
969
+ domain: ErrorDomain.STORAGE,
970
+ category: ErrorCategory.THIRD_PARTY,
971
+ details: {
972
+ tableName
973
+ }
974
+ },
975
+ error
976
+ );
855
977
  }
856
978
  }
857
979
  getSqlType(type) {
@@ -894,10 +1016,17 @@ var LibSQLStore = class extends MastraStorage {
894
1016
  }
895
1017
  }
896
1018
  } catch (error) {
897
- this.logger?.error?.(
898
- `Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`
1019
+ throw new MastraError(
1020
+ {
1021
+ id: "LIBSQL_STORE_ALTER_TABLE_FAILED",
1022
+ domain: ErrorDomain.STORAGE,
1023
+ category: ErrorCategory.THIRD_PARTY,
1024
+ details: {
1025
+ tableName
1026
+ }
1027
+ },
1028
+ error
899
1029
  );
900
- throw new Error(`Failed to alter table ${tableName}: ${error}`);
901
1030
  }
902
1031
  }
903
1032
  async clearTable({ tableName }) {
@@ -905,9 +1034,19 @@ var LibSQLStore = class extends MastraStorage {
905
1034
  try {
906
1035
  await this.client.execute(`DELETE FROM ${parsedTableName}`);
907
1036
  } catch (e) {
908
- if (e instanceof Error) {
909
- this.logger.error(e.message);
910
- }
1037
+ const mastraError = new MastraError(
1038
+ {
1039
+ id: "LIBSQL_STORE_CLEAR_TABLE_FAILED",
1040
+ domain: ErrorDomain.STORAGE,
1041
+ category: ErrorCategory.THIRD_PARTY,
1042
+ details: {
1043
+ tableName
1044
+ }
1045
+ },
1046
+ e
1047
+ );
1048
+ this.logger?.trackException?.(mastraError);
1049
+ this.logger?.error?.(mastraError.toString());
911
1050
  }
912
1051
  }
913
1052
  prepareStatement({ tableName, record }) {
@@ -966,7 +1105,19 @@ var LibSQLStore = class extends MastraStorage {
966
1105
  return this.executeWriteOperationWithRetry(
967
1106
  () => this.doBatchInsert(args),
968
1107
  `batch insert into table ${args.tableName}`
969
- );
1108
+ ).catch((error) => {
1109
+ throw new MastraError(
1110
+ {
1111
+ id: "LIBSQL_STORE_BATCH_INSERT_FAILED",
1112
+ domain: ErrorDomain.STORAGE,
1113
+ category: ErrorCategory.THIRD_PARTY,
1114
+ details: {
1115
+ tableName: args.tableName
1116
+ }
1117
+ },
1118
+ error
1119
+ );
1120
+ });
970
1121
  }
971
1122
  async doBatchInsert({
972
1123
  tableName,
@@ -1001,17 +1152,29 @@ var LibSQLStore = class extends MastraStorage {
1001
1152
  return parsed;
1002
1153
  }
1003
1154
  async getThreadById({ threadId }) {
1004
- const result = await this.load({
1005
- tableName: TABLE_THREADS,
1006
- keys: { id: threadId }
1007
- });
1008
- if (!result) {
1009
- return null;
1155
+ try {
1156
+ const result = await this.load({
1157
+ tableName: TABLE_THREADS,
1158
+ keys: { id: threadId }
1159
+ });
1160
+ if (!result) {
1161
+ return null;
1162
+ }
1163
+ return {
1164
+ ...result,
1165
+ metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
1166
+ };
1167
+ } catch (error) {
1168
+ throw new MastraError(
1169
+ {
1170
+ id: "LIBSQL_STORE_GET_THREAD_BY_ID_FAILED",
1171
+ domain: ErrorDomain.STORAGE,
1172
+ category: ErrorCategory.THIRD_PARTY,
1173
+ details: { threadId }
1174
+ },
1175
+ error
1176
+ );
1010
1177
  }
1011
- return {
1012
- ...result,
1013
- metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
1014
- };
1015
1178
  }
1016
1179
  /**
1017
1180
  * @deprecated use getThreadsByResourceIdPaginated instead for paginated results.
@@ -1040,7 +1203,17 @@ var LibSQLStore = class extends MastraStorage {
1040
1203
  }
1041
1204
  return result.rows.map(mapRowToStorageThreadType);
1042
1205
  } catch (error) {
1043
- this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
1206
+ const mastraError = new MastraError(
1207
+ {
1208
+ id: "LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1209
+ domain: ErrorDomain.STORAGE,
1210
+ category: ErrorCategory.THIRD_PARTY,
1211
+ details: { resourceId }
1212
+ },
1213
+ error
1214
+ );
1215
+ this.logger?.trackException?.(mastraError);
1216
+ this.logger?.error?.(mastraError.toString());
1044
1217
  return [];
1045
1218
  }
1046
1219
  }
@@ -1087,19 +1260,44 @@ var LibSQLStore = class extends MastraStorage {
1087
1260
  hasMore: currentOffset + threads.length < total
1088
1261
  };
1089
1262
  } catch (error) {
1090
- this.logger.error(`Error getting threads for resource ${resourceId}:`, error);
1263
+ const mastraError = new MastraError(
1264
+ {
1265
+ id: "LIBSQL_STORE_GET_THREADS_BY_RESOURCE_ID_FAILED",
1266
+ domain: ErrorDomain.STORAGE,
1267
+ category: ErrorCategory.THIRD_PARTY,
1268
+ details: { resourceId }
1269
+ },
1270
+ error
1271
+ );
1272
+ this.logger?.trackException?.(mastraError);
1273
+ this.logger?.error?.(mastraError.toString());
1091
1274
  return { threads: [], total: 0, page, perPage, hasMore: false };
1092
1275
  }
1093
1276
  }
1094
1277
  async saveThread({ thread }) {
1095
- await this.insert({
1096
- tableName: TABLE_THREADS,
1097
- record: {
1098
- ...thread,
1099
- metadata: JSON.stringify(thread.metadata)
1100
- }
1101
- });
1102
- return thread;
1278
+ try {
1279
+ await this.insert({
1280
+ tableName: TABLE_THREADS,
1281
+ record: {
1282
+ ...thread,
1283
+ metadata: JSON.stringify(thread.metadata)
1284
+ }
1285
+ });
1286
+ return thread;
1287
+ } catch (error) {
1288
+ const mastraError = new MastraError(
1289
+ {
1290
+ id: "LIBSQL_STORE_SAVE_THREAD_FAILED",
1291
+ domain: ErrorDomain.STORAGE,
1292
+ category: ErrorCategory.THIRD_PARTY,
1293
+ details: { threadId: thread.id }
1294
+ },
1295
+ error
1296
+ );
1297
+ this.logger?.trackException?.(mastraError);
1298
+ this.logger?.error?.(mastraError.toString());
1299
+ throw mastraError;
1300
+ }
1103
1301
  }
1104
1302
  async updateThread({
1105
1303
  id,
@@ -1108,7 +1306,13 @@ var LibSQLStore = class extends MastraStorage {
1108
1306
  }) {
1109
1307
  const thread = await this.getThreadById({ threadId: id });
1110
1308
  if (!thread) {
1111
- throw new Error(`Thread ${id} not found`);
1309
+ throw new MastraError({
1310
+ id: "LIBSQL_STORE_UPDATE_THREAD_FAILED_THREAD_NOT_FOUND",
1311
+ domain: ErrorDomain.STORAGE,
1312
+ category: ErrorCategory.USER,
1313
+ text: `Thread ${id} not found`,
1314
+ details: { threadId: id }
1315
+ });
1112
1316
  }
1113
1317
  const updatedThread = {
1114
1318
  ...thread,
@@ -1118,21 +1322,46 @@ var LibSQLStore = class extends MastraStorage {
1118
1322
  ...metadata
1119
1323
  }
1120
1324
  };
1121
- await this.client.execute({
1122
- sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
1123
- args: [title, JSON.stringify(updatedThread.metadata), id]
1124
- });
1125
- return updatedThread;
1325
+ try {
1326
+ await this.client.execute({
1327
+ sql: `UPDATE ${TABLE_THREADS} SET title = ?, metadata = ? WHERE id = ?`,
1328
+ args: [title, JSON.stringify(updatedThread.metadata), id]
1329
+ });
1330
+ return updatedThread;
1331
+ } catch (error) {
1332
+ throw new MastraError(
1333
+ {
1334
+ id: "LIBSQL_STORE_UPDATE_THREAD_FAILED",
1335
+ domain: ErrorDomain.STORAGE,
1336
+ category: ErrorCategory.THIRD_PARTY,
1337
+ text: `Failed to update thread ${id}`,
1338
+ details: { threadId: id }
1339
+ },
1340
+ error
1341
+ );
1342
+ }
1126
1343
  }
1127
1344
  async deleteThread({ threadId }) {
1128
- await this.client.execute({
1129
- sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
1130
- args: [threadId]
1131
- });
1132
- await this.client.execute({
1133
- sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
1134
- args: [threadId]
1135
- });
1345
+ try {
1346
+ await this.client.execute({
1347
+ sql: `DELETE FROM ${TABLE_MESSAGES} WHERE thread_id = ?`,
1348
+ args: [threadId]
1349
+ });
1350
+ await this.client.execute({
1351
+ sql: `DELETE FROM ${TABLE_THREADS} WHERE id = ?`,
1352
+ args: [threadId]
1353
+ });
1354
+ } catch (error) {
1355
+ throw new MastraError(
1356
+ {
1357
+ id: "LIBSQL_STORE_DELETE_THREAD_FAILED",
1358
+ domain: ErrorDomain.STORAGE,
1359
+ category: ErrorCategory.THIRD_PARTY,
1360
+ details: { threadId }
1361
+ },
1362
+ error
1363
+ );
1364
+ }
1136
1365
  }
1137
1366
  parseRow(row) {
1138
1367
  let content = row.content;
@@ -1205,7 +1434,7 @@ var LibSQLStore = class extends MastraStorage {
1205
1434
  }) {
1206
1435
  try {
1207
1436
  const messages = [];
1208
- const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
1437
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
1209
1438
  if (selectBy?.include?.length) {
1210
1439
  const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
1211
1440
  if (includeMessages) {
@@ -1238,20 +1467,40 @@ var LibSQLStore = class extends MastraStorage {
1238
1467
  if (format === `v2`) return list.get.all.v2();
1239
1468
  return list.get.all.v1();
1240
1469
  } catch (error) {
1241
- this.logger.error("Error getting messages:", error);
1242
- throw error;
1470
+ throw new MastraError(
1471
+ {
1472
+ id: "LIBSQL_STORE_GET_MESSAGES_FAILED",
1473
+ domain: ErrorDomain.STORAGE,
1474
+ category: ErrorCategory.THIRD_PARTY,
1475
+ details: { threadId }
1476
+ },
1477
+ error
1478
+ );
1243
1479
  }
1244
1480
  }
1245
1481
  async getMessagesPaginated(args) {
1246
1482
  const { threadId, format, selectBy } = args;
1247
- const { page = 0, perPage = 40, dateRange } = selectBy?.pagination || {};
1483
+ const { page = 0, perPage: perPageInput, dateRange } = selectBy?.pagination || {};
1484
+ const perPage = perPageInput !== void 0 ? perPageInput : this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
1248
1485
  const fromDate = dateRange?.start;
1249
1486
  const toDate = dateRange?.end;
1250
1487
  const messages = [];
1251
1488
  if (selectBy?.include?.length) {
1252
- const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
1253
- if (includeMessages) {
1254
- messages.push(...includeMessages);
1489
+ try {
1490
+ const includeMessages = await this._getIncludedMessages({ threadId, selectBy });
1491
+ if (includeMessages) {
1492
+ messages.push(...includeMessages);
1493
+ }
1494
+ } catch (error) {
1495
+ throw new MastraError(
1496
+ {
1497
+ id: "LIBSQL_STORE_GET_MESSAGES_PAGINATED_GET_INCLUDE_MESSAGES_FAILED",
1498
+ domain: ErrorDomain.STORAGE,
1499
+ category: ErrorCategory.THIRD_PARTY,
1500
+ details: { threadId }
1501
+ },
1502
+ error
1503
+ );
1255
1504
  }
1256
1505
  }
1257
1506
  try {
@@ -1272,7 +1521,7 @@ var LibSQLStore = class extends MastraStorage {
1272
1521
  args: queryParams
1273
1522
  });
1274
1523
  const total = Number(countResult.rows?.[0]?.count ?? 0);
1275
- if (total === 0) {
1524
+ if (total === 0 && messages.length === 0) {
1276
1525
  return {
1277
1526
  messages: [],
1278
1527
  total: 0,
@@ -1281,9 +1530,11 @@ var LibSQLStore = class extends MastraStorage {
1281
1530
  hasMore: false
1282
1531
  };
1283
1532
  }
1533
+ const excludeIds = messages.map((m) => m.id);
1534
+ const excludeIdsParam = excludeIds.map((_, idx) => `$${idx + queryParams.length + 1}`).join(", ");
1284
1535
  const dataResult = await this.client.execute({
1285
- sql: `SELECT id, content, role, type, "createdAt", thread_id FROM ${TABLE_MESSAGES} ${whereClause} ORDER BY "createdAt" DESC LIMIT ? OFFSET ?`,
1286
- args: [...queryParams, perPage, currentOffset]
1536
+ sql: `SELECT id, content, role, type, "createdAt", "resourceId", "thread_id" FROM ${TABLE_MESSAGES} ${whereClause} ${excludeIds.length ? `AND id NOT IN (${excludeIdsParam})` : ""} ORDER BY "createdAt" DESC LIMIT ? OFFSET ?`,
1537
+ args: [...queryParams, ...excludeIds, perPage, currentOffset]
1287
1538
  });
1288
1539
  messages.push(...(dataResult.rows || []).map((row) => this.parseRow(row)));
1289
1540
  const messagesToReturn = format === "v1" ? new MessageList().add(messages, "memory").get.all.v1() : new MessageList().add(messages, "memory").get.all.v2();
@@ -1295,7 +1546,17 @@ var LibSQLStore = class extends MastraStorage {
1295
1546
  hasMore: currentOffset + messages.length < total
1296
1547
  };
1297
1548
  } catch (error) {
1298
- this.logger.error("Error getting paginated messages:", error);
1549
+ const mastraError = new MastraError(
1550
+ {
1551
+ id: "LIBSQL_STORE_GET_MESSAGES_PAGINATED_FAILED",
1552
+ domain: ErrorDomain.STORAGE,
1553
+ category: ErrorCategory.THIRD_PARTY,
1554
+ details: { threadId }
1555
+ },
1556
+ error
1557
+ );
1558
+ this.logger?.trackException?.(mastraError);
1559
+ this.logger?.error?.(mastraError.toString());
1299
1560
  return { messages: [], total: 0, page, perPage, hasMore: false };
1300
1561
  }
1301
1562
  }
@@ -1323,7 +1584,14 @@ var LibSQLStore = class extends MastraStorage {
1323
1584
  }
1324
1585
  return {
1325
1586
  sql: `INSERT INTO ${TABLE_MESSAGES} (id, thread_id, content, role, type, createdAt, resourceId)
1326
- VALUES (?, ?, ?, ?, ?, ?, ?)`,
1587
+ VALUES (?, ?, ?, ?, ?, ?, ?)
1588
+ ON CONFLICT(id) DO UPDATE SET
1589
+ thread_id=excluded.thread_id,
1590
+ content=excluded.content,
1591
+ role=excluded.role,
1592
+ type=excluded.type,
1593
+ resourceId=excluded.resourceId
1594
+ `,
1327
1595
  args: [
1328
1596
  message.id,
1329
1597
  message.threadId,
@@ -1345,8 +1613,14 @@ var LibSQLStore = class extends MastraStorage {
1345
1613
  if (format === `v2`) return list.get.all.v2();
1346
1614
  return list.get.all.v1();
1347
1615
  } catch (error) {
1348
- this.logger.error("Failed to save messages in database: " + error?.message);
1349
- throw error;
1616
+ throw new MastraError(
1617
+ {
1618
+ id: "LIBSQL_STORE_SAVE_MESSAGES_FAILED",
1619
+ domain: ErrorDomain.STORAGE,
1620
+ category: ErrorCategory.THIRD_PARTY
1621
+ },
1622
+ error
1623
+ );
1350
1624
  }
1351
1625
  }
1352
1626
  async updateMessages({
@@ -1461,8 +1735,15 @@ var LibSQLStore = class extends MastraStorage {
1461
1735
  if (error instanceof Error && error.message.includes("no such table")) {
1462
1736
  return [];
1463
1737
  }
1464
- this.logger.error("Failed to get evals for the specified agent: " + error?.message);
1465
- throw error;
1738
+ throw new MastraError(
1739
+ {
1740
+ id: "LIBSQL_STORE_GET_EVALS_BY_AGENT_NAME_FAILED",
1741
+ domain: ErrorDomain.STORAGE,
1742
+ category: ErrorCategory.THIRD_PARTY,
1743
+ details: { agentName }
1744
+ },
1745
+ error
1746
+ );
1466
1747
  }
1467
1748
  }
1468
1749
  async getEvals(options = {}) {
@@ -1489,33 +1770,44 @@ var LibSQLStore = class extends MastraStorage {
1489
1770
  queryParams.push(toDate.toISOString());
1490
1771
  }
1491
1772
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1492
- const countResult = await this.client.execute({
1493
- sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
1494
- args: queryParams
1495
- });
1496
- const total = Number(countResult.rows?.[0]?.count ?? 0);
1497
- const currentOffset = page * perPage;
1498
- const hasMore = currentOffset + perPage < total;
1499
- if (total === 0) {
1773
+ try {
1774
+ const countResult = await this.client.execute({
1775
+ sql: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
1776
+ args: queryParams
1777
+ });
1778
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
1779
+ const currentOffset = page * perPage;
1780
+ const hasMore = currentOffset + perPage < total;
1781
+ if (total === 0) {
1782
+ return {
1783
+ evals: [],
1784
+ total: 0,
1785
+ page,
1786
+ perPage,
1787
+ hasMore: false
1788
+ };
1789
+ }
1790
+ const dataResult = await this.client.execute({
1791
+ sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
1792
+ args: [...queryParams, perPage, currentOffset]
1793
+ });
1500
1794
  return {
1501
- evals: [],
1502
- total: 0,
1795
+ evals: dataResult.rows?.map((row) => this.transformEvalRow(row)) ?? [],
1796
+ total,
1503
1797
  page,
1504
1798
  perPage,
1505
- hasMore: false
1799
+ hasMore
1506
1800
  };
1801
+ } catch (error) {
1802
+ throw new MastraError(
1803
+ {
1804
+ id: "LIBSQL_STORE_GET_EVALS_FAILED",
1805
+ domain: ErrorDomain.STORAGE,
1806
+ category: ErrorCategory.THIRD_PARTY
1807
+ },
1808
+ error
1809
+ );
1507
1810
  }
1508
- const dataResult = await this.client.execute({
1509
- sql: `SELECT * FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT ? OFFSET ?`,
1510
- args: [...queryParams, perPage, currentOffset]
1511
- });
1512
- return {
1513
- evals: dataResult.rows?.map((row) => this.transformEvalRow(row)) ?? [],
1514
- total,
1515
- page,
1516
- perPage,
1517
- hasMore
1518
- };
1519
1811
  }
1520
1812
  /**
1521
1813
  * @deprecated use getTracesPaginated instead.
@@ -1527,8 +1819,19 @@ var LibSQLStore = class extends MastraStorage {
1527
1819
  end: args.toDate
1528
1820
  };
1529
1821
  }
1530
- const result = await this.getTracesPaginated(args);
1531
- return result.traces;
1822
+ try {
1823
+ const result = await this.getTracesPaginated(args);
1824
+ return result.traces;
1825
+ } catch (error) {
1826
+ throw new MastraError(
1827
+ {
1828
+ id: "LIBSQL_STORE_GET_TRACES_FAILED",
1829
+ domain: ErrorDomain.STORAGE,
1830
+ category: ErrorCategory.THIRD_PARTY
1831
+ },
1832
+ error
1833
+ );
1834
+ }
1532
1835
  }
1533
1836
  async getTracesPaginated(args) {
1534
1837
  const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
@@ -1566,49 +1869,60 @@ var LibSQLStore = class extends MastraStorage {
1566
1869
  queryArgs.push(toDate.toISOString());
1567
1870
  }
1568
1871
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1569
- const countResult = await this.client.execute({
1570
- sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
1571
- args: queryArgs
1572
- });
1573
- const total = Number(countResult.rows?.[0]?.count ?? 0);
1574
- if (total === 0) {
1872
+ try {
1873
+ const countResult = await this.client.execute({
1874
+ sql: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
1875
+ args: queryArgs
1876
+ });
1877
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
1878
+ if (total === 0) {
1879
+ return {
1880
+ traces: [],
1881
+ total: 0,
1882
+ page,
1883
+ perPage,
1884
+ hasMore: false
1885
+ };
1886
+ }
1887
+ const dataResult = await this.client.execute({
1888
+ sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
1889
+ args: [...queryArgs, perPage, currentOffset]
1890
+ });
1891
+ const traces = dataResult.rows?.map(
1892
+ (row) => ({
1893
+ id: row.id,
1894
+ parentSpanId: row.parentSpanId,
1895
+ traceId: row.traceId,
1896
+ name: row.name,
1897
+ scope: row.scope,
1898
+ kind: row.kind,
1899
+ status: safelyParseJSON(row.status),
1900
+ events: safelyParseJSON(row.events),
1901
+ links: safelyParseJSON(row.links),
1902
+ attributes: safelyParseJSON(row.attributes),
1903
+ startTime: row.startTime,
1904
+ endTime: row.endTime,
1905
+ other: safelyParseJSON(row.other),
1906
+ createdAt: row.createdAt
1907
+ })
1908
+ ) ?? [];
1575
1909
  return {
1576
- traces: [],
1577
- total: 0,
1910
+ traces,
1911
+ total,
1578
1912
  page,
1579
1913
  perPage,
1580
- hasMore: false
1914
+ hasMore: currentOffset + traces.length < total
1581
1915
  };
1916
+ } catch (error) {
1917
+ throw new MastraError(
1918
+ {
1919
+ id: "LIBSQL_STORE_GET_TRACES_PAGINATED_FAILED",
1920
+ domain: ErrorDomain.STORAGE,
1921
+ category: ErrorCategory.THIRD_PARTY
1922
+ },
1923
+ error
1924
+ );
1582
1925
  }
1583
- const dataResult = await this.client.execute({
1584
- sql: `SELECT * FROM ${TABLE_TRACES} ${whereClause} ORDER BY "startTime" DESC LIMIT ? OFFSET ?`,
1585
- args: [...queryArgs, perPage, currentOffset]
1586
- });
1587
- const traces = dataResult.rows?.map(
1588
- (row) => ({
1589
- id: row.id,
1590
- parentSpanId: row.parentSpanId,
1591
- traceId: row.traceId,
1592
- name: row.name,
1593
- scope: row.scope,
1594
- kind: row.kind,
1595
- status: safelyParseJSON(row.status),
1596
- events: safelyParseJSON(row.events),
1597
- links: safelyParseJSON(row.links),
1598
- attributes: safelyParseJSON(row.attributes),
1599
- startTime: row.startTime,
1600
- endTime: row.endTime,
1601
- other: safelyParseJSON(row.other),
1602
- createdAt: row.createdAt
1603
- })
1604
- ) ?? [];
1605
- return {
1606
- traces,
1607
- total,
1608
- page,
1609
- perPage,
1610
- hasMore: currentOffset + traces.length < total
1611
- };
1612
1926
  }
1613
1927
  async getWorkflowRuns({
1614
1928
  workflowName,
@@ -1658,8 +1972,14 @@ var LibSQLStore = class extends MastraStorage {
1658
1972
  const runs = (result.rows || []).map((row) => this.parseWorkflowRun(row));
1659
1973
  return { runs, total: total || runs.length };
1660
1974
  } catch (error) {
1661
- console.error("Error getting workflow runs:", error);
1662
- throw error;
1975
+ throw new MastraError(
1976
+ {
1977
+ id: "LIBSQL_STORE_GET_WORKFLOW_RUNS_FAILED",
1978
+ domain: ErrorDomain.STORAGE,
1979
+ category: ErrorCategory.THIRD_PARTY
1980
+ },
1981
+ error
1982
+ );
1663
1983
  }
1664
1984
  }
1665
1985
  async getWorkflowRunById({
@@ -1677,14 +1997,94 @@ var LibSQLStore = class extends MastraStorage {
1677
1997
  args.push(workflowName);
1678
1998
  }
1679
1999
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1680
- const result = await this.client.execute({
1681
- sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
1682
- args
2000
+ try {
2001
+ const result = await this.client.execute({
2002
+ sql: `SELECT * FROM ${TABLE_WORKFLOW_SNAPSHOT} ${whereClause}`,
2003
+ args
2004
+ });
2005
+ if (!result.rows?.[0]) {
2006
+ return null;
2007
+ }
2008
+ return this.parseWorkflowRun(result.rows[0]);
2009
+ } catch (error) {
2010
+ throw new MastraError(
2011
+ {
2012
+ id: "LIBSQL_STORE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2013
+ domain: ErrorDomain.STORAGE,
2014
+ category: ErrorCategory.THIRD_PARTY
2015
+ },
2016
+ error
2017
+ );
2018
+ }
2019
+ }
2020
+ async getResourceById({ resourceId }) {
2021
+ const result = await this.load({
2022
+ tableName: TABLE_RESOURCES,
2023
+ keys: { id: resourceId }
1683
2024
  });
1684
- if (!result.rows?.[0]) {
2025
+ if (!result) {
1685
2026
  return null;
1686
2027
  }
1687
- return this.parseWorkflowRun(result.rows[0]);
2028
+ return {
2029
+ ...result,
2030
+ // Ensure workingMemory is always returned as a string, even if auto-parsed as JSON
2031
+ workingMemory: typeof result.workingMemory === "object" ? JSON.stringify(result.workingMemory) : result.workingMemory,
2032
+ metadata: typeof result.metadata === "string" ? JSON.parse(result.metadata) : result.metadata
2033
+ };
2034
+ }
2035
+ async saveResource({ resource }) {
2036
+ await this.insert({
2037
+ tableName: TABLE_RESOURCES,
2038
+ record: {
2039
+ ...resource,
2040
+ metadata: JSON.stringify(resource.metadata)
2041
+ }
2042
+ });
2043
+ return resource;
2044
+ }
2045
+ async updateResource({
2046
+ resourceId,
2047
+ workingMemory,
2048
+ metadata
2049
+ }) {
2050
+ const existingResource = await this.getResourceById({ resourceId });
2051
+ if (!existingResource) {
2052
+ const newResource = {
2053
+ id: resourceId,
2054
+ workingMemory,
2055
+ metadata: metadata || {},
2056
+ createdAt: /* @__PURE__ */ new Date(),
2057
+ updatedAt: /* @__PURE__ */ new Date()
2058
+ };
2059
+ return this.saveResource({ resource: newResource });
2060
+ }
2061
+ const updatedResource = {
2062
+ ...existingResource,
2063
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
2064
+ metadata: {
2065
+ ...existingResource.metadata,
2066
+ ...metadata
2067
+ },
2068
+ updatedAt: /* @__PURE__ */ new Date()
2069
+ };
2070
+ const updates = [];
2071
+ const values = [];
2072
+ if (workingMemory !== void 0) {
2073
+ updates.push("workingMemory = ?");
2074
+ values.push(workingMemory);
2075
+ }
2076
+ if (metadata) {
2077
+ updates.push("metadata = ?");
2078
+ values.push(JSON.stringify(updatedResource.metadata));
2079
+ }
2080
+ updates.push("updatedAt = ?");
2081
+ values.push(updatedResource.updatedAt.toISOString());
2082
+ values.push(resourceId);
2083
+ await this.client.execute({
2084
+ sql: `UPDATE ${TABLE_RESOURCES} SET ${updates.join(", ")} WHERE id = ?`,
2085
+ args: values
2086
+ });
2087
+ return updatedResource;
1688
2088
  }
1689
2089
  async hasColumn(table, column) {
1690
2090
  const result = await this.client.execute({