@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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/upstash@0.2.2-alpha.1 build /home/runner/work/mastra/mastra/stores/upstash
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
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.4.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 10071ms
9
+ TSC ⚡️ Build success in 9547ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.2
13
13
  Writing package typings: /home/runner/work/mastra/mastra/stores/upstash/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.2
15
15
  Writing package typings: /home/runner/work/mastra/mastra/stores/upstash/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 10569ms
16
+ DTS ⚡️ Build success in 10120ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 17.20 KB
21
- CJS ⚡️ Build success in 1018ms
22
- ESM dist/index.js 17.07 KB
23
- ESM ⚡️ Build success in 1022ms
20
+ CJS dist/index.cjs 21.72 KB
21
+ CJS ⚡️ Build success in 916ms
22
+ ESM dist/index.js 21.62 KB
23
+ ESM ⚡️ 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(_agentName: string, _type?: 'test' | 'live'): Promise<EvalRow[]>;
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(_agentName: string, _type?: 'test' | 'live'): Promise<EvalRow[]>;
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(_agentName, _type) {
15
- throw new Error("Method not implemented.");
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.MastraStorage.TABLE_MESSAGES) {
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.MastraStorage.TABLE_THREADS,
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.MastraStorage.TABLE_THREADS}:*`;
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.MastraStorage.TABLE_THREADS,
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.MastraStorage.TABLE_THREADS, { id: threadId });
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.MastraStorage.TABLE_MESSAGES, { threadId, id: messageId });
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
- const key = this.getKey(storage.MastraStorage.TABLE_WORKFLOW_SNAPSHOT, {
197
- namespace,
198
- workflow_name: workflowName,
199
- run_id: runId
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.MastraStorage.TABLE_WORKFLOW_SNAPSHOT, {
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
- return data || null;
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(_agentName, _type) {
13
- throw new Error("Method not implemented.");
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 === MastraStorage.TABLE_MESSAGES) {
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: MastraStorage.TABLE_THREADS,
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 = `${MastraStorage.TABLE_THREADS}:*`;
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: MastraStorage.TABLE_THREADS,
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(MastraStorage.TABLE_THREADS, { id: threadId });
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(MastraStorage.TABLE_MESSAGES, { threadId, id: messageId });
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
- const key = this.getKey(MastraStorage.TABLE_WORKFLOW_SNAPSHOT, {
195
- namespace,
196
- workflow_name: workflowName,
197
- run_id: runId
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(MastraStorage.TABLE_WORKFLOW_SNAPSHOT, {
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
- return data || null;
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.1",
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.1"
24
+ "@mastra/core": "^0.8.0-alpha.3"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@microsoft/api-extractor": "^7.52.1",