@mastra/cloudflare 0.0.0-vnextWorkflows-20250422142014 → 0.0.0-working-memory-per-user-20250620161509

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.js CHANGED
@@ -1,4 +1,5 @@
1
- import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES } from '@mastra/core/storage';
1
+ import { MessageList } from '@mastra/core/agent';
2
+ import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES, TABLE_RESOURCES } from '@mastra/core/storage';
2
3
  import Cloudflare from 'cloudflare';
3
4
 
4
5
  // src/storage/index.ts
@@ -21,7 +22,7 @@ var CloudflareStore = class extends MastraStorage {
21
22
  if (!config.bindings) {
22
23
  throw new Error("KV bindings are required when using Workers Binding API");
23
24
  }
24
- const requiredTables = [TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES];
25
+ const requiredTables = [TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES, TABLE_RESOURCES];
25
26
  for (const table of requiredTables) {
26
27
  if (!(table in config.bindings)) {
27
28
  throw new Error(`Missing KV binding for table: ${table}`);
@@ -57,7 +58,8 @@ var CloudflareStore = class extends MastraStorage {
57
58
  this.logger.info("Using Cloudflare KV REST API");
58
59
  }
59
60
  } catch (error) {
60
- this.logger.error("Failed to initialize CloudflareStore:", { error });
61
+ const message = error instanceof Error ? error.message : String(error);
62
+ this.logger.error("Failed to initialize CloudflareStore:", { message });
61
63
  throw error;
62
64
  }
63
65
  }
@@ -79,7 +81,25 @@ var CloudflareStore = class extends MastraStorage {
79
81
  }))
80
82
  };
81
83
  }
82
- return await this.client.kv.namespaces.list({ account_id: this.accountId });
84
+ let allNamespaces = [];
85
+ let currentPage = 1;
86
+ const perPage = 50;
87
+ let morePagesExist = true;
88
+ while (morePagesExist) {
89
+ const response = await this.client.kv.namespaces.list({
90
+ account_id: this.accountId,
91
+ page: currentPage,
92
+ per_page: perPage
93
+ });
94
+ if (response.result) {
95
+ allNamespaces = allNamespaces.concat(response.result);
96
+ }
97
+ morePagesExist = response.result ? response.result.length === perPage : false;
98
+ if (morePagesExist) {
99
+ currentPage++;
100
+ }
101
+ }
102
+ return { result: allNamespaces };
83
103
  }
84
104
  async getNamespaceValue(tableName, key) {
85
105
  try {
@@ -99,7 +119,8 @@ var CloudflareStore = class extends MastraStorage {
99
119
  if (error.message && error.message.includes("key not found")) {
100
120
  return null;
101
121
  }
102
- this.logger.error(`Failed to get value for ${tableName} ${key}:`, { error });
122
+ const message = error instanceof Error ? error.message : String(error);
123
+ this.logger.error(`Failed to get value for ${tableName} ${key}:`, { message });
103
124
  throw error;
104
125
  }
105
126
  }
@@ -124,7 +145,8 @@ var CloudflareStore = class extends MastraStorage {
124
145
  });
125
146
  }
126
147
  } catch (error) {
127
- this.logger.error(`Failed to put value for ${tableName} ${key}:`, { error });
148
+ const message = error instanceof Error ? error.message : String(error);
149
+ this.logger.error(`Failed to put value for ${tableName} ${key}:`, { message });
128
150
  throw error;
129
151
  }
130
152
  }
