@mastra/cloudflare 0.0.0-vnextWorkflows-20250422142014 → 0.0.0-workflow-deno-20250616132510

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/dist/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var agent = require('@mastra/core/agent');
3
4
  var storage = require('@mastra/core/storage');
4
5
  var Cloudflare = require('cloudflare');
5
6
 
@@ -63,7 +64,8 @@ var CloudflareStore = class extends storage.MastraStorage {
63
64
  this.logger.info("Using Cloudflare KV REST API");
64
65
  }
65
66
  } catch (error) {
66
- this.logger.error("Failed to initialize CloudflareStore:", { error });
67
+ const message = error instanceof Error ? error.message : String(error);
68
+ this.logger.error("Failed to initialize CloudflareStore:", { message });
67
69
  throw error;
68
70
  }
69
71
  }
@@ -85,7 +87,25 @@ var CloudflareStore = class extends storage.MastraStorage {
85
87
  }))
86
88
  };
87
89
  }
88
- return await this.client.kv.namespaces.list({ account_id: this.accountId });
90
+ let allNamespaces = [];
91
+ let currentPage = 1;
92
+ const perPage = 50;
93
+ let morePagesExist = true;
94
+ while (morePagesExist) {
95
+ const response = await this.client.kv.namespaces.list({
96
+ account_id: this.accountId,
97
+ page: currentPage,
98
+ per_page: perPage
99
+ });
100
+ if (response.result) {
101
+ allNamespaces = allNamespaces.concat(response.result);
102
+ }
103
+ morePagesExist = response.result ? response.result.length === perPage : false;
104
+ if (morePagesExist) {
105
+ currentPage++;
106
+ }
107
+ }
108
+ return { result: allNamespaces };
89
109
  }
90
110
  async getNamespaceValue(tableName, key) {
91
111
  try {
@@ -105,7 +125,8 @@ var CloudflareStore = class extends storage.MastraStorage {
105
125
  if (error.message && error.message.includes("key not found")) {
106
126
  return null;
107
127
  }
108
- this.logger.error(`Failed to get value for ${tableName} ${key}:`, { error });
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ this.logger.error(`Failed to get value for ${tableName} ${key}:`, { message });
109
130
  throw error;
110
131
  }
111
132
  }
@@ -130,7 +151,8 @@ var CloudflareStore = class extends storage.MastraStorage {
130
151
  });
131
152
  }
132
153
  } catch (error) {
133
- this.logger.error(`Failed to put value for ${tableName} ${key}:`, { error });
154
+ const message = error instanceof Error ? error.message : String(error);
155
+ this.logger.error(`Failed to put value for ${tableName} ${key}:`, { message });
134
156
  throw error;
135
157
  }
136
158
  }
