@mastra/libsql 0.16.2 → 0.16.3-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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @mastra/libsql
2
2
 
3
+ ## 0.16.3-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - deleteVectors, deleteFilter when upserting, updateVector filter (#10244) ([#10526](https://github.com/mastra-ai/mastra/pull/10526))
8
+
9
+ - Fix message sorting in getMessagesPaginated when using semantic recall (include parameter). Messages are now always sorted by createdAt after combining paginated and included messages, ensuring correct chronological ordering of conversation history. All stores now consistently use MessageList for deduplication followed by explicit sorting. ([#10573](https://github.com/mastra-ai/mastra/pull/10573))
10
+
11
+ - Updated dependencies [[`5657314`](https://github.com/mastra-ai/mastra/commit/5657314a1f9d49019bb53f357fa48f75a69247ca), [`e5aca78`](https://github.com/mastra-ai/mastra/commit/e5aca78bb7f263bb8b470bedae81efe9805d7544), [`33a607a`](https://github.com/mastra-ai/mastra/commit/33a607a1f716c2029d4a1ff1603dd756129a33b3), [`cc10fc1`](https://github.com/mastra-ai/mastra/commit/cc10fc192d9f527c71a23cc9def10d8718935ee1), [`1f7ee84`](https://github.com/mastra-ai/mastra/commit/1f7ee841a643ef12d90392125881f06fdf877293), [`e7d5149`](https://github.com/mastra-ai/mastra/commit/e7d514995260b63b2108308e85c64de37dcd0f71), [`f195082`](https://github.com/mastra-ai/mastra/commit/f1950822a2425d5ccae78c5d010e02ddb027a869), [`d9986dd`](https://github.com/mastra-ai/mastra/commit/d9986dd3513f7ca3244a8e599a440ccf4d8bc28b), [`a45b0f0`](https://github.com/mastra-ai/mastra/commit/a45b0f0cd19eab1fe4deceae3abf029442c22f74), [`f6e8eb3`](https://github.com/mastra-ai/mastra/commit/f6e8eb3dac53b70b06e906b2818b1d2a5b0486d7), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`3236f35`](https://github.com/mastra-ai/mastra/commit/3236f352ae13cc8552c2965164e97bd125dae48d), [`ce57a2b`](https://github.com/mastra-ai/mastra/commit/ce57a2b62fd0d5f6532e4ecd1ba9ba93ac9b95fc), [`0230321`](https://github.com/mastra-ai/mastra/commit/02303217870bedea0ef009bea9a952f24ed38aaf), [`7b541f4`](https://github.com/mastra-ai/mastra/commit/7b541f49eda6f5a87b738198edbd136927599475), [`0eea842`](https://github.com/mastra-ai/mastra/commit/0eea8423cbdd37f2111593c6f7d2efcde4b7e4ce), [`63ae8a2`](https://github.com/mastra-ai/mastra/commit/63ae8a22c0c09bbb8b9779f5f38934cd75f616af), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`ac7ef07`](https://github.com/mastra-ai/mastra/commit/ac7ef07633caee89707142171d2873c888ffef85), [`522f0b4`](https://github.com/mastra-ai/mastra/commit/522f0b45330719858794eabffffde4f343f55549), [`bf810c5`](https://github.com/mastra-ai/mastra/commit/bf810c5c561bd8ef221c0f6bd84e69770b9a38cc), [`8b51d55`](https://github.com/mastra-ai/mastra/commit/8b51d55bae531edf7e383958d7ecee04df31f5d5), [`2131ac5`](https://github.com/mastra-ai/mastra/commit/2131ac571d5065f0a656c57494bca98691bb7609)]:
12
+ - @mastra/core@0.24.6-alpha.0
13
+
3
14
  ## 0.16.2
4
15
 
5
16
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -92,12 +92,20 @@ var createBasicOperator = (symbol) => {
92
92
  };
93
93
  };
94
94
  var createNumericOperator = (symbol) => {
95
- return (key) => {
95
+ return (key, value) => {
96
96
  const jsonPath = getJsonPath(key);
97
- return {
98
- sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
99
- needsValue: true
100
- };
97
+ const isNumeric = typeof value === "number" || typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "";
98
+ if (isNumeric) {
99
+ return {
100
+ sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
101
+ needsValue: true
102
+ };
103
+ } else {
104
+ return {
105
+ sql: `CAST(json_extract(metadata, ${jsonPath}) AS TEXT) ${symbol} ?`,
106
+ needsValue: true
107
+ };
108
+ }
101
109
  };
102
110
  };
103
111
  var validateJsonArray = (key) => {
@@ -825,8 +833,27 @@ var LibSQLVector = class extends vector.MastraVector {
825
833
  updateVector(args) {
826
834
  return this.executeWriteOperationWithRetry(() => this.doUpdateVector(args));
827
835
  }
828
- async doUpdateVector({ indexName, id, update }) {
836
+ async doUpdateVector(params) {
837
+ const { indexName, update } = params;
829
838
  const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
839
+ if ("id" in params && params.id && "filter" in params && params.filter) {
840
+ throw new error.MastraError({
841
+ id: "LIBSQL_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS",
842
+ domain: error.ErrorDomain.STORAGE,
843
+ category: error.ErrorCategory.USER,
844
+ details: { indexName },
845
+ text: "id and filter are mutually exclusive - provide only one"
846
+ });
847
+ }
848
+ if (!update.vector && !update.metadata) {
849
+ throw new error.MastraError({
850
+ id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
851
+ domain: error.ErrorDomain.STORAGE,
852
+ category: error.ErrorCategory.USER,
853
+ details: { indexName },
854
+ text: "No updates provided"
855
+ });
856
+ }
830
857
  const updates = [];
831
858
  const args = [];
832
859
  if (update.vector) {
@@ -838,32 +865,81 @@ var LibSQLVector = class extends vector.MastraVector {
838
865
  args.push(JSON.stringify(update.metadata));
839
866
  }
840
867
  if (updates.length === 0) {
868
+ return;
869
+ }
870
+ let whereClause;
871
+ let whereValues;
872
+ if ("id" in params && params.id) {
873
+ whereClause = "vector_id = ?";
874
+ whereValues = [params.id];
875
+ } else if ("filter" in params && params.filter) {
876
+ const filter = params.filter;
877
+ if (!filter || Object.keys(filter).length === 0) {
878
+ throw new error.MastraError({
879
+ id: "LIBSQL_VECTOR_UPDATE_EMPTY_FILTER",
880
+ domain: error.ErrorDomain.STORAGE,
881
+ category: error.ErrorCategory.USER,
882
+ details: { indexName },
883
+ text: "Cannot update with empty filter"
884
+ });
885
+ }
886
+ const translatedFilter = this.transformFilter(filter);
887
+ const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
888
+ if (!filterSql || filterSql.trim() === "") {
889
+ throw new error.MastraError({
890
+ id: "LIBSQL_VECTOR_UPDATE_INVALID_FILTER",
891
+ domain: error.ErrorDomain.STORAGE,
892
+ category: error.ErrorCategory.USER,
893
+ details: { indexName },
894
+ text: "Filter produced empty WHERE clause"
895
+ });
896
+ }
897
+ const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
898
+ const matchAllPatterns = ["true", "1 = 1", "1=1"];
899
+ if (matchAllPatterns.includes(normalizedCondition)) {
900
+ throw new error.MastraError({
901
+ id: "LIBSQL_VECTOR_UPDATE_MATCH_ALL_FILTER",
902
+ domain: error.ErrorDomain.STORAGE,
903
+ category: error.ErrorCategory.USER,
904
+ details: { indexName, filterSql: normalizedCondition },
905
+ text: "Filter matches all vectors. Provide a specific filter to update targeted vectors."
906
+ });
907
+ }
908
+ whereClause = filterSql.replace(/^WHERE\s+/i, "");
909
+ whereValues = filterValues;
910
+ } else {
841
911
  throw new error.MastraError({
842
- id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
912
+ id: "LIBSQL_VECTOR_UPDATE_MISSING_PARAMS",
843
913
  domain: error.ErrorDomain.STORAGE,
844
914
  category: error.ErrorCategory.USER,
845
- details: { indexName, id },
846
- text: "No updates provided"
915
+ details: { indexName },
916
+ text: "Either id or filter must be provided"
847
917
  });
848
918
  }
849
- args.push(id);
850
919
  const query = `
851
- UPDATE ${parsedIndexName}
852
- SET ${updates.join(", ")}
853
- WHERE vector_id = ?;
854
- `;
920
+ UPDATE ${parsedIndexName}
921
+ SET ${updates.join(", ")}
922
+ WHERE ${whereClause};
923
+ `;
855
924
  try {
856
925
  await this.turso.execute({
857
926
  sql: query,
858
- args
927
+ args: [...args, ...whereValues]
859
928
  });
860
929
  } catch (error$1) {
930
+ const errorDetails = { indexName };
931
+ if ("id" in params && params.id) {
932
+ errorDetails.id = params.id;
933
+ }
934
+ if ("filter" in params && params.filter) {
935
+ errorDetails.filter = JSON.stringify(params.filter);
936
+ }
861
937
  throw new error.MastraError(
862
938
  {
863
939
  id: "LIBSQL_VECTOR_UPDATE_VECTOR_FAILED",
864
940
  domain: error.ErrorDomain.STORAGE,
865
941
  category: error.ErrorCategory.THIRD_PARTY,
866
- details: { indexName, id }
942
+ details: errorDetails
867
943
  },
868
944
  error$1
869
945
  );
@@ -885,7 +961,10 @@ var LibSQLVector = class extends vector.MastraVector {
885
961
  id: "LIBSQL_VECTOR_DELETE_VECTOR_FAILED",
886
962
  domain: error.ErrorDomain.STORAGE,
887
963
  category: error.ErrorCategory.THIRD_PARTY,
888
- details: { indexName: args.indexName, id: args.id }
964
+ details: {
965
+ indexName: args.indexName,
966
+ ...args.id && { id: args.id }
967
+ }
889
968
  },
890
969
  error$1
891
970
  );
@@ -898,6 +977,100 @@ var LibSQLVector = class extends vector.MastraVector {
898
977
  args: [id]
899
978
  });
900
979
  }
980
+ deleteVectors(args) {
981
+ return this.executeWriteOperationWithRetry(() => this.doDeleteVectors(args));
982
+ }
983
+ async doDeleteVectors({ indexName, filter, ids }) {
984
+ const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
985
+ if (!filter && !ids) {
986
+ throw new error.MastraError({
987
+ id: "LIBSQL_VECTOR_DELETE_MISSING_PARAMS",
988
+ domain: error.ErrorDomain.STORAGE,
989
+ category: error.ErrorCategory.USER,
990
+ details: { indexName },
991
+ text: "Either filter or ids must be provided"
992
+ });
993
+ }
994
+ if (filter && ids) {
995
+ throw new error.MastraError({
996
+ id: "LIBSQL_VECTOR_DELETE_CONFLICTING_PARAMS",
997
+ domain: error.ErrorDomain.STORAGE,
998
+ category: error.ErrorCategory.USER,
999
+ details: { indexName },
1000
+ text: "Cannot provide both filter and ids - they are mutually exclusive"
1001
+ });
1002
+ }
1003
+ let query;
1004
+ let values;
1005
+ if (ids) {
1006
+ if (ids.length === 0) {
1007
+ throw new error.MastraError({
1008
+ id: "LIBSQL_VECTOR_DELETE_EMPTY_IDS",
1009
+ domain: error.ErrorDomain.STORAGE,
1010
+ category: error.ErrorCategory.USER,
1011
+ details: { indexName },
1012
+ text: "Cannot delete with empty ids array"
1013
+ });
1014
+ }
1015
+ const placeholders = ids.map(() => "?").join(", ");
1016
+ query = `DELETE FROM ${parsedIndexName} WHERE vector_id IN (${placeholders})`;
1017
+ values = ids;
1018
+ } else {
1019
+ if (!filter || Object.keys(filter).length === 0) {
1020
+ throw new error.MastraError({
1021
+ id: "LIBSQL_VECTOR_DELETE_EMPTY_FILTER",
1022
+ domain: error.ErrorDomain.STORAGE,
1023
+ category: error.ErrorCategory.USER,
1024
+ details: { indexName },
1025
+ text: "Cannot delete with empty filter. Use deleteIndex to delete all vectors."
1026
+ });
1027
+ }
1028
+ const translatedFilter = this.transformFilter(filter);
1029
+ const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
1030
+ if (!filterSql || filterSql.trim() === "") {
1031
+ throw new error.MastraError({
1032
+ id: "LIBSQL_VECTOR_DELETE_INVALID_FILTER",
1033
+ domain: error.ErrorDomain.STORAGE,
1034
+ category: error.ErrorCategory.USER,
1035
+ details: { indexName },
1036
+ text: "Filter produced empty WHERE clause"
1037
+ });
1038
+ }
1039
+ const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
1040
+ const matchAllPatterns = ["true", "1 = 1", "1=1"];
1041
+ if (matchAllPatterns.includes(normalizedCondition)) {
1042
+ throw new error.MastraError({
1043
+ id: "LIBSQL_VECTOR_DELETE_MATCH_ALL_FILTER",
1044
+ domain: error.ErrorDomain.STORAGE,
1045
+ category: error.ErrorCategory.USER,
1046
+ details: { indexName, filterSql: normalizedCondition },
1047
+ text: "Filter matches all vectors. Use deleteIndex to delete all vectors from an index."
1048
+ });
1049
+ }
1050
+ query = `DELETE FROM ${parsedIndexName} ${filterSql}`;
1051
+ values = filterValues;
1052
+ }
1053
+ try {
1054
+ await this.turso.execute({
1055
+ sql: query,
1056
+ args: values
1057
+ });
1058
+ } catch (error$1) {
1059
+ throw new error.MastraError(
1060
+ {
1061
+ id: "LIBSQL_VECTOR_DELETE_VECTORS_FAILED",
1062
+ domain: error.ErrorDomain.STORAGE,
1063
+ category: error.ErrorCategory.THIRD_PARTY,
1064
+ details: {
1065
+ indexName,
1066
+ ...filter && { filter: JSON.stringify(filter) },
1067
+ ...ids && { idsCount: ids.length }
1068
+ }
1069
+ },
1070
+ error$1
1071
+ );
1072
+ }
1073
+ }
901
1074
  truncateIndex(args) {
902
1075
  try {
903
1076
  return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
@@ -1256,7 +1429,11 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
1256
1429
  args: [...queryParams, ...excludeIds, perPage, currentOffset]
1257
1430
  });
1258
1431
  messages.push(...(dataResult.rows || []).map((row) => this.parseRow(row)));
1259
- const messagesToReturn = format === "v1" ? new agent.MessageList().add(messages, "memory").get.all.v1() : new agent.MessageList().add(messages, "memory").get.all.v2();
1432
+ const list = new agent.MessageList().add(messages, "memory");
1433
+ let messagesToReturn = format === "v1" ? list.get.all.v1() : list.get.all.v2();
1434
+ messagesToReturn = messagesToReturn.sort(
1435
+ (a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
1436
+ );
1260
1437
  return {
1261
1438
  messages: messagesToReturn,
1262
1439
  total,