@@ -210,18 +232,57 @@ var CloudflareStore = class extends MastraStorage {
210
232
  async getNamespaceId(tableName) {
211
233
  const prefix = this.namespacePrefix ? `${this.namespacePrefix}_` : "";
212
234
  try {
213
- if (tableName === TABLE_MESSAGES || tableName === TABLE_THREADS) {
214
- return await this.getOrCreateNamespaceId(`${prefix}mastra_threads`);
215
- } else if (tableName === TABLE_WORKFLOW_SNAPSHOT) {
216
- return await this.getOrCreateNamespaceId(`${prefix}mastra_workflows`);
217
- } else {
218
- return await this.getOrCreateNamespaceId(`${prefix}mastra_evals`);
235
+ const legacyNamespaceId = await this.checkLegacyNamespace(tableName, prefix);
236
+ if (legacyNamespaceId) {
237
+ return legacyNamespaceId;
219
238
  }
239
+ return await this.getOrCreateNamespaceId(`${prefix}${tableName}`);
220
240
  } catch (error) {
221
241
  this.logger.error("Error fetching namespace ID:", error);
222
242
  throw new Error(`Failed to fetch namespace ID for table ${tableName}: ${error.message}`);
223
243
  }
224
244
  }
245
+ LEGACY_NAMESPACE_MAP = {
246
+ [TABLE_MESSAGES]: TABLE_THREADS,
247
+ [TABLE_WORKFLOW_SNAPSHOT]: "mastra_workflows",
248
+ [TABLE_TRACES]: TABLE_EVALS
249
+ };
250
+ /**
251
+ * There were a few legacy mappings for tables such as
252
+ * - messages -> threads
253
+ * - workflow_snapshot -> mastra_workflows
254
+ * - traces -> evals
255
+ * This has been updated to use dedicated namespaces for each table.
256
+ * In the case of data for a table existing in the legacy namespace, warn the user to migrate to the new namespace.
257
+ *
258
+ * @param tableName The table name to check for legacy data
259
+ * @param prefix The namespace prefix
260
+ * @returns The legacy namespace ID if data exists; otherwise, null
261
+ */
262
+ async checkLegacyNamespace(tableName, prefix) {
263
+ const legacyNamespaceBase = this.LEGACY_NAMESPACE_MAP[tableName];
264
+ if (legacyNamespaceBase) {
265
+ const legacyNamespace = `${prefix}${legacyNamespaceBase}`;
266
+ const keyPrefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
267
+ const prefixKey = `${keyPrefix}${tableName}:`;
268
+ const legacyId = await this.getNamespaceIdByName(legacyNamespace);
269
+ if (legacyId) {
270
+ const response = await this.client.kv.namespaces.keys.list(legacyId, {
271
+ account_id: this.accountId,
272
+ prefix: prefixKey
273
+ });
274
+ const keys = response.result;
275
+ const hasTableData = keys.length > 0;
276
+ if (hasTableData) {
277
+ this.logger.warn(
278
+ `Using legacy namespace "${legacyNamespace}" for ${tableName}. Consider migrating to a dedicated namespace "${prefix}${tableName}".`
279
+ );
280
+ return legacyId;
281
+ }
282
+ }
283
+ }
284
+ return null;
285
+ }
225
286
  /**
226
287
  * Helper to safely serialize data for KV storage
227
288
  */
@@ -247,7 +308,8 @@ var CloudflareStore = class extends MastraStorage {
247
308
  }
248
309
  return data;
249
310
  } catch (error) {
250
- this.logger.error("Failed to parse text:", { error, text });
311
+ const message = error instanceof Error ? error.message : String(error);
312
+ this.logger.error("Failed to parse text:", { message, text });
251
313
  return null;
252
314
  }
253
315
  }
@@ -281,9 +343,9 @@ var CloudflareStore = class extends MastraStorage {
281
343
  throw new Error(`Failed to delete KV value: ${error.message}`);
282
344
  }
283
345
  }
284
- async listKV(tableName) {
346
+ async listKV(tableName, options) {
285
347
  try {
286
- return await this.listNamespaceKeys(tableName);
348
+ return await this.listNamespaceKeys(tableName, options);
287
349
  } catch (error) {
288
350
  this.logger.error(`Failed to list KV for ${tableName}:`, error);
289
351
  throw new Error(`Failed to list KV: ${error.message}`);
@@ -356,7 +418,8 @@ var CloudflareStore = class extends MastraStorage {
356
418
  if (!data) return null;
357
419
  return typeof data === "string" ? JSON.parse(data) : data;
358
420
  } catch (error) {
359
- this.logger.error(`Error retrieving message ${id}:`, { error });
421
+ const message = error instanceof Error ? error.message : String(error);
422
+ this.logger.error(`Error retrieving message ${id}:`, { message });
360
423
  return null;
361
424
  }
362
425
  })
@@ -389,7 +452,8 @@ var CloudflareStore = class extends MastraStorage {
389
452
  value: JSON.stringify(updatedOrder)
390
453
  });