@@ -216,18 +238,57 @@ var CloudflareStore = class extends storage.MastraStorage {
216
238
  async getNamespaceId(tableName) {
217
239
  const prefix = this.namespacePrefix ? `${this.namespacePrefix}_` : "";
218
240
  try {
219
- if (tableName === storage.TABLE_MESSAGES || tableName === storage.TABLE_THREADS) {
220
- return await this.getOrCreateNamespaceId(`${prefix}mastra_threads`);
221
- } else if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
222
- return await this.getOrCreateNamespaceId(`${prefix}mastra_workflows`);
223
- } else {
224
- return await this.getOrCreateNamespaceId(`${prefix}mastra_evals`);
241
+ const legacyNamespaceId = await this.checkLegacyNamespace(tableName, prefix);
242
+ if (legacyNamespaceId) {
243
+ return legacyNamespaceId;
225
244
  }
245
+ return await this.getOrCreateNamespaceId(`${prefix}${tableName}`);
226
246
  } catch (error) {
227
247
  this.logger.error("Error fetching namespace ID:", error);
228
248
  throw new Error(`Failed to fetch namespace ID for table ${tableName}: ${error.message}`);
229
249
  }
230
250
  }
251
+ LEGACY_NAMESPACE_MAP = {
252
+ [storage.TABLE_MESSAGES]: storage.TABLE_THREADS,
253
+ [storage.TABLE_WORKFLOW_SNAPSHOT]: "mastra_workflows",
254
+ [storage.TABLE_TRACES]: storage.TABLE_EVALS
255
+ };
256
+ /**
257
+ * There were a few legacy mappings for tables such as
258
+ * - messages -> threads
259
+ * - workflow_snapshot -> mastra_workflows
260
+ * - traces -> evals
261
+ * This has been updated to use dedicated namespaces for each table.
262
+ * In the case of data for a table existing in the legacy namespace, warn the user to migrate to the new namespace.
263
+ *
264
+ * @param tableName The table name to check for legacy data
265
+ * @param prefix The namespace prefix
266
+ * @returns The legacy namespace ID if data exists; otherwise, null
267
+ */
268
+ async checkLegacyNamespace(tableName, prefix) {
269
+ const legacyNamespaceBase = this.LEGACY_NAMESPACE_MAP[tableName];
270
+ if (legacyNamespaceBase) {
271
+ const legacyNamespace = `${prefix}${legacyNamespaceBase}`;
272
+ const keyPrefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
273
+ const prefixKey = `${keyPrefix}${tableName}:`;
274
+ const legacyId = await this.getNamespaceIdByName(legacyNamespace);
275
+ if (legacyId) {
276
+ const response = await this.client.kv.namespaces.keys.list(legacyId, {
277
+ account_id: this.accountId,
278
+ prefix: prefixKey
279
+ });
280
+ const keys = response.result;
281
+ const hasTableData = keys.length > 0;
282
+ if (hasTableData) {
283
+ this.logger.warn(
284
+ `Using legacy namespace "${legacyNamespace}" for ${tableName}. Consider migrating to a dedicated namespace "${prefix}${tableName}".`
285
+ );
286
+ return legacyId;
287
+ }
288
+ }
289
+ }
290
+ return null;
291
+ }
231
292
  /**
232
293
  * Helper to safely serialize data for KV storage
233
294
  */
@@ -253,7 +314,8 @@ var CloudflareStore = class extends storage.MastraStorage {
253
314
  }
254
315
  return data;
255
316
  } catch (error) {
256
- this.logger.error("Failed to parse text:", { error, text });
317
+ const message = error instanceof Error ? error.message : String(error);
318
+ this.logger.error("Failed to parse text:", { message, text });
257
319
  return null;
258
320
  }
259
321
  }
@@ -287,9 +349,9 @@ var CloudflareStore = class extends storage.MastraStorage {
287
349
  throw new Error(`Failed to delete KV value: ${error.message}`);
288
350
  }
289
351
  }
290
- async listKV(tableName) {
352
+ async listKV(tableName, options) {
291
353
  try {
292
- return await this.listNamespaceKeys(tableName);
354
+ return await this.listNamespaceKeys(tableName, options);
293
355
  } catch (error) {
294
356
  this.logger.error(`Failed to list KV for ${tableName}:`, error);
295
357
  throw new Error(`Failed to list KV: ${error.message}`);
@@ -362,7 +424,8 @@ var CloudflareStore = class extends storage.MastraStorage {
362
424
  if (!data) return null;
363
425
  return typeof data === "string" ? JSON.parse(data) : data;
364
426
  } catch (error) {
365
- this.logger.error(`Error retrieving message ${id}:`, { error });
427
+ const message = error instanceof Error ? error.message : String(error);
428
+ this.logger.error(`Error retrieving message ${id}:`, { message });
366
429
  return null;
367
430
  }
368
431
  })
@@ -395,7 +458,8 @@ var CloudflareStore = class extends storage.MastraStorage {
395
458
  value: JSON.stringify(updatedOrder)
396
459
  });
