@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 +9 -0
- package/dist/index.cjs +210 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +210 -45
- package/dist/index.js.map +1 -1
- package/dist/vector/filter.d.ts +5 -5
- package/dist/vector/index.d.ts +3 -2
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2843,7 +2843,44 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2843
2843
|
);
|
|
2844
2844
|
}
|
|
2845
2845
|
}
|
|
2846
|
-
async updateVector(
|
|
2846
|
+
async updateVector(params) {
|
|
2847
|
+
const { indexName, update } = params;
|
|
2848
|
+
if ("id" in params && "filter" in params && params.id && params.filter) {
|
|
2849
|
+
throw new MastraError({
|
|
2850
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2851
|
+
domain: ErrorDomain.STORAGE,
|
|
2852
|
+
category: ErrorCategory.USER,
|
|
2853
|
+
text: "id and filter are mutually exclusive",
|
|
2854
|
+
details: { indexName }
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
if (!("id" in params || "filter" in params) || !params.id && !params.filter) {
|
|
2858
|
+
throw new MastraError({
|
|
2859
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2860
|
+
domain: ErrorDomain.STORAGE,
|
|
2861
|
+
category: ErrorCategory.USER,
|
|
2862
|
+
text: "Either id or filter must be provided",
|
|
2863
|
+
details: { indexName }
|
|
2864
|
+
});
|
|
2865
|
+
}
|
|
2866
|
+
if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
|
|
2867
|
+
throw new MastraError({
|
|
2868
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2869
|
+
domain: ErrorDomain.STORAGE,
|
|
2870
|
+
category: ErrorCategory.USER,
|
|
2871
|
+
text: "Cannot update with empty filter",
|
|
2872
|
+
details: { indexName }
|
|
2873
|
+
});
|
|
2874
|
+
}
|
|
2875
|
+
if (!update.vector && !update.metadata) {
|
|
2876
|
+
throw new MastraError({
|
|
2877
|
+
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
2878
|
+
domain: ErrorDomain.STORAGE,
|
|
2879
|
+
category: ErrorCategory.USER,
|
|
2880
|
+
text: "No updates provided",
|
|
2881
|
+
details: { indexName }
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2847
2884
|
try {
|
|
2848
2885
|
if (!this.lanceClient) {
|
|
2849
2886
|
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
@@ -2851,21 +2888,6 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2851
2888
|
if (!indexName) {
|
|
2852
2889
|
throw new Error("indexName is required");
|
|
2853
2890
|
}
|
|
2854
|
-
if (!id) {
|
|
2855
|
-
throw new Error("id is required");
|
|
2856
|
-
}
|
|
2857
|
-
} catch (err) {
|
|
2858
|
-
throw new MastraError(
|
|
2859
|
-
{
|
|
2860
|
-
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED_INVALID_ARGS",
|
|
2861
|
-
domain: ErrorDomain.STORAGE,
|
|
2862
|
-
category: ErrorCategory.USER,
|
|
2863
|
-
details: { indexName, id }
|
|
2864
|
-
},
|
|
2865
|
-
err
|
|
2866
|
-
);
|
|
2867
|
-
}
|
|
2868
|
-
try {
|
|
2869
2891
|
const tables = await this.lanceClient.tableNames();
|
|
2870
2892
|
for (const tableName of tables) {
|
|
2871
2893
|
this.logger.debug("Checking table:" + tableName);
|
|
@@ -2875,39 +2897,66 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2875
2897
|
const hasColumn = schema.fields.some((field) => field.name === indexName);
|
|
2876
2898
|
if (hasColumn) {
|
|
2877
2899
|
this.logger.debug(`Found column ${indexName} in table ${tableName}`);
|
|
2878
|
-
|
|
2879
|
-
if (
|
|
2880
|
-
|
|
2900
|
+
let whereClause;
|
|
2901
|
+
if ("id" in params && params.id) {
|
|
2902
|
+
whereClause = `id = '${params.id}'`;
|
|
2903
|
+
} else if ("filter" in params && params.filter) {
|
|
2904
|
+
const translator = new LanceFilterTranslator();
|
|
2905
|
+
const processFilterKeys = (filter) => {
|
|
2906
|
+
const processedFilter = {};
|
|
2907
|
+
Object.entries(filter).forEach(([key, value]) => {
|
|
2908
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
2909
|
+
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
|
|
2910
|
+
processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
|
|
2911
|
+
});
|
|
2912
|
+
} else {
|
|
2913
|
+
processedFilter[`metadata_${key}`] = value;
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
return processedFilter;
|
|
2917
|
+
};
|
|
2918
|
+
const prefixedFilter = processFilterKeys(params.filter);
|
|
2919
|
+
whereClause = translator.translate(prefixedFilter) || "";
|
|
2920
|
+
if (!whereClause) {
|
|
2921
|
+
throw new Error("Failed to translate filter to SQL");
|
|
2922
|
+
}
|
|
2923
|
+
} else {
|
|
2924
|
+
throw new Error("Either id or filter must be provided");
|
|
2881
2925
|
}
|
|
2882
|
-
const
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2926
|
+
const existingRecords = await table.query().where(whereClause).select(schema.fields.map((field) => field.name)).toArray();
|
|
2927
|
+
if (existingRecords.length === 0) {
|
|
2928
|
+
this.logger.info(`No records found matching criteria in table ${tableName}`);
|
|
2929
|
+
return;
|
|
2930
|
+
}
|
|
2931
|
+
const updatedRecords = existingRecords.map((record) => {
|
|
2932
|
+
const rowData = {};
|
|
2933
|
+
Object.entries(record).forEach(([key, value]) => {
|
|
2934
|
+
if (key !== "_distance") {
|
|
2935
|
+
if (key === indexName) {
|
|
2936
|
+
if (update.vector) {
|
|
2937
|
+
rowData[key] = update.vector;
|
|
2893
2938
|
} else {
|
|
2894
|
-
|
|
2939
|
+
if (Array.isArray(value)) {
|
|
2940
|
+
rowData[key] = [...value];
|
|
2941
|
+
} else if (typeof value === "object" && value !== null) {
|
|
2942
|
+
rowData[key] = Array.from(value);
|
|
2943
|
+
} else {
|
|
2944
|
+
rowData[key] = value;
|
|
2945
|
+
}
|
|
2895
2946
|
}
|
|
2947
|
+
} else {
|
|
2948
|
+
rowData[key] = value;
|
|
2896
2949
|
}
|
|
2897
|
-
} else {
|
|
2898
|
-
rowData[key] = value;
|
|
2899
2950
|
}
|
|
2951
|
+
});
|
|
2952
|
+
if (update.metadata) {
|
|
2953
|
+
Object.entries(update.metadata).forEach(([key, value]) => {
|
|
2954
|
+
rowData[`metadata_${key}`] = value;
|
|
2955
|
+
});
|
|
2900
2956
|
}
|
|
2957
|
+
return rowData;
|
|
2901
2958
|
});
|
|
2902
|
-
|
|
2903
|
-
rowData[indexName] = update.vector;
|
|
2904
|
-
}
|
|
2905
|
-
if (update.metadata) {
|
|
2906
|
-
Object.entries(update.metadata).forEach(([key, value]) => {
|
|
2907
|
-
rowData[`metadata_${key}`] = value;
|
|
2908
|
-
});
|
|
2909
|
-
}
|
|
2910
|
-
await table.add([rowData], { mode: "overwrite" });
|
|
2959
|
+
await table.add(updatedRecords, { mode: "overwrite" });
|
|
2911
2960
|
return;
|
|
2912
2961
|
}
|
|
2913
2962
|
} catch (err) {
|
|
@@ -2917,12 +2966,19 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2917
2966
|
}
|
|
2918
2967
|
throw new Error(`No table found with column/index '${indexName}'`);
|
|
2919
2968
|
} catch (error) {
|
|
2969
|
+
if (error instanceof MastraError) throw error;
|
|
2920
2970
|
throw new MastraError(
|
|
2921
2971
|
{
|
|
2922
2972
|
id: "STORAGE_LANCE_VECTOR_UPDATE_VECTOR_FAILED",
|
|
2923
2973
|
domain: ErrorDomain.STORAGE,
|
|
2924
2974
|
category: ErrorCategory.THIRD_PARTY,
|
|
2925
|
-
details: {
|
|
2975
|
+
details: {
|
|
2976
|
+
indexName,
|
|
2977
|
+
..."id" in params && params.id && { id: params.id },
|
|
2978
|
+
..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) },
|
|
2979
|
+
hasVector: !!update.vector,
|
|
2980
|
+
hasMetadata: !!update.metadata
|
|
2981
|
+
}
|
|
2926
2982
|
},
|
|
2927
2983
|
error
|
|
2928
2984
|
);
|
|
@@ -2945,7 +3001,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2945
3001
|
id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED_INVALID_ARGS",
|
|
2946
3002
|
domain: ErrorDomain.STORAGE,
|
|
2947
3003
|
category: ErrorCategory.USER,
|
|
2948
|
-
details: {
|
|
3004
|
+
details: {
|
|
3005
|
+
indexName,
|
|
3006
|
+
...id && { id }
|
|
3007
|
+
}
|
|
2949
3008
|
},
|
|
2950
3009
|
err
|
|
2951
3010
|
);
|
|
@@ -2975,7 +3034,10 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
2975
3034
|
id: "STORAGE_LANCE_VECTOR_DELETE_VECTOR_FAILED",
|
|
2976
3035
|
domain: ErrorDomain.STORAGE,
|
|
2977
3036
|
category: ErrorCategory.THIRD_PARTY,
|
|
2978
|
-
details: {
|
|
3037
|
+
details: {
|
|
3038
|
+
indexName,
|
|
3039
|
+
...id && { id }
|
|
3040
|
+
}
|
|
2979
3041
|
},
|
|
2980
3042
|
error
|
|
2981
3043
|
);
|
|
@@ -3006,6 +3068,109 @@ var LanceVectorStore = class _LanceVectorStore extends MastraVector {
|
|
|
3006
3068
|
});
|
|
3007
3069
|
return result;
|
|
3008
3070
|
}
|
|
3071
|
+
async deleteVectors({ indexName, filter, ids }) {
|
|
3072
|
+
if (ids && filter) {
|
|
3073
|
+
throw new MastraError({
|
|
3074
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3075
|
+
domain: ErrorDomain.STORAGE,
|
|
3076
|
+
category: ErrorCategory.USER,
|
|
3077
|
+
text: "ids and filter are mutually exclusive",
|
|
3078
|
+
details: { indexName }
|
|
3079
|
+
});
|
|
3080
|
+
}
|
|
3081
|
+
if (!ids && !filter) {
|
|
3082
|
+
throw new MastraError({
|
|
3083
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3084
|
+
domain: ErrorDomain.STORAGE,
|
|
3085
|
+
category: ErrorCategory.USER,
|
|
3086
|
+
text: "Either filter or ids must be provided",
|
|
3087
|
+
details: { indexName }
|
|
3088
|
+
});
|
|
3089
|
+
}
|
|
3090
|
+
if (ids && ids.length === 0) {
|
|
3091
|
+
throw new MastraError({
|
|
3092
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3093
|
+
domain: ErrorDomain.STORAGE,
|
|
3094
|
+
category: ErrorCategory.USER,
|
|
3095
|
+
text: "Cannot delete with empty ids array",
|
|
3096
|
+
details: { indexName }
|
|
3097
|
+
});
|
|
3098
|
+
}
|
|
3099
|
+
if (filter && Object.keys(filter).length === 0) {
|
|
3100
|
+
throw new MastraError({
|
|
3101
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_INVALID_ARGS",
|
|
3102
|
+
domain: ErrorDomain.STORAGE,
|
|
3103
|
+
category: ErrorCategory.USER,
|
|
3104
|
+
text: "Cannot delete with empty filter",
|
|
3105
|
+
details: { indexName }
|
|
3106
|
+
});
|
|
3107
|
+
}
|
|
3108
|
+
try {
|
|
3109
|
+
if (!this.lanceClient) {
|
|
3110
|
+
throw new Error("LanceDB client not initialized. Use LanceVectorStore.create() to create an instance");
|
|
3111
|
+
}
|
|
3112
|
+
if (!indexName) {
|
|
3113
|
+
throw new Error("indexName is required");
|
|
3114
|
+
}
|
|
3115
|
+
const tables = await this.lanceClient.tableNames();
|
|
3116
|
+
for (const tableName of tables) {
|
|
3117
|
+
this.logger.debug("Checking table:" + tableName);
|
|
3118
|
+
const table = await this.lanceClient.openTable(tableName);
|
|
3119
|
+
try {
|
|
3120
|
+
const schema = await table.schema();
|
|
3121
|
+
const hasColumn = schema.fields.some((field) => field.name === indexName);
|
|
3122
|
+
if (hasColumn) {
|
|
3123
|
+
this.logger.debug(`Found column ${indexName} in table ${tableName}`);
|
|
3124
|
+
if (ids) {
|
|
3125
|
+
const idsConditions = ids.map((id) => `id = '${id}'`).join(" OR ");
|
|
3126
|
+
await table.delete(idsConditions);
|
|
3127
|
+
} else if (filter) {
|
|
3128
|
+
const translator = new LanceFilterTranslator();
|
|
3129
|
+
const processFilterKeys = (filter2) => {
|
|
3130
|
+
const processedFilter = {};
|
|
3131
|
+
Object.entries(filter2).forEach(([key, value]) => {
|
|
3132
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
3133
|
+
Object.entries(value).forEach(([nestedKey, nestedValue]) => {
|
|
3134
|
+
processedFilter[`metadata_${key}_${nestedKey}`] = nestedValue;
|
|
3135
|
+
});
|
|
3136
|
+
} else {
|
|
3137
|
+
processedFilter[`metadata_${key}`] = value;
|
|
3138
|
+
}
|
|
3139
|
+
});
|
|
3140
|
+
return processedFilter;
|
|
3141
|
+
};
|
|
3142
|
+
const prefixedFilter = processFilterKeys(filter);
|
|
3143
|
+
const whereClause = translator.translate(prefixedFilter);
|
|
3144
|
+
if (!whereClause) {
|
|
3145
|
+
throw new Error("Failed to translate filter to SQL");
|
|
3146
|
+
}
|
|
3147
|
+
await table.delete(whereClause);
|
|
3148
|
+
}
|
|
3149
|
+
return;
|
|
3150
|
+
}
|
|
3151
|
+
} catch (err) {
|
|
3152
|
+
this.logger.error(`Error checking schema for table ${tableName}:` + err);
|
|
3153
|
+
continue;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
throw new Error(`No table found with column/index '${indexName}'`);
|
|
3157
|
+
} catch (error) {
|
|
3158
|
+
if (error instanceof MastraError) throw error;
|
|
3159
|
+
throw new MastraError(
|
|
3160
|
+
{
|
|
3161
|
+
id: "STORAGE_LANCE_VECTOR_DELETE_VECTORS_FAILED",
|
|
3162
|
+
domain: ErrorDomain.STORAGE,
|
|
3163
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3164
|
+
details: {
|
|
3165
|
+
indexName,
|
|
3166
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
3167
|
+
...ids && { idsCount: ids.length }
|
|
3168
|
+
}
|
|
3169
|
+
},
|
|
3170
|
+
error
|
|
3171
|
+
);
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3009
3174
|
};
|
|
3010
3175
|
|
|
3011
3176
|
export { LanceStorage, LanceVectorStore };
|