@mastra/cloudflare 1.0.0-beta.2 → 1.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/index.cjs +69 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +70 -28
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +36 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
2
|
-
import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCORERS, StoreOperations, TABLE_TRACES, WorkflowsStorage, ensureDate, normalizePerPage, MemoryStorage, calculatePagination, serializeDate, TABLE_RESOURCES, ScoresStorage,
|
|
2
|
+
import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_SCORERS, StoreOperations, TABLE_TRACES, WorkflowsStorage, ensureDate, normalizePerPage, MemoryStorage, calculatePagination, serializeDate, TABLE_RESOURCES, ScoresStorage, transformScoreRow as transformScoreRow$1 } from '@mastra/core/storage';
|
|
3
3
|
import Cloudflare from 'cloudflare';
|
|
4
4
|
import { MessageList } from '@mastra/core/agent';
|
|
5
5
|
import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
@@ -207,6 +207,17 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
207
207
|
);
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Searches all threads in the KV store to find a message by its ID.
|
|
212
|
+
*
|
|
213
|
+
* **Performance Warning**: This method sequentially scans all threads to locate
|
|
214
|
+
* the message. For stores with many threads, this can result in significant
|
|
215
|
+
* latency and API calls. When possible, callers should provide the `threadId`
|
|
216
|
+
* directly to avoid this full scan.
|
|
217
|
+
*
|
|
218
|
+
* @param messageId - The globally unique message ID to search for
|
|
219
|
+
* @returns The message with its threadId if found, null otherwise
|
|
220
|
+
*/
|
|
210
221
|
async findMessageInAnyThread(messageId) {
|
|
211
222
|
try {
|
|
212
223
|
const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
|
|
@@ -436,10 +447,25 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
436
447
|
async getFullOrder(orderKey) {
|
|
437
448
|
return this.getRange(orderKey, 0, -1);
|
|
438
449
|
}
|
|
439
|
-
|
|
450
|
+
/**
|
|
451
|
+
* Retrieves messages specified in the include array along with their surrounding context.
|
|
452
|
+
*
|
|
453
|
+
* **Performance Note**: When `threadId` is not provided in an include entry, this method
|
|
454
|
+
* must call `findMessageInAnyThread` which sequentially scans all threads in the KV store.
|
|
455
|
+
* For optimal performance, callers should provide `threadId` in include entries when known.
|
|
456
|
+
*
|
|
457
|
+
* @param include - Array of message IDs to include, optionally with context windows
|
|
458
|
+
* @param messageIds - Set to accumulate the message IDs that should be fetched
|
|
459
|
+
*/
|
|
460
|
+
async getIncludedMessagesWithContext(include, messageIds) {
|
|
440
461
|
await Promise.all(
|
|
441
462
|
include.map(async (item) => {
|
|
442
|
-
|
|
463
|
+
let targetThreadId = item.threadId;
|
|
464
|
+
if (!targetThreadId) {
|
|
465
|
+
const foundMessage = await this.findMessageInAnyThread(item.id);
|
|
466
|
+
if (!foundMessage) return;
|
|
467
|
+
targetThreadId = foundMessage.threadId;
|
|
468
|
+
}
|
|
443
469
|
if (!targetThreadId) return;
|
|
444
470
|
const threadMessagesKey = this.getThreadMessagesKey(targetThreadId);
|
|
445
471
|
messageIds.add(item.id);
|
|
@@ -472,6 +498,13 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
472
498
|
this.logger?.debug(`No message order found for thread ${threadId}, skipping latest messages`);
|
|
473
499
|
}
|
|
474
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* Fetches and parses messages from one or more threads.
|
|
503
|
+
*
|
|
504
|
+
* **Performance Note**: When neither `include` entries with `threadId` nor `targetThreadId`
|
|
505
|
+
* are provided, this method falls back to `findMessageInAnyThread` which scans all threads.
|
|
506
|
+
* For optimal performance, provide `threadId` in include entries or specify `targetThreadId`.
|
|
507
|
+
*/
|
|
475
508
|
async fetchAndParseMessagesFromMultipleThreads(messageIds, include, targetThreadId) {
|
|
476
509
|
const messageIdToThreadId = /* @__PURE__ */ new Map();
|
|
477
510
|
if (include) {
|
|
@@ -513,6 +546,14 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
513
546
|
);
|
|
514
547
|
return messages.filter((msg) => msg !== null);
|
|
515
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* Retrieves messages by their IDs.
|
|
551
|
+
*
|
|
552
|
+
* **Performance Warning**: This method calls `findMessageInAnyThread` for each message ID,
|
|
553
|
+
* which scans all threads in the KV store. For large numbers of messages or threads,
|
|
554
|
+
* this can result in significant latency. Consider using `listMessages` with specific
|
|
555
|
+
* thread IDs when the thread context is known.
|
|
556
|
+
*/
|
|
516
557
|
async listMessagesById({ messageIds }) {
|
|
517
558
|
if (messageIds.length === 0) return { messages: [] };
|
|
518
559
|
try {
|
|
@@ -546,15 +587,17 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
546
587
|
}
|
|
547
588
|
async listMessages(args) {
|
|
548
589
|
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
549
|
-
|
|
590
|
+
const threadIds = Array.isArray(threadId) ? threadId : [threadId];
|
|
591
|
+
const isValidThreadId = (id) => typeof id === "string" && id.trim().length > 0;
|
|
592
|
+
if (threadIds.length === 0 || threadIds.some((id) => !isValidThreadId(id))) {
|
|
550
593
|
throw new MastraError(
|
|
551
594
|
{
|
|
552
595
|
id: "STORAGE_CLOUDFLARE_LIST_MESSAGES_INVALID_THREAD_ID",
|
|
553
596
|
domain: ErrorDomain.STORAGE,
|
|
554
597
|
category: ErrorCategory.THIRD_PARTY,
|
|
555
|
-
details: { threadId }
|
|
598
|
+
details: { threadId: Array.isArray(threadId) ? JSON.stringify(threadId) : String(threadId) }
|
|
556
599
|
},
|
|
557
|
-
new Error("threadId must be a non-empty string")
|
|
600
|
+
new Error("threadId must be a non-empty string or array of non-empty strings")
|
|
558
601
|
);
|
|
559
602
|
}
|
|
560
603
|
const perPage = normalizePerPage(perPageInput, 40);
|
|
@@ -573,16 +616,18 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
573
616
|
}
|
|
574
617
|
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
575
618
|
const threadMessageIds = /* @__PURE__ */ new Set();
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
619
|
+
for (const tid of threadIds) {
|
|
620
|
+
try {
|
|
621
|
+
const threadMessagesKey = this.getThreadMessagesKey(tid);
|
|
622
|
+
const allIds = await this.getFullOrder(threadMessagesKey);
|
|
623
|
+
allIds.forEach((id) => threadMessageIds.add(id));
|
|
624
|
+
} catch {
|
|
625
|
+
}
|
|
581
626
|
}
|
|
582
627
|
const threadMessages = await this.fetchAndParseMessagesFromMultipleThreads(
|
|
583
628
|
Array.from(threadMessageIds),
|
|
584
629
|
void 0,
|
|
585
|
-
|
|
630
|
+
threadIds.length === 1 ? threadIds[0] : void 0
|
|
586
631
|
);
|
|
587
632
|
let filteredThreadMessages = threadMessages;
|
|
588
633
|
if (resourceId) {
|
|
@@ -627,7 +672,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
627
672
|
let includedMessages = [];
|
|
628
673
|
if (include && include.length > 0) {
|
|
629
674
|
const includedMessageIds = /* @__PURE__ */ new Set();
|
|
630
|
-
await this.getIncludedMessagesWithContext(
|
|
675
|
+
await this.getIncludedMessagesWithContext(include, includedMessageIds);
|
|
631
676
|
const paginatedIds = new Set(paginatedMessages.map((m) => m.id));
|
|
632
677
|
const idsToFetch = Array.from(includedMessageIds).filter((id) => !paginatedIds.has(id));
|
|
633
678
|
if (idsToFetch.length > 0) {
|
|
@@ -673,7 +718,11 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
673
718
|
type: message.type !== "v2" ? message.type : void 0,
|
|
674
719
|
createdAt: ensureDate(message.createdAt)
|
|
675
720
|
}));
|
|
676
|
-
const
|
|
721
|
+
const primaryThreadId = Array.isArray(threadId) ? threadId[0] : threadId;
|
|
722
|
+
const list = new MessageList({ threadId: primaryThreadId, resourceId }).add(
|
|
723
|
+
prepared,
|
|
724
|
+
"memory"
|
|
725
|
+
);
|
|
677
726
|
let finalMessages = list.get.all.db();
|
|
678
727
|
finalMessages = finalMessages.sort((a, b) => {
|
|
679
728
|
const isDateField = field === "createdAt" || field === "updatedAt";
|
|
@@ -689,7 +738,10 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
689
738
|
const cmp = direction === "ASC" ? String(aVal).localeCompare(String(bVal)) : String(bVal).localeCompare(String(aVal));
|
|
690
739
|
return cmp !== 0 ? cmp : a.id.localeCompare(b.id);
|
|
691
740
|
});
|
|
692
|
-
const
|
|
741
|
+
const threadIdSet = new Set(threadIds);
|
|
742
|
+
const returnedThreadMessageIds = new Set(
|
|
743
|
+
finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
|
|
744
|
+
);
|
|
693
745
|
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
694
746
|
const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + paginatedCount < total;
|
|
695
747
|
return {
|
|
@@ -705,9 +757,9 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
|
|
|
705
757
|
id: "CLOUDFLARE_STORAGE_LIST_MESSAGES_FAILED",
|
|
706
758
|
domain: ErrorDomain.STORAGE,
|
|
707
759
|
category: ErrorCategory.THIRD_PARTY,
|
|
708
|
-
text: `Failed to list messages for thread ${threadId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
760
|
+
text: `Failed to list messages for thread ${Array.isArray(threadId) ? threadId.join(",") : threadId}: ${error instanceof Error ? error.message : String(error)}`,
|
|
709
761
|
details: {
|
|
710
|
-
threadId,
|
|
762
|
+
threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
|
|
711
763
|
resourceId: resourceId ?? ""
|
|
712
764
|
}
|
|
713
765
|
},
|
|
@@ -1459,17 +1511,7 @@ var StoreOperationsCloudflare = class extends StoreOperations {
|
|
|
1459
1511
|
}
|
|
1460
1512
|
};
|
|
1461
1513
|
function transformScoreRow(row) {
|
|
1462
|
-
|
|
1463
|
-
deserialized.input = safelyParseJSON(row.input);
|
|
1464
|
-
deserialized.output = safelyParseJSON(row.output);
|
|
1465
|
-
deserialized.scorer = safelyParseJSON(row.scorer);
|
|
1466
|
-
deserialized.preprocessStepResult = safelyParseJSON(row.preprocessStepResult);
|
|
1467
|
-
deserialized.analyzeStepResult = safelyParseJSON(row.analyzeStepResult);
|
|
1468
|
-
deserialized.metadata = safelyParseJSON(row.metadata);
|
|
1469
|
-
deserialized.additionalContext = safelyParseJSON(row.additionalContext);
|
|
1470
|
-
deserialized.requestContext = safelyParseJSON(row.requestContext);
|
|
1471
|
-
deserialized.entity = safelyParseJSON(row.entity);
|
|
1472
|
-
return deserialized;
|
|
1514
|
+
return transformScoreRow$1(row);
|
|
1473
1515
|
}
|
|
1474
1516
|
var ScoresStorageCloudflare = class extends ScoresStorage {
|
|
1475
1517
|
operations;
|