391
454
  } catch (error) {
392
- this.logger.error(`Error updating sorted order for key ${orderKey}:`, { error });
455
+ const message = error instanceof Error ? error.message : String(error);
456
+ this.logger.error(`Error updating sorted order for key ${orderKey}:`, { message });
393
457
  throw error;
394
458
  } finally {
395
459
  if (this.updateQueue.get(orderKey) === nextPromise) {
@@ -431,7 +495,11 @@ var CloudflareStore = class extends MastraStorage {
431
495
  if (!record.namespace || !record.workflow_name || !record.run_id) {
432
496
  throw new Error("Namespace, workflow name, and run ID are required");
433
497
  }
434
- return `${prefix}${tableName}:${record.namespace}:${record.workflow_name}:${record.run_id}`;
498
+ let key = `${prefix}${tableName}:${record.namespace}:${record.workflow_name}:${record.run_id}`;
499
+ if (record.resourceId) {
500
+ key = `${key}:${record.resourceId}`;
501
+ }
502
+ return key;
435
503
  case TABLE_TRACES:
436
504
  if (!record.id) throw new Error("Trace ID is required");
437
505
  return `${prefix}${tableName}:${record.id}`;
@@ -448,7 +516,8 @@ var CloudflareStore = class extends MastraStorage {
448
516
  const schemaKey = this.getSchemaKey(tableName);
449
517
  return await this.getKV(tableName, schemaKey);
450
518
  } catch (error) {
451
- this.logger.error(`Failed to get schema for ${tableName}:`, { error });
519
+ const message = error instanceof Error ? error.message : String(error);
520
+ this.logger.error(`Failed to get schema for ${tableName}:`, { message });
452
521
  return null;
453
522
  }
454
523
  }
@@ -493,7 +562,8 @@ var CloudflareStore = class extends MastraStorage {
493
562
  }
494
563
  }
495
564
  } catch (error) {
496
- this.logger.error(`Error validating record against schema:`, { error, record, schema });
565
+ const message = error instanceof Error ? error.message : String(error);
566
+ this.logger.error(`Error validating record against schema:`, { message, record, schema });
497
567
  throw error;
498
568
  }
499
569
  }
@@ -520,7 +590,7 @@ var CloudflareStore = class extends MastraStorage {
520
590
  }
521
591
  break;
522
592
  case TABLE_WORKFLOW_SNAPSHOT:
523
- if (!("namespace" in recordTyped) || !("workflowName" in recordTyped) || !("runId" in recordTyped)) {
593
+ if (!("namespace" in recordTyped) || !("workflow_name" in recordTyped) || !("run_id" in recordTyped)) {
524
594
  throw new Error("Workflow record missing required fields");
525
595
  }
526
596
  break;
@@ -533,19 +603,11 @@ var CloudflareStore = class extends MastraStorage {
533
603
  throw new Error(`Unknown table type: ${tableName}`);
534
604
  }
535
605
  } catch (error) {
536
- this.logger.error(`Failed to validate record for ${tableName}:`, { error, record });
606
+ const message = error instanceof Error ? error.message : String(error);
607
+ this.logger.error(`Failed to validate record for ${tableName}:`, { message, record });
537
608
  throw error;
538
609
  }
539
610
  }
540
- ensureDate(date) {
541
- if (!date) return void 0;
542
- return date instanceof Date ? date : new Date(date);
543
- }
544
- serializeDate(date) {
545
- if (!date) return void 0;
546
- const dateObj = this.ensureDate(date);
547
- return dateObj?.toISOString();
548
- }
549
611
  ensureMetadata(metadata) {
550
612
  if (!metadata) return {};
551
613
  return typeof metadata === "string" ? JSON.parse(metadata) : metadata;
@@ -567,13 +629,24 @@ var CloudflareStore = class extends MastraStorage {
567
629
  throw new Error(`Failed to store schema: ${error.message}`);
568
630
  }
569
631
  }
