@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/_tsup-dts-rollup.d.cts +99 -33
- package/dist/_tsup-dts-rollup.d.ts +99 -33
- package/dist/index.cjs +311 -73
- package/dist/index.js +312 -74
- package/package.json +17 -13
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
|
|
|
@@ -27,7 +28,7 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
27
28
|
if (!config.bindings) {
|
|
28
29
|
throw new Error("KV bindings are required when using Workers Binding API");
|
|
29
30
|
}
|
|
30
|
-
const requiredTables = [storage.TABLE_THREADS, storage.TABLE_MESSAGES, storage.TABLE_WORKFLOW_SNAPSHOT, storage.TABLE_EVALS, storage.TABLE_TRACES];
|
|
31
|
+
const requiredTables = [storage.TABLE_THREADS, storage.TABLE_MESSAGES, storage.TABLE_WORKFLOW_SNAPSHOT, storage.TABLE_EVALS, storage.TABLE_TRACES, storage.TABLE_RESOURCES];
|
|
31
32
|
for (const table of requiredTables) {
|
|
32
33
|
if (!(table in config.bindings)) {
|
|
33
34
|
throw new Error(`Missing KV binding for table: ${table}`);
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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) || !("
|
|
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
|
-
|
|
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({
|
|
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
|
-
|
|
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}:`, {
|
|
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}:`, {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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 || "
|
|
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
|
-
|
|
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 =
|
|
854
|
+
const key = this.getMessageKey(threadId, message.id);
|
|
767
855
|
const { _index, ...cleanMessage } = message;
|
|
768
856
|
const serializedMessage = {
|
|
769
857
|
...cleanMessage,
|
|
@@ -782,21 +870,26 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
782
870
|
}
|
|
783
871
|
})
|
|
784
872
|
);
|
|
785
|
-
|
|
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({
|
|
885
|
+
async getMessages({
|
|
886
|
+
threadId,
|
|
887
|
+
resourceId,
|
|
888
|
+
selectBy,
|
|
889
|
+
format
|
|
890
|
+
}) {
|
|
793
891
|
if (!threadId) throw new Error("threadId is required");
|
|
794
|
-
|
|
795
|
-
if (typeof selectBy?.last === "number") {
|
|
796
|
-
limit = Math.max(0, selectBy.last);
|
|
797
|
-
} else if (selectBy?.last === false) {
|
|
798
|
-
limit = 0;
|
|
799
|
-
}
|
|
892
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
800
893
|
const messageIds = /* @__PURE__ */ new Set();
|
|
801
894
|
if (limit === 0 && !selectBy?.include?.length) return [];
|
|
802
895
|
try {
|
|
@@ -821,10 +914,14 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
821
914
|
this.logger.warn(`Error sorting messages, falling back to creation time: ${errorMessage}`);
|
|
822
915
|
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
823
916
|
}
|
|
824
|
-
|
|
917
|
+
const prepared = messages.map(({ _index, ...message }) => ({
|
|
825
918
|
...message,
|
|
919
|
+
type: message.type === `v2` ? void 0 : message.type,
|
|
826
920
|
createdAt: this.ensureDate(message.createdAt)
|
|
827
921
|
}));
|
|
922
|
+
const list = new agent.MessageList({ threadId, resourceId }).add(prepared, "memory");
|
|
923
|
+
if (format === `v1`) return list.get.all.v1();
|
|
924
|
+
return list.get.all.v2();
|
|
828
925
|
} catch (error) {
|
|
829
926
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
830
927
|
this.logger.error(`Error retrieving messages for thread ${threadId}: ${errorMessage}`);
|
|
@@ -838,7 +935,7 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
838
935
|
}
|
|
839
936
|
}
|
|
840
937
|
validateWorkflowState(state) {
|
|
841
|
-
if (!state?.runId || !state?.value || !state?.context?.
|
|
938
|
+
if (!state?.runId || !state?.value || !state?.context?.input || !state?.activePaths) {
|
|
842
939
|
throw new Error("Invalid workflow state structure");
|
|
843
940
|
}
|
|
844
941
|
}
|
|
@@ -854,18 +951,17 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
854
951
|
return normalizedSteps;
|
|
855
952
|
}
|
|
856
953
|
normalizeWorkflowState(data) {
|
|
857
|
-
const steps = data.context?.stepResults || data.context?.steps || {};
|
|
858
954
|
return {
|
|
859
955
|
runId: data.runId,
|
|
860
956
|
value: data.value,
|
|
861
|
-
context:
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
attempts: data.context?.attempts || {}
|
|
865
|
-
},
|
|
866
|
-
suspendedPaths: data.suspendedPaths || [],
|
|
957
|
+
context: data.context,
|
|
958
|
+
serializedStepGraph: data.serializedStepGraph,
|
|
959
|
+
suspendedPaths: data.suspendedPaths || {},
|
|
867
960
|
activePaths: data.activePaths || [],
|
|
868
|
-
timestamp: data.timestamp || Date.now()
|
|
961
|
+
timestamp: data.timestamp || Date.now(),
|
|
962
|
+
status: data.status,
|
|
963
|
+
result: data.result,
|
|
964
|
+
error: data.error
|
|
869
965
|
};
|
|
870
966
|
}
|
|
871
967
|
async persistWorkflowSnapshot(params) {
|
|
@@ -874,10 +970,20 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
874
970
|
const { namespace, workflowName, runId, snapshot } = params;
|
|
875
971
|
const normalizedState = this.normalizeWorkflowState(snapshot);
|
|
876
972
|
this.validateWorkflowState(normalizedState);
|
|
877
|
-
|
|
878
|
-
|
|
973
|
+
await this.insert({
|
|
974
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
975
|
+
record: {
|
|
976
|
+
namespace,
|
|
977
|
+
workflow_name: workflowName,
|
|
978
|
+
run_id: runId,
|
|
979
|
+
snapshot: normalizedState,
|
|
980
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
981
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
982
|
+
}
|
|
983
|
+
});
|
|
879
984
|
} catch (error) {
|
|
880
|
-
|
|
985
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
986
|
+
this.logger.error("Error persisting workflow snapshot:", { message });
|
|
881
987
|
throw error;
|
|
882
988
|
}
|
|
883
989
|
}
|
|
@@ -888,11 +994,13 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
888
994
|
const key = this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
|
|
889
995
|
const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
|
|
890
996
|
if (!data) return null;
|
|
891
|
-
const state = this.normalizeWorkflowState(data);
|
|
997
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
892
998
|
this.validateWorkflowState(state);
|
|
893
999
|
return state;
|
|
894
1000
|
} catch (error) {
|
|
895
|
-
this.logger.error("Error loading workflow snapshot:", {
|
|
1001
|
+
this.logger.error("Error loading workflow snapshot:", {
|
|
1002
|
+
error: error instanceof Error ? error.message : String(error)
|
|
1003
|
+
});
|
|
896
1004
|
return null;
|
|
897
1005
|
}
|
|
898
1006
|
}
|
|
@@ -912,7 +1020,8 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
912
1020
|
})
|
|
913
1021
|
);
|
|
914
1022
|
} catch (error) {
|
|
915
|
-
|
|
1023
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1024
|
+
this.logger.error("Error in batch insert:", { message });
|
|
916
1025
|
throw error;
|
|
917
1026
|
}
|
|
918
1027
|
}
|
|
@@ -921,7 +1030,9 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
921
1030
|
scope,
|
|
922
1031
|
page = 0,
|
|
923
1032
|
perPage = 100,
|
|
924
|
-
attributes
|
|
1033
|
+
attributes,
|
|
1034
|
+
fromDate,
|
|
1035
|
+
toDate
|
|
925
1036
|
}) {
|
|
926
1037
|
try {
|
|
927
1038
|
let keys;
|
|
@@ -960,6 +1071,12 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
960
1071
|
return Object.entries(attributes).every(([key, value]) => recordAttrs[key] === value);
|
|
961
1072
|
});
|
|
962
1073
|
}
|
|
1074
|
+
if (fromDate) {
|
|
1075
|
+
filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() >= fromDate.getTime());
|
|
1076
|
+
}
|
|
1077
|
+
if (toDate) {
|
|
1078
|
+
filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() <= toDate.getTime());
|
|
1079
|
+
}
|
|
963
1080
|
filteredTraces.sort((a, b) => {
|
|
964
1081
|
const dateA = new Date(a.createdAt).getTime();
|
|
965
1082
|
const dateB = new Date(b.createdAt).getTime();
|
|
@@ -985,7 +1102,8 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
985
1102
|
createdAt: record.createdAt
|
|
986
1103
|
}));
|
|
987
1104
|
} catch (error) {
|
|
988
|
-
|
|
1105
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1106
|
+
this.logger.error("Failed to get traces:", { message });
|
|
989
1107
|
return [];
|
|
990
1108
|
}
|
|
991
1109
|
}
|
|
@@ -1002,11 +1120,131 @@ var CloudflareStore = class extends storage.MastraStorage {
|
|
|
1002
1120
|
getEvalsByAgentName(_agentName, _type) {
|
|
1003
1121
|
throw new Error("Method not implemented.");
|
|
1004
1122
|
}
|
|
1005
|
-
|
|
1123
|
+
parseWorkflowRun(row) {
|
|
1124
|
+
let parsedSnapshot = row.snapshot;
|
|
1125
|
+
if (typeof parsedSnapshot === "string") {
|
|
1126
|
+
try {
|
|
1127
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1128
|
+
} catch (e) {
|
|
1129
|
+
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return {
|
|
1133
|
+
workflowName: row.workflow_name,
|
|
1134
|
+
runId: row.run_id,
|
|
1135
|
+
snapshot: parsedSnapshot,
|
|
1136
|
+
createdAt: this.ensureDate(row.createdAt),
|
|
1137
|
+
updatedAt: this.ensureDate(row.updatedAt),
|
|
1138
|
+
resourceId: row.resourceId
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
buildWorkflowSnapshotPrefix({
|
|
1142
|
+
namespace,
|
|
1143
|
+
workflowName,
|
|
1144
|
+
runId,
|
|
1145
|
+
resourceId
|
|
1146
|
+
}) {
|
|
1147
|
+
const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
|
|
1148
|
+
let key = `${prefix}${storage.TABLE_WORKFLOW_SNAPSHOT}`;
|
|
1149
|
+
if (namespace) key += `:${namespace}`;
|
|
1150
|
+
if (workflowName) key += `:${workflowName}`;
|
|
1151
|
+
if (runId) key += `:${runId}`;
|
|
1152
|
+
if (resourceId) key += `:${resourceId}`;
|
|
1153
|
+
if (!resourceId && (runId || workflowName || namespace)) key += ":";
|
|
1154
|
+
return key;
|
|
1155
|
+
}
|
|
1156
|
+
async getWorkflowRuns({
|
|
1157
|
+
namespace,
|
|
1158
|
+
workflowName,
|
|
1159
|
+
limit = 20,
|
|
1160
|
+
offset = 0,
|
|
1161
|
+
resourceId,
|
|
1162
|
+
fromDate,
|
|
1163
|
+
toDate
|
|
1164
|
+
} = {}) {
|
|
1165
|
+
try {
|
|
1166
|
+
const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName });
|
|
1167
|
+
const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
|
|
1168
|
+
const runs = [];
|
|
1169
|
+
for (const { name: key } of keyObjs) {
|
|
1170
|
+
const parts = key.split(":");
|
|
1171
|
+
const idx = parts.indexOf(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1172
|
+
if (idx === -1 || parts.length < idx + 4) continue;
|
|
1173
|
+
const ns = parts[idx + 1];
|
|
1174
|
+
const wfName = parts[idx + 2];
|
|
1175
|
+
const keyResourceId = parts.length > idx + 4 ? parts[idx + 4] : void 0;
|
|
1176
|
+
if (namespace && ns !== namespace || workflowName && wfName !== workflowName) continue;
|
|
1177
|
+
if (resourceId && keyResourceId && keyResourceId !== resourceId) continue;
|
|
1178
|
+
const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
|
|
1179
|
+
if (!data) continue;
|
|
1180
|
+
try {
|
|
1181
|
+
if (resourceId && data.resourceId && data.resourceId !== resourceId) continue;
|
|
1182
|
+
const createdAt = this.ensureDate(data.createdAt);
|
|
1183
|
+
if (fromDate && createdAt && createdAt < fromDate) continue;
|
|
1184
|
+
if (toDate && createdAt && createdAt > toDate) continue;
|
|
1185
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
1186
|
+
this.validateWorkflowState(state);
|
|
1187
|
+
const run = this.parseWorkflowRun({ ...data, snapshot: state });
|
|
1188
|
+
runs.push(run);
|
|
1189
|
+
} catch (err) {
|
|
1190
|
+
this.logger.error("Failed to parse workflow snapshot:", { key, error: err });
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
runs.sort((a, b) => {
|
|
1194
|
+
const aDate = a.createdAt ? new Date(a.createdAt).getTime() : 0;
|
|
1195
|
+
const bDate = b.createdAt ? new Date(b.createdAt).getTime() : 0;
|
|
1196
|
+
return bDate - aDate;
|
|
1197
|
+
});
|
|
1198
|
+
const pagedRuns = runs.slice(offset, offset + limit);
|
|
1199
|
+
return {
|
|
1200
|
+
runs: pagedRuns,
|
|
1201
|
+
total: runs.length
|
|
1202
|
+
};
|
|
1203
|
+
} catch (error) {
|
|
1204
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1205
|
+
this.logger.error("Error in getWorkflowRuns:", { message });
|
|
1206
|
+
return { runs: [], total: 0 };
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
async getWorkflowRunById({
|
|
1210
|
+
namespace,
|
|
1211
|
+
runId,
|
|
1212
|
+
workflowName
|
|
1213
|
+
}) {
|
|
1214
|
+
try {
|
|
1215
|
+
if (!runId || !workflowName || !namespace) {
|
|
1216
|
+
throw new Error("runId, workflowName, and namespace are required");
|
|
1217
|
+
}
|
|
1218
|
+
const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName, runId });
|
|
1219
|
+
const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
|
|
1220
|
+
if (!keyObjs.length) return null;
|
|
1221
|
+
const key = keyObjs[0]?.name;
|
|
1222
|
+
const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
|
|
1223
|
+
if (!data) return null;
|
|
1224
|
+
const state = this.normalizeWorkflowState(data.snapshot || data);
|
|
1225
|
+
this.validateWorkflowState(state);
|
|
1226
|
+
return this.parseWorkflowRun({ ...data, snapshot: state });
|
|
1227
|
+
} catch (error) {
|
|
1228
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1229
|
+
this.logger.error("Error in getWorkflowRunById:", { message });
|
|
1230
|
+
return null;
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
async getTracesPaginated(_args) {
|
|
1234
|
+
throw new Error("Method not implemented.");
|
|
1235
|
+
}
|
|
1236
|
+
async getThreadsByResourceIdPaginated(_args) {
|
|
1237
|
+
throw new Error("Method not implemented.");
|
|
1238
|
+
}
|
|
1239
|
+
async getMessagesPaginated(_args) {
|
|
1006
1240
|
throw new Error("Method not implemented.");
|
|
1007
1241
|
}
|
|
1008
1242
|
async close() {
|
|
1009
1243
|
}
|
|
1244
|
+
async updateMessages(_args) {
|
|
1245
|
+
this.logger.error("updateMessages is not yet implemented in CloudflareStore");
|
|
1246
|
+
throw new Error("Method not implemented");
|
|
1247
|
+
}
|
|
1010
1248
|
};
|
|
1011
1249
|
|
|
1012
1250
|
exports.CloudflareStore = CloudflareStore;
|