@mastra/lance 1.0.0-beta.1 → 1.0.0-beta.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @mastra/lance
2
2
 
3
+ ## 1.0.0-beta.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Add new deleteVectors, updateVector by filter ([#10408](https://github.com/mastra-ai/mastra/pull/10408))
8
+
9
+ - Updated dependencies [[`21a15de`](https://github.com/mastra-ai/mastra/commit/21a15de369fe82aac26bb642ed7be73505475e8b), [`feb7ee4`](https://github.com/mastra-ai/mastra/commit/feb7ee4d09a75edb46c6669a3beaceec78811747), [`b0e2ea5`](https://github.com/mastra-ai/mastra/commit/b0e2ea5b52c40fae438b9e2f7baee6f0f89c5442), [`c456e01`](https://github.com/mastra-ai/mastra/commit/c456e0149e3c176afcefdbd9bb1d2c5917723725), [`ab035c2`](https://github.com/mastra-ai/mastra/commit/ab035c2ef6d8cc7bb25f06f1a38508bd9e6f126b), [`1a46a56`](https://github.com/mastra-ai/mastra/commit/1a46a566f45a3fcbadc1cf36bf86d351f264bfa3), [`3cf540b`](https://github.com/mastra-ai/mastra/commit/3cf540b9fbfea8f4fc8d3a2319a4e6c0b0cbfd52), [`1c6ce51`](https://github.com/mastra-ai/mastra/commit/1c6ce51f875915ab57fd36873623013699a2a65d), [`898a972`](https://github.com/mastra-ai/mastra/commit/898a9727d286c2510d6b702dfd367e6aaf5c6b0f), [`a97003a`](https://github.com/mastra-ai/mastra/commit/a97003aa1cf2f4022a41912324a1e77263b326b8), [`ccc141e`](https://github.com/mastra-ai/mastra/commit/ccc141ed27da0abc3a3fc28e9e5128152e8e37f4), [`fe3b897`](https://github.com/mastra-ai/mastra/commit/fe3b897c2ccbcd2b10e81b099438c7337feddf89), [`00123ba`](https://github.com/mastra-ai/mastra/commit/00123ba96dc9e5cd0b110420ebdba56d8f237b25), [`29c4309`](https://github.com/mastra-ai/mastra/commit/29c4309f818b24304c041bcb4a8f19b5f13f6b62), [`16785ce`](https://github.com/mastra-ai/mastra/commit/16785ced928f6f22638f4488cf8a125d99211799), [`de8239b`](https://github.com/mastra-ai/mastra/commit/de8239bdcb1d8c0cfa06da21f1569912a66bbc8a), [`b5e6cd7`](https://github.com/mastra-ai/mastra/commit/b5e6cd77fc8c8e64e0494c1d06cee3d84e795d1e), [`3759cb0`](https://github.com/mastra-ai/mastra/commit/3759cb064935b5f74c65ac2f52a1145f7352899d), [`651e772`](https://github.com/mastra-ai/mastra/commit/651e772eb1475fb13e126d3fcc01751297a88214), [`b61b93f`](https://github.com/mastra-ai/mastra/commit/b61b93f9e058b11dd2eec169853175d31dbdd567), [`bae33d9`](https://github.com/mastra-ai/mastra/commit/bae33d91a63fbb64d1e80519e1fc1acaed1e9013), [`c0b731f`](https://github.com/mastra-ai/mastra/commit/c0b731fb27d712dc8582e846df5c0332a6a0c5ba), [`43ca8f2`](https://github.com/mastra-ai/mastra/commit/43ca8f2c7334851cc7b4d3d2f037d8784bfbdd5f), [`2ca67cc`](https://github.com/mastra-ai/mastra/commit/2ca67cc3bb1f6a617353fdcab197d9efebe60d6f), [`9e67002`](https://github.com/mastra-ai/mastra/commit/9e67002b52c9be19936c420a489dbee9c5fd6a78), [`35edc49`](https://github.com/mastra-ai/mastra/commit/35edc49ac0556db609189641d6341e76771b81fc)]:
10
+ - @mastra/core@1.0.0-beta.5
11
+
3
12
  ## 1.0.0-beta.1
4
13
 
5
14
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -2845,7 +2845,44 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2845
2845
  );
2846
2846
  }