632
+ /**
633
+ * No-op: This backend is schemaless and does not require schema changes.
634
+ * @param tableName Name of the table
635
+ * @param schema Schema of the table
636
+ * @param ifNotExists Array of column names to add if they don't exist
637
+ */
638
+ async alterTable(_args) {
639
+ }
570
640
  async clearTable({ tableName }) {
571
641
  const keys = await this.listKV(tableName);
572
642
  if (keys.length > 0) {
573
643
  await Promise.all(keys.map((keyObj) => this.deleteKV(tableName, keyObj.name)));
574
644
  }
575
645
  }
576
- async insert({ tableName, record }) {
646
+ async insert({
647
+ tableName,
648
+ record
649
+ }) {
577
650
  try {
578
651
  const key = this.getKey(tableName, record);
579
652
  const processedRecord = {
@@ -585,7 +658,8 @@ var CloudflareStore = class extends MastraStorage {
585
658
  await this.validateRecord(processedRecord, tableName);
586
659
  await this.putKV({ tableName, key, value: processedRecord });
587
660
  } catch (error) {
588
- this.logger.error(`Failed to insert record for ${tableName}:`, { error });
661
+ const message = error instanceof Error ? error.message : String(error);
662
+ this.logger.error(`Failed to insert record for ${tableName}:`, { message });
589
663
  throw error;
590
664
  }
591
665
  }
@@ -602,7 +676,9 @@ var CloudflareStore = class extends MastraStorage {
602
676
  };
603
677
  return processed;
604
678
  } catch (error) {
605
- this.logger.error(`Failed to load data for ${tableName}:`, { error });
679
+ this.logger.error(`Failed to load data for ${tableName}:`, {
680
+ error: error instanceof Error ? error.message : String(error)
681
+ });
606
682
  return null;
607
683
  }
608
684
  }
@@ -617,7 +693,9 @@ var CloudflareStore = class extends MastraStorage {
617
693
  metadata: this.ensureMetadata(thread.metadata)
618
694
  };
619
695
  } catch (error) {
620
- this.logger.error(`Error processing thread ${threadId}:`, { error });
696
+ this.logger.error(`Error processing thread ${threadId}:`, {
697
+ error: error instanceof Error ? error.message : String(error)
698
+ });
621
699
  return null;
622
700
  }
623
701
  }
@@ -638,14 +716,16 @@ var CloudflareStore = class extends MastraStorage {
638
716
  metadata: this.ensureMetadata(thread.metadata)
639
717
  };
640
718
  } catch (error) {
641
- this.logger.error(`Error processing thread from key ${keyObj.name}:`, { error });
719
+ const message = error instanceof Error ? error.message : String(error);
720
+ this.logger.error(`Error processing thread from key ${keyObj.name}:`, { message });
642
721
  return null;
643
722
  }
644
723
  })
645
724
  );
646
725
  return threads.filter((thread) => thread !== null);
647
726
  } catch (error) {
648
- this.logger.error(`Error getting threads for resourceId ${resourceId}:`, { error });
727
+ const message = error instanceof Error ? error.message : String(error);
728
+ this.logger.error(`Error getting threads for resourceId ${resourceId}:`, { message });
649
729
  return [];
650
730
  }
651
731
  }
@@ -654,7 +734,8 @@ var CloudflareStore = class extends MastraStorage {
654
734
  await this.insert({ tableName: TABLE_THREADS, record: thread });
655
735
  return thread;
656
736
  } catch (error) {
657
- this.logger.error("Error saving thread:", { error });
737
+ const message = error instanceof Error ? error.message : String(error);
738
+ this.logger.error("Error saving thread:", { message });
658
739
  throw error;
659
740
  }
660
741
  }
@@ -680,7 +761,8 @@ var CloudflareStore = class extends MastraStorage {
680
761
  await this.insert({ tableName: TABLE_THREADS, record: updatedThread });
681
762
  return updatedThread;
682
763
  } catch (error) {
683
- this.logger.error(`Error updating thread ${id}:`, { error });
764
+ const message = error instanceof Error ? error.message : String(error);
765
+ this.logger.error(`Error updating thread ${id}:`, { message });
684
766
  throw error;
685
767
  }
686
768
  }
