@mastra/upstash 1.0.0-beta.10 → 1.0.0-beta.12

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 CHANGED
@@ -1,5 +1,123 @@
1
1
  # @mastra/upstash
2
2
 
3
+ ## 1.0.0-beta.12
4
+
5
+ ### Patch Changes
6
+
7
+ - Added new `listThreads` method for flexible thread filtering across all storage adapters. ([#11832](https://github.com/mastra-ai/mastra/pull/11832))
8
+
9
+ **New Features**
10
+ - Filter threads by `resourceId`, `metadata`, or both (with AND logic for metadata key-value pairs)
11
+ - All filter parameters are optional, allowing you to list all threads or filter as needed
12
+ - Full pagination and sorting support
13
+
14
+ **Example Usage**
15
+
16
+ ```typescript
17
+ // List all threads
18
+ const allThreads = await memory.listThreads({});
19
+
20
+ // Filter by resourceId only
21
+ const userThreads = await memory.listThreads({
22
+ filter: { resourceId: 'user-123' },
23
+ });
24
+
25
+ // Filter by metadata only
26
+ const supportThreads = await memory.listThreads({
27
+ filter: { metadata: { category: 'support' } },
28
+ });
29
+
30
+ // Filter by both with pagination
31
+ const filteredThreads = await memory.listThreads({
32
+ filter: {
33
+ resourceId: 'user-123',
34
+ metadata: { priority: 'high', status: 'open' },
35
+ },
36
+ orderBy: { field: 'updatedAt', direction: 'DESC' },
37
+ page: 0,
38
+ perPage: 20,
39
+ });
40
+ ```
41
+
42
+ **Security Improvements**
43
+ - Added validation to prevent SQL injection via malicious metadata keys
44
+ - Added pagination parameter validation to prevent integer overflow attacks
45
+
46
+ - Updated dependencies [[`ed3e3dd`](https://github.com/mastra-ai/mastra/commit/ed3e3ddec69d564fe2b125e083437f76331f1283), [`6833c69`](https://github.com/mastra-ai/mastra/commit/6833c69607418d257750bbcdd84638993d343539), [`47b1c16`](https://github.com/mastra-ai/mastra/commit/47b1c16a01c7ffb6765fe1e499b49092f8b7eba3), [`3a76a80`](https://github.com/mastra-ai/mastra/commit/3a76a80284cb71a0faa975abb3d4b2a9631e60cd), [`8538a0d`](https://github.com/mastra-ai/mastra/commit/8538a0d232619bf55dad7ddc2a8b0ca77c679a87), [`9312dcd`](https://github.com/mastra-ai/mastra/commit/9312dcd1c6f5b321929e7d382e763d95fdc030f5)]:
47
+ - @mastra/core@1.0.0-beta.25
48
+
49
+ ## 1.0.0-beta.11
50
+
51
+ ### Patch Changes
52
+
53
+ - Aligned vector store configuration with underlying library APIs, giving you access to all library options directly. ([#11742](https://github.com/mastra-ai/mastra/pull/11742))
54
+
55
+ **Why this change?**
56
+
57
+ Previously, each vector store defined its own configuration types that only exposed a subset of the underlying library's options. This meant users couldn't access advanced features like authentication, SSL, compression, or custom headers without creating their own client instances. Now, the configuration types extend the library types directly, so all options are available.
58
+
59
+ **@mastra/libsql** (Breaking)
60
+
61
+ Renamed `connectionUrl` to `url` to match the `@libsql/client` API and align with LibSQLStorage.
62
+
63
+ ```typescript
64
+ // Before
65
+ new LibSQLVector({ id: 'my-vector', connectionUrl: 'file:./db.sqlite' });
66
+
67
+ // After
68
+ new LibSQLVector({ id: 'my-vector', url: 'file:./db.sqlite' });
69
+ ```
70
+
71
+ **@mastra/opensearch** (Breaking)
72
+
73
+ Renamed `url` to `node` and added support for all OpenSearch `ClientOptions` including authentication, SSL, and compression.
74
+
75
+ ```typescript
76
+ // Before
77
+ new OpenSearchVector({ id: 'my-vector', url: 'http://localhost:9200' });
78
+
79
+ // After
80
+ new OpenSearchVector({ id: 'my-vector', node: 'http://localhost:9200' });
81
+
82
+ // With authentication (now possible)
83
+ new OpenSearchVector({
84
+ id: 'my-vector',
85
+ node: 'https://localhost:9200',
86
+ auth: { username: 'admin', password: 'admin' },
87
+ ssl: { rejectUnauthorized: false },
88
+ });
89
+ ```
90
+
91
+ **@mastra/pinecone** (Breaking)
92
+
93
+ Removed `environment` parameter. Use `controllerHostUrl` instead (the actual Pinecone SDK field name). Added support for all `PineconeConfiguration` options.
94
+
95
+ ```typescript
96
+ // Before
97
+ new PineconeVector({ id: 'my-vector', apiKey: '...', environment: '...' });
98
+
99
+ // After
100
+ new PineconeVector({ id: 'my-vector', apiKey: '...' });
101
+
102
+ // With custom controller host (if needed)
103
+ new PineconeVector({ id: 'my-vector', apiKey: '...', controllerHostUrl: '...' });
104
+ ```
105
+
106
+ **@mastra/clickhouse**
107
+
108
+ Added support for all `ClickHouseClientConfigOptions` like `request_timeout`, `compression`, `keep_alive`, and `database`. Existing configurations continue to work unchanged.
109
+
110
+ **@mastra/cloudflare, @mastra/cloudflare-d1, @mastra/lance, @mastra/libsql, @mastra/mongodb, @mastra/pg, @mastra/upstash**
111
+
112
+ Improved logging by replacing `console.warn` with structured logger in workflow storage domains.
113
+
114
+ **@mastra/deployer-cloud**
115
+
116
+ Updated internal LibSQLVector configuration for compatibility with the new API.
117
+
118
+ - Updated dependencies [[`ebae12a`](https://github.com/mastra-ai/mastra/commit/ebae12a2dd0212e75478981053b148a2c246962d), [`c61a0a5`](https://github.com/mastra-ai/mastra/commit/c61a0a5de4904c88fd8b3718bc26d1be1c2ec6e7), [`69136e7`](https://github.com/mastra-ai/mastra/commit/69136e748e32f57297728a4e0f9a75988462f1a7), [`449aed2`](https://github.com/mastra-ai/mastra/commit/449aed2ba9d507b75bf93d427646ea94f734dfd1), [`eb648a2`](https://github.com/mastra-ai/mastra/commit/eb648a2cc1728f7678768dd70cd77619b448dab9), [`0131105`](https://github.com/mastra-ai/mastra/commit/0131105532e83bdcbb73352fc7d0879eebf140dc), [`9d5059e`](https://github.com/mastra-ai/mastra/commit/9d5059eae810829935fb08e81a9bb7ecd5b144a7), [`ef756c6`](https://github.com/mastra-ai/mastra/commit/ef756c65f82d16531c43f49a27290a416611e526), [`b00ccd3`](https://github.com/mastra-ai/mastra/commit/b00ccd325ebd5d9e37e34dd0a105caae67eb568f), [`3bdfa75`](https://github.com/mastra-ai/mastra/commit/3bdfa7507a91db66f176ba8221aa28dd546e464a), [`e770de9`](https://github.com/mastra-ai/mastra/commit/e770de941a287a49b1964d44db5a5763d19890a6), [`52e2716`](https://github.com/mastra-ai/mastra/commit/52e2716b42df6eff443de72360ae83e86ec23993), [`27b4040`](https://github.com/mastra-ai/mastra/commit/27b4040bfa1a95d92546f420a02a626b1419a1d6), [`610a70b`](https://github.com/mastra-ai/mastra/commit/610a70bdad282079f0c630e0d7bb284578f20151), [`8dc7f55`](https://github.com/mastra-ai/mastra/commit/8dc7f55900395771da851dc7d78d53ae84fe34ec), [`8379099`](https://github.com/mastra-ai/mastra/commit/8379099fc467af6bef54dd7f80c9bd75bf8bbddf), [`8c0ec25`](https://github.com/mastra-ai/mastra/commit/8c0ec25646c8a7df253ed1e5ff4863a0d3f1316c), [`ff4d9a6`](https://github.com/mastra-ai/mastra/commit/ff4d9a6704fc87b31a380a76ed22736fdedbba5a), [`69821ef`](https://github.com/mastra-ai/mastra/commit/69821ef806482e2c44e2197ac0b050c3fe3a5285), [`1ed5716`](https://github.com/mastra-ai/mastra/commit/1ed5716830867b3774c4a1b43cc0d82935f32b96), [`4186bdd`](https://github.com/mastra-ai/mastra/commit/4186bdd00731305726fa06adba0b076a1d50b49f), [`7aaf973`](https://github.com/mastra-ai/mastra/commit/7aaf973f83fbbe9521f1f9e7a4fd99b8de464617)]:
119
+ - @mastra/core@1.0.0-beta.22
120
+
3
121
  ## 1.0.0-beta.10
4
122
 
5
123
  ### Patch Changes
@@ -31,4 +31,4 @@ docs/
31
31
  ## Version
32
32
 
33
33
  Package: @mastra/upstash
34
- Version: 1.0.0-beta.10
34
+ Version: 1.0.0-beta.12
@@ -5,7 +5,7 @@ description: Documentation for @mastra/upstash. Includes links to type definitio
5
5
 
6
6
  # @mastra/upstash Documentation
7
7
 
8
- > **Version**: 1.0.0-beta.10
8
+ > **Version**: 1.0.0-beta.12
9
9
  > **Package**: @mastra/upstash
10
10
 
11
11
  ## Quick Navigation
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-beta.10",
2
+ "version": "1.0.0-beta.12",
3
3
  "package": "@mastra/upstash",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -80,13 +80,15 @@ const memory = new Memory({
80
80
 
81
81
  ### Usage with Agents
82
82
 
83
- When using resource-scoped memory, make sure to pass the `resourceId` parameter:
83
+ When using resource-scoped memory, make sure to pass the `resource` parameter in the memory options:
84
84
 
85
85
  ```typescript
86
- // Resource-scoped memory requires resourceId
86
+ // Resource-scoped memory requires resource
87
87
  const response = await agent.generate("Hello!", {
88
- threadId: "conversation-123",
89
- resourceId: "user-alice-456", // Same user across different threads
88
+ memory: {
89
+ thread: "conversation-123",
90
+ resource: "user-alice-456", // Same user across different threads
91
+ },
90
92
  });
91
93
  ```
92
94
 
@@ -339,8 +341,10 @@ const thread = await memory.createThread({
339
341
 
340
342
  // The agent will now have access to this information in all messages
341
343
  await agent.generate("What's my blood type?", {
342
- threadId: thread.id,
343
- resourceId: "user-456",
344
+ memory: {
345
+ thread: thread.id,
346
+ resource: "user-456",
347
+ },
344
348
  });
345
349
  // Response: "Your blood type is O+."
346
350
  ```
@@ -12,6 +12,7 @@ After generating embeddings, you need to store them in a database that supports
12
12
  import { MongoDBVector } from "@mastra/mongodb";
13
13
 
14
14
  const store = new MongoDBVector({
15
+ id: 'mongodb-vector',
15
16
  uri: process.env.MONGODB_URI,
16
17
  dbName: process.env.MONGODB_DATABASE,
17
18
  });
@@ -26,7 +27,7 @@ await store.upsert({
26
27
  });
27
28
  ```
28
29
 
29
- ### Using MongoDB Atlas Vector search
30
+ <h3>Using MongoDB Atlas Vector search</h3>
30
31
 
31
32
  For detailed setup instructions and best practices, see the [official MongoDB Atlas Vector Search documentation](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-overview/?utm_campaign=devrel&utm_source=third-party-content&utm_medium=cta&utm_content=mastra-docs).
32
33
 
@@ -54,7 +55,7 @@ await store.upsert({
54
55
  });
55
56
  ```
56
57
 
57
- ### Using PostgreSQL with pgvector
58
+ <h3>Using PostgreSQL with pgvector</h3>
58
59
 
59
60
  PostgreSQL with the pgvector extension is a good solution for teams already using PostgreSQL who want to minimize infrastructure complexity.
60
61
  For detailed setup instructions and best practices, see the [official pgvector repository](https://github.com/pgvector/pgvector).
@@ -144,6 +145,7 @@ await store.upsert({
144
145
  import { AstraVector } from "@mastra/astra";
145
146
 
146
147
  const store = new AstraVector({
148
+ id: 'astra-vector',
147
149
  token: process.env.ASTRA_DB_TOKEN,
148
150
  endpoint: process.env.ASTRA_DB_ENDPOINT,
149
151
  keyspace: process.env.ASTRA_DB_KEYSPACE,
@@ -170,7 +172,7 @@ import { LibSQLVector } from "@mastra/core/vector/libsql";
170
172
 
171
173
  const store = new LibSQLVector({
172
174
  id: 'libsql-vector',
173
- connectionUrl: process.env.DATABASE_URL,
175
+ url: process.env.DATABASE_URL,
174
176
  authToken: process.env.DATABASE_AUTH_TOKEN, // Optional: for Turso cloud databases
175
177
  });
176
178
 
@@ -217,6 +219,7 @@ await store.upsert({
217
219
  import { CloudflareVector } from "@mastra/vectorize";
218
220
 
219
221
  const store = new CloudflareVector({
222
+ id: 'cloudflare-vector',
220
223
  accountId: process.env.CF_ACCOUNT_ID,
221
224
  apiToken: process.env.CF_API_TOKEN,
222
225
  });
@@ -238,7 +241,7 @@ await store.upsert({
238
241
  ```ts title="vector-store.ts"
239
242
  import { OpenSearchVector } from "@mastra/opensearch";
240
243
 
241
- const store = new OpenSearchVector({ url: process.env.OPENSEARCH_URL });
244
+ const store = new OpenSearchVector({ id: "opensearch", node: process.env.OPENSEARCH_URL });
242
245
 
243
246
  await store.createIndex({
244
247
  indexName: "my-collection",
@@ -259,7 +262,7 @@ await store.upsert({
259
262
  ```ts title="vector-store.ts"
260
263
  import { ElasticSearchVector } from "@mastra/elasticsearch";
261
264
 
262
- const store = new ElasticSearchVector({ url: process.env.ELASTICSEARCH_URL });
265
+ const store = new ElasticSearchVector({ id: 'elasticsearch-vector', url: process.env.ELASTICSEARCH_URL });
263
266
 
264
267
  await store.createIndex({
265
268
  indexName: "my-collection",
@@ -280,6 +283,7 @@ await store.upsert({
280
283
  import { CouchbaseVector } from "@mastra/couchbase";
281
284
 
282
285
  const store = new CouchbaseVector({
286
+ id: 'couchbase-vector',
283
287
  connectionString: process.env.COUCHBASE_CONNECTION_STRING,
284
288
  username: process.env.COUCHBASE_USERNAME,
285
289
  password: process.env.COUCHBASE_PASSWORD,
@@ -319,7 +323,7 @@ await store.upsert({
319
323
  });
320
324
  ```
321
325
 
322
- ### Using LanceDB
326
+ <h3>Using LanceDB</h3>
323
327
 
324
328
  LanceDB is an embedded vector database built on the Lance columnar format, suitable for local development or cloud deployment.
325
329
  For detailed setup instructions and best practices, see the [official LanceDB documentation](https://lancedb.github.io/lancedb/).
@@ -331,6 +335,7 @@ For detailed setup instructions and best practices, see the [official LanceDB do
331
335
  import { S3Vectors } from "@mastra/s3vectors";
332
336
 
333
337
  const store = new S3Vectors({
338
+ id: 's3-vectors',
334
339
  vectorBucketName: "my-vector-bucket",
335
340
  clientConfig: {
336
341
  region: "us-east-1",
@@ -373,7 +378,7 @@ The dimension size must match the output dimension of your chosen embedding mode
373
378
  - Cohere embed-multilingual-v3: 1024 dimensions
374
379
  - Google text-embedding-004: 768 dimensions (or custom)
375
380
 
376
- important
381
+ > **Note:**
377
382
  Index dimensions cannot be changed after creation. To use a different model, delete and recreate the index with the new dimension size.
378
383
 
379
384
  ### Naming Rules for Databases
@@ -537,7 +542,7 @@ The upsert operation:
537
542
 
538
543
  Vector stores support rich metadata (any JSON-serializable fields) for filtering and organization. Since metadata is stored with no fixed schema, use consistent field naming to avoid unexpected query results.
539
544
 
540
- important
545
+ > **Note:**
541
546
  Metadata is crucial for vector storage - without it, you'd only have numerical embeddings with no way to return the original text or filter results. Always store at least the source text as metadata.
542
547
 
543
548
  ```ts
@@ -171,7 +171,7 @@ The Vector Query Tool supports database-specific configurations that enable you
171
171
  > **Note:**
172
172
  These configurations are for **query-time options** like namespaces, performance tuning, and filtering—not for database connection setup.
173
173
 
174
- Connection credentials (URLs, auth tokens) are configured when you instantiate the vector store class (e.g., `new LibSQLVector({ connectionUrl: '...' })`).
174
+ Connection credentials (URLs, auth tokens) are configured when you instantiate the vector store class (e.g., `new LibSQLVector({ url: '...' })`).
175
175
 
176
176
  ```ts
177
177
  import { createVectorQueryTool } from "@mastra/rag";
@@ -258,11 +258,10 @@ requestContext.set("databaseConfig", {
258
258
  },
259
259
  });
260
260
 
261
- await pineconeQueryTool.execute({
262
- context: { queryText: "search query" },
263
- mastra,
264
- requestContext,
265
- });
261
+ await pineconeQueryTool.execute(
262
+ { queryText: "search query" },
263
+ { mastra, requestContext }
264
+ );
266
265
  ```
267
266
 
268
267
  For detailed configuration options and advanced usage, see the [Vector Query Tool Reference](https://mastra.ai/reference/v1/tools/vector-query-tool).
package/dist/index.cjs CHANGED
@@ -192,19 +192,34 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
192
192
  );
193
193
  }
194
194
  }
195
- async listThreadsByResourceId(args) {
196
- const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
195
+ async listThreads(args) {
196
+ const { page = 0, perPage: perPageInput, orderBy, filter } = args;
197
197
  const { field, direction } = this.parseOrderBy(orderBy);
198
+ try {
199
+ this.validatePaginationInput(page, perPageInput ?? 100);
200
+ } catch (error$1) {
201
+ throw new error.MastraError(
202
+ {
203
+ id: storage.createStorageErrorId("UPSTASH", "LIST_THREADS", "INVALID_PAGE"),
204
+ domain: error.ErrorDomain.STORAGE,
205
+ category: error.ErrorCategory.USER,
206
+ details: { page, ...perPageInput !== void 0 && { perPage: perPageInput } }
207
+ },
208
+ error$1 instanceof Error ? error$1 : new Error("Invalid pagination parameters")
209
+ );
210
+ }
198
211
  const perPage = storage.normalizePerPage(perPageInput, 100);
199
- if (page < 0) {
212
+ try {
213
+ this.validateMetadataKeys(filter?.metadata);
214
+ } catch (error$1) {
200
215
  throw new error.MastraError(
201
216
  {
202
- id: storage.createStorageErrorId("UPSTASH", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
217
+ id: storage.createStorageErrorId("UPSTASH", "LIST_THREADS", "INVALID_METADATA_KEY"),
203
218
  domain: error.ErrorDomain.STORAGE,
204
219
  category: error.ErrorCategory.USER,
205
- details: { page }
220
+ details: { metadataKeys: filter?.metadata ? Object.keys(filter.metadata).join(", ") : "" }
206
221
  },
207
- new Error("page must be >= 0")
222
+ error$1 instanceof Error ? error$1 : new Error("Invalid metadata key")
208
223
  );
209
224
  }
210
225
  const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
@@ -212,19 +227,35 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
212
227
  let allThreads = [];
213
228
  const pattern = `${storage.TABLE_THREADS}:*`;
214
229
  const keys = await this.#db.scanKeys(pattern);
230
+ if (keys.length === 0) {
231
+ return {
232
+ threads: [],
233
+ total: 0,
234
+ page,
235
+ perPage: perPageForResponse,
236
+ hasMore: false
237
+ };
238
+ }
215
239
  const pipeline = this.client.pipeline();
216
240
  keys.forEach((key) => pipeline.get(key));
217
241
  const results = await pipeline.exec();
218
242
  for (let i = 0; i < results.length; i++) {
219
243
  const thread = results[i];
220
- if (thread && thread.resourceId === resourceId) {
221
- allThreads.push({
222
- ...thread,
223
- createdAt: storage.ensureDate(thread.createdAt),
224
- updatedAt: storage.ensureDate(thread.updatedAt),
225
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata
226
- });
244
+ if (!thread) continue;
245
+ if (filter?.resourceId && thread.resourceId !== filter.resourceId) {
246
+ continue;
247
+ }
248
+ if (filter?.metadata && Object.keys(filter.metadata).length > 0) {
249
+ const threadMetadata = typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata;
250
+ const matches = Object.entries(filter.metadata).every(([key, value]) => threadMetadata?.[key] === value);
251
+ if (!matches) continue;
227
252
  }
253
+ allThreads.push({
254
+ ...thread,
255
+ createdAt: storage.ensureDate(thread.createdAt),
256
+ updatedAt: storage.ensureDate(thread.updatedAt),
257
+ metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata
258
+ });
228
259
  }
229
260
  const sortedThreads = this.sortThreads(allThreads, field, direction);
230
261
  const total = sortedThreads.length;
@@ -241,11 +272,12 @@ var StoreMemoryUpstash = class extends storage.MemoryStorage {
241
272
  } catch (error$1) {
242
273
  const mastraError = new error.MastraError(
243
274
  {
244
- id: storage.createStorageErrorId("UPSTASH", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
275
+ id: storage.createStorageErrorId("UPSTASH", "LIST_THREADS", "FAILED"),
245
276
  domain: error.ErrorDomain.STORAGE,
246
277
  category: error.ErrorCategory.THIRD_PARTY,
247
278
  details: {
248
- resourceId,
279
+ ...filter?.resourceId && { resourceId: filter.resourceId },
280
+ hasMetadataFilter: !!filter?.metadata,
249
281
  page,
250
282
  perPage
251
283
  }
@@ -1381,24 +1413,6 @@ var ScoresUpstash = class extends storage.ScoresStorage {
1381
1413
  };
1382
1414
  }
1383
1415
  };
1384
- function parseWorkflowRun(row) {
1385
- let parsedSnapshot = row.snapshot;
1386
- if (typeof parsedSnapshot === "string") {
1387
- try {
1388
- parsedSnapshot = JSON.parse(row.snapshot);
1389
- } catch (e) {
1390
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1391
- }
1392
- }
1393
- return {
1394
- workflowName: row.workflow_name,
1395
- runId: row.run_id,
1396
- snapshot: parsedSnapshot,
1397
- createdAt: storage.ensureDate(row.createdAt),
1398
- updatedAt: storage.ensureDate(row.updatedAt),
1399
- resourceId: row.resourceId
1400
- };
1401
- }
1402
1416
  var WorkflowsUpstash = class extends storage.WorkflowsStorage {
1403
1417
  client;
1404
1418
  #db;
@@ -1408,6 +1422,24 @@ var WorkflowsUpstash = class extends storage.WorkflowsStorage {
1408
1422
  this.client = client;
1409
1423
  this.#db = new UpstashDB({ client });
1410
1424
  }
1425
+ parseWorkflowRun(row) {
1426
+ let parsedSnapshot = row.snapshot;
1427
+ if (typeof parsedSnapshot === "string") {
1428
+ try {
1429
+ parsedSnapshot = JSON.parse(row.snapshot);
1430
+ } catch (e) {
1431
+ this.logger.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1432
+ }
1433
+ }
1434
+ return {
1435
+ workflowName: row.workflow_name,
1436
+ runId: row.run_id,
1437
+ snapshot: parsedSnapshot,
1438
+ createdAt: storage.ensureDate(row.createdAt),
1439
+ updatedAt: storage.ensureDate(row.updatedAt),
1440
+ resourceId: row.resourceId
1441
+ };
1442
+ }
1411
1443
  async dangerouslyClearAll() {
1412
1444
  await this.#db.deleteData({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT });
1413
1445
  }
@@ -1573,7 +1605,7 @@ var WorkflowsUpstash = class extends storage.WorkflowsStorage {
1573
1605
  );
1574
1606
  const data = workflows.find((w) => w?.run_id === runId && w?.workflow_name === workflowName);
1575
1607
  if (!data) return null;
1576
- return parseWorkflowRun(data);
1608
+ return this.parseWorkflowRun(data);
1577
1609
  } catch (error$1) {
1578
1610
  throw new error.MastraError(
1579
1611
  {
@@ -1658,7 +1690,7 @@ var WorkflowsUpstash = class extends storage.WorkflowsStorage {
1658
1690
  const results = await pipeline.exec();
1659
1691
  let runs = results.map((result) => result).filter(
1660
1692
  (record) => record !== null && record !== void 0 && typeof record === "object" && "workflow_name" in record
1661
- ).filter((record) => !workflowName || record.workflow_name === workflowName).map((w) => parseWorkflowRun(w)).filter((w) => {
1693
+ ).filter((record) => !workflowName || record.workflow_name === workflowName).map((w) => this.parseWorkflowRun(w)).filter((w) => {
1662
1694
  if (fromDate && w.createdAt < fromDate) return false;
1663
1695
  if (toDate && w.createdAt > toDate) return false;
1664
1696
  if (status) {
@@ -1667,7 +1699,7 @@ var WorkflowsUpstash = class extends storage.WorkflowsStorage {
1667
1699
  try {
1668
1700
  snapshot = JSON.parse(snapshot);
1669
1701
  } catch (e) {
1670
- console.warn(`Failed to parse snapshot for workflow ${w.workflowName}: ${e}`);
1702
+ this.logger.warn(`Failed to parse snapshot for workflow ${w.workflowName}: ${e}`);
1671
1703
  return false;
1672
1704
  }
1673
1705
  }