2847
2847
  }
2848
- async updateVector({ indexName, id, update }) {
2848
+ async updateVector(params) {
2849
+ const { indexName, update } = params;
2850
+ if ("id" in params && "filter" in params && params.id && params.filter) {
2851
+ throw new error.MastraError({
2852
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
2853
+ domain: error.ErrorDomain.STORAGE,
2854
+ category: error.ErrorCategory.USER,
2855
+ text: "id and filter are mutually exclusive",
2856
+ details: { indexName }
2857
+ });
2858
+ }
2859
+ if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
2860
+ throw new error.MastraError({
2861
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
2862
+ domain: error.ErrorDomain.STORAGE,
2863
+ category: error.ErrorCategory.USER,
2864
+ text: "Either id or filter must be provided",
2865
+ details: { indexName }
2866
+ });
2867
+ }
2868
+ if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
2869
+ throw new error.MastraError({
2870
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
2871
+ domain: error.ErrorDomain.STORAGE,
2872
+ category: error.ErrorCategory.USER,
2873
+ text: "Cannot update with empty filter",
2874
+ details: { indexName }
2875
+ });
2876
+ }
2877
+ if (!update.vector && !update.metadata) {
2878
+ throw new error.MastraError({
2879
+ id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
2880
+ domain: error.ErrorDomain.STORAGE,
2881
+ category: error.ErrorCategory.USER,
2882
+ text: "No updates provided",
2883
+ details: { indexName }
2884
+ });
2885
+ }
2849
2886
  try {
2850
2887
  if (!this.lanceClient) {
2851
2888
  throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
@@ -2853,21 +2890,6 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2853
2890
  if (!indexName) {
2854
2891
  throw new Error("indexName is required");
2855
2892
  }
2856
- if (!id) {
2857
- throw new Error("id is required");
2858
- }
2859
- } catch (err) {
2860
- throw new error.MastraError(
2861
- {
2862
- id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
2863
- domain: error.ErrorDomain.STORAGE,
2864
- category: error.ErrorCategory.USER,
2865
- details: { indexName, id }
2866
- },
2867
- err
2868
- );
2869
- }
2870
- try {
2871
2893
  const tables = await this.lanceClient.tableNames();
2872
2894
  for (const tableName of tables) {
2873
2895
  this.logger.debug("Checking table:" + tableName);
@@ -2877,39 +2899,66 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2877
2899
  const hasColumn = schema.fields.some((field) => field.name === indexName);
2878
2900
  if (hasColumn) {
2879
2901
  this.logger.debug(`Found column ${indexName} in table ${tableName}`);
2880
- const existingRecord = await table.query().where(`id = '${id}'`).select(schema.fields.map((field) => field.name)).limit(1).toArray();
2881
- if (existingRecord.length === 0) {
2882
- throw new Error(`Record with id '${id}' not found in table ${tableName}`);
2902
+ let whereClause;
2903
+ if ("id" in params && params.id) {
2904
+ whereClause = `id = '${params.id}'`;
2905
+ } else if ("filter" in params && params.filter) {
2906
+ const translator = new LanceFilterTranslator();
2907
+ const processFilterKeys = (filter) => {
2908
+ const processedFilter = {};
2909
+ Object.entries(filter).forEach(([key, value]) => {
2910
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
2911
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
2912
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
2913
+ });
2914
+ } else {
2915
+ processedFilter[`metadata_${key}`] = value;
2916
+ }
2917
+ });
2918
+ return processedFilter;
2919
+ };
2920
+ const prefixedFilter = processFilterKeys(params.filter);
2921
+ whereClause = translator.translate(prefixedFilter) || "";
2922
+ if (!whereClause) {
2923
+ throw new Error("Failed to translate filter to SQL");
2924
+ }
2925
+ } else {
2926
+ throw new Error("Either id or filter must be provided");
2883
2927
  }
2884
- const rowData = {
2885
- id
2886
- };
2887
- Object.entries(existingRecord[0]).forEach(([key, value]) => {
2888
- if (key !== "id" && key !== "_distance") {
2889
- if (key === indexName) {
2890
- if (!update.vector) {
2891
- if (Array.isArray(value)) {
2892
- rowData[key] = [...value];
2893
- } else if (typeof value === "object" && value !== null) {
2894
- rowData[key] = Array.from(value);
2928
+ const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
2929
+ if (existingRecords.length === 0) {
2930
+ this.logger.info(`No records found matching criteria in table ${tableName}`);
2931
+ return;
2932
+ }
2933
+ const updatedRecords = existingRecords.map((record) => {
2934
+ const rowData = {};
2935
+ Object.entries(record).forEach(([key, value]) => {
2936
+ if (key !== "_distance") {
2937
+ if (key === indexName) {
2938
+ if (update.vector) {
2939
+ rowData[key] = update.vector;
2895
2940
  } else {
2896
- rowData[key] = value;
2941
+ if (Array.isArray(value)) {
2942
+ rowData[key] = [...value];
2943
+ } else if (typeof value === "object" && value !== null) {
2944
+ rowData[key] = Array.from(value);
2945
+ } else {
2946
+ rowData[key] = value;
2947
+ }
2897
2948
  }
2949
+ } else {
2950
+ rowData[key] = value;
2898
2951
  }
2899
- } else {
2900
- rowData[key] = value;
2901
2952
  }
2953
+ });
2954
+ if (update.metadata) {
2955
+ Object.entries(update.metadata).forEach(([key, value]) => {
2956
+ rowData[`metadata_${key}`] = value;
2957
+ });
2902
2958
  }
2959
+ return rowData;
2903
2960
  });
2904
- if (update.vector) {
2905
- rowData[indexName] = update.vector;
2906
- }
2907
- if (update.metadata) {
2908
- Object.entries(update.metadata).forEach(([key, value]) => {
2909
- rowData[`metadata_${key}`] = value;
2910
- });
2911
- }
2912
- await table.add([rowData], { mode: "overwrite" });
2961
+ await table.add(updatedRecords, { mode: "overwrite" });
2913
2962
  return;
2914
2963
  }
2915
2964
  } catch (err) {
@@ -2919,12 +2968,19 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2919
2968
  }
2920
2969
  throw new Error(`No table found with column/index '${indexName}'`);
2921
2970
  } catch (error$1) {
2971
+ if (error$1 instanceof error.MastraError) throw error$1;
2922
2972
  throw new error.MastraError(
2923
2973
  {
2924
2974
  id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
2925
2975
  domain: error.ErrorDomain.STORAGE,
2926
2976
  category: error.ErrorCategory.THIRD_PARTY,
2927
- details: { indexName, id, hasVector: !!update.vector, hasMetadata: !!update.metadata }
2977
+ details: {
2978
+ indexName,
2979
+ ..."id" in params && params.id && { id: params.id },
2980
+ ..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
2981
+ hasVector: !!update.vector,
2982
+ hasMetadata: !!update.metadata
2983
+ }
2928
2984
  },
2929
2985
  error$1
2930
2986
  );
@@ -2947,7 +3003,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2947
3003
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
2948
3004
  domain: error.ErrorDomain.STORAGE,
2949
3005
  category: error.ErrorCategory.USER,
2950
- details: { indexName, id }
3006
+ details: {
3007
+ indexName,
3008
+ ...id && { id }
3009
+ }
2951
3010
  },
2952
3011
  err
2953
3012
  );
@@ -2977,7 +3036,10 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
2977
3036
  id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
2978
3037
  domain: error.ErrorDomain.STORAGE,
2979
3038
  category: error.ErrorCategory.THIRD_PARTY,
2980
- details: { indexName, id }
3039
+ details: {
3040
+ indexName,
3041
+ ...id && { id }
3042
+ }
2981
3043
  },
2982
3044
  error$1
2983
3045
  );
@@ -3008,6 +3070,109 @@ var LanceVectorStore = class _LanceVectorStore extends vector.MastraVector {
3008
3070
  });
3009
3071
  return result;
3010
3072
  }