397
460
  } catch (error) {
398
- this.logger.error(`Error updating sorted order for key ${orderKey}:`, { error });
461
+ const message = error instanceof Error ? error.message : String(error);
462
+ this.logger.error(`Error updating sorted order for key ${orderKey}:`, { message });
399
463
  throw error;
400
464
  } finally {
401
465
  if (this.updateQueue.get(orderKey) === nextPromise) {
@@ -437,7 +501,11 @@ var CloudflareStore = class extends storage.MastraStorage {
437
501
  if (!record.namespace || !record.workflow_name || !record.run_id) {
438
502
  throw new Error("Namespace, workflow name, and run ID are required");
439
503
  }
440
- return `${prefix}${tableName}:${record.namespace}:${record.workflow_name}:${record.run_id}`;
504
+ let key = `${prefix}${tableName}:${record.namespace}:${record.workflow_name}:${record.run_id}`;
505
+ if (record.resourceId) {
506
+ key = `${key}:${record.resourceId}`;
507
+ }
508
+ return key;
441
509
  case storage.TABLE_TRACES:
442
510
  if (!record.id) throw new Error("Trace ID is required");
443
511
  return `${prefix}${tableName}:${record.id}`;
@@ -454,7 +522,8 @@ var CloudflareStore = class extends storage.MastraStorage {
454
522
  const schemaKey = this.getSchemaKey(tableName);
455
523
  return await this.getKV(tableName, schemaKey);
456
524
  } catch (error) {
457
- this.logger.error(`Failed to get schema for ${tableName}:`, { error });
525
+ const message = error instanceof Error ? error.message : String(error);
526
+ this.logger.error(`Failed to get schema for ${tableName}:`, { message });
458
527
  return null;
459
528
  }
460
529
  }
@@ -499,7 +568,8 @@ var CloudflareStore = class extends storage.MastraStorage {
499
568
  }
500
569
  }
501
570
  } catch (error) {
502
- this.logger.error(`Error validating record against schema:`, { error, record, schema });
571
+ const message = error instanceof Error ? error.message : String(error);
572
+ this.logger.error(`Error validating record against schema:`, { message, record, schema });
503
573
  throw error;
504
574
  }
505
575
  }
@@ -526,7 +596,7 @@ var CloudflareStore = class extends storage.MastraStorage {
526
596
  }
527
597
  break;
528
598
  case storage.TABLE_WORKFLOW_SNAPSHOT:
529
- if (!("namespace" in recordTyped) || !("workflowName" in recordTyped) || !("runId" in recordTyped)) {
599
+ if (!("namespace" in recordTyped) || !("workflow_name" in recordTyped) || !("run_id" in recordTyped)) {
530
600
  throw new Error("Workflow record missing required fields");
531
601
  }
532
602
  break;
@@ -539,19 +609,11 @@ var CloudflareStore = class extends storage.MastraStorage {
539
609
  throw new Error(`Unknown table type: ${tableName}`);
540
610
  }
541
611
  } catch (error) {
542
- this.logger.error(`Failed to validate record for ${tableName}:`, { error, record });
612
+ const message = error instanceof Error ? error.message : String(error);
613
+ this.logger.error(`Failed to validate record for ${tableName}:`, { message, record });
543
614
  throw error;
544
615
  }
545
616
  }
546
- ensureDate(date) {
547
- if (!date) return void 0;
548
- return date instanceof Date ? date : new Date(date);
549
- }
550
- serializeDate(date) {
551
- if (!date) return void 0;
552
- const dateObj = this.ensureDate(date);
553
- return dateObj?.toISOString();
554
- }
555
617
  ensureMetadata(metadata) {
556
618
  if (!metadata) return {};
557
619
  return typeof metadata === "string" ? JSON.parse(metadata) : metadata;
@@ -573,13 +635,24 @@ var CloudflareStore = class extends storage.MastraStorage {
573
635
  throw new Error(`Failed to store schema: ${error.message}`);
574
636
  }
575
637
  }
638
+ /**
639
+ * No-op: This backend is schemaless and does not require schema changes.
640
+ * @param tableName Name of the table
641
+ * @param schema Schema of the table
642
+ * @param ifNotExists Array of column names to add if they don't exist
643
+ */
644
+ async alterTable(_args) {
645
+ }
576
646
  async clearTable({ tableName }) {
577
647
  const keys = await this.listKV(tableName);
578
648
  if (keys.length > 0) {
579
649
  await Promise.all(keys.map((keyObj) => this.deleteKV(tableName, keyObj.name)));
580
650
  }
581
651
  }
