@mastra/upstash 0.11.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.
@@ -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({ threadId: 'thread-one', content: 'First', resourceId: 'cross-thread-resource' }),
348
- createSampleMessageV2({ threadId: 'thread-one', content: 'Second', resourceId: 'cross-thread-resource' }),
349
- createSampleMessageV2({ threadId: 'thread-one', content: 'Third', resourceId: 'cross-thread-resource' }),
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({ threadId: 'thread-two', content: 'Fourth', resourceId: 'cross-thread-resource' }),
352
- createSampleMessageV2({ threadId: 'thread-two', content: 'Fifth', resourceId: 'cross-thread-resource' }),
353
- createSampleMessageV2({ threadId: 'thread-two', content: 'Sixth', resourceId: 'cross-thread-resource' }),
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({ threadId: 'thread-three', content: 'Seventh', resourceId: 'other-resource' }),
356
- createSampleMessageV2({ threadId: 'thread-three', content: 'Eighth', resourceId: 'other-resource' }),
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
  });
@@ -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
- await this.client.upsert(points, {
50
- namespace,
51
- });
52
- return generatedIds;
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
- const ns = this.client.namespace(namespace);
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
- // Map the results to our expected format
98
- return (results || []).map(result => ({
99
- id: `${result.id}`,
100
- score: result.score,
101
- metadata: result.metadata,
102
- ...(includeVector && { vector: result.vector || [] }),
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
- const indexes = await this.client.listNamespaces();
112
- return indexes.filter(Boolean);
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
- const info = await this.client.info();
158
+ try {
159
+ const info = await this.client.info();
123
160
 
124
- return {
125
- dimension: info.dimension,
126
- count: info.namespaces?.[namespace]?.vectorCount || 0,
127
- metric: info?.similarityFunction?.toLowerCase() as 'cosine' | 'euclidean' | 'dotproduct',
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
- this.logger.error('Failed to delete namespace:', error);
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: any) {
184
- throw new Error(`Failed to update vector by id: ${id} for index name: ${namespace}: ${error.message}`);
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
- this.logger.error(`Failed to delete vector by id: ${id} for namespace: ${namespace}:`, error);
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
  }