@@ -701,7 +783,8 @@ var CloudflareStore = class extends MastraStorage {
701
783
  this.deleteKV(TABLE_THREADS, this.getKey(TABLE_THREADS, { id: threadId }))
702
784
  ]);
703
785
  } catch (error) {
704
- this.logger.error(`Error deleting thread ${threadId}:`, { error });
786
+ const message = error instanceof Error ? error.message : String(error);
787
+ this.logger.error(`Error deleting thread ${threadId}:`, { message });
705
788
  throw error;
706
789
  }
707
790
  }
@@ -709,7 +792,8 @@ var CloudflareStore = class extends MastraStorage {
709
792
  try {
710
793
  return this.getKey(TABLE_MESSAGES, { threadId, id: messageId });
711
794
  } catch (error) {
712
- this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { error });
795
+ const message = error instanceof Error ? error.message : String(error);
796
+ this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
713
797
  throw error;
714
798
  }
715
799
  }
@@ -717,11 +801,13 @@ var CloudflareStore = class extends MastraStorage {
717
801
  try {
718
802
  return this.getKey(TABLE_MESSAGES, { threadId, id: "messages" });
719
803
  } catch (error) {
720
- this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { error });
804
+ const message = error instanceof Error ? error.message : String(error);
805
+ this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { message });
721
806
  throw error;
722
807
  }
723
808
  }