582
- async insert({ tableName, record }) {
652
+ async insert({
653
+ tableName,
654
+ record
655
+ }) {
583
656
  try {
584
657
  const key = this.getKey(tableName, record);
585
658
  const processedRecord = {
@@ -591,7 +664,8 @@ var CloudflareStore = class extends storage.MastraStorage {
591
664
  await this.validateRecord(processedRecord, tableName);
592
665
  await this.putKV({ tableName, key, value: processedRecord });
593
666
  } catch (error) {
594
- this.logger.error(`Failed to insert record for ${tableName}:`, { error });
667
+ const message = error instanceof Error ? error.message : String(error);
668
+ this.logger.error(`Failed to insert record for ${tableName}:`, { message });
595
669
  throw error;
596
670
  }
597
671
  }
@@ -608,7 +682,9 @@ var CloudflareStore = class extends storage.MastraStorage {
608
682
  };
609
683
  return processed;
610
684
  } catch (error) {
611
- this.logger.error(`Failed to load data for ${tableName}:`, { error });
685
+ this.logger.error(`Failed to load data for ${tableName}:`, {
686
+ error: error instanceof Error ? error.message : String(error)
687
+ });
612
688
  return null;
613
689
  }
614
690
  }
@@ -623,7 +699,9 @@ var CloudflareStore = class extends storage.MastraStorage {
623
699
  metadata: this.ensureMetadata(thread.metadata)
624
700
  };
625
701
  } catch (error) {
626
- this.logger.error(`Error processing thread ${threadId}:`, { error });
702
+ this.logger.error(`Error processing thread ${threadId}:`, {
703
+ error: error instanceof Error ? error.message : String(error)
704
+ });
627
705
  return null;
628
706
  }
629
707
  }
@@ -644,14 +722,16 @@ var CloudflareStore = class extends storage.MastraStorage {
644
722
  metadata: this.ensureMetadata(thread.metadata)
645
723
  };
646
724
  } catch (error) {
647
- this.logger.error(`Error processing thread from key ${keyObj.name}:`, { error });
725
+ const message = error instanceof Error ? error.message : String(error);
726
+ this.logger.error(`Error processing thread from key ${keyObj.name}:`, { message });
648
727
  return null;
649
728
  }
650
729
  })
651
730
  );
652
731
  return threads.filter((thread) => thread !== null);
653
732
  } catch (error) {
654
- this.logger.error(`Error getting threads for resourceId ${resourceId}:`, { error });
733
+ const message = error instanceof Error ? error.message : String(error);
734
+ this.logger.error(`Error getting threads for resourceId ${resourceId}:`, { message });
655
735
  return [];
656
736
  }
657
737
  }
@@ -660,7 +740,8 @@ var CloudflareStore = class extends storage.MastraStorage {
660
740
  await this.insert({ tableName: storage.TABLE_THREADS, record: thread });
661
741
  return thread;
662
742
  } catch (error) {
663
- this.logger.error("Error saving thread:", { error });
743
+ const message = error instanceof Error ? error.message : String(error);
744
+ this.logger.error("Error saving thread:", { message });
664
745
  throw error;
665
746
  }
666
747
  }
@@ -686,7 +767,8 @@ var CloudflareStore = class extends storage.MastraStorage {
686
767
  await this.insert({ tableName: storage.TABLE_THREADS, record: updatedThread });
687
768
  return updatedThread;
688
769
  } catch (error) {
689
- this.logger.error(`Error updating thread ${id}:`, { error });
770
+ const message = error instanceof Error ? error.message : String(error);
771
+ this.logger.error(`Error updating thread ${id}:`, { message });
690
772
  throw error;
691
773
  }
692
774
  }
