@mastra/upstash 0.2.2-alpha.1 → 0.2.2-alpha.3
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 +27 -0
- package/dist/_tsup-dts-rollup.d.cts +20 -1
- package/dist/_tsup-dts-rollup.d.ts +20 -1
- package/dist/index.cjs +146 -15
- package/dist/index.js +147 -16
- package/package.json +2 -2
- package/src/storage/index.ts +234 -17
- package/src/storage/upstash.test.ts +369 -137
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
|
-
> @mastra/upstash@0.2.2-alpha.
|
|
2
|
+
> @mastra/upstash@0.2.2-alpha.3 build /home/runner/work/mastra/mastra/stores/upstash
|
|
3
3
|
> tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
6
6
|
[34mCLI[39m Using tsconfig: tsconfig.json
|
|
7
7
|
[34mCLI[39m tsup v8.4.0
|
|
8
8
|
[34mTSC[39m Build start
|
|
9
|
-
[32mTSC[39m ⚡️ Build success in
|
|
9
|
+
[32mTSC[39m ⚡️ Build success in 9547ms
|
|
10
10
|
[34mDTS[39m Build start
|
|
11
11
|
[34mCLI[39m Target: es2022
|
|
12
12
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
13
13
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/upstash/dist/_tsup-dts-rollup.d.ts[39m
|
|
14
14
|
Analysis will use the bundled TypeScript version 5.8.2
|
|
15
15
|
[36mWriting package typings: /home/runner/work/mastra/mastra/stores/upstash/dist/_tsup-dts-rollup.d.cts[39m
|
|
16
|
-
[32mDTS[39m ⚡️ Build success in
|
|
16
|
+
[32mDTS[39m ⚡️ Build success in 10120ms
|
|
17
17
|
[34mCLI[39m Cleaning output folder
|
|
18
18
|
[34mESM[39m Build start
|
|
19
19
|
[34mCJS[39m Build start
|
|
20
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
21
|
-
[32mCJS[39m ⚡️ Build success in
|
|
22
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
23
|
-
[32mESM[39m ⚡️ Build success in
|
|
20
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m21.72 KB[39m
|
|
21
|
+
[32mCJS[39m ⚡️ Build success in 916ms
|
|
22
|
+
[32mESM[39m [1mdist/index.js [22m[32m21.62 KB[39m
|
|
23
|
+
[32mESM[39m ⚡️ Build success in 917ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @mastra/upstash
|
|
2
2
|
|
|
3
|
+
## 0.2.2-alpha.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 88fa727: Added getWorkflowRuns for libsql, pg, clickhouse and upstash as well as added route getWorkflowRunsHandler
|
|
8
|
+
- 4d67826: Fix eval writes, remove id column
|
|
9
|
+
- 58a4146: Support missing methods in pg and upstash
|
|
10
|
+
- Updated dependencies [5ae0180]
|
|
11
|
+
- Updated dependencies [9bfa12b]
|
|
12
|
+
- Updated dependencies [515ebfb]
|
|
13
|
+
- Updated dependencies [88fa727]
|
|
14
|
+
- Updated dependencies [f37f535]
|
|
15
|
+
- Updated dependencies [4d67826]
|
|
16
|
+
- Updated dependencies [6330967]
|
|
17
|
+
- Updated dependencies [8393832]
|
|
18
|
+
- Updated dependencies [6330967]
|
|
19
|
+
- @mastra/core@0.8.0-alpha.3
|
|
20
|
+
|
|
21
|
+
## 0.2.2-alpha.2
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [56c31b7]
|
|
26
|
+
- Updated dependencies [dbbbf80]
|
|
27
|
+
- Updated dependencies [99d43b9]
|
|
28
|
+
- @mastra/core@0.8.0-alpha.2
|
|
29
|
+
|
|
3
30
|
## 0.2.2-alpha.1
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
|
@@ -42,13 +42,15 @@ declare class UpstashStore extends MastraStorage {
|
|
|
42
42
|
tableName: TABLE_NAMES;
|
|
43
43
|
records: Record<string, any>[];
|
|
44
44
|
}): Promise<void>;
|
|
45
|
-
getEvalsByAgentName(
|
|
45
|
+
getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
|
|
46
|
+
private transformEvalRecord;
|
|
46
47
|
getTraces(_input: {
|
|
47
48
|
name?: string;
|
|
48
49
|
scope?: string;
|
|
49
50
|
page: number;
|
|
50
51
|
perPage: number;
|
|
51
52
|
attributes?: Record<string, string>;
|
|
53
|
+
filters?: Record<string, any>;
|
|
52
54
|
}): Promise<any[]>;
|
|
53
55
|
private redis;
|
|
54
56
|
constructor(config: UpstashConfig);
|
|
@@ -104,6 +106,23 @@ declare class UpstashStore extends MastraStorage {
|
|
|
104
106
|
workflowName: string;
|
|
105
107
|
runId: string;
|
|
106
108
|
}): Promise<WorkflowRunState | null>;
|
|
109
|
+
getWorkflowRuns({ namespace, workflowName, fromDate, toDate, limit, offset, }?: {
|
|
110
|
+
namespace: string;
|
|
111
|
+
workflowName?: string;
|
|
112
|
+
fromDate?: Date;
|
|
113
|
+
toDate?: Date;
|
|
114
|
+
limit?: number;
|
|
115
|
+
offset?: number;
|
|
116
|
+
}): Promise<{
|
|
117
|
+
runs: Array<{
|
|
118
|
+
workflowName: string;
|
|
119
|
+
runId: string;
|
|
120
|
+
snapshot: WorkflowRunState | string;
|
|
121
|
+
createdAt: Date;
|
|
122
|
+
updatedAt: Date;
|
|
123
|
+
}>;
|
|
124
|
+
total: number;
|
|
125
|
+
}>;
|
|
107
126
|
close(): Promise<void>;
|
|
108
127
|
}
|
|
109
128
|
export { UpstashStore }
|
|
@@ -42,13 +42,15 @@ declare class UpstashStore extends MastraStorage {
|
|
|
42
42
|
tableName: TABLE_NAMES;
|
|
43
43
|
records: Record<string, any>[];
|
|
44
44
|
}): Promise<void>;
|
|
45
|
-
getEvalsByAgentName(
|
|
45
|
+
getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]>;
|
|
46
|
+
private transformEvalRecord;
|
|
46
47
|
getTraces(_input: {
|
|
47
48
|
name?: string;
|
|
48
49
|
scope?: string;
|
|
49
50
|
page: number;
|
|
50
51
|
perPage: number;
|
|
51
52
|
attributes?: Record<string, string>;
|
|
53
|
+
filters?: Record<string, any>;
|
|
52
54
|
}): Promise<any[]>;
|
|
53
55
|
private redis;
|
|
54
56
|
constructor(config: UpstashConfig);
|
|
@@ -104,6 +106,23 @@ declare class UpstashStore extends MastraStorage {
|
|
|
104
106
|
workflowName: string;
|
|
105
107
|
runId: string;
|
|
106
108
|
}): Promise<WorkflowRunState | null>;
|
|
109
|
+
getWorkflowRuns({ namespace, workflowName, fromDate, toDate, limit, offset, }?: {
|
|
110
|
+
namespace: string;
|
|
111
|
+
workflowName?: string;
|
|
112
|
+
fromDate?: Date;
|
|
113
|
+
toDate?: Date;
|
|
114
|
+
limit?: number;
|
|
115
|
+
offset?: number;
|
|
116
|
+
}): Promise<{
|
|
117
|
+
runs: Array<{
|
|
118
|
+
workflowName: string;
|
|
119
|
+
runId: string;
|
|
120
|
+
snapshot: WorkflowRunState | string;
|
|
121
|
+
createdAt: Date;
|
|
122
|
+
updatedAt: Date;
|
|
123
|
+
}>;
|
|
124
|
+
total: number;
|
|
125
|
+
}>;
|
|
107
126
|
close(): Promise<void>;
|
|
108
127
|
}
|
|
109
128
|
export { UpstashStore }
|
package/dist/index.cjs
CHANGED
|
@@ -11,8 +11,82 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
11
11
|
batchInsert(_input) {
|
|
12
12
|
throw new Error("Method not implemented.");
|
|
13
13
|
}
|
|
14
|
-
getEvalsByAgentName(
|
|
15
|
-
|
|
14
|
+
async getEvalsByAgentName(agentName, type) {
|
|
15
|
+
try {
|
|
16
|
+
const pattern = `${storage.TABLE_EVALS}:*`;
|
|
17
|
+
const keys = await this.redis.keys(pattern);
|
|
18
|
+
const evalRecords = await Promise.all(
|
|
19
|
+
keys.map(async (key) => {
|
|
20
|
+
const data = await this.redis.get(key);
|
|
21
|
+
return data;
|
|
22
|
+
})
|
|
23
|
+
);
|
|
24
|
+
const nonNullRecords = evalRecords.filter(
|
|
25
|
+
(record) => record !== null && typeof record === "object" && "agent_name" in record && record.agent_name === agentName
|
|
26
|
+
);
|
|
27
|
+
let filteredEvals = nonNullRecords;
|
|
28
|
+
if (type === "test") {
|
|
29
|
+
filteredEvals = filteredEvals.filter((record) => {
|
|
30
|
+
if (!record.test_info) return false;
|
|
31
|
+
try {
|
|
32
|
+
if (typeof record.test_info === "string") {
|
|
33
|
+
const parsedTestInfo = JSON.parse(record.test_info);
|
|
34
|
+
return parsedTestInfo && typeof parsedTestInfo === "object" && "testPath" in parsedTestInfo;
|
|
35
|
+
}
|
|
36
|
+
return typeof record.test_info === "object" && "testPath" in record.test_info;
|
|
37
|
+
} catch (_e) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
} else if (type === "live") {
|
|
42
|
+
filteredEvals = filteredEvals.filter((record) => {
|
|
43
|
+
if (!record.test_info) return true;
|
|
44
|
+
try {
|
|
45
|
+
if (typeof record.test_info === "string") {
|
|
46
|
+
const parsedTestInfo = JSON.parse(record.test_info);
|
|
47
|
+
return !(parsedTestInfo && typeof parsedTestInfo === "object" && "testPath" in parsedTestInfo);
|
|
48
|
+
}
|
|
49
|
+
return !(typeof record.test_info === "object" && "testPath" in record.test_info);
|
|
50
|
+
} catch (_e) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return filteredEvals.map((record) => this.transformEvalRecord(record));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error("Failed to get evals for the specified agent:", error);
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
transformEvalRecord(record) {
|
|
62
|
+
let result = record.result;
|
|
63
|
+
if (typeof result === "string") {
|
|
64
|
+
try {
|
|
65
|
+
result = JSON.parse(result);
|
|
66
|
+
} catch (_e) {
|
|
67
|
+
console.warn("Failed to parse result JSON:");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let testInfo = record.test_info;
|
|
71
|
+
if (typeof testInfo === "string") {
|
|
72
|
+
try {
|
|
73
|
+
testInfo = JSON.parse(testInfo);
|
|
74
|
+
} catch (_e) {
|
|
75
|
+
console.warn("Failed to parse test_info JSON:");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
agentName: record.agent_name,
|
|
80
|
+
input: record.input,
|
|
81
|
+
output: record.output,
|
|
82
|
+
result,
|
|
83
|
+
metricName: record.metric_name,
|
|
84
|
+
instructions: record.instructions,
|
|
85
|
+
testInfo,
|
|
86
|
+
globalRunId: record.global_run_id,
|
|
87
|
+
runId: record.run_id,
|
|
88
|
+
createdAt: typeof record.created_at === "string" ? record.created_at : record.created_at instanceof Date ? record.created_at.toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
89
|
+
};
|
|
16
90
|
}
|
|
17
91
|
getTraces(_input) {
|
|
18
92
|
throw new Error("Method not implemented.");
|
|
@@ -53,8 +127,16 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
53
127
|
}
|
|
54
128
|
async insert({ tableName, record }) {
|
|
55
129
|
let key;
|
|
56
|
-
if (tableName === storage.
|
|
130
|
+
if (tableName === storage.TABLE_MESSAGES) {
|
|
57
131
|
key = this.getKey(tableName, { threadId: record.threadId, id: record.id });
|
|
132
|
+
} else if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
|
|
133
|
+
key = this.getKey(tableName, {
|
|
134
|
+
namespace: record.namespace || "workflows",
|
|
135
|
+
workflow_name: record.workflow_name,
|
|
136
|
+
run_id: record.run_id
|
|
137
|
+
});
|
|
138
|
+
} else if (tableName === storage.TABLE_EVALS) {
|
|
139
|
+
key = this.getKey(tableName, { id: record.run_id });
|
|
58
140
|
} else {
|
|
59
141
|
key = this.getKey(tableName, { id: record.id });
|
|
60
142
|
}
|
|
@@ -72,7 +154,7 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
72
154
|
}
|
|
73
155
|
async getThreadById({ threadId }) {
|
|
74
156
|
const thread = await this.load({
|
|
75
|
-
tableName: storage.
|
|
157
|
+
tableName: storage.TABLE_THREADS,
|
|
76
158
|
keys: { id: threadId }
|
|
77
159
|
});
|
|
78
160
|
if (!thread) return null;
|
|
@@ -84,7 +166,7 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
84
166
|
};
|
|
85
167
|
}
|
|
86
168
|
async getThreadsByResourceId({ resourceId }) {
|
|
87
|
-
const pattern = `${storage.
|
|
169
|
+
const pattern = `${storage.TABLE_THREADS}:*`;
|
|
88
170
|
const keys = await this.redis.keys(pattern);
|
|
89
171
|
const threads = await Promise.all(
|
|
90
172
|
keys.map(async (key) => {
|
|
@@ -101,7 +183,7 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
101
183
|
}
|
|
102
184
|
async saveThread({ thread }) {
|
|
103
185
|
await this.insert({
|
|
104
|
-
tableName: storage.
|
|
186
|
+
tableName: storage.TABLE_THREADS,
|
|
105
187
|
record: thread
|
|
106
188
|
});
|
|
107
189
|
return thread;
|
|
@@ -127,11 +209,11 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
127
209
|
return updatedThread;
|
|
128
210
|
}
|
|
129
211
|
async deleteThread({ threadId }) {
|
|
130
|
-
const key = this.getKey(storage.
|
|
212
|
+
const key = this.getKey(storage.TABLE_THREADS, { id: threadId });
|
|
131
213
|
await this.redis.del(key);
|
|
132
214
|
}
|
|
133
215
|
getMessageKey(threadId, messageId) {
|
|
134
|
-
return this.getKey(storage.
|
|
216
|
+
return this.getKey(storage.TABLE_MESSAGES, { threadId, id: messageId });
|
|
135
217
|
}
|
|
136
218
|
getThreadMessagesKey(threadId) {
|
|
137
219
|
return `thread:${threadId}:messages`;
|
|
@@ -193,22 +275,71 @@ var UpstashStore = class extends storage.MastraStorage {
|
|
|
193
275
|
}
|
|
194
276
|
async persistWorkflowSnapshot(params) {
|
|
195
277
|
const { namespace = "workflows", workflowName, runId, snapshot } = params;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
278
|
+
await this.insert({
|
|
279
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
280
|
+
record: {
|
|
281
|
+
namespace,
|
|
282
|
+
workflow_name: workflowName,
|
|
283
|
+
run_id: runId,
|
|
284
|
+
snapshot,
|
|
285
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
286
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
287
|
+
}
|
|
200
288
|
});
|
|
201
|
-
await this.redis.set(key, snapshot);
|
|
202
289
|
}
|
|
203
290
|
async loadWorkflowSnapshot(params) {
|
|
204
291
|
const { namespace = "workflows", workflowName, runId } = params;
|
|
205
|
-
const key = this.getKey(storage.
|
|
292
|
+
const key = this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, {
|
|
206
293
|
namespace,
|
|
207
294
|
workflow_name: workflowName,
|
|
208
295
|
run_id: runId
|
|
209
296
|
});
|
|
210
297
|
const data = await this.redis.get(key);
|
|
211
|
-
|
|
298
|
+
if (!data) return null;
|
|
299
|
+
return data.snapshot;
|
|
300
|
+
}
|
|
301
|
+
async getWorkflowRuns({
|
|
302
|
+
namespace,
|
|
303
|
+
workflowName,
|
|
304
|
+
fromDate,
|
|
305
|
+
toDate,
|
|
306
|
+
limit,
|
|
307
|
+
offset
|
|
308
|
+
} = { namespace: "workflows" }) {
|
|
309
|
+
const pattern = workflowName ? this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName }) + ":*" : this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace }) + ":*";
|
|
310
|
+
const keys = await this.redis.keys(pattern);
|
|
311
|
+
const workflows = await Promise.all(
|
|
312
|
+
keys.map(async (key) => {
|
|
313
|
+
const data = await this.redis.get(key);
|
|
314
|
+
return data;
|
|
315
|
+
})
|
|
316
|
+
);
|
|
317
|
+
let runs = workflows.filter((w) => w !== null).map((w) => {
|
|
318
|
+
let parsedSnapshot = w.snapshot;
|
|
319
|
+
if (typeof parsedSnapshot === "string") {
|
|
320
|
+
try {
|
|
321
|
+
parsedSnapshot = JSON.parse(w.snapshot);
|
|
322
|
+
} catch (_e) {
|
|
323
|
+
console.warn(`Failed to parse snapshot for workflow ${w.workflow_name}:`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
workflowName: w.workflow_name,
|
|
328
|
+
runId: w.run_id,
|
|
329
|
+
snapshot: parsedSnapshot,
|
|
330
|
+
createdAt: this.ensureDate(w.createdAt),
|
|
331
|
+
updatedAt: this.ensureDate(w.updatedAt)
|
|
332
|
+
};
|
|
333
|
+
}).filter((w) => {
|
|
334
|
+
if (fromDate && w.createdAt < fromDate) return false;
|
|
335
|
+
if (toDate && w.createdAt > toDate) return false;
|
|
336
|
+
return true;
|
|
337
|
+
}).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
338
|
+
const total = runs.length;
|
|
339
|
+
if (limit !== void 0 && offset !== void 0) {
|
|
340
|
+
runs = runs.slice(offset, offset + limit);
|
|
341
|
+
}
|
|
342
|
+
return { runs, total };
|
|
212
343
|
}
|
|
213
344
|
async close() {
|
|
214
345
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MastraStorage } from '@mastra/core/storage';
|
|
1
|
+
import { MastraStorage, TABLE_EVALS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_THREADS } from '@mastra/core/storage';
|
|
2
2
|
import { Redis } from '@upstash/redis';
|
|
3
3
|
import { MastraVector } from '@mastra/core/vector';
|
|
4
4
|
import { Index } from '@upstash/vector';
|
|
@@ -9,8 +9,82 @@ var UpstashStore = class extends MastraStorage {
|
|
|
9
9
|
batchInsert(_input) {
|
|
10
10
|
throw new Error("Method not implemented.");
|
|
11
11
|
}
|
|
12
|
-
getEvalsByAgentName(
|
|
13
|
-
|
|
12
|
+
async getEvalsByAgentName(agentName, type) {
|
|
13
|
+
try {
|
|
14
|
+
const pattern = `${TABLE_EVALS}:*`;
|
|
15
|
+
const keys = await this.redis.keys(pattern);
|
|
16
|
+
const evalRecords = await Promise.all(
|
|
17
|
+
keys.map(async (key) => {
|
|
18
|
+
const data = await this.redis.get(key);
|
|
19
|
+
return data;
|
|
20
|
+
})
|
|
21
|
+
);
|
|
22
|
+
const nonNullRecords = evalRecords.filter(
|
|
23
|
+
(record) => record !== null && typeof record === "object" && "agent_name" in record && record.agent_name === agentName
|
|
24
|
+
);
|
|
25
|
+
let filteredEvals = nonNullRecords;
|
|
26
|
+
if (type === "test") {
|
|
27
|
+
filteredEvals = filteredEvals.filter((record) => {
|
|
28
|
+
if (!record.test_info) return false;
|
|
29
|
+
try {
|
|
30
|
+
if (typeof record.test_info === "string") {
|
|
31
|
+
const parsedTestInfo = JSON.parse(record.test_info);
|
|
32
|
+
return parsedTestInfo && typeof parsedTestInfo === "object" && "testPath" in parsedTestInfo;
|
|
33
|
+
}
|
|
34
|
+
return typeof record.test_info === "object" && "testPath" in record.test_info;
|
|
35
|
+
} catch (_e) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
} else if (type === "live") {
|
|
40
|
+
filteredEvals = filteredEvals.filter((record) => {
|
|
41
|
+
if (!record.test_info) return true;
|
|
42
|
+
try {
|
|
43
|
+
if (typeof record.test_info === "string") {
|
|
44
|
+
const parsedTestInfo = JSON.parse(record.test_info);
|
|
45
|
+
return !(parsedTestInfo && typeof parsedTestInfo === "object" && "testPath" in parsedTestInfo);
|
|
46
|
+
}
|
|
47
|
+
return !(typeof record.test_info === "object" && "testPath" in record.test_info);
|
|
48
|
+
} catch (_e) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return filteredEvals.map((record) => this.transformEvalRecord(record));
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error("Failed to get evals for the specified agent:", error);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
transformEvalRecord(record) {
|
|
60
|
+
let result = record.result;
|
|
61
|
+
if (typeof result === "string") {
|
|
62
|
+
try {
|
|
63
|
+
result = JSON.parse(result);
|
|
64
|
+
} catch (_e) {
|
|
65
|
+
console.warn("Failed to parse result JSON:");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
let testInfo = record.test_info;
|
|
69
|
+
if (typeof testInfo === "string") {
|
|
70
|
+
try {
|
|
71
|
+
testInfo = JSON.parse(testInfo);
|
|
72
|
+
} catch (_e) {
|
|
73
|
+
console.warn("Failed to parse test_info JSON:");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
agentName: record.agent_name,
|
|
78
|
+
input: record.input,
|
|
79
|
+
output: record.output,
|
|
80
|
+
result,
|
|
81
|
+
metricName: record.metric_name,
|
|
82
|
+
instructions: record.instructions,
|
|
83
|
+
testInfo,
|
|
84
|
+
globalRunId: record.global_run_id,
|
|
85
|
+
runId: record.run_id,
|
|
86
|
+
createdAt: typeof record.created_at === "string" ? record.created_at : record.created_at instanceof Date ? record.created_at.toISOString() : (/* @__PURE__ */ new Date()).toISOString()
|
|
87
|
+
};
|
|
14
88
|
}
|
|
15
89
|
getTraces(_input) {
|
|
16
90
|
throw new Error("Method not implemented.");
|
|
@@ -51,8 +125,16 @@ var UpstashStore = class extends MastraStorage {
|
|
|
51
125
|
}
|
|
52
126
|
async insert({ tableName, record }) {
|
|
53
127
|
let key;
|
|
54
|
-
if (tableName ===
|
|
128
|
+
if (tableName === TABLE_MESSAGES) {
|
|
55
129
|
key = this.getKey(tableName, { threadId: record.threadId, id: record.id });
|
|
130
|
+
} else if (tableName === TABLE_WORKFLOW_SNAPSHOT) {
|
|
131
|
+
key = this.getKey(tableName, {
|
|
132
|
+
namespace: record.namespace || "workflows",
|
|
133
|
+
workflow_name: record.workflow_name,
|
|
134
|
+
run_id: record.run_id
|
|
135
|
+
});
|
|
136
|
+
} else if (tableName === TABLE_EVALS) {
|
|
137
|
+
key = this.getKey(tableName, { id: record.run_id });
|
|
56
138
|
} else {
|
|
57
139
|
key = this.getKey(tableName, { id: record.id });
|
|
58
140
|
}
|
|
@@ -70,7 +152,7 @@ var UpstashStore = class extends MastraStorage {
|
|
|
70
152
|
}
|
|
71
153
|
async getThreadById({ threadId }) {
|
|
72
154
|
const thread = await this.load({
|
|
73
|
-
tableName:
|
|
155
|
+
tableName: TABLE_THREADS,
|
|
74
156
|
keys: { id: threadId }
|
|
75
157
|
});
|
|
76
158
|
if (!thread) return null;
|
|
@@ -82,7 +164,7 @@ var UpstashStore = class extends MastraStorage {
|
|
|
82
164
|
};
|
|
83
165
|
}
|
|
84
166
|
async getThreadsByResourceId({ resourceId }) {
|
|
85
|
-
const pattern = `${
|
|
167
|
+
const pattern = `${TABLE_THREADS}:*`;
|
|
86
168
|
const keys = await this.redis.keys(pattern);
|
|
87
169
|
const threads = await Promise.all(
|
|
88
170
|
keys.map(async (key) => {
|
|
@@ -99,7 +181,7 @@ var UpstashStore = class extends MastraStorage {
|
|
|
99
181
|
}
|
|
100
182
|
async saveThread({ thread }) {
|
|
101
183
|
await this.insert({
|
|
102
|
-
tableName:
|
|
184
|
+
tableName: TABLE_THREADS,
|
|
103
185
|
record: thread
|
|
104
186
|
});
|
|
105
187
|
return thread;
|
|
@@ -125,11 +207,11 @@ var UpstashStore = class extends MastraStorage {
|
|
|
125
207
|
return updatedThread;
|
|
126
208
|
}
|
|
127
209
|
async deleteThread({ threadId }) {
|
|
128
|
-
const key = this.getKey(
|
|
210
|
+
const key = this.getKey(TABLE_THREADS, { id: threadId });
|
|
129
211
|
await this.redis.del(key);
|
|
130
212
|
}
|
|
131
213
|
getMessageKey(threadId, messageId) {
|
|
132
|
-
return this.getKey(
|
|
214
|
+
return this.getKey(TABLE_MESSAGES, { threadId, id: messageId });
|
|
133
215
|
}
|
|
134
216
|
getThreadMessagesKey(threadId) {
|
|
135
217
|
return `thread:${threadId}:messages`;
|
|
@@ -191,22 +273,71 @@ var UpstashStore = class extends MastraStorage {
|
|
|
191
273
|
}
|
|
192
274
|
async persistWorkflowSnapshot(params) {
|
|
193
275
|
const { namespace = "workflows", workflowName, runId, snapshot } = params;
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
276
|
+
await this.insert({
|
|
277
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
278
|
+
record: {
|
|
279
|
+
namespace,
|
|
280
|
+
workflow_name: workflowName,
|
|
281
|
+
run_id: runId,
|
|
282
|
+
snapshot,
|
|
283
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
284
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
285
|
+
}
|
|
198
286
|
});
|
|
199
|
-
await this.redis.set(key, snapshot);
|
|
200
287
|
}
|
|
201
288
|
async loadWorkflowSnapshot(params) {
|
|
202
289
|
const { namespace = "workflows", workflowName, runId } = params;
|
|
203
|
-
const key = this.getKey(
|
|
290
|
+
const key = this.getKey(TABLE_WORKFLOW_SNAPSHOT, {
|
|
204
291
|
namespace,
|
|
205
292
|
workflow_name: workflowName,
|
|
206
293
|
run_id: runId
|
|
207
294
|
});
|
|
208
295
|
const data = await this.redis.get(key);
|
|
209
|
-
|
|
296
|
+
if (!data) return null;
|
|
297
|
+
return data.snapshot;
|
|
298
|
+
}
|
|
299
|
+
async getWorkflowRuns({
|
|
300
|
+
namespace,
|
|
301
|
+
workflowName,
|
|
302
|
+
fromDate,
|
|
303
|
+
toDate,
|
|
304
|
+
limit,
|
|
305
|
+
offset
|
|
306
|
+
} = { namespace: "workflows" }) {
|
|
307
|
+
const pattern = workflowName ? this.getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName }) + ":*" : this.getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace }) + ":*";
|
|
308
|
+
const keys = await this.redis.keys(pattern);
|
|
309
|
+
const workflows = await Promise.all(
|
|
310
|
+
keys.map(async (key) => {
|
|
311
|
+
const data = await this.redis.get(key);
|
|
312
|
+
return data;
|
|
313
|
+
})
|
|
314
|
+
);
|
|
315
|
+
let runs = workflows.filter((w) => w !== null).map((w) => {
|
|
316
|
+
let parsedSnapshot = w.snapshot;
|
|
317
|
+
if (typeof parsedSnapshot === "string") {
|
|
318
|
+
try {
|
|
319
|
+
parsedSnapshot = JSON.parse(w.snapshot);
|
|
320
|
+
} catch (_e) {
|
|
321
|
+
console.warn(`Failed to parse snapshot for workflow ${w.workflow_name}:`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
workflowName: w.workflow_name,
|
|
326
|
+
runId: w.run_id,
|
|
327
|
+
snapshot: parsedSnapshot,
|
|
328
|
+
createdAt: this.ensureDate(w.createdAt),
|
|
329
|
+
updatedAt: this.ensureDate(w.updatedAt)
|
|
330
|
+
};
|
|
331
|
+
}).filter((w) => {
|
|
332
|
+
if (fromDate && w.createdAt < fromDate) return false;
|
|
333
|
+
if (toDate && w.createdAt > toDate) return false;
|
|
334
|
+
return true;
|
|
335
|
+
}).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
|
|
336
|
+
const total = runs.length;
|
|
337
|
+
if (limit !== void 0 && offset !== void 0) {
|
|
338
|
+
runs = runs.slice(offset, offset + limit);
|
|
339
|
+
}
|
|
340
|
+
return { runs, total };
|
|
210
341
|
}
|
|
211
342
|
async close() {
|
|
212
343
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/upstash",
|
|
3
|
-
"version": "0.2.2-alpha.
|
|
3
|
+
"version": "0.2.2-alpha.3",
|
|
4
4
|
"description": "Upstash provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@upstash/redis": "^1.34.5",
|
|
23
23
|
"@upstash/vector": "^1.2.1",
|
|
24
|
-
"@mastra/core": "^0.8.0-alpha.
|
|
24
|
+
"@mastra/core": "^0.8.0-alpha.3"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@microsoft/api-extractor": "^7.52.1",
|