@mastra/upstash 0.11.1-alpha.0 → 0.11.1-alpha.1
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +14 -0
- package/dist/index.cjs +589 -194
- package/dist/index.js +578 -183
- package/package.json +2 -2
- package/src/storage/index.ts +496 -187
- package/src/storage/upstash.test.ts +47 -15
- package/src/vector/index.ts +118 -33
|
@@ -321,9 +321,9 @@ describe('UpstashStore', () => {
|
|
|
321
321
|
|
|
322
322
|
it('should save and retrieve messages in order', async () => {
|
|
323
323
|
const messages: MastraMessageV2[] = [
|
|
324
|
-
createSampleMessageV2({ threadId, content: 'First' }),
|
|
325
|
-
createSampleMessageV2({ threadId, content: 'Second' }),
|
|
326
|
-
createSampleMessageV2({ threadId, content: 'Third' }),
|
|
324
|
+
createSampleMessageV2({ threadId, content: { content: 'First' } }),
|
|
325
|
+
createSampleMessageV2({ threadId, content: { content: 'Second' } }),
|
|
326
|
+
createSampleMessageV2({ threadId, content: { content: 'Third' } }),
|
|
327
327
|
];
|
|
328
328
|
|
|
329
329
|
await store.saveMessages({ messages, format: 'v2' });
|
|
@@ -344,16 +344,48 @@ describe('UpstashStore', () => {
|
|
|
344
344
|
await store.saveThread({ thread: thread3 });
|
|
345
345
|
|
|
346
346
|
const messages: MastraMessageV2[] = [
|
|
347
|
-
createSampleMessageV2({
|
|
348
|
-
|
|
349
|
-
|
|
347
|
+
createSampleMessageV2({
|
|
348
|
+
threadId: 'thread-one',
|
|
349
|
+
content: { content: 'First' },
|
|
350
|
+
resourceId: 'cross-thread-resource',
|
|
351
|
+
}),
|
|
352
|
+
createSampleMessageV2({
|
|
353
|
+
threadId: 'thread-one',
|
|
354
|
+
content: { content: 'Second' },
|
|
355
|
+
resourceId: 'cross-thread-resource',
|
|
356
|
+
}),
|
|
357
|
+
createSampleMessageV2({
|
|
358
|
+
threadId: 'thread-one',
|
|
359
|
+
content: { content: 'Third' },
|
|
360
|
+
resourceId: 'cross-thread-resource',
|
|
361
|
+
}),
|
|
350
362
|
|
|
351
|
-
createSampleMessageV2({
|
|
352
|
-
|
|
353
|
-
|
|
363
|
+
createSampleMessageV2({
|
|
364
|
+
threadId: 'thread-two',
|
|
365
|
+
content: { content: 'Fourth' },
|
|
366
|
+
resourceId: 'cross-thread-resource',
|
|
367
|
+
}),
|
|
368
|
+
createSampleMessageV2({
|
|
369
|
+
threadId: 'thread-two',
|
|
370
|
+
content: { content: 'Fifth' },
|
|
371
|
+
resourceId: 'cross-thread-resource',
|
|
372
|
+
}),
|
|
373
|
+
createSampleMessageV2({
|
|
374
|
+
threadId: 'thread-two',
|
|
375
|
+
content: { content: 'Sixth' },
|
|
376
|
+
resourceId: 'cross-thread-resource',
|
|
377
|
+
}),
|
|
354
378
|
|
|
355
|
-
createSampleMessageV2({
|
|
356
|
-
|
|
379
|
+
createSampleMessageV2({
|
|
380
|
+
threadId: 'thread-three',
|
|
381
|
+
content: { content: 'Seventh' },
|
|
382
|
+
resourceId: 'other-resource',
|
|
383
|
+
}),
|
|
384
|
+
createSampleMessageV2({
|
|
385
|
+
threadId: 'thread-three',
|
|
386
|
+
content: { content: 'Eighth' },
|
|
387
|
+
resourceId: 'other-resource',
|
|
388
|
+
}),
|
|
357
389
|
];
|
|
358
390
|
|
|
359
391
|
await store.saveMessages({ messages: messages, format: 'v2' });
|
|
@@ -472,7 +504,7 @@ describe('UpstashStore', () => {
|
|
|
472
504
|
await store.saveThread({ thread });
|
|
473
505
|
|
|
474
506
|
const messages = Array.from({ length: 15 }, (_, i) =>
|
|
475
|
-
createSampleMessageV2({ threadId: thread.id, content: `Message ${i + 1}` }),
|
|
507
|
+
createSampleMessageV2({ threadId: thread.id, content: { content: `Message ${i + 1}` } }),
|
|
476
508
|
);
|
|
477
509
|
|
|
478
510
|
await store.saveMessages({ messages, format: 'v2' });
|
|
@@ -512,7 +544,7 @@ describe('UpstashStore', () => {
|
|
|
512
544
|
await store.saveThread({ thread });
|
|
513
545
|
|
|
514
546
|
const messages = Array.from({ length: 10 }, (_, i) => {
|
|
515
|
-
const message = createSampleMessageV2({ threadId: thread.id, content: `Message ${i + 1}` });
|
|
547
|
+
const message = createSampleMessageV2({ threadId: thread.id, content: { content: `Message ${i + 1}` } });
|
|
516
548
|
// Ensure different timestamps
|
|
517
549
|
message.createdAt = new Date(Date.now() + i * 1000);
|
|
518
550
|
return message;
|
|
@@ -545,13 +577,13 @@ describe('UpstashStore', () => {
|
|
|
545
577
|
const tomorrow = new Date(now.getTime() + 24 * 60 * 60 * 1000);
|
|
546
578
|
|
|
547
579
|
const oldMessages = Array.from({ length: 3 }, (_, i) => {
|
|
548
|
-
const message = createSampleMessageV2({ threadId: thread.id, content: `Old Message ${i + 1}` });
|
|
580
|
+
const message = createSampleMessageV2({ threadId: thread.id, content: { content: `Old Message ${i + 1}` } });
|
|
549
581
|
message.createdAt = yesterday;
|
|
550
582
|
return message;
|
|
551
583
|
});
|
|
552
584
|
|
|
553
585
|
const newMessages = Array.from({ length: 4 }, (_, i) => {
|
|
554
|
-
const message = createSampleMessageV2({ threadId: thread.id, content: `New Message ${i + 1}` });
|
|
586
|
+
const message = createSampleMessageV2({ threadId: thread.id, content: { content: `New Message ${i + 1}` } });
|
|
555
587
|
message.createdAt = tomorrow;
|
|
556
588
|
return message;
|
|
557
589
|
});
|
package/src/vector/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
|
|
1
2
|
import { MastraVector } from '@mastra/core/vector';
|
|
2
3
|
import type {
|
|
3
4
|
CreateIndexParams,
|
|
@@ -46,10 +47,22 @@ export class UpstashVector extends MastraVector {
|
|
|
46
47
|
metadata: metadata?.[index],
|
|
47
48
|
}));
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
try {
|
|
51
|
+
await this.client.upsert(points, {
|
|
52
|
+
namespace,
|
|
53
|
+
});
|
|
54
|
+
return generatedIds;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw new MastraError(
|
|
57
|
+
{
|
|
58
|
+
id: 'STORAGE_UPSTASH_VECTOR_UPSERT_FAILED',
|
|
59
|
+
domain: ErrorDomain.STORAGE,
|
|
60
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
61
|
+
details: { namespace, vectorCount: vectors.length },
|
|
62
|
+
},
|
|
63
|
+
error,
|
|
64
|
+
);
|
|
65
|
+
}
|
|
53
66
|
}
|
|
54
67
|
|
|
55
68
|
/**
|
|
@@ -83,24 +96,36 @@ export class UpstashVector extends MastraVector {
|
|
|
83
96
|
filter,
|
|
84
97
|
includeVector = false,
|
|
85
98
|
}: QueryVectorParams): Promise<QueryResult[]> {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const filterString = this.transformFilter(filter);
|
|
89
|
-
const results = await ns.query({
|
|
90
|
-
topK,
|
|
91
|
-
vector: queryVector,
|
|
92
|
-
includeVectors: includeVector,
|
|
93
|
-
includeMetadata: true,
|
|
94
|
-
...(filterString ? { filter: filterString } : {}),
|
|
95
|
-
});
|
|
99
|
+
try {
|
|
100
|
+
const ns = this.client.namespace(namespace);
|
|
96
101
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
const filterString = this.transformFilter(filter);
|
|
103
|
+
const results = await ns.query({
|
|
104
|
+
topK,
|
|
105
|
+
vector: queryVector,
|
|
106
|
+
includeVectors: includeVector,
|
|
107
|
+
includeMetadata: true,
|
|
108
|
+
...(filterString ? { filter: filterString } : {}),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Map the results to our expected format
|
|
112
|
+
return (results || []).map(result => ({
|
|
113
|
+
id: `${result.id}`,
|
|
114
|
+
score: result.score,
|
|
115
|
+
metadata: result.metadata,
|
|
116
|
+
...(includeVector && { vector: result.vector || [] }),
|
|
117
|
+
}));
|
|
118
|
+
} catch (error) {
|
|
119
|
+
throw new MastraError(
|
|
120
|
+
{
|
|
121
|
+
id: 'STORAGE_UPSTASH_VECTOR_QUERY_FAILED',
|
|
122
|
+
domain: ErrorDomain.STORAGE,
|
|
123
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
124
|
+
details: { namespace, topK },
|
|
125
|
+
},
|
|
126
|
+
error,
|
|
127
|
+
);
|
|
128
|
+
}
|
|
104
129
|
}
|
|
105
130
|
|
|
106
131
|
/**
|
|
@@ -108,8 +133,19 @@ export class UpstashVector extends MastraVector {
|
|
|
108
133
|
* @returns {Promise<string[]>} A promise that resolves to a list of index names.
|
|
109
134
|
*/
|
|
110
135
|
async listIndexes(): Promise<string[]> {
|
|
111
|
-
|
|
112
|
-
|
|
136
|
+
try {
|
|
137
|
+
const indexes = await this.client.listNamespaces();
|
|
138
|
+
return indexes.filter(Boolean);
|
|
139
|
+
} catch (error) {
|
|
140
|
+
throw new MastraError(
|
|
141
|
+
{
|
|
142
|
+
id: 'STORAGE_UPSTASH_VECTOR_LIST_INDEXES_FAILED',
|
|
143
|
+
domain: ErrorDomain.STORAGE,
|
|
144
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
145
|
+
},
|
|
146
|
+
error,
|
|
147
|
+
);
|
|
148
|
+
}
|
|
113
149
|
}
|
|
114
150
|
|
|
115
151
|
/**
|
|
@@ -119,13 +155,25 @@ export class UpstashVector extends MastraVector {
|
|
|
119
155
|
* @returns A promise that resolves to the index statistics including dimension, count and metric
|
|
120
156
|
*/
|
|
121
157
|
async describeIndex({ indexName: namespace }: DescribeIndexParams): Promise<IndexStats> {
|
|
122
|
-
|
|
158
|
+
try {
|
|
159
|
+
const info = await this.client.info();
|
|
123
160
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
return {
|
|
162
|
+
dimension: info.dimension,
|
|
163
|
+
count: info.namespaces?.[namespace]?.vectorCount || 0,
|
|
164
|
+
metric: info?.similarityFunction?.toLowerCase() as 'cosine' | 'euclidean' | 'dotproduct',
|
|
165
|
+
};
|
|
166
|
+
} catch (error) {
|
|
167
|
+
throw new MastraError(
|
|
168
|
+
{
|
|
169
|
+
id: 'STORAGE_UPSTASH_VECTOR_DESCRIBE_INDEX_FAILED',
|
|
170
|
+
domain: ErrorDomain.STORAGE,
|
|
171
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
172
|
+
details: { namespace },
|
|
173
|
+
},
|
|
174
|
+
error,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
129
177
|
}
|
|
130
178
|
|
|
131
179
|
/**
|
|
@@ -137,7 +185,15 @@ export class UpstashVector extends MastraVector {
|
|
|
137
185
|
try {
|
|
138
186
|
await this.client.deleteNamespace(namespace);
|
|
139
187
|
} catch (error) {
|
|
140
|
-
|
|
188
|
+
throw new MastraError(
|
|
189
|
+
{
|
|
190
|
+
id: 'STORAGE_UPSTASH_VECTOR_DELETE_INDEX_FAILED',
|
|
191
|
+
domain: ErrorDomain.STORAGE,
|
|
192
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
193
|
+
details: { namespace },
|
|
194
|
+
},
|
|
195
|
+
error,
|
|
196
|
+
);
|
|
141
197
|
}
|
|
142
198
|
}
|
|
143
199
|
|
|
@@ -162,7 +218,19 @@ export class UpstashVector extends MastraVector {
|
|
|
162
218
|
if (!update.vector && update.metadata) {
|
|
163
219
|
throw new Error('Both vector and metadata must be provided for an update');
|
|
164
220
|
}
|
|
221
|
+
} catch (error) {
|
|
222
|
+
throw new MastraError(
|
|
223
|
+
{
|
|
224
|
+
id: 'STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
225
|
+
domain: ErrorDomain.STORAGE,
|
|
226
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
227
|
+
details: { namespace, id },
|
|
228
|
+
},
|
|
229
|
+
error,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
165
232
|
|
|
233
|
+
try {
|
|
166
234
|
const updatePayload: any = { id: id };
|
|
167
235
|
if (update.vector) {
|
|
168
236
|
updatePayload.vector = update.vector;
|
|
@@ -180,8 +248,16 @@ export class UpstashVector extends MastraVector {
|
|
|
180
248
|
await this.client.upsert(points, {
|
|
181
249
|
namespace,
|
|
182
250
|
});
|
|
183
|
-
} catch (error
|
|
184
|
-
throw new
|
|
251
|
+
} catch (error) {
|
|
252
|
+
throw new MastraError(
|
|
253
|
+
{
|
|
254
|
+
id: 'STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED',
|
|
255
|
+
domain: ErrorDomain.STORAGE,
|
|
256
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
257
|
+
details: { namespace, id },
|
|
258
|
+
},
|
|
259
|
+
error,
|
|
260
|
+
);
|
|
185
261
|
}
|
|
186
262
|
}
|
|
187
263
|
|
|
@@ -198,7 +274,16 @@ export class UpstashVector extends MastraVector {
|
|
|
198
274
|
namespace,
|
|
199
275
|
});
|
|
200
276
|
} catch (error) {
|
|
201
|
-
|
|
277
|
+
const mastraError = new MastraError(
|
|
278
|
+
{
|
|
279
|
+
id: 'STORAGE_UPSTASH_VECTOR_DELETE_VECTOR_FAILED',
|
|
280
|
+
domain: ErrorDomain.STORAGE,
|
|
281
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
282
|
+
details: { namespace, id },
|
|
283
|
+
},
|
|
284
|
+
error,
|
|
285
|
+
);
|
|
286
|
+
this.logger?.error(mastraError.toString());
|
|
202
287
|
}
|
|
203
288
|
}
|
|
204
289
|
}
|