@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.
- package/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +24 -0
- package/dist/_tsup-dts-rollup.d.cts +11 -1
- package/dist/_tsup-dts-rollup.d.ts +11 -1
- package/dist/index.cjs +593 -194
- package/dist/index.js +582 -183
- package/package.json +3 -3
- package/src/storage/index.ts +509 -188
- package/src/storage/upstash.test.ts +47 -15
- package/src/vector/index.ts +118 -33
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MessageList } from '@mastra/core/agent';
|
|
2
|
+
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
3
|
import { MastraStorage, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES, TABLE_THREADS } from '@mastra/core/storage';
|
|
3
4
|
import { Redis } from '@upstash/redis';
|
|
4
5
|
import { MastraVector } from '@mastra/core/vector';
|
|
@@ -197,7 +198,17 @@ var UpstashStore = class extends MastraStorage {
|
|
|
197
198
|
}
|
|
198
199
|
return filteredEvals.map((record) => this.transformEvalRecord(record));
|
|
199
200
|
} catch (error) {
|
|
200
|
-
|
|
201
|
+
const mastraError = new MastraError(
|
|
202
|
+
{
|
|
203
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_EVALS_BY_AGENT_NAME_FAILED",
|
|
204
|
+
domain: ErrorDomain.STORAGE,
|
|
205
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
206
|
+
details: { agentName }
|
|
207
|
+
},
|
|
208
|
+
error
|
|
209
|
+
);
|
|
210
|
+
this.logger?.trackException(mastraError);
|
|
211
|
+
this.logger.error(mastraError.toString());
|
|
201
212
|
return [];
|
|
202
213
|
}
|
|
203
214
|
}
|
|
@@ -211,8 +222,19 @@ var UpstashStore = class extends MastraStorage {
|
|
|
211
222
|
end: args.toDate
|
|
212
223
|
};
|
|
213
224
|
}
|
|
214
|
-
|
|
215
|
-
|
|
225
|
+
try {
|
|
226
|
+
const { traces } = await this.getTracesPaginated(args);
|
|
227
|
+
return traces;
|
|
228
|
+
} catch (error) {
|
|
229
|
+
throw new MastraError(
|
|
230
|
+
{
|
|
231
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_TRACES_FAILED",
|
|
232
|
+
domain: ErrorDomain.STORAGE,
|
|
233
|
+
category: ErrorCategory.THIRD_PARTY
|
|
234
|
+
},
|
|
235
|
+
error
|
|
236
|
+
);
|
|
237
|
+
}
|
|
216
238
|
}
|
|
217
239
|
async getTracesPaginated(args) {
|
|
218
240
|
const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
|
|
@@ -296,7 +318,20 @@ var UpstashStore = class extends MastraStorage {
|
|
|
296
318
|
hasMore
|
|
297
319
|
};
|
|
298
320
|
} catch (error) {
|
|
299
|
-
|
|
321
|
+
const mastraError = new MastraError(
|
|
322
|
+
{
|
|
323
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_TRACES_PAGINATED_FAILED",
|
|
324
|
+
domain: ErrorDomain.STORAGE,
|
|
325
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
326
|
+
details: {
|
|
327
|
+
name: args.name || "",
|
|
328
|
+
scope: args.scope || ""
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
error
|
|
332
|
+
);
|
|
333
|
+
this.logger?.trackException(mastraError);
|
|
334
|
+
this.logger.error(mastraError.toString());
|
|
300
335
|
return {
|
|
301
336
|
traces: [],
|
|
302
337
|
total: 0,
|
|
@@ -310,7 +345,21 @@ var UpstashStore = class extends MastraStorage {
|
|
|
310
345
|
tableName,
|
|
311
346
|
schema
|
|
312
347
|
}) {
|
|
313
|
-
|
|
348
|
+
try {
|
|
349
|
+
await this.redis.set(`schema:${tableName}`, schema);
|
|
350
|
+
} catch (error) {
|
|
351
|
+
throw new MastraError(
|
|
352
|
+
{
|
|
353
|
+
id: "STORAGE_UPSTASH_STORAGE_CREATE_TABLE_FAILED",
|
|
354
|
+
domain: ErrorDomain.STORAGE,
|
|
355
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
356
|
+
details: {
|
|
357
|
+
tableName
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
error
|
|
361
|
+
);
|
|
362
|
+
}
|
|
314
363
|
}
|
|
315
364
|
/**
|
|
316
365
|
* No-op: This backend is schemaless and does not require schema changes.
|
|
@@ -322,43 +371,113 @@ var UpstashStore = class extends MastraStorage {
|
|
|
322
371
|
}
|
|
323
372
|
async clearTable({ tableName }) {
|
|
324
373
|
const pattern = `${tableName}:*`;
|
|
325
|
-
|
|
374
|
+
try {
|
|
375
|
+
await this.scanAndDelete(pattern);
|
|
376
|
+
} catch (error) {
|
|
377
|
+
throw new MastraError(
|
|
378
|
+
{
|
|
379
|
+
id: "STORAGE_UPSTASH_STORAGE_CLEAR_TABLE_FAILED",
|
|
380
|
+
domain: ErrorDomain.STORAGE,
|
|
381
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
382
|
+
details: {
|
|
383
|
+
tableName
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
error
|
|
387
|
+
);
|
|
388
|
+
}
|
|
326
389
|
}
|
|
327
390
|
async insert({ tableName, record }) {
|
|
328
391
|
const { key, processedRecord } = this.processRecord(tableName, record);
|
|
329
|
-
|
|
392
|
+
try {
|
|
393
|
+
await this.redis.set(key, processedRecord);
|
|
394
|
+
} catch (error) {
|
|
395
|
+
throw new MastraError(
|
|
396
|
+
{
|
|
397
|
+
id: "STORAGE_UPSTASH_STORAGE_INSERT_FAILED",
|
|
398
|
+
domain: ErrorDomain.STORAGE,
|
|
399
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
400
|
+
details: {
|
|
401
|
+
tableName
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
error
|
|
405
|
+
);
|
|
406
|
+
}
|
|
330
407
|
}
|
|
331
408
|
async batchInsert(input) {
|
|
332
409
|
const { tableName, records } = input;
|
|
333
410
|
if (!records.length) return;
|
|
334
411
|
const batchSize = 1e3;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
const
|
|
340
|
-
|
|
412
|
+
try {
|
|
413
|
+
for (let i = 0; i < records.length; i += batchSize) {
|
|
414
|
+
const batch = records.slice(i, i + batchSize);
|
|
415
|
+
const pipeline = this.redis.pipeline();
|
|
416
|
+
for (const record of batch) {
|
|
417
|
+
const { key, processedRecord } = this.processRecord(tableName, record);
|
|
418
|
+
pipeline.set(key, processedRecord);
|
|
419
|
+
}
|
|
420
|
+
await pipeline.exec();
|
|
341
421
|
}
|
|
342
|
-
|
|
422
|
+
} catch (error) {
|
|
423
|
+
throw new MastraError(
|
|
424
|
+
{
|
|
425
|
+
id: "STORAGE_UPSTASH_STORAGE_BATCH_INSERT_FAILED",
|
|
426
|
+
domain: ErrorDomain.STORAGE,
|
|
427
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
428
|
+
details: {
|
|
429
|
+
tableName
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
error
|
|
433
|
+
);
|
|
343
434
|
}
|
|
344
435
|
}
|
|
345
436
|
async load({ tableName, keys }) {
|
|
346
437
|
const key = this.getKey(tableName, keys);
|
|
347
|
-
|
|
348
|
-
|
|
438
|
+
try {
|
|
439
|
+
const data = await this.redis.get(key);
|
|
440
|
+
return data || null;
|
|
441
|
+
} catch (error) {
|
|
442
|
+
throw new MastraError(
|
|
443
|
+
{
|
|
444
|
+
id: "STORAGE_UPSTASH_STORAGE_LOAD_FAILED",
|
|
445
|
+
domain: ErrorDomain.STORAGE,
|
|
446
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
447
|
+
details: {
|
|
448
|
+
tableName
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
error
|
|
452
|
+
);
|
|
453
|
+
}
|
|
349
454
|
}
|
|
350
455
|
async getThreadById({ threadId }) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
456
|
+
try {
|
|
457
|
+
const thread = await this.load({
|
|
458
|
+
tableName: TABLE_THREADS,
|
|
459
|
+
keys: { id: threadId }
|
|
460
|
+
});
|
|
461
|
+
if (!thread) return null;
|
|
462
|
+
return {
|
|
463
|
+
...thread,
|
|
464
|
+
createdAt: this.ensureDate(thread.createdAt),
|
|
465
|
+
updatedAt: this.ensureDate(thread.updatedAt),
|
|
466
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata
|
|
467
|
+
};
|
|
468
|
+
} catch (error) {
|
|
469
|
+
throw new MastraError(
|
|
470
|
+
{
|
|
471
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_THREAD_BY_ID_FAILED",
|
|
472
|
+
domain: ErrorDomain.STORAGE,
|
|
473
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
474
|
+
details: {
|
|
475
|
+
threadId
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
error
|
|
479
|
+
);
|
|
480
|
+
}
|
|
362
481
|
}
|
|
363
482
|
/**
|
|
364
483
|
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
@@ -388,7 +507,19 @@ var UpstashStore = class extends MastraStorage {
|
|
|
388
507
|
allThreads.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
389
508
|
return allThreads;
|
|
390
509
|
} catch (error) {
|
|
391
|
-
|
|
510
|
+
const mastraError = new MastraError(
|
|
511
|
+
{
|
|
512
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_THREADS_BY_RESOURCE_ID_FAILED",
|
|
513
|
+
domain: ErrorDomain.STORAGE,
|
|
514
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
515
|
+
details: {
|
|
516
|
+
resourceId
|
|
517
|
+
}
|
|
518
|
+
},
|
|
519
|
+
error
|
|
520
|
+
);
|
|
521
|
+
this.logger?.trackException(mastraError);
|
|
522
|
+
this.logger.error(mastraError.toString());
|
|
392
523
|
return [];
|
|
393
524
|
}
|
|
394
525
|
}
|
|
@@ -409,7 +540,21 @@ var UpstashStore = class extends MastraStorage {
|
|
|
409
540
|
hasMore
|
|
410
541
|
};
|
|
411
542
|
} catch (error) {
|
|
412
|
-
|
|
543
|
+
const mastraError = new MastraError(
|
|
544
|
+
{
|
|
545
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
|
|
546
|
+
domain: ErrorDomain.STORAGE,
|
|
547
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
548
|
+
details: {
|
|
549
|
+
resourceId,
|
|
550
|
+
page,
|
|
551
|
+
perPage
|
|
552
|
+
}
|
|
553
|
+
},
|
|
554
|
+
error
|
|
555
|
+
);
|
|
556
|
+
this.logger?.trackException(mastraError);
|
|
557
|
+
this.logger.error(mastraError.toString());
|
|
413
558
|
return {
|
|
414
559
|
threads: [],
|
|
415
560
|
total: 0,
|
|
@@ -420,11 +565,28 @@ var UpstashStore = class extends MastraStorage {
|
|
|
420
565
|
}
|
|
421
566
|
}
|
|
422
567
|
async saveThread({ thread }) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
568
|
+
try {
|
|
569
|
+
await this.insert({
|
|
570
|
+
tableName: TABLE_THREADS,
|
|
571
|
+
record: thread
|
|
572
|
+
});
|
|
573
|
+
return thread;
|
|
574
|
+
} catch (error) {
|
|
575
|
+
const mastraError = new MastraError(
|
|
576
|
+
{
|
|
577
|
+
id: "STORAGE_UPSTASH_STORAGE_SAVE_THREAD_FAILED",
|
|
578
|
+
domain: ErrorDomain.STORAGE,
|
|
579
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
580
|
+
details: {
|
|
581
|
+
threadId: thread.id
|
|
582
|
+
}
|
|
583
|
+
},
|
|
584
|
+
error
|
|
585
|
+
);
|
|
586
|
+
this.logger?.trackException(mastraError);
|
|
587
|
+
this.logger.error(mastraError.toString());
|
|
588
|
+
throw mastraError;
|
|
589
|
+
}
|
|
428
590
|
}
|
|
429
591
|
async updateThread({
|
|
430
592
|
id,
|
|
@@ -433,7 +595,15 @@ var UpstashStore = class extends MastraStorage {
|
|
|
433
595
|
}) {
|
|
434
596
|
const thread = await this.getThreadById({ threadId: id });
|
|
435
597
|
if (!thread) {
|
|
436
|
-
throw new
|
|
598
|
+
throw new MastraError({
|
|
599
|
+
id: "STORAGE_UPSTASH_STORAGE_UPDATE_THREAD_FAILED",
|
|
600
|
+
domain: ErrorDomain.STORAGE,
|
|
601
|
+
category: ErrorCategory.USER,
|
|
602
|
+
text: `Thread ${id} not found`,
|
|
603
|
+
details: {
|
|
604
|
+
threadId: id
|
|
605
|
+
}
|
|
606
|
+
});
|
|
437
607
|
}
|
|
438
608
|
const updatedThread = {
|
|
439
609
|
...thread,
|
|
@@ -443,34 +613,73 @@ var UpstashStore = class extends MastraStorage {
|
|
|
443
613
|
...metadata
|
|
444
614
|
}
|
|
445
615
|
};
|
|
446
|
-
|
|
447
|
-
|
|
616
|
+
try {
|
|
617
|
+
await this.saveThread({ thread: updatedThread });
|
|
618
|
+
return updatedThread;
|
|
619
|
+
} catch (error) {
|
|
620
|
+
throw new MastraError(
|
|
621
|
+
{
|
|
622
|
+
id: "STORAGE_UPSTASH_STORAGE_UPDATE_THREAD_FAILED",
|
|
623
|
+
domain: ErrorDomain.STORAGE,
|
|
624
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
625
|
+
details: {
|
|
626
|
+
threadId: id
|
|
627
|
+
}
|
|
628
|
+
},
|
|
629
|
+
error
|
|
630
|
+
);
|
|
631
|
+
}
|
|
448
632
|
}
|
|
449
633
|
async deleteThread({ threadId }) {
|
|
450
634
|
const threadKey = this.getKey(TABLE_THREADS, { id: threadId });
|
|
451
635
|
const threadMessagesKey = this.getThreadMessagesKey(threadId);
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
636
|
+
try {
|
|
637
|
+
const messageIds = await this.redis.zrange(threadMessagesKey, 0, -1);
|
|
638
|
+
const pipeline = this.redis.pipeline();
|
|
639
|
+
pipeline.del(threadKey);
|
|
640
|
+
pipeline.del(threadMessagesKey);
|
|
641
|
+
for (let i = 0; i < messageIds.length; i++) {
|
|
642
|
+
const messageId = messageIds[i];
|
|
643
|
+
const messageKey = this.getMessageKey(threadId, messageId);
|
|
644
|
+
pipeline.del(messageKey);
|
|
645
|
+
}
|
|
646
|
+
await pipeline.exec();
|
|
647
|
+
await this.scanAndDelete(this.getMessageKey(threadId, "*"));
|
|
648
|
+
} catch (error) {
|
|
649
|
+
throw new MastraError(
|
|
650
|
+
{
|
|
651
|
+
id: "STORAGE_UPSTASH_STORAGE_DELETE_THREAD_FAILED",
|
|
652
|
+
domain: ErrorDomain.STORAGE,
|
|
653
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
654
|
+
details: {
|
|
655
|
+
threadId
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
error
|
|
659
|
+
);
|
|
460
660
|
}
|
|
461
|
-
await pipeline.exec();
|
|
462
|
-
await this.scanAndDelete(this.getMessageKey(threadId, "*"));
|
|
463
661
|
}
|
|
464
662
|
async saveMessages(args) {
|
|
465
663
|
const { messages, format = "v1" } = args;
|
|
466
664
|
if (messages.length === 0) return [];
|
|
467
665
|
const threadId = messages[0]?.threadId;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
666
|
+
try {
|
|
667
|
+
if (!threadId) {
|
|
668
|
+
throw new Error("Thread ID is required");
|
|
669
|
+
}
|
|
670
|
+
const thread = await this.getThreadById({ threadId });
|
|
671
|
+
if (!thread) {
|
|
672
|
+
throw new Error(`Thread ${threadId} not found`);
|
|
673
|
+
}
|
|
674
|
+
} catch (error) {
|
|
675
|
+
throw new MastraError(
|
|
676
|
+
{
|
|
677
|
+
id: "STORAGE_UPSTASH_STORAGE_SAVE_MESSAGES_INVALID_ARGS",
|
|
678
|
+
domain: ErrorDomain.STORAGE,
|
|
679
|
+
category: ErrorCategory.USER
|
|
680
|
+
},
|
|
681
|
+
error
|
|
682
|
+
);
|
|
474
683
|
}
|
|
475
684
|
const messagesWithIndex = messages.map((message, index) => ({
|
|
476
685
|
...message,
|
|
@@ -478,32 +687,46 @@ var UpstashStore = class extends MastraStorage {
|
|
|
478
687
|
}));
|
|
479
688
|
const threadKey = this.getKey(TABLE_THREADS, { id: threadId });
|
|
480
689
|
const existingThread = await this.redis.get(threadKey);
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
690
|
+
try {
|
|
691
|
+
const batchSize = 1e3;
|
|
692
|
+
for (let i = 0; i < messagesWithIndex.length; i += batchSize) {
|
|
693
|
+
const batch = messagesWithIndex.slice(i, i + batchSize);
|
|
694
|
+
const pipeline = this.redis.pipeline();
|
|
695
|
+
for (const message of batch) {
|
|
696
|
+
const key = this.getMessageKey(message.threadId, message.id);
|
|
697
|
+
const createdAtScore = new Date(message.createdAt).getTime();
|
|
698
|
+
const score = message._index !== void 0 ? message._index : createdAtScore;
|
|
699
|
+
pipeline.set(key, message);
|
|
700
|
+
pipeline.zadd(this.getThreadMessagesKey(message.threadId), {
|
|
701
|
+
score,
|
|
702
|
+
member: message.id
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
if (i === 0 && existingThread) {
|
|
706
|
+
const updatedThread = {
|
|
707
|
+
...existingThread,
|
|
708
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
709
|
+
};
|
|
710
|
+
pipeline.set(threadKey, this.processRecord(TABLE_THREADS, updatedThread).processedRecord);
|
|
711
|
+
}
|
|
712
|
+
await pipeline.exec();
|
|
501
713
|
}
|
|
502
|
-
|
|
714
|
+
const list = new MessageList().add(messages, "memory");
|
|
715
|
+
if (format === `v2`) return list.get.all.v2();
|
|
716
|
+
return list.get.all.v1();
|
|
717
|
+
} catch (error) {
|
|
718
|
+
throw new MastraError(
|
|
719
|
+
{
|
|
720
|
+
id: "STORAGE_UPSTASH_STORAGE_SAVE_MESSAGES_FAILED",
|
|
721
|
+
domain: ErrorDomain.STORAGE,
|
|
722
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
723
|
+
details: {
|
|
724
|
+
threadId
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
error
|
|
728
|
+
);
|
|
503
729
|
}
|
|
504
|
-
const list = new MessageList().add(messages, "memory");
|
|
505
|
-
if (format === `v2`) return list.get.all.v2();
|
|
506
|
-
return list.get.all.v1();
|
|
507
730
|
}
|
|
508
731
|
async _getIncludedMessages(threadId, selectBy) {
|
|
509
732
|
const messageIds = /* @__PURE__ */ new Set();
|
|
@@ -548,63 +771,72 @@ var UpstashStore = class extends MastraStorage {
|
|
|
548
771
|
format
|
|
549
772
|
}) {
|
|
550
773
|
const threadMessagesKey = this.getThreadMessagesKey(threadId);
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
limit
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
774
|
+
try {
|
|
775
|
+
const allMessageIds = await this.redis.zrange(threadMessagesKey, 0, -1);
|
|
776
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: Number.MAX_SAFE_INTEGER });
|
|
777
|
+
const messageIds = /* @__PURE__ */ new Set();
|
|
778
|
+
const messageIdToThreadIds = {};
|
|
779
|
+
if (limit === 0 && !selectBy?.include) {
|
|
780
|
+
return [];
|
|
781
|
+
}
|
|
782
|
+
if (limit === Number.MAX_SAFE_INTEGER) {
|
|
783
|
+
const allIds = await this.redis.zrange(threadMessagesKey, 0, -1);
|
|
784
|
+
allIds.forEach((id) => {
|
|
785
|
+
messageIds.add(id);
|
|
786
|
+
messageIdToThreadIds[id] = threadId;
|
|
787
|
+
});
|
|
788
|
+
} else if (limit > 0) {
|
|
789
|
+
const latestIds = await this.redis.zrange(threadMessagesKey, -limit, -1);
|
|
790
|
+
latestIds.forEach((id) => {
|
|
791
|
+
messageIds.add(id);
|
|
792
|
+
messageIdToThreadIds[id] = threadId;
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
const includedMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
796
|
+
const messages = [
|
|
797
|
+
...includedMessages,
|
|
798
|
+
...(await Promise.all(
|
|
799
|
+
Array.from(messageIds).map(async (id) => {
|
|
800
|
+
const tId = messageIdToThreadIds[id] || threadId;
|
|
801
|
+
const byThreadId = await this.redis.get(
|
|
802
|
+
this.getMessageKey(tId, id)
|
|
803
|
+
);
|
|
804
|
+
if (byThreadId) return byThreadId;
|
|
805
|
+
return null;
|
|
806
|
+
})
|
|
807
|
+
)).filter((msg) => msg !== null)
|
|
808
|
+
];
|
|
809
|
+
messages.sort((a, b) => allMessageIds.indexOf(a.id) - allMessageIds.indexOf(b.id));
|
|
810
|
+
const seen = /* @__PURE__ */ new Set();
|
|
811
|
+
const dedupedMessages = messages.filter((row) => {
|
|
812
|
+
if (seen.has(row.id)) return false;
|
|
813
|
+
seen.add(row.id);
|
|
814
|
+
return true;
|
|
570
815
|
});
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
messageIds.add(id);
|
|
575
|
-
messageIdToThreadIds[id] = threadId;
|
|
816
|
+
const prepared = dedupedMessages.filter((message) => message !== null && message !== void 0).map((message) => {
|
|
817
|
+
const { _index, ...messageWithoutIndex } = message;
|
|
818
|
+
return messageWithoutIndex;
|
|
576
819
|
});
|
|
820
|
+
if (format === "v2") {
|
|
821
|
+
return prepared.map((msg) => ({
|
|
822
|
+
...msg,
|
|
823
|
+
content: msg.content || { format: 2, parts: [{ type: "text", text: "" }] }
|
|
824
|
+
}));
|
|
825
|
+
}
|
|
826
|
+
return prepared;
|
|
827
|
+
} catch (error) {
|
|
828
|
+
throw new MastraError(
|
|
829
|
+
{
|
|
830
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_MESSAGES_FAILED",
|
|
831
|
+
domain: ErrorDomain.STORAGE,
|
|
832
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
833
|
+
details: {
|
|
834
|
+
threadId
|
|
835
|
+
}
|
|
836
|
+
},
|
|
837
|
+
error
|
|
838
|
+
);
|
|
577
839
|
}
|
|
578
|
-
const includedMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
579
|
-
const messages = [
|
|
580
|
-
...includedMessages,
|
|
581
|
-
...(await Promise.all(
|
|
582
|
-
Array.from(messageIds).map(async (id) => {
|
|
583
|
-
const tId = messageIdToThreadIds[id] || threadId;
|
|
584
|
-
const byThreadId = await this.redis.get(this.getMessageKey(tId, id));
|
|
585
|
-
if (byThreadId) return byThreadId;
|
|
586
|
-
return null;
|
|
587
|
-
})
|
|
588
|
-
)).filter((msg) => msg !== null)
|
|
589
|
-
];
|
|
590
|
-
messages.sort((a, b) => allMessageIds.indexOf(a.id) - allMessageIds.indexOf(b.id));
|
|
591
|
-
const seen = /* @__PURE__ */ new Set();
|
|
592
|
-
const dedupedMessages = messages.filter((row) => {
|
|
593
|
-
if (seen.has(row.id)) return false;
|
|
594
|
-
seen.add(row.id);
|
|
595
|
-
return true;
|
|
596
|
-
});
|
|
597
|
-
const prepared = dedupedMessages.filter((message) => message !== null && message !== void 0).map((message) => {
|
|
598
|
-
const { _index, ...messageWithoutIndex } = message;
|
|
599
|
-
return messageWithoutIndex;
|
|
600
|
-
});
|
|
601
|
-
if (format === "v2") {
|
|
602
|
-
return prepared.map((msg) => ({
|
|
603
|
-
...msg,
|
|
604
|
-
content: msg.content || { format: 2, parts: [{ type: "text", text: "" }] }
|
|
605
|
-
}));
|
|
606
|
-
}
|
|
607
|
-
return prepared;
|
|
608
840
|
}
|
|
609
841
|
async getMessagesPaginated(args) {
|
|
610
842
|
const { threadId, selectBy, format } = args;
|
|
@@ -613,9 +845,9 @@ var UpstashStore = class extends MastraStorage {
|
|
|
613
845
|
const toDate = dateRange?.end;
|
|
614
846
|
const threadMessagesKey = this.getThreadMessagesKey(threadId);
|
|
615
847
|
const messages = [];
|
|
616
|
-
const includedMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
617
|
-
messages.push(...includedMessages);
|
|
618
848
|
try {
|
|
849
|
+
const includedMessages = await this._getIncludedMessages(threadId, selectBy);
|
|
850
|
+
messages.push(...includedMessages);
|
|
619
851
|
const allMessageIds = await this.redis.zrange(threadMessagesKey, 0, -1);
|
|
620
852
|
if (allMessageIds.length === 0) {
|
|
621
853
|
return {
|
|
@@ -653,7 +885,19 @@ var UpstashStore = class extends MastraStorage {
|
|
|
653
885
|
hasMore
|
|
654
886
|
};
|
|
655
887
|
} catch (error) {
|
|
656
|
-
|
|
888
|
+
const mastraError = new MastraError(
|
|
889
|
+
{
|
|
890
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_MESSAGES_PAGINATED_FAILED",
|
|
891
|
+
domain: ErrorDomain.STORAGE,
|
|
892
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
893
|
+
details: {
|
|
894
|
+
threadId
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
error
|
|
898
|
+
);
|
|
899
|
+
this.logger.error(mastraError.toString());
|
|
900
|
+
this.logger?.trackException(mastraError);
|
|
657
901
|
return {
|
|
658
902
|
messages: [],
|
|
659
903
|
total: 0,
|
|
@@ -665,17 +909,33 @@ var UpstashStore = class extends MastraStorage {
|
|
|
665
909
|
}
|
|
666
910
|
async persistWorkflowSnapshot(params) {
|
|
667
911
|
const { namespace = "workflows", workflowName, runId, snapshot } = params;
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
912
|
+
try {
|
|
913
|
+
await this.insert({
|
|
914
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
915
|
+
record: {
|
|
916
|
+
namespace,
|
|
917
|
+
workflow_name: workflowName,
|
|
918
|
+
run_id: runId,
|
|
919
|
+
snapshot,
|
|
920
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
921
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
} catch (error) {
|
|
925
|
+
throw new MastraError(
|
|
926
|
+
{
|
|
927
|
+
id: "STORAGE_UPSTASH_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
|
|
928
|
+
domain: ErrorDomain.STORAGE,
|
|
929
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
930
|
+
details: {
|
|
931
|
+
namespace,
|
|
932
|
+
workflowName,
|
|
933
|
+
runId
|
|
934
|
+
}
|
|
935
|
+
},
|
|
936
|
+
error
|
|
937
|
+
);
|
|
938
|
+
}
|
|
679
939
|
}
|
|
680
940
|
async loadWorkflowSnapshot(params) {
|
|
681
941
|
const { namespace = "workflows", workflowName, runId } = params;
|
|
@@ -684,9 +944,25 @@ var UpstashStore = class extends MastraStorage {
|
|
|
684
944
|
workflow_name: workflowName,
|
|
685
945
|
run_id: runId
|
|
686
946
|
});
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
947
|
+
try {
|
|
948
|
+
const data = await this.redis.get(key);
|
|
949
|
+
if (!data) return null;
|
|
950
|
+
return data.snapshot;
|
|
951
|
+
} catch (error) {
|
|
952
|
+
throw new MastraError(
|
|
953
|
+
{
|
|
954
|
+
id: "STORAGE_UPSTASH_STORAGE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
|
|
955
|
+
domain: ErrorDomain.STORAGE,
|
|
956
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
957
|
+
details: {
|
|
958
|
+
namespace,
|
|
959
|
+
workflowName,
|
|
960
|
+
runId
|
|
961
|
+
}
|
|
962
|
+
},
|
|
963
|
+
error
|
|
964
|
+
);
|
|
965
|
+
}
|
|
690
966
|
}
|
|
691
967
|
/**
|
|
692
968
|
* Get all evaluations with pagination and total count
|
|
@@ -775,7 +1051,20 @@ var UpstashStore = class extends MastraStorage {
|
|
|
775
1051
|
};
|
|
776
1052
|
} catch (error) {
|
|
777
1053
|
const { page = 0, perPage = 100 } = options || {};
|
|
778
|
-
|
|
1054
|
+
const mastraError = new MastraError(
|
|
1055
|
+
{
|
|
1056
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_EVALS_FAILED",
|
|
1057
|
+
domain: ErrorDomain.STORAGE,
|
|
1058
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1059
|
+
details: {
|
|
1060
|
+
page,
|
|
1061
|
+
perPage
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
error
|
|
1065
|
+
);
|
|
1066
|
+
this.logger.error(mastraError.toString());
|
|
1067
|
+
this.logger?.trackException(mastraError);
|
|
779
1068
|
return {
|
|
780
1069
|
evals: [],
|
|
781
1070
|
total: 0,
|
|
@@ -828,8 +1117,19 @@ var UpstashStore = class extends MastraStorage {
|
|
|
828
1117
|
}
|
|
829
1118
|
return { runs, total };
|
|
830
1119
|
} catch (error) {
|
|
831
|
-
|
|
832
|
-
|
|
1120
|
+
throw new MastraError(
|
|
1121
|
+
{
|
|
1122
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_WORKFLOW_RUNS_FAILED",
|
|
1123
|
+
domain: ErrorDomain.STORAGE,
|
|
1124
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1125
|
+
details: {
|
|
1126
|
+
namespace,
|
|
1127
|
+
workflowName: workflowName || "",
|
|
1128
|
+
resourceId: resourceId || ""
|
|
1129
|
+
}
|
|
1130
|
+
},
|
|
1131
|
+
error
|
|
1132
|
+
);
|
|
833
1133
|
}
|
|
834
1134
|
}
|
|
835
1135
|
async getWorkflowRunById({
|
|
@@ -850,12 +1150,27 @@ var UpstashStore = class extends MastraStorage {
|
|
|
850
1150
|
if (!data) return null;
|
|
851
1151
|
return this.parseWorkflowRun(data);
|
|
852
1152
|
} catch (error) {
|
|
853
|
-
|
|
854
|
-
|
|
1153
|
+
throw new MastraError(
|
|
1154
|
+
{
|
|
1155
|
+
id: "STORAGE_UPSTASH_STORAGE_GET_WORKFLOW_RUN_BY_ID_FAILED",
|
|
1156
|
+
domain: ErrorDomain.STORAGE,
|
|
1157
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1158
|
+
details: {
|
|
1159
|
+
namespace,
|
|
1160
|
+
runId,
|
|
1161
|
+
workflowName: workflowName || ""
|
|
1162
|
+
}
|
|
1163
|
+
},
|
|
1164
|
+
error
|
|
1165
|
+
);
|
|
855
1166
|
}
|
|
856
1167
|
}
|
|
857
1168
|
async close() {
|
|
858
1169
|
}
|
|
1170
|
+
async updateMessages(_args) {
|
|
1171
|
+
this.logger.error("updateMessages is not yet implemented in UpstashStore");
|
|
1172
|
+
throw new Error("Method not implemented");
|
|
1173
|
+
}
|
|
859
1174
|
};
|
|
860
1175
|
var UpstashFilterTranslator = class extends BaseFilterTranslator {
|
|
861
1176
|
getSupportedOperators() {
|
|
@@ -1077,10 +1392,22 @@ var UpstashVector = class extends MastraVector {
|
|
|
1077
1392
|
vector,
|
|
1078
1393
|
metadata: metadata?.[index]
|
|
1079
1394
|
}));
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1395
|
+
try {
|
|
1396
|
+
await this.client.upsert(points, {
|
|
1397
|
+
namespace
|
|
1398
|
+
});
|
|
1399
|
+
return generatedIds;
|
|
1400
|
+
} catch (error) {
|
|
1401
|
+
throw new MastraError(
|
|
1402
|
+
{
|
|
1403
|
+
id: "STORAGE_UPSTASH_VECTOR_UPSERT_FAILED",
|
|
1404
|
+
domain: ErrorDomain.STORAGE,
|
|
1405
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1406
|
+
details: { namespace, vectorCount: vectors.length }
|
|
1407
|
+
},
|
|
1408
|
+
error
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1084
1411
|
}
|
|
1085
1412
|
/**
|
|
1086
1413
|
* Transforms a Mastra vector filter into an Upstash-compatible filter string.
|
|
@@ -1111,29 +1438,52 @@ var UpstashVector = class extends MastraVector {
|
|
|
1111
1438
|
filter,
|
|
1112
1439
|
includeVector = false
|
|
1113
1440
|
}) {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1441
|
+
try {
|
|
1442
|
+
const ns = this.client.namespace(namespace);
|
|
1443
|
+
const filterString = this.transformFilter(filter);
|
|
1444
|
+
const results = await ns.query({
|
|
1445
|
+
topK,
|
|
1446
|
+
vector: queryVector,
|
|
1447
|
+
includeVectors: includeVector,
|
|
1448
|
+
includeMetadata: true,
|
|
1449
|
+
...filterString ? { filter: filterString } : {}
|
|
1450
|
+
});
|
|
1451
|
+
return (results || []).map((result) => ({
|
|
1452
|
+
id: `${result.id}`,
|
|
1453
|
+
score: result.score,
|
|
1454
|
+
metadata: result.metadata,
|
|
1455
|
+
...includeVector && { vector: result.vector || [] }
|
|
1456
|
+
}));
|
|
1457
|
+
} catch (error) {
|
|
1458
|
+
throw new MastraError(
|
|
1459
|
+
{
|
|
1460
|
+
id: "STORAGE_UPSTASH_VECTOR_QUERY_FAILED",
|
|
1461
|
+
domain: ErrorDomain.STORAGE,
|
|
1462
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1463
|
+
details: { namespace, topK }
|
|
1464
|
+
},
|
|
1465
|
+
error
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1129
1468
|
}
|
|
1130
1469
|
/**
|
|
1131
1470
|
* Lists all namespaces in the Upstash vector index, which correspond to indexes.
|
|
1132
1471
|
* @returns {Promise<string[]>} A promise that resolves to a list of index names.
|
|
1133
1472
|
*/
|
|
1134
1473
|
async listIndexes() {
|
|
1135
|
-
|
|
1136
|
-
|
|
1474
|
+
try {
|
|
1475
|
+
const indexes = await this.client.listNamespaces();
|
|
1476
|
+
return indexes.filter(Boolean);
|
|
1477
|
+
} catch (error) {
|
|
1478
|
+
throw new MastraError(
|
|
1479
|
+
{
|
|
1480
|
+
id: "STORAGE_UPSTASH_VECTOR_LIST_INDEXES_FAILED",
|
|
1481
|
+
domain: ErrorDomain.STORAGE,
|
|
1482
|
+
category: ErrorCategory.THIRD_PARTY
|
|
1483
|
+
},
|
|
1484
|
+
error
|
|
1485
|
+
);
|
|
1486
|
+
}
|
|
1137
1487
|
}
|
|
1138
1488
|
/**
|
|
1139
1489
|
* Retrieves statistics about a vector index.
|
|
@@ -1142,12 +1492,24 @@ var UpstashVector = class extends MastraVector {
|
|
|
1142
1492
|
* @returns A promise that resolves to the index statistics including dimension, count and metric
|
|
1143
1493
|
*/
|
|
1144
1494
|
async describeIndex({ indexName: namespace }) {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1495
|
+
try {
|
|
1496
|
+
const info = await this.client.info();
|
|
1497
|
+
return {
|
|
1498
|
+
dimension: info.dimension,
|
|
1499
|
+
count: info.namespaces?.[namespace]?.vectorCount || 0,
|
|
1500
|
+
metric: info?.similarityFunction?.toLowerCase()
|
|
1501
|
+
};
|
|
1502
|
+
} catch (error) {
|
|
1503
|
+
throw new MastraError(
|
|
1504
|
+
{
|
|
1505
|
+
id: "STORAGE_UPSTASH_VECTOR_DESCRIBE_INDEX_FAILED",
|
|
1506
|
+
domain: ErrorDomain.STORAGE,
|
|
1507
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1508
|
+
details: { namespace }
|
|
1509
|
+
},
|
|
1510
|
+
error
|
|
1511
|
+
);
|
|
1512
|
+
}
|
|
1151
1513
|
}
|
|
1152
1514
|
/**
|
|
1153
1515
|
* Deletes an index (namespace).
|
|
@@ -1158,7 +1520,15 @@ var UpstashVector = class extends MastraVector {
|
|
|
1158
1520
|
try {
|
|
1159
1521
|
await this.client.deleteNamespace(namespace);
|
|
1160
1522
|
} catch (error) {
|
|
1161
|
-
|
|
1523
|
+
throw new MastraError(
|
|
1524
|
+
{
|
|
1525
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_INDEX_FAILED",
|
|
1526
|
+
domain: ErrorDomain.STORAGE,
|
|
1527
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1528
|
+
details: { namespace }
|
|
1529
|
+
},
|
|
1530
|
+
error
|
|
1531
|
+
);
|
|
1162
1532
|
}
|
|
1163
1533
|
}
|
|
1164
1534
|
/**
|
|
@@ -1179,6 +1549,18 @@ var UpstashVector = class extends MastraVector {
|
|
|
1179
1549
|
if (!update.vector && update.metadata) {
|
|
1180
1550
|
throw new Error("Both vector and metadata must be provided for an update");
|
|
1181
1551
|
}
|
|
1552
|
+
} catch (error) {
|
|
1553
|
+
throw new MastraError(
|
|
1554
|
+
{
|
|
1555
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
1556
|
+
domain: ErrorDomain.STORAGE,
|
|
1557
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1558
|
+
details: { namespace, id }
|
|
1559
|
+
},
|
|
1560
|
+
error
|
|
1561
|
+
);
|
|
1562
|
+
}
|
|
1563
|
+
try {
|
|
1182
1564
|
const updatePayload = { id };
|
|
1183
1565
|
if (update.vector) {
|
|
1184
1566
|
updatePayload.vector = update.vector;
|
|
@@ -1195,7 +1577,15 @@ var UpstashVector = class extends MastraVector {
|
|
|
1195
1577
|
namespace
|
|
1196
1578
|
});
|
|
1197
1579
|
} catch (error) {
|
|
1198
|
-
throw new
|
|
1580
|
+
throw new MastraError(
|
|
1581
|
+
{
|
|
1582
|
+
id: "STORAGE_UPSTASH_VECTOR_UPDATE_VECTOR_FAILED",
|
|
1583
|
+
domain: ErrorDomain.STORAGE,
|
|
1584
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1585
|
+
details: { namespace, id }
|
|
1586
|
+
},
|
|
1587
|
+
error
|
|
1588
|
+
);
|
|
1199
1589
|
}
|
|
1200
1590
|
}
|
|
1201
1591
|
/**
|
|
@@ -1211,7 +1601,16 @@ var UpstashVector = class extends MastraVector {
|
|
|
1211
1601
|
namespace
|
|
1212
1602
|
});
|
|
1213
1603
|
} catch (error) {
|
|
1214
|
-
|
|
1604
|
+
const mastraError = new MastraError(
|
|
1605
|
+
{
|
|
1606
|
+
id: "STORAGE_UPSTASH_VECTOR_DELETE_VECTOR_FAILED",
|
|
1607
|
+
domain: ErrorDomain.STORAGE,
|
|
1608
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1609
|
+
details: { namespace, id }
|
|
1610
|
+
},
|
|
1611
|
+
error
|
|
1612
|
+
);
|
|
1613
|
+
this.logger?.error(mastraError.toString());
|
|
1215
1614
|
}
|
|
1216
1615
|
}
|
|
1217
1616
|
};
|