@mastra/upstash 1.0.0-beta.6 → 1.0.0-beta.8
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 +232 -0
- package/dist/index.cjs +261 -346
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +256 -341
- package/dist/index.js.map +1 -1
- package/dist/storage/db/index.d.ts +47 -0
- package/dist/storage/db/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +4 -7
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +4 -7
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/utils.d.ts +0 -2
- package/dist/storage/domains/utils.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +12 -19
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +54 -173
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +3 -4
- package/dist/storage/domains/operations/index.d.ts +0 -40
- package/dist/storage/domains/operations/index.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MastraStorage, createVectorErrorId,
|
|
1
|
+
import { MastraStorage, createVectorErrorId, ScoresStorage, TABLE_SCORERS, createStorageErrorId, normalizePerPage, calculatePagination, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ensureDate, transformScoreRow as transformScoreRow$1, serializeDate } from '@mastra/core/storage';
|
|
2
2
|
import { Redis } from '@upstash/redis';
|
|
3
3
|
import { MessageList } from '@mastra/core/agent';
|
|
4
4
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
@@ -9,13 +9,6 @@ import { Index } from '@upstash/vector';
|
|
|
9
9
|
import { BaseFilterTranslator } from '@mastra/core/vector/filter';
|
|
10
10
|
|
|
11
11
|
// src/storage/index.ts
|
|
12
|
-
function ensureDate(value) {
|
|
13
|
-
if (!value) return null;
|
|
14
|
-
if (value instanceof Date) return value;
|
|
15
|
-
if (typeof value === "string") return new Date(value);
|
|
16
|
-
if (typeof value === "number") return new Date(value);
|
|
17
|
-
return null;
|
|
18
|
-
}
|
|
19
12
|
function getKey(tableName, keys) {
|
|
20
13
|
const keyParts = Object.entries(keys).filter(([_, value]) => value !== void 0).map(([key, value]) => `${key}:${value}`);
|
|
21
14
|
return `${tableName}:${keyParts.join(":")}`;
|
|
@@ -44,6 +37,107 @@ function processRecord(tableName, record) {
|
|
|
44
37
|
return { key, processedRecord };
|
|
45
38
|
}
|
|
46
39
|
|
|
40
|
+
// src/storage/db/index.ts
|
|
41
|
+
function resolveUpstashConfig(config) {
|
|
42
|
+
if ("client" in config) {
|
|
43
|
+
return config.client;
|
|
44
|
+
}
|
|
45
|
+
return new Redis({
|
|
46
|
+
url: config.url,
|
|
47
|
+
token: config.token
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var UpstashDB = class {
|
|
51
|
+
client;
|
|
52
|
+
constructor({ client }) {
|
|
53
|
+
this.client = client;
|
|
54
|
+
}
|
|
55
|
+
async insert({ tableName, record }) {
|
|
56
|
+
const { key, processedRecord } = processRecord(tableName, record);
|
|
57
|
+
try {
|
|
58
|
+
await this.client.set(key, processedRecord);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new MastraError(
|
|
61
|
+
{
|
|
62
|
+
id: createStorageErrorId("UPSTASH", "INSERT", "FAILED"),
|
|
63
|
+
domain: ErrorDomain.STORAGE,
|
|
64
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
65
|
+
details: {
|
|
66
|
+
tableName
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
error
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async get({ tableName, keys }) {
|
|
74
|
+
const key = getKey(tableName, keys);
|
|
75
|
+
try {
|
|
76
|
+
const data = await this.client.get(key);
|
|
77
|
+
return data || null;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
throw new MastraError(
|
|
80
|
+
{
|
|
81
|
+
id: createStorageErrorId("UPSTASH", "LOAD", "FAILED"),
|
|
82
|
+
domain: ErrorDomain.STORAGE,
|
|
83
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
84
|
+
details: {
|
|
85
|
+
tableName
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
error
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async scanAndDelete(pattern, batchSize = 1e4) {
|
|
93
|
+
let cursor = "0";
|
|
94
|
+
let totalDeleted = 0;
|
|
95
|
+
do {
|
|
96
|
+
const [nextCursor, keys] = await this.client.scan(cursor, {
|
|
97
|
+
match: pattern,
|
|
98
|
+
count: batchSize
|
|
99
|
+
});
|
|
100
|
+
if (keys.length > 0) {
|
|
101
|
+
await this.client.del(...keys);
|
|
102
|
+
totalDeleted += keys.length;
|
|
103
|
+
}
|
|
104
|
+
cursor = nextCursor;
|
|
105
|
+
} while (cursor !== "0");
|
|
106
|
+
return totalDeleted;
|
|
107
|
+
}
|
|
108
|
+
async scanKeys(pattern, batchSize = 1e4) {
|
|
109
|
+
let cursor = "0";
|
|
110
|
+
let keys = [];
|
|
111
|
+
do {
|
|
112
|
+
const [nextCursor, batch] = await this.client.scan(cursor, {
|
|
113
|
+
match: pattern,
|
|
114
|
+
count: batchSize
|
|
115
|
+
});
|
|
116
|
+
keys.push(...batch);
|
|
117
|
+
cursor = nextCursor;
|
|
118
|
+
} while (cursor !== "0");
|
|
119
|
+
return keys;
|
|
120
|
+
}
|
|
121
|
+
async deleteData({ tableName }) {
|
|
122
|
+
const pattern = `${tableName}:*`;
|
|
123
|
+
try {
|
|
124
|
+
await this.scanAndDelete(pattern);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
throw new MastraError(
|
|
127
|
+
{
|
|
128
|
+
id: createStorageErrorId("UPSTASH", "CLEAR_TABLE", "FAILED"),
|
|
129
|
+
domain: ErrorDomain.STORAGE,
|
|
130
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
131
|
+
details: {
|
|
132
|
+
tableName
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
error
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
47
141
|
// src/storage/domains/memory/index.ts
|
|
48
142
|
function getThreadMessagesKey(threadId) {
|
|
49
143
|
return `thread:${threadId}:messages`;
|
|
@@ -57,15 +151,21 @@ function getMessageIndexKey(messageId) {
|
|
|
57
151
|
}
|
|
58
152
|
var StoreMemoryUpstash = class extends MemoryStorage {
|
|
59
153
|
client;
|
|
60
|
-
|
|
61
|
-
constructor(
|
|
154
|
+
#db;
|
|
155
|
+
constructor(config) {
|
|
62
156
|
super();
|
|
157
|
+
const client = resolveUpstashConfig(config);
|
|
63
158
|
this.client = client;
|
|
64
|
-
this
|
|
159
|
+
this.#db = new UpstashDB({ client });
|
|
160
|
+
}
|
|
161
|
+
async dangerouslyClearAll() {
|
|
162
|
+
await this.#db.deleteData({ tableName: TABLE_THREADS });
|
|
163
|
+
await this.#db.deleteData({ tableName: TABLE_MESSAGES });
|
|
164
|
+
await this.#db.deleteData({ tableName: TABLE_RESOURCES });
|
|
65
165
|
}
|
|
66
166
|
async getThreadById({ threadId }) {
|
|
67
167
|
try {
|
|
68
|
-
const thread = await this.
|
|
168
|
+
const thread = await this.#db.get({
|
|
69
169
|
tableName: TABLE_THREADS,
|
|
70
170
|
keys: { id: threadId }
|
|
71
171
|
});
|
|
@@ -109,7 +209,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
109
209
|
try {
|
|
110
210
|
let allThreads = [];
|
|
111
211
|
const pattern = `${TABLE_THREADS}:*`;
|
|
112
|
-
const keys = await this.
|
|
212
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
113
213
|
const pipeline = this.client.pipeline();
|
|
114
214
|
keys.forEach((key) => pipeline.get(key));
|
|
115
215
|
const results = await pipeline.exec();
|
|
@@ -163,7 +263,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
163
263
|
}
|
|
164
264
|
async saveThread({ thread }) {
|
|
165
265
|
try {
|
|
166
|
-
await this.
|
|
266
|
+
await this.#db.insert({
|
|
167
267
|
tableName: TABLE_THREADS,
|
|
168
268
|
record: thread
|
|
169
269
|
});
|
|
@@ -241,7 +341,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
241
341
|
pipeline.del(messageKey);
|
|
242
342
|
}
|
|
243
343
|
await pipeline.exec();
|
|
244
|
-
await this.
|
|
344
|
+
await this.#db.scanAndDelete(getMessageKey(threadId, "*"));
|
|
245
345
|
} catch (error) {
|
|
246
346
|
throw new MastraError(
|
|
247
347
|
{
|
|
@@ -306,7 +406,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
306
406
|
const createdAtScore = new Date(message.createdAt).getTime();
|
|
307
407
|
const score = message._index !== void 0 ? message._index : createdAtScore;
|
|
308
408
|
const existingKeyPattern = getMessageKey("*", message.id);
|
|
309
|
-
const keys = await this.
|
|
409
|
+
const keys = await this.#db.scanKeys(existingKeyPattern);
|
|
310
410
|
if (keys.length > 0) {
|
|
311
411
|
const pipeline2 = this.client.pipeline();
|
|
312
412
|
keys.forEach((key2) => pipeline2.get(key2));
|
|
@@ -361,7 +461,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
361
461
|
return indexedThreadId;
|
|
362
462
|
}
|
|
363
463
|
const existingKeyPattern = getMessageKey("*", messageId);
|
|
364
|
-
const keys = await this.
|
|
464
|
+
const keys = await this.#db.scanKeys(existingKeyPattern);
|
|
365
465
|
if (keys.length === 0) return null;
|
|
366
466
|
const messageData = await this.client.get(keys[0]);
|
|
367
467
|
if (!messageData) return null;
|
|
@@ -702,7 +802,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
702
802
|
const messageIdToKey = {};
|
|
703
803
|
for (const messageId of messageIds) {
|
|
704
804
|
const pattern = getMessageKey("*", messageId);
|
|
705
|
-
const keys = await this.
|
|
805
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
706
806
|
for (const key of keys) {
|
|
707
807
|
const message = await this.client.get(key);
|
|
708
808
|
if (message && message.id === messageId) {
|
|
@@ -831,7 +931,7 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
831
931
|
}
|
|
832
932
|
for (const messageId of unindexedMessageIds) {
|
|
833
933
|
const pattern = getMessageKey("*", messageId);
|
|
834
|
-
const keys = await this.
|
|
934
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
835
935
|
for (const key of keys) {
|
|
836
936
|
const message = await this.client.get(key);
|
|
837
937
|
if (message && message.id === messageId) {
|
|
@@ -892,156 +992,24 @@ var StoreMemoryUpstash = class extends MemoryStorage {
|
|
|
892
992
|
});
|
|
893
993
|
}
|
|
894
994
|
};
|
|
895
|
-
var StoreOperationsUpstash = class extends StoreOperations {
|
|
896
|
-
client;
|
|
897
|
-
constructor({ client }) {
|
|
898
|
-
super();
|
|
899
|
-
this.client = client;
|
|
900
|
-
}
|
|
901
|
-
async createTable({
|
|
902
|
-
tableName: _tableName,
|
|
903
|
-
schema: _schema
|
|
904
|
-
}) {
|
|
905
|
-
}
|
|
906
|
-
async alterTable({
|
|
907
|
-
tableName: _tableName,
|
|
908
|
-
schema: _schema,
|
|
909
|
-
ifNotExists: _ifNotExists
|
|
910
|
-
}) {
|
|
911
|
-
}
|
|
912
|
-
async clearTable({ tableName }) {
|
|
913
|
-
const pattern = `${tableName}:*`;
|
|
914
|
-
try {
|
|
915
|
-
await this.scanAndDelete(pattern);
|
|
916
|
-
} catch (error) {
|
|
917
|
-
throw new MastraError(
|
|
918
|
-
{
|
|
919
|
-
id: createStorageErrorId("UPSTASH", "CLEAR_TABLE", "FAILED"),
|
|
920
|
-
domain: ErrorDomain.STORAGE,
|
|
921
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
922
|
-
details: {
|
|
923
|
-
tableName
|
|
924
|
-
}
|
|
925
|
-
},
|
|
926
|
-
error
|
|
927
|
-
);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
async dropTable({ tableName }) {
|
|
931
|
-
return this.clearTable({ tableName });
|
|
932
|
-
}
|
|
933
|
-
async insert({ tableName, record }) {
|
|
934
|
-
const { key, processedRecord } = processRecord(tableName, record);
|
|
935
|
-
try {
|
|
936
|
-
await this.client.set(key, processedRecord);
|
|
937
|
-
} catch (error) {
|
|
938
|
-
throw new MastraError(
|
|
939
|
-
{
|
|
940
|
-
id: createStorageErrorId("UPSTASH", "INSERT", "FAILED"),
|
|
941
|
-
domain: ErrorDomain.STORAGE,
|
|
942
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
943
|
-
details: {
|
|
944
|
-
tableName
|
|
945
|
-
}
|
|
946
|
-
},
|
|
947
|
-
error
|
|
948
|
-
);
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
async batchInsert(input) {
|
|
952
|
-
const { tableName, records } = input;
|
|
953
|
-
if (!records.length) return;
|
|
954
|
-
const batchSize = 1e3;
|
|
955
|
-
try {
|
|
956
|
-
for (let i = 0; i < records.length; i += batchSize) {
|
|
957
|
-
const batch = records.slice(i, i + batchSize);
|
|
958
|
-
const pipeline = this.client.pipeline();
|
|
959
|
-
for (const record of batch) {
|
|
960
|
-
const { key, processedRecord } = processRecord(tableName, record);
|
|
961
|
-
pipeline.set(key, processedRecord);
|
|
962
|
-
}
|
|
963
|
-
await pipeline.exec();
|
|
964
|
-
}
|
|
965
|
-
} catch (error) {
|
|
966
|
-
throw new MastraError(
|
|
967
|
-
{
|
|
968
|
-
id: createStorageErrorId("UPSTASH", "BATCH_INSERT", "FAILED"),
|
|
969
|
-
domain: ErrorDomain.STORAGE,
|
|
970
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
971
|
-
details: {
|
|
972
|
-
tableName
|
|
973
|
-
}
|
|
974
|
-
},
|
|
975
|
-
error
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
async load({ tableName, keys }) {
|
|
980
|
-
const key = getKey(tableName, keys);
|
|
981
|
-
try {
|
|
982
|
-
const data = await this.client.get(key);
|
|
983
|
-
return data || null;
|
|
984
|
-
} catch (error) {
|
|
985
|
-
throw new MastraError(
|
|
986
|
-
{
|
|
987
|
-
id: createStorageErrorId("UPSTASH", "LOAD", "FAILED"),
|
|
988
|
-
domain: ErrorDomain.STORAGE,
|
|
989
|
-
category: ErrorCategory.THIRD_PARTY,
|
|
990
|
-
details: {
|
|
991
|
-
tableName
|
|
992
|
-
}
|
|
993
|
-
},
|
|
994
|
-
error
|
|
995
|
-
);
|
|
996
|
-
}
|
|
997
|
-
}
|
|
998
|
-
async hasColumn(_tableName, _column) {
|
|
999
|
-
return true;
|
|
1000
|
-
}
|
|
1001
|
-
async scanKeys(pattern, batchSize = 1e4) {
|
|
1002
|
-
let cursor = "0";
|
|
1003
|
-
let keys = [];
|
|
1004
|
-
do {
|
|
1005
|
-
const [nextCursor, batch] = await this.client.scan(cursor, {
|
|
1006
|
-
match: pattern,
|
|
1007
|
-
count: batchSize
|
|
1008
|
-
});
|
|
1009
|
-
keys.push(...batch);
|
|
1010
|
-
cursor = nextCursor;
|
|
1011
|
-
} while (cursor !== "0");
|
|
1012
|
-
return keys;
|
|
1013
|
-
}
|
|
1014
|
-
async scanAndDelete(pattern, batchSize = 1e4) {
|
|
1015
|
-
let cursor = "0";
|
|
1016
|
-
let totalDeleted = 0;
|
|
1017
|
-
do {
|
|
1018
|
-
const [nextCursor, keys] = await this.client.scan(cursor, {
|
|
1019
|
-
match: pattern,
|
|
1020
|
-
count: batchSize
|
|
1021
|
-
});
|
|
1022
|
-
if (keys.length > 0) {
|
|
1023
|
-
await this.client.del(...keys);
|
|
1024
|
-
totalDeleted += keys.length;
|
|
1025
|
-
}
|
|
1026
|
-
cursor = nextCursor;
|
|
1027
|
-
} while (cursor !== "0");
|
|
1028
|
-
return totalDeleted;
|
|
1029
|
-
}
|
|
1030
|
-
};
|
|
1031
995
|
function transformScoreRow(row) {
|
|
1032
996
|
return transformScoreRow$1(row);
|
|
1033
997
|
}
|
|
1034
998
|
var ScoresUpstash = class extends ScoresStorage {
|
|
1035
999
|
client;
|
|
1036
|
-
|
|
1037
|
-
constructor(
|
|
1000
|
+
#db;
|
|
1001
|
+
constructor(config) {
|
|
1038
1002
|
super();
|
|
1003
|
+
const client = resolveUpstashConfig(config);
|
|
1039
1004
|
this.client = client;
|
|
1040
|
-
this
|
|
1005
|
+
this.#db = new UpstashDB({ client });
|
|
1006
|
+
}
|
|
1007
|
+
async dangerouslyClearAll() {
|
|
1008
|
+
await this.#db.deleteData({ tableName: TABLE_SCORERS });
|
|
1041
1009
|
}
|
|
1042
1010
|
async getScoreById({ id }) {
|
|
1043
1011
|
try {
|
|
1044
|
-
const data = await this.
|
|
1012
|
+
const data = await this.#db.get({
|
|
1045
1013
|
tableName: TABLE_SCORERS,
|
|
1046
1014
|
keys: { id }
|
|
1047
1015
|
});
|
|
@@ -1069,7 +1037,7 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1069
1037
|
pagination = { page: 0, perPage: 20 }
|
|
1070
1038
|
}) {
|
|
1071
1039
|
const pattern = `${TABLE_SCORERS}:*`;
|
|
1072
|
-
const keys = await this.
|
|
1040
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
1073
1041
|
const { page, perPage: perPageInput } = pagination;
|
|
1074
1042
|
if (keys.length === 0) {
|
|
1075
1043
|
return {
|
|
@@ -1125,7 +1093,7 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1125
1093
|
domain: ErrorDomain.STORAGE,
|
|
1126
1094
|
category: ErrorCategory.USER,
|
|
1127
1095
|
details: {
|
|
1128
|
-
scorer: score.scorer?.id ?? "unknown",
|
|
1096
|
+
scorer: typeof score.scorer?.id === "string" ? score.scorer.id : String(score.scorer?.id ?? "unknown"),
|
|
1129
1097
|
entityId: score.entityId ?? "unknown",
|
|
1130
1098
|
entityType: score.entityType ?? "unknown",
|
|
1131
1099
|
traceId: score.traceId ?? "",
|
|
@@ -1166,7 +1134,7 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1166
1134
|
pagination = { page: 0, perPage: 20 }
|
|
1167
1135
|
}) {
|
|
1168
1136
|
const pattern = `${TABLE_SCORERS}:*`;
|
|
1169
|
-
const keys = await this.
|
|
1137
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
1170
1138
|
const { page, perPage: perPageInput } = pagination;
|
|
1171
1139
|
if (keys.length === 0) {
|
|
1172
1140
|
return {
|
|
@@ -1210,7 +1178,7 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1210
1178
|
pagination = { page: 0, perPage: 20 }
|
|
1211
1179
|
}) {
|
|
1212
1180
|
const pattern = `${TABLE_SCORERS}:*`;
|
|
1213
|
-
const keys = await this.
|
|
1181
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
1214
1182
|
const { page, perPage: perPageInput } = pagination;
|
|
1215
1183
|
if (keys.length === 0) {
|
|
1216
1184
|
return {
|
|
@@ -1259,7 +1227,7 @@ var ScoresUpstash = class extends ScoresStorage {
|
|
|
1259
1227
|
pagination = { page: 0, perPage: 20 }
|
|
1260
1228
|
}) {
|
|
1261
1229
|
const pattern = `${TABLE_SCORERS}:*`;
|
|
1262
|
-
const keys = await this.
|
|
1230
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
1263
1231
|
const { page, perPage: perPageInput } = pagination;
|
|
1264
1232
|
if (keys.length === 0) {
|
|
1265
1233
|
return {
|
|
@@ -1323,32 +1291,109 @@ function parseWorkflowRun(row) {
|
|
|
1323
1291
|
}
|
|
1324
1292
|
var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
1325
1293
|
client;
|
|
1326
|
-
|
|
1327
|
-
constructor(
|
|
1294
|
+
#db;
|
|
1295
|
+
constructor(config) {
|
|
1328
1296
|
super();
|
|
1297
|
+
const client = resolveUpstashConfig(config);
|
|
1329
1298
|
this.client = client;
|
|
1330
|
-
this
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1299
|
+
this.#db = new UpstashDB({ client });
|
|
1300
|
+
}
|
|
1301
|
+
async dangerouslyClearAll() {
|
|
1302
|
+
await this.#db.deleteData({ tableName: TABLE_WORKFLOW_SNAPSHOT });
|
|
1303
|
+
}
|
|
1304
|
+
async updateWorkflowResults({
|
|
1305
|
+
workflowName,
|
|
1306
|
+
runId,
|
|
1307
|
+
stepId,
|
|
1308
|
+
result,
|
|
1309
|
+
requestContext
|
|
1338
1310
|
}) {
|
|
1339
|
-
|
|
1311
|
+
try {
|
|
1312
|
+
const existingSnapshot = await this.loadWorkflowSnapshot({
|
|
1313
|
+
namespace: "workflows",
|
|
1314
|
+
workflowName,
|
|
1315
|
+
runId
|
|
1316
|
+
});
|
|
1317
|
+
let snapshot;
|
|
1318
|
+
if (!existingSnapshot) {
|
|
1319
|
+
snapshot = {
|
|
1320
|
+
context: {},
|
|
1321
|
+
activePaths: [],
|
|
1322
|
+
timestamp: Date.now(),
|
|
1323
|
+
suspendedPaths: {},
|
|
1324
|
+
activeStepsPath: {},
|
|
1325
|
+
resumeLabels: {},
|
|
1326
|
+
serializedStepGraph: [],
|
|
1327
|
+
status: "pending",
|
|
1328
|
+
value: {},
|
|
1329
|
+
waitingPaths: {},
|
|
1330
|
+
runId,
|
|
1331
|
+
requestContext: {}
|
|
1332
|
+
};
|
|
1333
|
+
} else {
|
|
1334
|
+
snapshot = existingSnapshot;
|
|
1335
|
+
}
|
|
1336
|
+
snapshot.context[stepId] = result;
|
|
1337
|
+
snapshot.requestContext = { ...snapshot.requestContext, ...requestContext };
|
|
1338
|
+
await this.persistWorkflowSnapshot({
|
|
1339
|
+
namespace: "workflows",
|
|
1340
|
+
workflowName,
|
|
1341
|
+
runId,
|
|
1342
|
+
snapshot
|
|
1343
|
+
});
|
|
1344
|
+
return snapshot.context;
|
|
1345
|
+
} catch (error) {
|
|
1346
|
+
if (error instanceof MastraError) throw error;
|
|
1347
|
+
throw new MastraError(
|
|
1348
|
+
{
|
|
1349
|
+
id: createStorageErrorId("UPSTASH", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
|
|
1350
|
+
domain: ErrorDomain.STORAGE,
|
|
1351
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1352
|
+
details: { workflowName, runId, stepId }
|
|
1353
|
+
},
|
|
1354
|
+
error
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1340
1357
|
}
|
|
1341
|
-
updateWorkflowState({
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1358
|
+
async updateWorkflowState({
|
|
1359
|
+
workflowName,
|
|
1360
|
+
runId,
|
|
1361
|
+
opts
|
|
1345
1362
|
}) {
|
|
1346
|
-
|
|
1363
|
+
try {
|
|
1364
|
+
const existingSnapshot = await this.loadWorkflowSnapshot({
|
|
1365
|
+
namespace: "workflows",
|
|
1366
|
+
workflowName,
|
|
1367
|
+
runId
|
|
1368
|
+
});
|
|
1369
|
+
if (!existingSnapshot || !existingSnapshot.context) {
|
|
1370
|
+
return void 0;
|
|
1371
|
+
}
|
|
1372
|
+
const updatedSnapshot = { ...existingSnapshot, ...opts };
|
|
1373
|
+
await this.persistWorkflowSnapshot({
|
|
1374
|
+
namespace: "workflows",
|
|
1375
|
+
workflowName,
|
|
1376
|
+
runId,
|
|
1377
|
+
snapshot: updatedSnapshot
|
|
1378
|
+
});
|
|
1379
|
+
return updatedSnapshot;
|
|
1380
|
+
} catch (error) {
|
|
1381
|
+
if (error instanceof MastraError) throw error;
|
|
1382
|
+
throw new MastraError(
|
|
1383
|
+
{
|
|
1384
|
+
id: createStorageErrorId("UPSTASH", "UPDATE_WORKFLOW_STATE", "FAILED"),
|
|
1385
|
+
domain: ErrorDomain.STORAGE,
|
|
1386
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1387
|
+
details: { workflowName, runId }
|
|
1388
|
+
},
|
|
1389
|
+
error
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1347
1392
|
}
|
|
1348
1393
|
async persistWorkflowSnapshot(params) {
|
|
1349
|
-
const { namespace = "workflows", workflowName, runId, resourceId, snapshot } = params;
|
|
1394
|
+
const { namespace = "workflows", workflowName, runId, resourceId, snapshot, createdAt, updatedAt } = params;
|
|
1350
1395
|
try {
|
|
1351
|
-
await this.
|
|
1396
|
+
await this.#db.insert({
|
|
1352
1397
|
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
1353
1398
|
record: {
|
|
1354
1399
|
namespace,
|
|
@@ -1356,8 +1401,8 @@ var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
|
1356
1401
|
run_id: runId,
|
|
1357
1402
|
resourceId,
|
|
1358
1403
|
snapshot,
|
|
1359
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
1360
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
1404
|
+
createdAt: createdAt ?? /* @__PURE__ */ new Date(),
|
|
1405
|
+
updatedAt: updatedAt ?? /* @__PURE__ */ new Date()
|
|
1361
1406
|
}
|
|
1362
1407
|
});
|
|
1363
1408
|
} catch (error) {
|
|
@@ -1409,7 +1454,7 @@ var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
|
1409
1454
|
}) {
|
|
1410
1455
|
try {
|
|
1411
1456
|
const key = getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace: "workflows", workflow_name: workflowName, run_id: runId }) + "*";
|
|
1412
|
-
const keys = await this.
|
|
1457
|
+
const keys = await this.#db.scanKeys(key);
|
|
1413
1458
|
const workflows = await Promise.all(
|
|
1414
1459
|
keys.map(async (key2) => {
|
|
1415
1460
|
const data2 = await this.client.get(key2);
|
|
@@ -1463,7 +1508,7 @@ var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
|
1463
1508
|
page,
|
|
1464
1509
|
resourceId,
|
|
1465
1510
|
status
|
|
1466
|
-
}) {
|
|
1511
|
+
} = {}) {
|
|
1467
1512
|
try {
|
|
1468
1513
|
if (page !== void 0 && page < 0) {
|
|
1469
1514
|
throw new MastraError(
|
|
@@ -1494,7 +1539,7 @@ var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
|
1494
1539
|
resourceId
|
|
1495
1540
|
});
|
|
1496
1541
|
}
|
|
1497
|
-
const keys = await this.
|
|
1542
|
+
const keys = await this.#db.scanKeys(pattern);
|
|
1498
1543
|
if (keys.length === 0) {
|
|
1499
1544
|
return { runs: [], total: 0 };
|
|
1500
1545
|
}
|
|
@@ -1547,21 +1592,32 @@ var WorkflowsUpstash = class extends WorkflowsStorage {
|
|
|
1547
1592
|
};
|
|
1548
1593
|
|
|
1549
1594
|
// src/storage/index.ts
|
|
1595
|
+
var isClientConfig = (config) => {
|
|
1596
|
+
return "client" in config;
|
|
1597
|
+
};
|
|
1550
1598
|
var UpstashStore = class extends MastraStorage {
|
|
1551
1599
|
redis;
|
|
1552
1600
|
stores;
|
|
1553
1601
|
constructor(config) {
|
|
1554
1602
|
super({ id: config.id, name: "Upstash", disableInit: config.disableInit });
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1603
|
+
if (isClientConfig(config)) {
|
|
1604
|
+
this.redis = config.client;
|
|
1605
|
+
} else {
|
|
1606
|
+
if (!config.url || typeof config.url !== "string" || config.url.trim() === "") {
|
|
1607
|
+
throw new Error("UpstashStore: url is required and cannot be empty.");
|
|
1608
|
+
}
|
|
1609
|
+
if (!config.token || typeof config.token !== "string" || config.token.trim() === "") {
|
|
1610
|
+
throw new Error("UpstashStore: token is required and cannot be empty.");
|
|
1611
|
+
}
|
|
1612
|
+
this.redis = new Redis({
|
|
1613
|
+
url: config.url,
|
|
1614
|
+
token: config.token
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
const scores = new ScoresUpstash({ client: this.redis });
|
|
1618
|
+
const workflows = new WorkflowsUpstash({ client: this.redis });
|
|
1619
|
+
const memory = new StoreMemoryUpstash({ client: this.redis });
|
|
1563
1620
|
this.stores = {
|
|
1564
|
-
operations,
|
|
1565
1621
|
scores,
|
|
1566
1622
|
workflows,
|
|
1567
1623
|
memory
|
|
@@ -1574,155 +1630,14 @@ var UpstashStore = class extends MastraStorage {
|
|
|
1574
1630
|
hasColumn: false,
|
|
1575
1631
|
createTable: false,
|
|
1576
1632
|
deleteMessages: true,
|
|
1577
|
-
|
|
1633
|
+
observability: false,
|
|
1634
|
+
indexManagement: false,
|
|
1635
|
+
listScoresBySpan: true,
|
|
1636
|
+
agents: false
|
|
1578
1637
|
};
|
|
1579
1638
|
}
|
|
1580
|
-
async createTable({
|
|
1581
|
-
tableName,
|
|
1582
|
-
schema
|
|
1583
|
-
}) {
|
|
1584
|
-
return this.stores.operations.createTable({ tableName, schema });
|
|
1585
|
-
}
|
|
1586
|
-
/**
|
|
1587
|
-
* No-op: This backend is schemaless and does not require schema changes.
|
|
1588
|
-
* @param tableName Name of the table
|
|
1589
|
-
* @param schema Schema of the table
|
|
1590
|
-
* @param ifNotExists Array of column names to add if they don't exist
|
|
1591
|
-
*/
|
|
1592
|
-
async alterTable(args) {
|
|
1593
|
-
return this.stores.operations.alterTable(args);
|
|
1594
|
-
}
|
|
1595
|
-
async clearTable({ tableName }) {
|
|
1596
|
-
return this.stores.operations.clearTable({ tableName });
|
|
1597
|
-
}
|
|
1598
|
-
async dropTable({ tableName }) {
|
|
1599
|
-
return this.stores.operations.dropTable({ tableName });
|
|
1600
|
-
}
|
|
1601
|
-
async insert({ tableName, record }) {
|
|
1602
|
-
return this.stores.operations.insert({ tableName, record });
|
|
1603
|
-
}
|
|
1604
|
-
async batchInsert(input) {
|
|
1605
|
-
return this.stores.operations.batchInsert(input);
|
|
1606
|
-
}
|
|
1607
|
-
async load({ tableName, keys }) {
|
|
1608
|
-
return this.stores.operations.load({ tableName, keys });
|
|
1609
|
-
}
|
|
1610
|
-
async getThreadById({ threadId }) {
|
|
1611
|
-
return this.stores.memory.getThreadById({ threadId });
|
|
1612
|
-
}
|
|
1613
|
-
async saveThread({ thread }) {
|
|
1614
|
-
return this.stores.memory.saveThread({ thread });
|
|
1615
|
-
}
|
|
1616
|
-
async updateThread({
|
|
1617
|
-
id,
|
|
1618
|
-
title,
|
|
1619
|
-
metadata
|
|
1620
|
-
}) {
|
|
1621
|
-
return this.stores.memory.updateThread({ id, title, metadata });
|
|
1622
|
-
}
|
|
1623
|
-
async deleteThread({ threadId }) {
|
|
1624
|
-
return this.stores.memory.deleteThread({ threadId });
|
|
1625
|
-
}
|
|
1626
|
-
async saveMessages(args) {
|
|
1627
|
-
return this.stores.memory.saveMessages(args);
|
|
1628
|
-
}
|
|
1629
|
-
async listMessagesById({ messageIds }) {
|
|
1630
|
-
return this.stores.memory.listMessagesById({ messageIds });
|
|
1631
|
-
}
|
|
1632
|
-
async updateWorkflowResults({
|
|
1633
|
-
workflowName,
|
|
1634
|
-
runId,
|
|
1635
|
-
stepId,
|
|
1636
|
-
result,
|
|
1637
|
-
requestContext
|
|
1638
|
-
}) {
|
|
1639
|
-
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
|
|
1640
|
-
}
|
|
1641
|
-
async updateWorkflowState({
|
|
1642
|
-
workflowName,
|
|
1643
|
-
runId,
|
|
1644
|
-
opts
|
|
1645
|
-
}) {
|
|
1646
|
-
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
1647
|
-
}
|
|
1648
|
-
async persistWorkflowSnapshot(params) {
|
|
1649
|
-
return this.stores.workflows.persistWorkflowSnapshot(params);
|
|
1650
|
-
}
|
|
1651
|
-
async loadWorkflowSnapshot(params) {
|
|
1652
|
-
return this.stores.workflows.loadWorkflowSnapshot(params);
|
|
1653
|
-
}
|
|
1654
|
-
async deleteWorkflowRunById({ runId, workflowName }) {
|
|
1655
|
-
return this.stores.workflows.deleteWorkflowRunById({ runId, workflowName });
|
|
1656
|
-
}
|
|
1657
|
-
async listWorkflowRuns(args = {}) {
|
|
1658
|
-
return this.stores.workflows.listWorkflowRuns(args);
|
|
1659
|
-
}
|
|
1660
|
-
async getWorkflowRunById({
|
|
1661
|
-
runId,
|
|
1662
|
-
workflowName
|
|
1663
|
-
}) {
|
|
1664
|
-
return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
|
|
1665
|
-
}
|
|
1666
1639
|
async close() {
|
|
1667
1640
|
}
|
|
1668
|
-
async updateMessages(args) {
|
|
1669
|
-
return this.stores.memory.updateMessages(args);
|
|
1670
|
-
}
|
|
1671
|
-
async deleteMessages(messageIds) {
|
|
1672
|
-
return this.stores.memory.deleteMessages(messageIds);
|
|
1673
|
-
}
|
|
1674
|
-
async getResourceById({ resourceId }) {
|
|
1675
|
-
return this.stores.memory.getResourceById({ resourceId });
|
|
1676
|
-
}
|
|
1677
|
-
async saveResource({ resource }) {
|
|
1678
|
-
return this.stores.memory.saveResource({ resource });
|
|
1679
|
-
}
|
|
1680
|
-
async updateResource({
|
|
1681
|
-
resourceId,
|
|
1682
|
-
workingMemory,
|
|
1683
|
-
metadata
|
|
1684
|
-
}) {
|
|
1685
|
-
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
1686
|
-
}
|
|
1687
|
-
async getScoreById({ id: _id }) {
|
|
1688
|
-
return this.stores.scores.getScoreById({ id: _id });
|
|
1689
|
-
}
|
|
1690
|
-
async saveScore(score) {
|
|
1691
|
-
return this.stores.scores.saveScore(score);
|
|
1692
|
-
}
|
|
1693
|
-
async listScoresByRunId({
|
|
1694
|
-
runId,
|
|
1695
|
-
pagination
|
|
1696
|
-
}) {
|
|
1697
|
-
return this.stores.scores.listScoresByRunId({ runId, pagination });
|
|
1698
|
-
}
|
|
1699
|
-
async listScoresByEntityId({
|
|
1700
|
-
entityId,
|
|
1701
|
-
entityType,
|
|
1702
|
-
pagination
|
|
1703
|
-
}) {
|
|
1704
|
-
return this.stores.scores.listScoresByEntityId({
|
|
1705
|
-
entityId,
|
|
1706
|
-
entityType,
|
|
1707
|
-
pagination
|
|
1708
|
-
});
|
|
1709
|
-
}
|
|
1710
|
-
async listScoresByScorerId({
|
|
1711
|
-
scorerId,
|
|
1712
|
-
pagination,
|
|
1713
|
-
entityId,
|
|
1714
|
-
entityType,
|
|
1715
|
-
source
|
|
1716
|
-
}) {
|
|
1717
|
-
return this.stores.scores.listScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
|
|
1718
|
-
}
|
|
1719
|
-
async listScoresBySpan({
|
|
1720
|
-
traceId,
|
|
1721
|
-
spanId,
|
|
1722
|
-
pagination
|
|
1723
|
-
}) {
|
|
1724
|
-
return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
|
|
1725
|
-
}
|
|
1726
1641
|
};
|
|
1727
1642
|
var UpstashFilterTranslator = class extends BaseFilterTranslator {
|
|
1728
1643
|
getSupportedOperators() {
|