3073
+ async deleteVectors({ indexName, filter, ids }) {
3074
+ if (ids && filter) {
3075
+ throw new error.MastraError({
3076
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3077
+ domain: error.ErrorDomain.STORAGE,
3078
+ category: error.ErrorCategory.USER,
3079
+ text: "ids and filter are mutually exclusive",
3080
+ details: { indexName }
3081
+ });
3082
+ }
3083
+ if (!ids && !filter) {
3084
+ throw new error.MastraError({
3085
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3086
+ domain: error.ErrorDomain.STORAGE,
3087
+ category: error.ErrorCategory.USER,
3088
+ text: "Either filter or ids must be provided",
3089
+ details: { indexName }
3090
+ });
3091
+ }
3092
+ if (ids && ids.length === 0) {
3093
+ throw new error.MastraError({
3094
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3095
+ domain: error.ErrorDomain.STORAGE,
3096
+ category: error.ErrorCategory.USER,
3097
+ text: "Cannot delete with empty ids array",
3098
+ details: { indexName }
3099
+ });
3100
+ }
3101
+ if (filter && Object.keys(filter).length === 0) {
3102
+ throw new error.MastraError({
3103
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
3104
+ domain: error.ErrorDomain.STORAGE,
3105
+ category: error.ErrorCategory.USER,
3106
+ text: "Cannot delete with empty filter",
3107
+ details: { indexName }
3108
+ });
3109
+ }
3110
+ try {
3111
+ if (!this.lanceClient) {
3112
+ throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
3113
+ }
3114
+ if (!indexName) {
3115
+ throw new Error("indexName is required");
3116
+ }
3117
+ const tables = await this.lanceClient.tableNames();
3118
+ for (const tableName of tables) {
3119
+ this.logger.debug("Checking table:" + tableName);
3120
+ const table = await this.lanceClient.openTable(tableName);
3121
+ try {
3122
+ const schema = await table.schema();
3123
+ const hasColumn = schema.fields.some((field) => field.name === indexName);
3124
+ if (hasColumn) {
3125
+ this.logger.debug(`Found column ${indexName} in table ${tableName}`);
3126
+ if (ids) {
3127
+ const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
3128
+ await table.delete(idsConditions);
3129
+ } else if (filter) {
3130
+ const translator = new LanceFilterTranslator();
3131
+ const processFilterKeys = (filter2) => {
3132
+ const processedFilter = {};
3133
+ Object.entries(filter2).forEach(([key, value]) => {
3134
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
3135
+ Object.entries(value).forEach(([nestedKey, nestedValue]) => {
3136
+ processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
3137
+ });
3138
+ } else {
3139
+ processedFilter[`metadata_${key}`] = value;
3140
+ }
3141
+ });
3142
+ return processedFilter;
3143
+ };
3144
+ const prefixedFilter = processFilterKeys(filter);
3145
+ const whereClause = translator.translate(prefixedFilter);
3146
+ if (!whereClause) {
3147
+ throw new Error("Failed to translate filter to SQL");
3148
+ }
3149
+ await table.delete(whereClause);
3150
+ }
3151
+ return;
3152
+ }
3153
+ } catch (err) {
3154
+ this.logger.error(`Error checking schema for table ${tableName}:` + err);
3155
+ continue;
3156
+ }
3157
+ }
3158
+ throw new Error(`No table found with column/index '${indexName}'`);
3159
+ } catch (error$1) {
3160
+ if (error$1 instanceof error.MastraError) throw error$1;
3161
+ throw new error.MastraError(
3162
+ {
3163
+ id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
3164
+ domain: error.ErrorDomain.STORAGE,
3165
+ category: error.ErrorCategory.THIRD_PARTY,
3166
+ details: {
3167
+ indexName,
3168
+ ...filter && { filter: JSON.stringify(filter) },
3169
+ ...ids && { idsCount: ids.length }
3170
+ }
3171
+ },
3172
+ error$1
3173
+ );
3174
+ }
3175
+ }
3011
3176
  };
3012
3177
 
3013
3178
  exports.LanceStorage = LanceStorage;