724
- async saveMessages({ messages }) {
809
+ async saveMessages(args) {
810
+ const { messages, format = "v1" } = args;
725
811
  if (!Array.isArray(messages) || messages.length === 0) return [];
726
812
  try {
727
813
  const validatedMessages = messages.map((message, index) => {
@@ -737,15 +823,17 @@ var CloudflareStore = class extends MastraStorage {
737
823
  return {
738
824
  ...message,
739
825
  createdAt: this.ensureDate(message.createdAt),
740
- type: message.type || "text",
826
+ type: message.type || "v2",
741
827
  _index: index
742
828
  };
743
829
  });
744
830
  const messagesByThread = validatedMessages.reduce((acc, message) => {
745
- if (!acc.has(message.threadId)) {
831
+ if (message.threadId && !acc.has(message.threadId)) {
746
832
  acc.set(message.threadId, []);
747
833
  }
748
- acc.get(message.threadId).push(message);
834
+ if (message.threadId) {
835
+ acc.get(message.threadId).push(message);
836
+ }
749
837
  return acc;
750
838
  }, /* @__PURE__ */ new Map());
751
839
  await Promise.all(
@@ -757,7 +845,7 @@ var CloudflareStore = class extends MastraStorage {
757
845
  }
758
846
  await Promise.all(
759
847
  threadMessages.map(async (message) => {
760
- const key = await this.getMessageKey(threadId, message.id);
848
+ const key = this.getMessageKey(threadId, message.id);
761
849
  const { _index, ...cleanMessage } = message;
762
850
  const serializedMessage = {
763
851
  ...cleanMessage,
@@ -776,21 +864,26 @@ var CloudflareStore = class extends MastraStorage {
776
864
  }
777
865
  })
778
866
  );
779
- return validatedMessages.map(({ _index, ...message }) => message);
867
+ const prepared = validatedMessages.map(
868
+ ({ _index, ...message }) => ({ ...message, type: message.type !== "v2" ? message.type : void 0 })
869
+ );
870
+ const list = new MessageList().add(prepared, "memory");
871
+ if (format === `v2`) return list.get.all.v2();
872
+ return list.get.all.v1();
780
873
  } catch (error) {
781
874
  const errorMessage = error instanceof Error ? error.message : String(error);
782
875
  this.logger.error(`Error saving messages: ${errorMessage}`);
783
876
  throw error;
784
877
  }
785
878
  }
786
- async getMessages({ threadId, selectBy }) {
879
+ async getMessages({
880
+ threadId,
881
+ resourceId,
882
+ selectBy,
883
+ format
884
+ }) {
787
885
  if (!threadId) throw new Error("threadId is required");
788
- let limit = 40;
789
- if (typeof selectBy?.last === "number") {
790
- limit = Math.max(0, selectBy.last);
791
- } else if (selectBy?.last === false) {
792
- limit = 0;
793
- }
886
+ const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
794
887
  const messageIds = /* @__PURE__ */ new Set();
795
888
  if (limit === 0 && !selectBy?.include?.length) return [];
796
889
  try {
@@ -815,10 +908,14 @@ var CloudflareStore = class extends MastraStorage {
815
908
  this.logger.warn(`Error sorting messages, falling back to creation time: ${errorMessage}`);
816
909
  messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
817
910
  }
818
- return messages.map(({ _index, ...message }) => ({
911
+ const prepared = messages.map(({ _index, ...message }) => ({
819
912
  ...message,
913
+ type: message.type === `v2` ? void 0 : message.type,
820
914
  createdAt: this.ensureDate(message.createdAt)
821
915
  }));
916
+ const list = new MessageList({ threadId, resourceId }).add(prepared, "memory");
917
+ if (format === `v1`) return list.get.all.v1();
918
+ return list.get.all.v2();
822
919
  } catch (error) {
823
920
  const errorMessage = error instanceof Error ? error.message : String(error);
824
921
  this.logger.error(`Error retrieving messages for thread ${threadId}: ${errorMessage}`);
@@ -832,7 +929,7 @@ var CloudflareStore = class extends MastraStorage {
832
929
  }
833
930
  }
834
931
  validateWorkflowState(state) {
835
- if (!state?.runId || !state?.value || !state?.context?.steps || !state?.context?.triggerData || !state?.context?.attempts || !state?.activePaths) {
932
+ if (!state?.runId || !state?.value || !state?.context?.input || !state?.activePaths) {
836
933
  throw new Error("Invalid workflow state structure");
837
934
  }
838
935
  }
@@ -848,18 +945,17 @@ var CloudflareStore = class extends MastraStorage {
848
945
  return normalizedSteps;
849
946
  }
850
947
  normalizeWorkflowState(data) {
851
- const steps = data.context?.stepResults || data.context?.steps || {};
852
948
  return {
853
949
  runId: data.runId,
854
950
  value: data.value,
855
- context: {
856
- steps: this.normalizeSteps(steps),
857
- triggerData: data.context?.triggerData || {},
858
- attempts: data.context?.attempts || {}
859
- },
860
- suspendedPaths: data.suspendedPaths || [],
951
+ context: data.context,
952
+ serializedStepGraph: data.serializedStepGraph,
953
+ suspendedPaths: data.suspendedPaths || {},
861
954
  activePaths: data.activePaths || [],
862
- timestamp: data.timestamp || Date.now()
955
+ timestamp: data.timestamp || Date.now(),
956
+ status: data.status,
957
+ result: data.result,
958
+ error: data.error
863
959
  };
864
960
  }
865
961
  async persistWorkflowSnapshot(params) {
@@ -868,10 +964,20 @@ var CloudflareStore = class extends MastraStorage {
868
964
  const { namespace, workflowName, runId, snapshot } = params;
869
965
  const normalizedState = this.normalizeWorkflowState(snapshot);
870
966
  this.validateWorkflowState(normalizedState);
871
- const key = this.getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
872
- await this.putKV({ tableName: TABLE_WORKFLOW_SNAPSHOT, key, value: normalizedState });
967
+ await this.insert({
968
+ tableName: TABLE_WORKFLOW_SNAPSHOT,
969
+ record: {
970
+ namespace,
971
+ workflow_name: workflowName,
972
+ run_id: runId,
973
+ snapshot: normalizedState,
974
+ createdAt: /* @__PURE__ */ new Date(),
975
+ updatedAt: /* @__PURE__ */ new Date()
976
+ }
977
+ });
873
978
  } catch (error) {
874
- this.logger.error("Error persisting workflow snapshot:", { error });
979
+ const message = error instanceof Error ? error.message : String(error);
980
+ this.logger.error("Error persisting workflow snapshot:", { message });
875
981
  throw error;
876
982
  }
877
983
  }
@@ -882,11 +988,13 @@ var CloudflareStore = class extends MastraStorage {
882
988
  const key = this.getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
883
989
  const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
884
990
  if (!data) return null;
885
- const state = this.normalizeWorkflowState(data);
991
+ const state = this.normalizeWorkflowState(data.snapshot || data);
886
992
  this.validateWorkflowState(state);
887
993
  return state;
888
994
  } catch (error) {
889
- this.logger.error("Error loading workflow snapshot:", { error });
995
+ this.logger.error("Error loading workflow snapshot:", {
996
+ error: error instanceof Error ? error.message : String(error)
997
+ });
890
998
  return null;
891
999
  }
892
1000
  }
@@ -906,7 +1014,8 @@ var CloudflareStore = class extends MastraStorage {
906
1014
  })
907
1015
  );
908
1016
  } catch (error) {
909
- this.logger.error("Error in batch insert:", { error });
1017
+ const message = error instanceof Error ? error.message : String(error);
1018
+ this.logger.error("Error in batch insert:", { message });
910
1019
  throw error;
911
1020
  }
912
1021
  }
@@ -915,7 +1024,9 @@ var CloudflareStore = class extends MastraStorage {
915
1024
  scope,
916
1025
  page = 0,
917
1026
  perPage = 100,
918
- attributes
1027
+ attributes,
1028
+ fromDate,
1029
+ toDate
919
1030
  }) {
920
1031
  try {
921
1032
  let keys;
@@ -954,6 +1065,12 @@ var CloudflareStore = class extends MastraStorage {
954
1065
  return Object.entries(attributes).every(([key, value]) => recordAttrs[key] === value);
955
1066
  });
956
1067
  }
1068
+ if (fromDate) {
1069
+ filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() >= fromDate.getTime());
1070
+ }
1071
+ if (toDate) {
1072
+ filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() <= toDate.getTime());
1073
+ }
957
1074
  filteredTraces.sort((a, b) => {
958
1075
  const dateA = new Date(a.createdAt).getTime();
959
1076
  const dateB = new Date(b.createdAt).getTime();
@@ -979,7 +1096,8 @@ var CloudflareStore = class extends MastraStorage {
979
1096
  createdAt: record.createdAt
980
1097
  }));
981
1098
  } catch (error) {
982
- this.logger.error("Failed to get traces:", { message: error instanceof Error ? error.message : String(error) });
1099
+ const message = error instanceof Error ? error.message : String(error);
1100
+ this.logger.error("Failed to get traces:", { message });
983
1101
  return [];
984
1102
  }
985
1103
  }
@@ -996,11 +1114,131 @@ var CloudflareStore = class extends MastraStorage {
996
1114
  getEvalsByAgentName(_agentName, _type) {
997
1115
  throw new Error("Method not implemented.");
998
1116
  }
999
- getWorkflowRuns(_args) {
1117
+ parseWorkflowRun(row) {
1118
+ let parsedSnapshot = row.snapshot;
1119
+ if (typeof parsedSnapshot === "string") {
1120
+ try {
1121
+ parsedSnapshot = JSON.parse(row.snapshot);
1122
+ } catch (e) {
1123
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
1124
+ }
1125
+ }
1126
+ return {
1127
+ workflowName: row.workflow_name,
1128
+ runId: row.run_id,
1129
+ snapshot: parsedSnapshot,
1130
+ createdAt: this.ensureDate(row.createdAt),
1131
+ updatedAt: this.ensureDate(row.updatedAt),
1132
+ resourceId: row.resourceId
1133
+ };
1134
+ }
1135
+ buildWorkflowSnapshotPrefix({
1136
+ namespace,
1137
+ workflowName,
1138
+ runId,
1139
+ resourceId
1140
+ }) {
1141
+ const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
1142
+ let key = `${prefix}${TABLE_WORKFLOW_SNAPSHOT}`;
1143
+ if (namespace) key += `:${namespace}`;
1144
+ if (workflowName) key += `:${workflowName}`;
1145
+ if (runId) key += `:${runId}`;
1146
+ if (resourceId) key += `:${resourceId}`;
1147
+ if (!resourceId && (runId || workflowName || namespace)) key += ":";
1148
+ return key;
1149
+ }
1150
+ async getWorkflowRuns({
1151
+ namespace,
1152
+ workflowName,
1153
+ limit = 20,
1154
+ offset = 0,
1155
+ resourceId,
1156
+ fromDate,
1157
+ toDate
1158
+ } = {}) {
1159
+ try {
1160
+ const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName });
1161
+ const keyObjs = await this.listKV(TABLE_WORKFLOW_SNAPSHOT, { prefix });
1162
+ const runs = [];
1163
+ for (const { name: key } of keyObjs) {
1164
+ const parts = key.split(":");
1165
+ const idx = parts.indexOf(TABLE_WORKFLOW_SNAPSHOT);
1166
+ if (idx === -1 || parts.length < idx + 4) continue;
1167
+ const ns = parts[idx + 1];
1168
+ const wfName = parts[idx + 2];
1169
+ const keyResourceId = parts.length > idx + 4 ? parts[idx + 4] : void 0;
1170
+ if (namespace && ns !== namespace || workflowName && wfName !== workflowName) continue;
1171
+ if (resourceId && keyResourceId && keyResourceId !== resourceId) continue;
1172
+ const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
1173
+ if (!data) continue;
1174
+ try {
1175
+ if (resourceId && data.resourceId && data.resourceId !== resourceId) continue;
1176
+ const createdAt = this.ensureDate(data.createdAt);
1177
+ if (fromDate && createdAt && createdAt < fromDate) continue;
1178
+ if (toDate && createdAt && createdAt > toDate) continue;
1179
+ const state = this.normalizeWorkflowState(data.snapshot || data);
1180
+ this.validateWorkflowState(state);
1181
+ const run = this.parseWorkflowRun({ ...data, snapshot: state });
1182
+ runs.push(run);
1183
+ } catch (err) {
1184
+ this.logger.error("Failed to parse workflow snapshot:", { key, error: err });
1185
+ }
1186
+ }
1187
+ runs.sort((a, b) => {
1188
+ const aDate = a.createdAt ? new Date(a.createdAt).getTime() : 0;
1189
+ const bDate = b.createdAt ? new Date(b.createdAt).getTime() : 0;
1190
+ return bDate - aDate;
1191
+ });
1192
+ const pagedRuns = runs.slice(offset, offset + limit);
1193
+ return {
1194
+ runs: pagedRuns,
1195
+ total: runs.length
1196
+ };
1197
+ } catch (error) {
1198
+ const message = error instanceof Error ? error.message : String(error);
1199
+ this.logger.error("Error in getWorkflowRuns:", { message });
1200
+ return { runs: [], total: 0 };
1201
+ }
1202
+ }
1203
+ async getWorkflowRunById({
1204
+ namespace,
1205
+ runId,
1206
+ workflowName
1207
+ }) {
1208
+ try {
1209
+ if (!runId || !workflowName || !namespace) {
1210
+ throw new Error("runId, workflowName, and namespace are required");
1211
+ }
1212
+ const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName, runId });
1213
+ const keyObjs = await this.listKV(TABLE_WORKFLOW_SNAPSHOT, { prefix });
1214
+ if (!keyObjs.length) return null;
1215
+ const key = keyObjs[0]?.name;
1216
+ const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
1217
+ if (!data) return null;
1218
+ const state = this.normalizeWorkflowState(data.snapshot || data);
1219
+ this.validateWorkflowState(state);
1220
+ return this.parseWorkflowRun({ ...data, snapshot: state });
1221
+ } catch (error) {
1222
+ const message = error instanceof Error ? error.message : String(error);
1223
+ this.logger.error("Error in getWorkflowRunById:", { message });
1224
+ return null;
1225
+ }
1226
+ }
1227
+ async getTracesPaginated(_args) {
1228
+ throw new Error("Method not implemented.");
1229
+ }
1230
+ async getThreadsByResourceIdPaginated(_args) {
1231
+ throw new Error("Method not implemented.");
1232
+ }
1233
+ async getMessagesPaginated(_args) {
1000
1234
  throw new Error("Method not implemented.");
1001
1235
  }
1002
1236
  async close() {
1003
1237
  }
1238
+ async updateMessages(_args) {
1239
+ this.logger.error("updateMessages is not yet implemented in CloudflareStore");
1240
+ throw new Error("Method not implemented");
1241
+ }
1004
1242
  };
1005
1243
 
1006
1244
  export { CloudflareStore };