@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/_tsup-dts-rollup.d.cts +86 -33
- package/dist/_tsup-dts-rollup.d.ts +86 -33
- package/dist/index.cjs +305 -66
- package/dist/index.js +305 -66
- package/package.json +17 -13
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MessageList } from '@mastra/core/agent';
|
|
1
2
|
import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_TRACES } from '@mastra/core/storage';
|
|
2
3
|
import Cloudflare from 'cloudflare';
|
|
3
4
|
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) || !("
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
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}:`, {
|
|
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}:`, {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 || "
|
|
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
|
-
|
|
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 =
|
|
848
|
+
const key = this.getMessageKey(threadId, message.id);
|
|
761
849
|
const { _index, ...cleanMessage } = message;
|
|
762
850
|
const serializedMessage = {
|
|
763
851
|
...cleanMessage,
|
|
@@ -776,14 +864,24 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
776
864
|
}
|
|
777
865
|
})
|
|
778
866
|
);
|
|
779
|
-
|
|
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({
|
|
879
|
+
async getMessages({
|
|
880
|
+
threadId,
|
|
881
|
+
resourceId,
|
|
882
|
+
selectBy,
|
|
883
|
+
format
|
|
884
|
+
}) {
|
|
787
885
|
if (!threadId) throw new Error("threadId is required");
|
|
788
886
|
let limit = 40;
|
|
789
887
|
if (typeof selectBy?.last === "number") {
|
|
@@ -815,10 +913,14 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
815
913
|
this.logger.warn(`Error sorting messages, falling back to creation time: ${errorMessage}`);
|
|
816
914
|
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
817
915
|
}
|
|
818
|
-
|
|
916
|
+
const prepared = messages.map(({ _index, ...message }) => ({
|
|
819
917
|
...message,
|
|
918
|
+
type: message.type === `v2` ? void 0 : message.type,
|
|
820
919
|
createdAt: this.ensureDate(message.createdAt)
|
|
821
920
|
}));
|
|
921
|
+
const list = new MessageList({ threadId, resourceId }).add(prepared, "memory");
|
|
922
|
+
if (format === `v1`) return list.get.all.v1();
|
|
923
|
+
return list.get.all.v2();
|
|
822
924
|
} catch (error) {
|
|
823
925
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
824
926
|
this.logger.error(`Error retrieving messages for thread ${threadId}: ${errorMessage}`);
|
|
@@ -832,7 +934,7 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
832
934
|
}
|
|
833
935
|
}
|
|
834
936
|
validateWorkflowState(state) {
|
|
835
|
-
if (!state?.runId || !state?.value || !state?.context?.
|
|
937
|
+
if (!state?.runId || !state?.value || !state?.context?.input || !state?.activePaths) {
|
|
836
938
|
throw new Error("Invalid workflow state structure");
|
|
837
939
|
}
|
|
838
940
|
}
|
|
@@ -848,18 +950,17 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
848
950
|
return normalizedSteps;
|
|
849
951
|
}
|
|
850
952
|
normalizeWorkflowState(data) {
|
|
851
|
-
const steps = data.context?.stepResults || data.context?.steps || {};
|
|
852
953
|
return {
|
|
853
954
|
runId: data.runId,
|
|
854
955
|
value: data.value,
|
|
855
|
-
context:
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
attempts: data.context?.attempts || {}
|
|
859
|
-
},
|
|
860
|
-
suspendedPaths: data.suspendedPaths || [],
|
|
956
|
+
context: data.context,
|
|
957
|
+
serializedStepGraph: data.serializedStepGraph,
|
|
958
|
+
suspendedPaths: data.suspendedPaths || {},
|
|
861
959
|
activePaths: data.activePaths || [],
|
|
862
|
-
timestamp: data.timestamp || Date.now()
|
|
960
|
+
timestamp: data.timestamp || Date.now(),
|
|
961
|
+
status: data.status,
|
|
962
|
+
result: data.result,
|
|
963
|
+
error: data.error
|
|
863
964
|
};
|
|
864
965
|
}
|
|
865
966
|
async persistWorkflowSnapshot(params) {
|
|
@@ -868,10 +969,20 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
868
969
|
const { namespace, workflowName, runId, snapshot } = params;
|
|
869
970
|
const normalizedState = this.normalizeWorkflowState(snapshot);
|
|
870
971
|
this.validateWorkflowState(normalizedState);
|
|
871
|
-
|
|
872
|
-
|
|
972
|
+
await this.insert({
|
|
973
|
+
tableName: TABLE_WORKFLOW_SNAPSHOT,
|
|
974
|
+
record: {
|
|
975
|
+
namespace,
|
|
976
|
+
workflow_name: workflowName,
|
|
977
|
+
run_id: runId,
|
|
978
|
+
snapshot: normalizedState,
|
|
979
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
980
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
981
|
+
}
|
|
982
|
+
});
|
|
873
983
|
} catch (error) {
|
|
874
|
-
|
|
984
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
985
|
+
this.logger.error("Error persisting workflow snapshot:", { message });
|
|
875
986
|
throw error;
|
|
876
987
|
}
|
|
877
988
|
}
|
|
@@ -882,11 +993,13 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
882
993
|
const key = this.getKey(TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
|
|
883
994
|
const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
|
|
884
995
|
if (!data) return null;
|
|
885
|
-
const state = this.normalizeWorkflowState(data);
|
|
996
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
886
997
|
this.validateWorkflowState(state);
|
|
887
998
|
return state;
|
|
888
999
|
} catch (error) {
|
|
889
|
-
this.logger.error("Error loading workflow snapshot:", {
|
|
1000
|
+
this.logger.error("Error loading workflow snapshot:", {
|
|
1001
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1002
|
+
});
|
|
890
1003
|
return null;
|
|
891
1004
|
}
|
|
892
1005
|
}
|
|
@@ -906,7 +1019,8 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
906
1019
|
})
|
|
907
1020
|
);
|
|
908
1021
|
} catch (error) {
|
|
909
|
-
|
|
1022
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1023
|
+
this.logger.error("Error in batch insert:", { message });
|
|
910
1024
|
throw error;
|
|
911
1025
|
}
|
|
912
1026
|
}
|
|
@@ -915,7 +1029,9 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
915
1029
|
scope,
|
|
916
1030
|
page = 0,
|
|
917
1031
|
perPage = 100,
|
|
918
|
-
attributes
|
|
1032
|
+
attributes,
|
|
1033
|
+
fromDate,
|
|
1034
|
+
toDate
|
|
919
1035
|
}) {
|
|
920
1036
|
try {
|
|
921
1037
|
let keys;
|
|
@@ -954,6 +1070,12 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
954
1070
|
return Object.entries(attributes).every(([key, value]) => recordAttrs[key] === value);
|
|
955
1071
|
});
|
|
956
1072
|
}
|
|
1073
|
+
if (fromDate) {
|
|
1074
|
+
filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() >= fromDate.getTime());
|
|
1075
|
+
}
|
|
1076
|
+
if (toDate) {
|
|
1077
|
+
filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() <= toDate.getTime());
|
|
1078
|
+
}
|
|
957
1079
|
filteredTraces.sort((a, b) => {
|
|
958
1080
|
const dateA = new Date(a.createdAt).getTime();
|
|
959
1081
|
const dateB = new Date(b.createdAt).getTime();
|
|
@@ -979,7 +1101,8 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
979
1101
|
createdAt: record.createdAt
|
|
980
1102
|
}));
|
|
981
1103
|
} catch (error) {
|
|
982
|
-
|
|
1104
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1105
|
+
this.logger.error("Failed to get traces:", { message });
|
|
983
1106
|
return [];
|
|
984
1107
|
}
|
|
985
1108
|
}
|
|
@@ -996,7 +1119,123 @@ var CloudflareStore = class extends MastraStorage {
|
|
|
996
1119
|
getEvalsByAgentName(_agentName, _type) {
|
|
997
1120
|
throw new Error("Method not implemented.");
|
|
998
1121
|
}
|
|
999
|
-
|
|
1122
|
+
parseWorkflowRun(row) {
|
|
1123
|
+
let parsedSnapshot = row.snapshot;
|
|
1124
|
+
if (typeof parsedSnapshot === "string") {
|
|
1125
|
+
try {
|
|
1126
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1127
|
+
} catch (e) {
|
|
1128
|
+
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1131
|
+
return {
|
|
1132
|
+
workflowName: row.workflow_name,
|
|
1133
|
+
runId: row.run_id,
|
|
1134
|
+
snapshot: parsedSnapshot,
|
|
1135
|
+
createdAt: this.ensureDate(row.createdAt),
|
|
1136
|
+
updatedAt: this.ensureDate(row.updatedAt),
|
|
1137
|
+
resourceId: row.resourceId
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
buildWorkflowSnapshotPrefix({
|
|
1141
|
+
namespace,
|
|
1142
|
+
workflowName,
|
|
1143
|
+
runId,
|
|
1144
|
+
resourceId
|
|
1145
|
+
}) {
|
|
1146
|
+
const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
|
|
1147
|
+
let key = `${prefix}${TABLE_WORKFLOW_SNAPSHOT}`;
|
|
1148
|
+
if (namespace) key += `:${namespace}`;
|
|
1149
|
+
if (workflowName) key += `:${workflowName}`;
|
|
1150
|
+
if (runId) key += `:${runId}`;
|
|
1151
|
+
if (resourceId) key += `:${resourceId}`;
|
|
1152
|
+
if (!resourceId && (runId || workflowName || namespace)) key += ":";
|
|
1153
|
+
return key;
|
|
1154
|
+
}
|
|
1155
|
+
async getWorkflowRuns({
|
|
1156
|
+
namespace,
|
|
1157
|
+
workflowName,
|
|
1158
|
+
limit = 20,
|
|
1159
|
+
offset = 0,
|
|
1160
|
+
resourceId,
|
|
1161
|
+
fromDate,
|
|
1162
|
+
toDate
|
|
1163
|
+
} = {}) {
|
|
1164
|
+
try {
|
|
1165
|
+
const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName });
|
|
1166
|
+
const keyObjs = await this.listKV(TABLE_WORKFLOW_SNAPSHOT, { prefix });
|
|
1167
|
+
const runs = [];
|
|
1168
|
+
for (const { name: key } of keyObjs) {
|
|
1169
|
+
const parts = key.split(":");
|
|
1170
|
+
const idx = parts.indexOf(TABLE_WORKFLOW_SNAPSHOT);
|
|
1171
|
+
if (idx === -1 || parts.length < idx + 4) continue;
|
|
1172
|
+
const ns = parts[idx + 1];
|
|
1173
|
+
const wfName = parts[idx + 2];
|
|
1174
|
+
const keyResourceId = parts.length > idx + 4 ? parts[idx + 4] : void 0;
|
|
1175
|
+
if (namespace && ns !== namespace || workflowName && wfName !== workflowName) continue;
|
|
1176
|
+
if (resourceId && keyResourceId && keyResourceId !== resourceId) continue;
|
|
1177
|
+
const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
|
|
1178
|
+
if (!data) continue;
|
|
1179
|
+
try {
|
|
1180
|
+
if (resourceId && data.resourceId && data.resourceId !== resourceId) continue;
|
|
1181
|
+
const createdAt = this.ensureDate(data.createdAt);
|
|
1182
|
+
if (fromDate && createdAt && createdAt < fromDate) continue;
|
|
1183
|
+
if (toDate && createdAt && createdAt > toDate) continue;
|
|
1184
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
1185
|
+
this.validateWorkflowState(state);
|
|
1186
|
+
const run = this.parseWorkflowRun({ ...data, snapshot: state });
|
|
1187
|
+
runs.push(run);
|
|
1188
|
+
} catch (err) {
|
|
1189
|
+
this.logger.error("Failed to parse workflow snapshot:", { key, error: err });
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1192
|
+
runs.sort((a, b) => {
|
|
1193
|
+
const aDate = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
1194
|
+
const bDate = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
1195
|
+
return bDate - aDate;
|
|
1196
|
+
});
|
|
1197
|
+
const pagedRuns = runs.slice(offset, offset + limit);
|
|
1198
|
+
return {
|
|
1199
|
+
runs: pagedRuns,
|
|
1200
|
+
total: runs.length
|
|
1201
|
+
};
|
|
1202
|
+
} catch (error) {
|
|
1203
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1204
|
+
this.logger.error("Error in getWorkflowRuns:", { message });
|
|
1205
|
+
return { runs: [], total: 0 };
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
async getWorkflowRunById({
|
|
1209
|
+
namespace,
|
|
1210
|
+
runId,
|
|
1211
|
+
workflowName
|
|
1212
|
+
}) {
|
|
1213
|
+
try {
|
|
1214
|
+
if (!runId || !workflowName || !namespace) {
|
|
1215
|
+
throw new Error("runId, workflowName, and namespace are required");
|
|
1216
|
+
}
|
|
1217
|
+
const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName, runId });
|
|
1218
|
+
const keyObjs = await this.listKV(TABLE_WORKFLOW_SNAPSHOT, { prefix });
|
|
1219
|
+
if (!keyObjs.length) return null;
|
|
1220
|
+
const key = keyObjs[0]?.name;
|
|
1221
|
+
const data = await this.getKV(TABLE_WORKFLOW_SNAPSHOT, key);
|
|
1222
|
+
if (!data) return null;
|
|
1223
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
1224
|
+
this.validateWorkflowState(state);
|
|
1225
|
+
return this.parseWorkflowRun({ ...data, snapshot: state });
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1228
|
+
this.logger.error("Error in getWorkflowRunById:", { message });
|
|
1229
|
+
return null;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
async getTracesPaginated(_args) {
|
|
1233
|
+
throw new Error("Method not implemented.");
|
|
1234
|
+
}
|
|
1235
|
+
async getThreadsByResourceIdPaginated(_args) {
|
|
1236
|
+
throw new Error("Method not implemented.");
|
|
1237
|
+
}
|
|
1238
|
+
async getMessagesPaginated(_args) {
|
|
1000
1239
|
throw new Error("Method not implemented.");
|
|
1001
1240
|
}
|
|
1002
1241
|
async close() {
|