@@ -707,7 +789,8 @@ var CloudflareStore = class extends storage.MastraStorage {
707
789
  this.deleteKV(storage.TABLE_THREADS, this.getKey(storage.TABLE_THREADS, { id: threadId }))
708
790
  ]);
709
791
  } catch (error) {
710
- this.logger.error(`Error deleting thread ${threadId}:`, { error });
792
+ const message = error instanceof Error ? error.message : String(error);
793
+ this.logger.error(`Error deleting thread ${threadId}:`, { message });
711
794
  throw error;
712
795
  }
713
796
  }
@@ -715,7 +798,8 @@ var CloudflareStore = class extends storage.MastraStorage {
715
798
  try {
716
799
  return this.getKey(storage.TABLE_MESSAGES, { threadId, id: messageId });
717
800
  } catch (error) {
718
- this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { error });
801
+ const message = error instanceof Error ? error.message : String(error);
802
+ this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
719
803
  throw error;
720
804
  }
721
805
  }
@@ -723,11 +807,13 @@ var CloudflareStore = class extends storage.MastraStorage {
723
807
  try {
724
808
  return this.getKey(storage.TABLE_MESSAGES, { threadId, id: "messages" });
725
809
  } catch (error) {
726
- this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { error });
810
+ const message = error instanceof Error ? error.message : String(error);
811
+ this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { message });
727
812
  throw error;
728
813
  }
729
814
  }
