@mastra/upstash 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 +11 -0
- package/README.md +12 -0
- package/dist/index.cjs +209 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +209 -52
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +18 -9
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/types.d.ts +15 -3
- package/dist/vector/types.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -498,13 +498,11 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
498
498
|
}
|
|
499
499
|
return 0;
|
|
500
500
|
};
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
});
|
|
507
|
-
}
|
|
501
|
+
messagesData.sort((a, b) => {
|
|
502
|
+
const aValue = getFieldValue(a);
|
|
503
|
+
const bValue = getFieldValue(b);
|
|
504
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
505
|
+
});
|
|
508
506
|
const total = messagesData.length;
|
|
509
507
|
const start = offset;
|
|
510
508
|
const end = perPageInput === false ? total : start + perPage;
|
|
@@ -525,23 +523,11 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
525
523
|
}
|
|
526
524
|
const list = new MessageList().add(allMessages, "memory");
|
|
527
525
|
let finalMessages = list.get.all.db();
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
});
|
|
534
|
-
} else {
|
|
535
|
-
const messageIdToPosition = /* @__PURE__ */ new Map();
|
|
536
|
-
allMessageIds.forEach((id, index) => {
|
|
537
|
-
messageIdToPosition.set(id, index);
|
|
538
|
-
});
|
|
539
|
-
finalMessages = finalMessages.sort((a, b) => {
|
|
540
|
-
const aPos = messageIdToPosition.get(a.id) ?? Number.MAX_SAFE_INTEGER;
|
|
541
|
-
const bPos = messageIdToPosition.get(b.id) ?? Number.MAX_SAFE_INTEGER;
|
|
542
|
-
return aPos - bPos;
|
|
543
|
-
});
|
|
544
|
-
}
|
|
526
|
+
finalMessages = finalMessages.sort((a, b) => {
|
|
527
|
+
const aValue = getFieldValue(a);
|
|
528
|
+
const bValue = getFieldValue(b);
|
|
529
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
530
|
+
});
|
|
545
531
|
const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
|
|
546
532
|
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
547
533
|
const hasMore = perPageInput !== false && !allThreadMessagesReturned && end < total;
|
|
@@ -1009,7 +995,9 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1009
995
|
id: "STORAGE_UPSTASH_STORAGE_GET_SCORE_BY_ID_FAILED",
|
|
1010
996
|
domain: ErrorDomain.STORAGE,
|
|
1011
997
|
category: ErrorCategory.THIRD_PARTY,
|
|
1012
|
-
details: {
|
|
998
|
+
details: {
|
|
999
|
+
...id && { id }
|
|
1000
|
+
}
|
|
1013
1001
|
},
|
|
1014
1002
|
error
|
|
1015
1003
|
);
|
|
@@ -1999,6 +1987,11 @@ var UpstashVector = class extends MastraVector {
|
|
|
1999
1987
|
try {
|
|
2000
1988
|
await this.client.deleteNamespace(namespace);
|
|
2001
1989
|
} catch (error) {
|
|
1990
|
+
const errorMessage = error?.message || "";
|
|
1991
|
+
if (errorMessage.includes("does not exist") || errorMessage.includes("not found")) {
|
|
1992
|
+
this.logger.info(`Namespace ${namespace} does not exist, treating as already deleted`);
|
|
1993
|
+
return;
|
|
1994
|
+
}
|
|
2002
1995
|
throw new MastraError(
|
|
2003
1996
|
{
|
|
2004
1997
|
id: "STORAGE_UPSTASH_VECTOR_DELETE_INDEX_FAILED",
|
|
@@ -2011,47 +2004,124 @@ var UpstashVector = class extends MastraVector {
|
|
|
2011
2004
|
}
|
|
2012
2005
|
}
|
|
2013
2006
|
/**
|
|
2014
|
-
* Updates a vector by its ID
|
|
2015
|
-
* @param
|
|
2016
|
-
* @param
|
|
2017
|
-
* @param
|
|
2018
|
-
* @param
|
|
2019
|
-
* @param update
|
|
2007
|
+
* Updates a vector by its ID or multiple vectors matching a filter.
|
|
2008
|
+
* @param params - Parameters containing the id or filter for targeting the vector(s) to update
|
|
2009
|
+
* @param params.indexName - The name of the namespace containing the vector.
|
|
2010
|
+
* @param params.id - The ID of the vector to update (mutually exclusive with filter).
|
|
2011
|
+
* @param params.filter - Filter to match multiple vectors to update (mutually exclusive with id).
|
|
2012
|
+
* @param params.update - An object containing the vector and/or metadata to update.
|
|
2020
2013
|
* @returns A promise that resolves when the update is complete.
|
|
2021
2014
|
* @throws Will throw an error if no updates are provided or if the update operation fails.
|
|
2022
2015
|
*/
|
|
2023
|
-
async updateVector(
|
|
2024
|
-
|
|
2016
|
+
async updateVector(params) {
|
|
2017
|
+
const { indexName: namespace, update } = params;
|
|
2018
|
+
const upstashUpdate = update;
|
|
2019
|
+
const sparseVector = upstashUpdate.sparseVector;
|
|
2020
|
+
if ("id" in params && params.id && "filter" in params && params.filter) {
|
|
2025
2021
|
throw new MastraError({
|
|
2026
|
-
id: "
|
|
2022
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE",
|
|
2023
|
+
text: "Cannot specify both id and filter - they are mutually exclusive",
|
|
2027
2024
|
domain: ErrorDomain.STORAGE,
|
|
2028
|
-
category: ErrorCategory.
|
|
2029
|
-
details: { namespace
|
|
2030
|
-
text: "No update data provided"
|
|
2025
|
+
category: ErrorCategory.USER,
|
|
2026
|
+
details: { namespace }
|
|
2031
2027
|
});
|
|
2032
2028
|
}
|
|
2033
|
-
if (!
|
|
2029
|
+
if (!("id" in params && params.id) && !("filter" in params && params.filter)) {
|
|
2034
2030
|
throw new MastraError({
|
|
2035
|
-
id: "
|
|
2031
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_NO_TARGET",
|
|
2032
|
+
text: "Either id or filter must be provided",
|
|
2036
2033
|
domain: ErrorDomain.STORAGE,
|
|
2037
|
-
category: ErrorCategory.
|
|
2038
|
-
details: { namespace
|
|
2039
|
-
|
|
2034
|
+
category: ErrorCategory.USER,
|
|
2035
|
+
details: { namespace }
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
if (!update.vector && !update.metadata && !sparseVector) {
|
|
2039
|
+
throw new MastraError({
|
|
2040
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_NO_PAYLOAD",
|
|
2041
|
+
text: "No update data provided",
|
|
2042
|
+
domain: ErrorDomain.STORAGE,
|
|
2043
|
+
category: ErrorCategory.USER,
|
|
2044
|
+
details: { namespace }
|
|
2045
|
+
});
|
|
2046
|
+
}
|
|
2047
|
+
if ("filter" in params && params.filter && Object.keys(params.filter).length === 0) {
|
|
2048
|
+
throw new MastraError({
|
|
2049
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_EMPTY_FILTER",
|
|
2050
|
+
text: "Filter cannot be an empty filter object",
|
|
2051
|
+
domain: ErrorDomain.STORAGE,
|
|
2052
|
+
category: ErrorCategory.USER,
|
|
2053
|
+
details: { namespace }
|
|
2040
2054
|
});
|
|
2041
2055
|
}
|
|
2042
2056
|
try {
|
|
2043
|
-
const
|
|
2044
|
-
if (
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2057
|
+
const ns = this.client.namespace(namespace);
|
|
2058
|
+
if ("id" in params && params.id) {
|
|
2059
|
+
const points = { id: params.id };
|
|
2060
|
+
if (!update.vector || !update.metadata) {
|
|
2061
|
+
try {
|
|
2062
|
+
const existing = await ns.fetch([params.id], {
|
|
2063
|
+
includeVectors: true,
|
|
2064
|
+
includeMetadata: true
|
|
2065
|
+
});
|
|
2066
|
+
if (existing && existing.length > 0 && existing[0]) {
|
|
2067
|
+
if (!update.vector && existing[0]?.vector) {
|
|
2068
|
+
points.vector = existing[0].vector;
|
|
2069
|
+
}
|
|
2070
|
+
if (!update.metadata && existing[0]?.metadata) {
|
|
2071
|
+
points.metadata = existing[0].metadata;
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
} catch (fetchError) {
|
|
2075
|
+
this.logger.warn(`Failed to fetch existing vector ${params.id} for partial update: ${fetchError}`);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
if (update.vector) points.vector = update.vector;
|
|
2079
|
+
if (update.metadata) points.metadata = update.metadata;
|
|
2080
|
+
if (sparseVector) points.sparseVector = sparseVector;
|
|
2081
|
+
await ns.upsert(points);
|
|
2082
|
+
} else if ("filter" in params && params.filter) {
|
|
2083
|
+
const filterString = this.transformFilter(params.filter);
|
|
2084
|
+
if (filterString) {
|
|
2085
|
+
const stats = await this.describeIndex({ indexName: namespace });
|
|
2086
|
+
const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));
|
|
2087
|
+
const needsVectors = !update.vector;
|
|
2088
|
+
const results = await ns.query({
|
|
2089
|
+
vector: dummyVector,
|
|
2090
|
+
topK: 1e3,
|
|
2091
|
+
// Upstash's max query limit
|
|
2092
|
+
filter: filterString,
|
|
2093
|
+
includeVectors: needsVectors,
|
|
2094
|
+
includeMetadata: needsVectors
|
|
2095
|
+
});
|
|
2096
|
+
for (const result of results) {
|
|
2097
|
+
const points = { id: `${result.id}` };
|
|
2098
|
+
if (update.vector) {
|
|
2099
|
+
points.vector = update.vector;
|
|
2100
|
+
} else if (result.vector) {
|
|
2101
|
+
points.vector = result.vector;
|
|
2102
|
+
}
|
|
2103
|
+
if (update.metadata) {
|
|
2104
|
+
points.metadata = update.metadata;
|
|
2105
|
+
} else if (result.metadata) {
|
|
2106
|
+
points.metadata = result.metadata;
|
|
2107
|
+
}
|
|
2108
|
+
if (sparseVector) points.sparseVector = sparseVector;
|
|
2109
|
+
await ns.upsert(points);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2048
2113
|
} catch (error) {
|
|
2114
|
+
if (error instanceof MastraError) throw error;
|
|
2049
2115
|
throw new MastraError(
|
|
2050
2116
|
{
|
|
2051
2117
|
id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
2052
2118
|
domain: ErrorDomain.STORAGE,
|
|
2053
2119
|
category: ErrorCategory.THIRD_PARTY,
|
|
2054
|
-
details: {
|
|
2120
|
+
details: {
|
|
2121
|
+
namespace,
|
|
2122
|
+
..."id" in params && params.id && { id: params.id },
|
|
2123
|
+
..."filter" in params && params.filter && { filter: JSON.stringify(params.filter) }
|
|
2124
|
+
}
|
|
2055
2125
|
},
|
|
2056
2126
|
error
|
|
2057
2127
|
);
|
|
@@ -2066,22 +2136,109 @@ var UpstashVector = class extends MastraVector {
|
|
|
2066
2136
|
*/
|
|
2067
2137
|
async deleteVector({ indexName: namespace, id }) {
|
|
2068
2138
|
try {
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
});
|
|
2139
|
+
const ns = this.client.namespace(namespace);
|
|
2140
|
+
await ns.delete(id);
|
|
2072
2141
|
} catch (error) {
|
|
2073
2142
|
const mastraError = new MastraError(
|
|
2074
2143
|
{
|
|
2075
2144
|
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTOR_FAILED",
|
|
2076
2145
|
domain: ErrorDomain.STORAGE,
|
|
2077
2146
|
category: ErrorCategory.THIRD_PARTY,
|
|
2078
|
-
details: {
|
|
2147
|
+
details: {
|
|
2148
|
+
namespace,
|
|
2149
|
+
...id && { id }
|
|
2150
|
+
}
|
|
2079
2151
|
},
|
|
2080
2152
|
error
|
|
2081
2153
|
);
|
|
2082
2154
|
this.logger?.error(mastraError.toString());
|
|
2083
2155
|
}
|
|
2084
2156
|
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Deletes multiple vectors by IDs or filter.
|
|
2159
|
+
* @param indexName - The name of the namespace containing the vectors.
|
|
2160
|
+
* @param ids - Array of vector IDs to delete (mutually exclusive with filter).
|
|
2161
|
+
* @param filter - Filter to match vectors to delete (mutually exclusive with ids).
|
|
2162
|
+
* @returns A promise that resolves when the deletion is complete.
|
|
2163
|
+
* @throws Will throw an error if both ids and filter are provided, or if neither is provided.
|
|
2164
|
+
*/
|
|
2165
|
+
async deleteVectors({ indexName: namespace, filter, ids }) {
|
|
2166
|
+
if (ids && filter) {
|
|
2167
|
+
throw new MastraError({
|
|
2168
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_MUTUALLY_EXCLUSIVE",
|
|
2169
|
+
text: "Cannot specify both ids and filter - they are mutually exclusive",
|
|
2170
|
+
domain: ErrorDomain.STORAGE,
|
|
2171
|
+
category: ErrorCategory.USER,
|
|
2172
|
+
details: { namespace }
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
if (!ids && !filter) {
|
|
2176
|
+
throw new MastraError({
|
|
2177
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_NO_TARGET",
|
|
2178
|
+
text: "Either filter or ids must be provided",
|
|
2179
|
+
domain: ErrorDomain.STORAGE,
|
|
2180
|
+
category: ErrorCategory.USER,
|
|
2181
|
+
details: { namespace }
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
if (ids && ids.length === 0) {
|
|
2185
|
+
throw new MastraError({
|
|
2186
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_EMPTY_IDS",
|
|
2187
|
+
text: "Cannot delete with empty ids array",
|
|
2188
|
+
domain: ErrorDomain.STORAGE,
|
|
2189
|
+
category: ErrorCategory.USER,
|
|
2190
|
+
details: { namespace }
|
|
2191
|
+
});
|
|
2192
|
+
}
|
|
2193
|
+
if (filter && Object.keys(filter).length === 0) {
|
|
2194
|
+
throw new MastraError({
|
|
2195
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_EMPTY_FILTER",
|
|
2196
|
+
text: "Cannot delete with empty filter object",
|
|
2197
|
+
domain: ErrorDomain.STORAGE,
|
|
2198
|
+
category: ErrorCategory.USER,
|
|
2199
|
+
details: { namespace }
|
|
2200
|
+
});
|
|
2201
|
+
}
|
|
2202
|
+
try {
|
|
2203
|
+
const ns = this.client.namespace(namespace);
|
|
2204
|
+
if (ids) {
|
|
2205
|
+
await ns.delete(ids);
|
|
2206
|
+
} else if (filter) {
|
|
2207
|
+
const filterString = this.transformFilter(filter);
|
|
2208
|
+
if (filterString) {
|
|
2209
|
+
const stats = await this.describeIndex({ indexName: namespace });
|
|
2210
|
+
const dummyVector = new Array(stats.dimension).fill(1 / Math.sqrt(stats.dimension));
|
|
2211
|
+
const results = await ns.query({
|
|
2212
|
+
vector: dummyVector,
|
|
2213
|
+
topK: 1e3,
|
|
2214
|
+
// Upstash's max query limit
|
|
2215
|
+
filter: filterString,
|
|
2216
|
+
includeVectors: false,
|
|
2217
|
+
includeMetadata: false
|
|
2218
|
+
});
|
|
2219
|
+
const idsToDelete = results.map((r) => `${r.id}`);
|
|
2220
|
+
if (idsToDelete.length > 0) {
|
|
2221
|
+
await ns.delete(idsToDelete);
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
if (error instanceof MastraError) throw error;
|
|
2227
|
+
throw new MastraError(
|
|
2228
|
+
{
|
|
2229
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTORS_FAILED",
|
|
2230
|
+
domain: ErrorDomain.STORAGE,
|
|
2231
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
2232
|
+
details: {
|
|
2233
|
+
namespace,
|
|
2234
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
2235
|
+
...ids && { idsCount: ids.length }
|
|
2236
|
+
}
|
|
2237
|
+
},
|
|
2238
|
+
error
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2085
2242
|
};
|
|
2086
2243
|
|
|
2087
2244
|
// src/vector/prompt.ts
|