730
- async saveMessages({ messages }) {
815
+ async saveMessages(args) {
816
+ const { messages, format = "v1" } = args;
731
817
  if (!Array.isArray(messages) || messages.length === 0) return [];
732
818
  try {
733
819
  const validatedMessages = messages.map((message, index) => {
@@ -743,15 +829,17 @@ var CloudflareStore = class extends storage.MastraStorage {
743
829
  return {
744
830
  ...message,
745
831
  createdAt: this.ensureDate(message.createdAt),
746
- type: message.type || "text",
832
+ type: message.type || "v2",
747
833
  _index: index
748
834
  };
749
835
  });
750
836
  const messagesByThread = validatedMessages.reduce((acc, message) => {
751
- if (!acc.has(message.threadId)) {
837
+ if (message.threadId && !acc.has(message.threadId)) {
752
838
  acc.set(message.threadId, []);
753
839
  }
754
- acc.get(message.threadId).push(message);
840
+ if (message.threadId) {
841
+ acc.get(message.threadId).push(message);
842
+ }
755
843
  return acc;
756
844
  }, /* @__PURE__ */ new Map());
757
845
  await Promise.all(
@@ -763,7 +851,7 @@ var CloudflareStore = class extends storage.MastraStorage {
763
851
  }
764
852
  await Promise.all(
765
853
  threadMessages.map(async (message) => {
766
- const key = await this.getMessageKey(threadId, message.id);
854
+ const key = this.getMessageKey(threadId, message.id);
767
855
  const { _index, ...cleanMessage } = message;
768
856
  const serializedMessage = {
769
857
  ...cleanMessage,
@@ -782,14 +870,24 @@ var CloudflareStore = class extends storage.MastraStorage {
782
870
  }
783
871
  })
784
872
  );
785
- return validatedMessages.map(({ _index, ...message }) => message);
873
+ const prepared = validatedMessages.map(
874
+ ({ _index, ...message }) => ({ ...message, type: message.type !== "v2" ? message.type : void 0 })
875
+ );
876
+ const list = new agent.MessageList().add(prepared, "memory");
877
+ if (format === `v2`) return list.get.all.v2();
878
+ return list.get.all.v1();
786
879
  } catch (error) {
787
880
  const errorMessage = error instanceof Error ? error.message : String(error);
788
881
  this.logger.error(`Error saving messages: ${errorMessage}`);
789
882
  throw error;
790
883
  }
791
884
  }
792
- async getMessages({ threadId, selectBy }) {
885
+ async getMessages({
886
+ threadId,
887
+ resourceId,
888
+ selectBy,
889
+ format
890
+ }) {
793
891
  if (!threadId) throw new Error("threadId is required");
794
892
  let limit = 40;
795
893
  if (typeof selectBy?.last === "number") {
@@ -821,10 +919,14 @@ var CloudflareStore = class extends storage.MastraStorage {
821
919
  this.logger.warn(`Error sorting messages, falling back to creation time: ${errorMessage}`);
822
920
  messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
823
921
  }
824
- return messages.map(({ _index, ...message }) => ({
922
+ const prepared = messages.map(({ _index, ...message }) => ({
825
923
  ...message,
924
+ type: message.type === `v2` ? void 0 : message.type,
826
925
  createdAt: this.ensureDate(message.createdAt)
827
926
  }));
927
+ const list = new agent.MessageList({ threadId, resourceId }).add(prepared, "memory");
928
+ if (format === `v1`) return list.get.all.v1();
929
+ return list.get.all.v2();
828
930
  } catch (error) {
829
931
  const errorMessage = error instanceof Error ? error.message : String(error);
830
932
  this.logger.error(`Error retrieving messages for thread ${threadId}: ${errorMessage}`);
@@ -838,7 +940,7 @@ var CloudflareStore = class extends storage.MastraStorage {
838
940
  }
839
941
  }
840
942
  validateWorkflowState(state) {
841
- if (!state?.runId || !state?.value || !state?.context?.steps || !state?.context?.triggerData || !state?.context?.attempts || !state?.activePaths) {
943
+ if (!state?.runId || !state?.value || !state?.context?.input || !state?.activePaths) {
842
944
  throw new Error("Invalid workflow state structure");
843
945
  }
844
946
  }
@@ -854,18 +956,17 @@ var CloudflareStore = class extends storage.MastraStorage {
854
956
  return normalizedSteps;
855
957
  }
856
958
  normalizeWorkflowState(data) {
857
- const steps = data.context?.stepResults || data.context?.steps || {};
858
959
  return {
859
960
  runId: data.runId,
860
961
  value: data.value,
861
- context: {
862
- steps: this.normalizeSteps(steps),
863
- triggerData: data.context?.triggerData || {},
864
- attempts: data.context?.attempts || {}
865
- },
866
- suspendedPaths: data.suspendedPaths || [],
962
+ context: data.context,
963
+ serializedStepGraph: data.serializedStepGraph,
964
+ suspendedPaths: data.suspendedPaths || {},
867
965
  activePaths: data.activePaths || [],
868
- timestamp: data.timestamp || Date.now()
966
+ timestamp: data.timestamp || Date.now(),
967
+ status: data.status,
968
+ result: data.result,
969
+ error: data.error
869
970
  };
870
971
  }
871
972
  async persistWorkflowSnapshot(params) {
@@ -874,10 +975,20 @@ var CloudflareStore = class extends storage.MastraStorage {
874
975
  const { namespace, workflowName, runId, snapshot } = params;
875
976
  const normalizedState = this.normalizeWorkflowState(snapshot);
876
977
  this.validateWorkflowState(normalizedState);
877
- const key = this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
878
- await this.putKV({ tableName: storage.TABLE_WORKFLOW_SNAPSHOT, key, value: normalizedState });
978
+ await this.insert({
979
+ tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
980
+ record: {
981
+ namespace,
982
+ workflow_name: workflowName,
983
+ run_id: runId,
984
+ snapshot: normalizedState,
985
+ createdAt: /* @__PURE__ */ new Date(),
986
+ updatedAt: /* @__PURE__ */ new Date()
987
+ }
988
+ });
879
989
  } catch (error) {
880
- this.logger.error("Error persisting workflow snapshot:", { error });
990
+ const message = error instanceof Error ? error.message : String(error);
991
+ this.logger.error("Error persisting workflow snapshot:", { message });
881
992
  throw error;
882
993
  }
883
994
  }
@@ -888,11 +999,13 @@ var CloudflareStore = class extends storage.MastraStorage {
888
999
  const key = this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
889
1000
  const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
890
1001
  if (!data) return null;
891
- const state = this.normalizeWorkflowState(data);
1002
+ const state = this.normalizeWorkflowState(data.snapshot || data);
892
1003
  this.validateWorkflowState(state);
893
1004
  return state;
894
1005
  } catch (error) {
895
- this.logger.error("Error loading workflow snapshot:", { error });
1006
+ this.logger.error("Error loading workflow snapshot:", {
1007
+ error: error instanceof Error ? error.message : String(error)
1008
+ });
896
1009
  return null;
897
1010
  }
898
1011
  }
@@ -912,7 +1025,8 @@ var CloudflareStore = class extends storage.MastraStorage {
912
1025
  })
913
1026
  );
914
1027
  } catch (error) {
915
- this.logger.error("Error in batch insert:", { error });
1028
+ const message = error instanceof Error ? error.message : String(error);
1029
+ this.logger.error("Error in batch insert:", { message });
916
1030
  throw error;
917
1031
  }
918
1032
  }
@@ -921,7 +1035,9 @@ var CloudflareStore = class extends storage.MastraStorage {
921
1035
  scope,
922
1036
  page = 0,
923
1037
  perPage = 100,
924
- attributes
1038
+ attributes,
1039
+ fromDate,
1040
+ toDate
925
1041
  }) {
926
1042
  try {
927
1043
  let keys;
@@ -960,6 +1076,12 @@ var CloudflareStore = class extends storage.MastraStorage {
960
1076
  return Object.entries(attributes).every(([key, value]) => recordAttrs[key] === value);
961
1077
  });
962
1078
  }
1079
+ if (fromDate) {
1080
+ filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() >= fromDate.getTime());
1081
+ }
1082
+ if (toDate) {
1083
+ filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() <= toDate.getTime());
1084
+ }
963
1085
  filteredTraces.sort((a, b) => {
964
1086
  const dateA = new Date(a.createdAt).getTime();
965
1087
  const dateB = new Date(b.createdAt).getTime();
@@ -985,7 +1107,8 @@ var CloudflareStore = class extends storage.MastraStorage {
985
1107
  createdAt: record.createdAt
986
1108
  }));
987
1109
  } catch (error) {
988
- this.logger.error("Failed to get traces:", { message: error instanceof Error ? error.message : String(error) });
1110
+ const message = error instanceof Error ? error.message : String(error);
1111
+ this.logger.error("Failed to get traces:", { message });
989
1112
  return [];
990
1113
  }
991
1114
  }
@@ -1002,7 +1125,123 @@ var CloudflareStore = class extends storage.MastraStorage {
1002
1125
  getEvalsByAgentName(_agentName, _type) {
1003
1126
  throw new Error("Method not implemented.");
1004
1127
  }
1005
- getWorkflowRuns(_args) {
1128
+ parseWorkflowRun(row) {
1129
+ let parsedSnapshot = row.snapshot;
1130
+ if (typeof parsedSnapshot === "string") {
1131
+ try {
1132
+ parsedSnapshot = JSON.parse(row.snapshot);
1133
+ } catch (e) {
1134
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1135
+ }
1136
+ }
1137
+ return {
1138
+ workflowName: row.workflow_name,
1139
+ runId: row.run_id,
1140
+ snapshot: parsedSnapshot,
1141
+ createdAt: this.ensureDate(row.createdAt),
1142
+ updatedAt: this.ensureDate(row.updatedAt),
1143
+ resourceId: row.resourceId
1144
+ };
1145
+ }
1146
+ buildWorkflowSnapshotPrefix({
1147
+ namespace,
1148
+ workflowName,
1149
+ runId,
1150
+ resourceId
1151
+ }) {
1152
+ const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
1153
+ let key = `${prefix}${storage.TABLE_WORKFLOW_SNAPSHOT}`;
1154
+ if (namespace) key += `:${namespace}`;
1155
+ if (workflowName) key += `:${workflowName}`;
1156
+ if (runId) key += `:${runId}`;
1157
+ if (resourceId) key += `:${resourceId}`;
1158
+ if (!resourceId && (runId || workflowName || namespace)) key += ":";
1159
+ return key;
1160
+ }
1161
+ async getWorkflowRuns({
1162
+ namespace,
1163
+ workflowName,
1164
+ limit = 20,
1165
+ offset = 0,
1166
+ resourceId,
1167
+ fromDate,
1168
+ toDate
1169
+ } = {}) {
1170
+ try {
1171
+ const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName });
1172
+ const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
1173
+ const runs = [];
1174
+ for (const { name: key } of keyObjs) {
1175
+ const parts = key.split(":");
1176
+ const idx = parts.indexOf(storage.TABLE_WORKFLOW_SNAPSHOT);
1177
+ if (idx === -1 || parts.length < idx + 4) continue;
1178
+ const ns = parts[idx + 1];
1179
+ const wfName = parts[idx + 2];
1180
+ const keyResourceId = parts.length > idx + 4 ? parts[idx + 4] : void 0;
1181
+ if (namespace && ns !== namespace || workflowName && wfName !== workflowName) continue;
1182
+ if (resourceId && keyResourceId && keyResourceId !== resourceId) continue;
1183
+ const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
1184
+ if (!data) continue;
1185
+ try {
1186
+ if (resourceId && data.resourceId && data.resourceId !== resourceId) continue;
1187
+ const createdAt = this.ensureDate(data.createdAt);
1188
+ if (fromDate && createdAt && createdAt < fromDate) continue;
1189
+ if (toDate && createdAt && createdAt > toDate) continue;
1190
+ const state = this.normalizeWorkflowState(data.snapshot || data);
1191
+ this.validateWorkflowState(state);
1192
+ const run = this.parseWorkflowRun({ ...data, snapshot: state });
1193
+ runs.push(run);
1194
+ } catch (err) {
1195
+ this.logger.error("Failed to parse workflow snapshot:", { key, error: err });
1196
+ }
1197
+ }
1198
+ runs.sort((a, b) => {
1199
+ const aDate = a.createdAt ? new Date(a.createdAt).getTime() : 0;
1200
+ const bDate = b.createdAt ? new Date(b.createdAt).getTime() : 0;
1201
+ return bDate - aDate;
1202
+ });
1203
+ const pagedRuns = runs.slice(offset, offset + limit);
1204
+ return {
1205
+ runs: pagedRuns,
1206
+ total: runs.length
1207
+ };
1208
+ } catch (error) {
1209
+ const message = error instanceof Error ? error.message : String(error);
1210
+ this.logger.error("Error in getWorkflowRuns:", { message });
1211
+ return { runs: [], total: 0 };
1212
+ }
1213
+ }
1214
+ async getWorkflowRunById({
1215
+ namespace,
1216
+ runId,
1217
+ workflowName
1218
+ }) {
1219
+ try {
1220
+ if (!runId || !workflowName || !namespace) {
1221
+ throw new Error("runId, workflowName, and namespace are required");
1222
+ }
1223
+ const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName, runId });
1224
+ const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
1225
+ if (!keyObjs.length) return null;
1226
+ const key = keyObjs[0]?.name;
1227
+ const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
1228
+ if (!data) return null;
1229
+ const state = this.normalizeWorkflowState(data.snapshot || data);
1230
+ this.validateWorkflowState(state);
1231
+ return this.parseWorkflowRun({ ...data, snapshot: state });
1232
+ } catch (error) {
1233
+ const message = error instanceof Error ? error.message : String(error);
1234
+ this.logger.error("Error in getWorkflowRunById:", { message });
1235
+ return null;
1236
+ }
1237
+ }
1238
+ async getTracesPaginated(_args) {
1239
+ throw new Error("Method not implemented.");
1240
+ }
1241
+ async getThreadsByResourceIdPaginated(_args) {
1242
+ throw new Error("Method not implemented.");
1243
+ }
1244
+ async getMessagesPaginated(_args) {
1006
1245
  throw new Error("Method not implemented.");
1007
1246
  }
1008
1247
  async close() {