@mastra/cloudflare 1.0.0-beta.1 → 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 CHANGED
@@ -1,5 +1,39 @@
1
1
  # @mastra/cloudflare
2
2
 
3
+ ## 1.0.0-beta.3
4
+
5
+ ### Patch Changes
6
+
7
+ - feat(storage): support querying messages from multiple threads ([#10663](https://github.com/mastra-ai/mastra/pull/10663))
8
+ - Fixed TypeScript errors where `threadId: string | string[]` was being passed to places expecting `Scalar` type
9
+ - Added proper multi-thread support for `listMessages` across all adapters when `threadId` is an array
10
+ - Updated `_getIncludedMessages` to look up message threadId by ID (since message IDs are globally unique)
11
+ - **upstash**: Added `msg-idx:{messageId}` index for O(1) message lookups (backwards compatible with fallback to scan for old messages, with automatic backfill)
12
+
13
+ - fix: ensure score responses match saved payloads for Mastra Stores. ([#10557](https://github.com/mastra-ai/mastra/pull/10557))
14
+
15
+ - Unify transformScoreRow functions across storage adapters ([#10648](https://github.com/mastra-ai/mastra/pull/10648))
16
+
17
+ Added a unified `transformScoreRow` function in `@mastra/core/storage` that provides schema-driven row transformation for score data. This eliminates code duplication across 10 storage adapters while maintaining store-specific behavior through configurable options:
18
+ - `preferredTimestampFields`: Preferred source fields for timestamps (PostgreSQL, Cloudflare D1)
19
+ - `convertTimestamps`: Convert timestamp strings to Date objects (MSSQL, MongoDB, ClickHouse)
20
+ - `nullValuePattern`: Skip values matching pattern (ClickHouse's `'_null_'`)
21
+ - `fieldMappings`: Map source column names to schema fields (LibSQL's `additionalLLMContext`)
22
+
23
+ Each store adapter now uses the unified function with appropriate options, reducing ~200 lines of duplicate transformation logic while ensuring consistent behavior across all storage backends.
24
+
25
+ - Updated dependencies [[`ac0d2f4`](https://github.com/mastra-ai/mastra/commit/ac0d2f4ff8831f72c1c66c2be809706d17f65789), [`1a0d3fc`](https://github.com/mastra-ai/mastra/commit/1a0d3fc811482c9c376cdf79ee615c23bae9b2d6), [`85a628b`](https://github.com/mastra-ai/mastra/commit/85a628b1224a8f64cd82ea7f033774bf22df7a7e), [`c237233`](https://github.com/mastra-ai/mastra/commit/c23723399ccedf7f5744b3f40997b79246bfbe64), [`15f9e21`](https://github.com/mastra-ai/mastra/commit/15f9e216177201ea6e3f6d0bfb063fcc0953444f), [`ff94dea`](https://github.com/mastra-ai/mastra/commit/ff94dea935f4e34545c63bcb6c29804732698809), [`5b2ff46`](https://github.com/mastra-ai/mastra/commit/5b2ff4651df70c146523a7fca773f8eb0a2272f8), [`db41688`](https://github.com/mastra-ai/mastra/commit/db4168806d007417e2e60b4f68656dca4e5f40c9), [`5ca599d`](https://github.com/mastra-ai/mastra/commit/5ca599d0bb59a1595f19f58473fcd67cc71cef58), [`bff1145`](https://github.com/mastra-ai/mastra/commit/bff114556b3cbadad9b2768488708f8ad0e91475), [`5c8ca24`](https://github.com/mastra-ai/mastra/commit/5c8ca247094e0cc2cdbd7137822fb47241f86e77), [`e191844`](https://github.com/mastra-ai/mastra/commit/e1918444ca3f80e82feef1dad506cd4ec6e2875f), [`22553f1`](https://github.com/mastra-ai/mastra/commit/22553f11c63ee5e966a9c034a349822249584691), [`7237163`](https://github.com/mastra-ai/mastra/commit/72371635dbf96a87df4b073cc48fc655afbdce3d), [`2500740`](https://github.com/mastra-ai/mastra/commit/2500740ea23da067d6e50ec71c625ab3ce275e64), [`873ecbb`](https://github.com/mastra-ai/mastra/commit/873ecbb517586aa17d2f1e99283755b3ebb2863f), [`4f9bbe5`](https://github.com/mastra-ai/mastra/commit/4f9bbe5968f42c86f4930b8193de3c3c17e5bd36), [`02e51fe`](https://github.com/mastra-ai/mastra/commit/02e51feddb3d4155cfbcc42624fd0d0970d032c0), [`8f3fa3a`](https://github.com/mastra-ai/mastra/commit/8f3fa3a652bb77da092f913ec51ae46e3a7e27dc), [`cd29ad2`](https://github.com/mastra-ai/mastra/commit/cd29ad23a255534e8191f249593849ed29160886), [`bdf4d8c`](https://github.com/mastra-ai/mastra/commit/bdf4d8cdc656d8a2c21d81834bfa3bfa70f56c16), [`854e3da`](https://github.com/mastra-ai/mastra/commit/854e3dad5daac17a91a20986399d3a51f54bf68b), [`ce18d38`](https://github.com/mastra-ai/mastra/commit/ce18d38678c65870350d123955014a8432075fd9), [`cccf9c8`](https://github.com/mastra-ai/mastra/commit/cccf9c8b2d2dfc1a5e63919395b83d78c89682a0), [`61a5705`](https://github.com/mastra-ai/mastra/commit/61a570551278b6743e64243b3ce7d73de915ca8a), [`db70a48`](https://github.com/mastra-ai/mastra/commit/db70a48aeeeeb8e5f92007e8ede52c364ce15287), [`f0fdc14`](https://github.com/mastra-ai/mastra/commit/f0fdc14ee233d619266b3d2bbdeea7d25cfc6d13), [`db18bc9`](https://github.com/mastra-ai/mastra/commit/db18bc9c3825e2c1a0ad9a183cc9935f6691bfa1), [`9b37b56`](https://github.com/mastra-ai/mastra/commit/9b37b565e1f2a76c24f728945cc740c2b09be9da), [`41a23c3`](https://github.com/mastra-ai/mastra/commit/41a23c32f9877d71810f37e24930515df2ff7a0f), [`5d171ad`](https://github.com/mastra-ai/mastra/commit/5d171ad9ef340387276b77c2bb3e83e83332d729), [`f03ae60`](https://github.com/mastra-ai/mastra/commit/f03ae60500fe350c9d828621006cdafe1975fdd8), [`d1e74a0`](https://github.com/mastra-ai/mastra/commit/d1e74a0a293866dece31022047f5dbab65a304d0), [`39e7869`](https://github.com/mastra-ai/mastra/commit/39e7869bc7d0ee391077ce291474d8a84eedccff), [`5761926`](https://github.com/mastra-ai/mastra/commit/57619260c4a2cdd598763abbacd90de594c6bc76), [`c900fdd`](https://github.com/mastra-ai/mastra/commit/c900fdd504c41348efdffb205cfe80d48c38fa33), [`604a79f`](https://github.com/mastra-ai/mastra/commit/604a79fecf276e26a54a3fe01bb94e65315d2e0e), [`887f0b4`](https://github.com/mastra-ai/mastra/commit/887f0b4746cdbd7cb7d6b17ac9f82aeb58037ea5), [`2562143`](https://github.com/mastra-ai/mastra/commit/256214336b4faa78646c9c1776612393790d8784), [`ef11a61`](https://github.com/mastra-ai/mastra/commit/ef11a61920fa0ed08a5b7ceedd192875af119749)]:
26
+ - @mastra/core@1.0.0-beta.6
27
+
28
+ ## 1.0.0-beta.2
29
+
30
+ ### Patch Changes
31
+
32
+ - Fix message sorting in listMessages when using semantic recall (include parameter). Messages are now always sorted by createdAt instead of storage order, ensuring correct chronological ordering of conversation history. ([#10491](https://github.com/mastra-ai/mastra/pull/10491))
33
+
34
+ - Updated dependencies [[`21a15de`](https://github.com/mastra-ai/mastra/commit/21a15de369fe82aac26bb642ed7be73505475e8b), [`feb7ee4`](https://github.com/mastra-ai/mastra/commit/feb7ee4d09a75edb46c6669a3beaceec78811747), [`b0e2ea5`](https://github.com/mastra-ai/mastra/commit/b0e2ea5b52c40fae438b9e2f7baee6f0f89c5442), [`c456e01`](https://github.com/mastra-ai/mastra/commit/c456e0149e3c176afcefdbd9bb1d2c5917723725), [`ab035c2`](https://github.com/mastra-ai/mastra/commit/ab035c2ef6d8cc7bb25f06f1a38508bd9e6f126b), [`1a46a56`](https://github.com/mastra-ai/mastra/commit/1a46a566f45a3fcbadc1cf36bf86d351f264bfa3), [`3cf540b`](https://github.com/mastra-ai/mastra/commit/3cf540b9fbfea8f4fc8d3a2319a4e6c0b0cbfd52), [`1c6ce51`](https://github.com/mastra-ai/mastra/commit/1c6ce51f875915ab57fd36873623013699a2a65d), [`898a972`](https://github.com/mastra-ai/mastra/commit/898a9727d286c2510d6b702dfd367e6aaf5c6b0f), [`a97003a`](https://github.com/mastra-ai/mastra/commit/a97003aa1cf2f4022a41912324a1e77263b326b8), [`ccc141e`](https://github.com/mastra-ai/mastra/commit/ccc141ed27da0abc3a3fc28e9e5128152e8e37f4), [`fe3b897`](https://github.com/mastra-ai/mastra/commit/fe3b897c2ccbcd2b10e81b099438c7337feddf89), [`00123ba`](https://github.com/mastra-ai/mastra/commit/00123ba96dc9e5cd0b110420ebdba56d8f237b25), [`29c4309`](https://github.com/mastra-ai/mastra/commit/29c4309f818b24304c041bcb4a8f19b5f13f6b62), [`16785ce`](https://github.com/mastra-ai/mastra/commit/16785ced928f6f22638f4488cf8a125d99211799), [`de8239b`](https://github.com/mastra-ai/mastra/commit/de8239bdcb1d8c0cfa06da21f1569912a66bbc8a), [`b5e6cd7`](https://github.com/mastra-ai/mastra/commit/b5e6cd77fc8c8e64e0494c1d06cee3d84e795d1e), [`3759cb0`](https://github.com/mastra-ai/mastra/commit/3759cb064935b5f74c65ac2f52a1145f7352899d), [`651e772`](https://github.com/mastra-ai/mastra/commit/651e772eb1475fb13e126d3fcc01751297a88214), [`b61b93f`](https://github.com/mastra-ai/mastra/commit/b61b93f9e058b11dd2eec169853175d31dbdd567), [`bae33d9`](https://github.com/mastra-ai/mastra/commit/bae33d91a63fbb64d1e80519e1fc1acaed1e9013), [`c0b731f`](https://github.com/mastra-ai/mastra/commit/c0b731fb27d712dc8582e846df5c0332a6a0c5ba), [`43ca8f2`](https://github.com/mastra-ai/mastra/commit/43ca8f2c7334851cc7b4d3d2f037d8784bfbdd5f), [`2ca67cc`](https://github.com/mastra-ai/mastra/commit/2ca67cc3bb1f6a617353fdcab197d9efebe60d6f), [`9e67002`](https://github.com/mastra-ai/mastra/commit/9e67002b52c9be19936c420a489dbee9c5fd6a78), [`35edc49`](https://github.com/mastra-ai/mastra/commit/35edc49ac0556db609189641d6341e76771b81fc)]:
35
+ - @mastra/core@1.0.0-beta.5
36
+
3
37
  ## 1.0.0-beta.1
4
38
 
5
39
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -213,6 +213,17 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
213
213
  );
214
214
  }
215
215
  }
216
+ /**
217
+ * Searches all threads in the KV store to find a message by its ID.
218
+ *
219
+ * **Performance Warning**: This method sequentially scans all threads to locate
220
+ * the message. For stores with many threads, this can result in significant
221
+ * latency and API calls. When possible, callers should provide the `threadId`
222
+ * directly to avoid this full scan.
223
+ *
224
+ * @param messageId - The globally unique message ID to search for
225
+ * @returns The message with its threadId if found, null otherwise
226
+ */
216
227
  async findMessageInAnyThread(messageId) {
217
228
  try {
218
229
  const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
@@ -442,10 +453,25 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
442
453
  async getFullOrder(orderKey) {
443
454
  return this.getRange(orderKey, 0, -1);
444
455
  }
445
- async getIncludedMessagesWithContext(threadId, include, messageIds) {
456
+ /**
457
+ * Retrieves messages specified in the include array along with their surrounding context.
458
+ *
459
+ * **Performance Note**: When `threadId` is not provided in an include entry, this method
460
+ * must call `findMessageInAnyThread` which sequentially scans all threads in the KV store.
461
+ * For optimal performance, callers should provide `threadId` in include entries when known.
462
+ *
463
+ * @param include - Array of message IDs to include, optionally with context windows
464
+ * @param messageIds - Set to accumulate the message IDs that should be fetched
465
+ */
466
+ async getIncludedMessagesWithContext(include, messageIds) {
446
467
  await Promise.all(
447
468
  include.map(async (item) => {
448
- const targetThreadId = item.threadId || threadId;
469
+ let targetThreadId = item.threadId;
470
+ if (!targetThreadId) {
471
+ const foundMessage = await this.findMessageInAnyThread(item.id);
472
+ if (!foundMessage) return;
473
+ targetThreadId = foundMessage.threadId;
474
+ }
449
475
  if (!targetThreadId) return;
450
476
  const threadMessagesKey = this.getThreadMessagesKey(targetThreadId);
451
477
  messageIds.add(item.id);
@@ -478,6 +504,13 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
478
504
  this.logger?.debug(`No message order found for thread ${threadId}, skipping latest messages`);
479
505
  }
480
506
  }
507
+ /**
508
+ * Fetches and parses messages from one or more threads.
509
+ *
510
+ * **Performance Note**: When neither `include` entries with `threadId` nor `targetThreadId`
511
+ * are provided, this method falls back to `findMessageInAnyThread` which scans all threads.
512
+ * For optimal performance, provide `threadId` in include entries or specify `targetThreadId`.
513
+ */
481
514
  async fetchAndParseMessagesFromMultipleThreads(messageIds, include, targetThreadId) {
482
515
  const messageIdToThreadId = /* @__PURE__ */ new Map();
483
516
  if (include) {
@@ -519,6 +552,14 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
519
552
  );
520
553
  return messages.filter((msg) => msg !== null);
521
554
  }
555
+ /**
556
+ * Retrieves messages by their IDs.
557
+ *
558
+ * **Performance Warning**: This method calls `findMessageInAnyThread` for each message ID,
559
+ * which scans all threads in the KV store. For large numbers of messages or threads,
560
+ * this can result in significant latency. Consider using `listMessages` with specific
561
+ * thread IDs when the thread context is known.
562
+ */
522
563
  async listMessagesById({ messageIds }) {
523
564
  if (messageIds.length === 0) return { messages: [] };
524
565
  try {
@@ -552,15 +593,17 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
552
593
  }
553
594
  async listMessages(args) {
554
595
  const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
555
- if (!threadId.trim()) {
596
+ const threadIds = Array.isArray(threadId) ? threadId : [threadId];
597
+ const isValidThreadId = (id) => typeof id === "string" && id.trim().length > 0;
598
+ if (threadIds.length === 0 || threadIds.some((id) => !isValidThreadId(id))) {
556
599
  throw new error.MastraError(
557
600
  {
558
601
  id: "STORAGE_CLOUDFLARE_LIST_MESSAGES_INVALID_THREAD_ID",
559
602
  domain: error.ErrorDomain.STORAGE,
560
603
  category: error.ErrorCategory.THIRD_PARTY,
561
- details: { threadId }
604
+ details: { threadId: Array.isArray(threadId) ? JSON.stringify(threadId) : String(threadId) }
562
605
  },
563
- new Error("threadId must be a non-empty string")
606
+ new Error("threadId must be a non-empty string or array of non-empty strings")
564
607
  );
565
608
  }
566
609
  const perPage = storage.normalizePerPage(perPageInput, 40);
@@ -578,69 +621,34 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
578
621
  );
579
622
  }
580
623
  const { field, direction } = this.parseOrderBy(orderBy, "ASC");
581
- const messageIds = /* @__PURE__ */ new Set();
582
- const hasFilters = !!resourceId || !!filter?.dateRange;
583
- if (hasFilters || perPage === Number.MAX_SAFE_INTEGER) {
624
+ const threadMessageIds = /* @__PURE__ */ new Set();
625
+ for (const tid of threadIds) {
584
626
  try {
585
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
627
+ const threadMessagesKey = this.getThreadMessagesKey(tid);
586
628
  const allIds = await this.getFullOrder(threadMessagesKey);
587
- allIds.forEach((id) => messageIds.add(id));
629
+ allIds.forEach((id) => threadMessageIds.add(id));
588
630
  } catch {
589
631
  }
590
- } else {
591
- if (perPage > 0) {
592
- try {
593
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
594
- const fullOrder = await this.getFullOrder(threadMessagesKey);
595
- const totalMessages = fullOrder.length;
596
- let start;
597
- let end;
598
- if (direction === "ASC") {
599
- start = offset;
600
- end = Math.min(offset + perPage - 1, totalMessages - 1);
601
- } else {
602
- start = Math.max(totalMessages - offset - perPage, 0);
603
- end = totalMessages - offset - 1;
604
- }
605
- const paginatedIds = await this.getRange(threadMessagesKey, start, end);
606
- paginatedIds.forEach((id) => messageIds.add(id));
607
- } catch {
608
- }
609
- }
610
632
  }
611
- if (include && include.length > 0) {
612
- await this.getIncludedMessagesWithContext(threadId, include, messageIds);
613
- }
614
- const messages = await this.fetchAndParseMessagesFromMultipleThreads(
615
- Array.from(messageIds),
616
- include,
617
- include && include.length > 0 ? void 0 : threadId
633
+ const threadMessages = await this.fetchAndParseMessagesFromMultipleThreads(
634
+ Array.from(threadMessageIds),
635
+ void 0,
636
+ threadIds.length === 1 ? threadIds[0] : void 0
618
637
  );
619
- let filteredMessages = messages;
638
+ let filteredThreadMessages = threadMessages;
620
639
  if (resourceId) {
621
- filteredMessages = filteredMessages.filter((msg) => msg.resourceId === resourceId);
640
+ filteredThreadMessages = filteredThreadMessages.filter((msg) => msg.resourceId === resourceId);
622
641
  }
623
642
  const dateRange = filter?.dateRange;
624
643
  if (dateRange) {
625
- filteredMessages = filteredMessages.filter((msg) => {
644
+ filteredThreadMessages = filteredThreadMessages.filter((msg) => {
626
645
  const messageDate = new Date(msg.createdAt);
627
646
  if (dateRange.start && messageDate < new Date(dateRange.start)) return false;
628
647
  if (dateRange.end && messageDate > new Date(dateRange.end)) return false;
629
648
  return true;
630
649
  });
631
650
  }
632
- let total;
633
- if (hasFilters) {
634
- total = filteredMessages.length;
635
- } else {
636
- try {
637
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
638
- const fullOrder = await this.getFullOrder(threadMessagesKey);
639
- total = fullOrder.length;
640
- } catch {
641
- total = filteredMessages.length;
642
- }
643
- }
651
+ const total = filteredThreadMessages.length;
644
652
  if (perPage === 0 && (!include || include.length === 0)) {
645
653
  return {
646
654
  messages: [],
@@ -650,45 +658,58 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
650
658
  hasMore: offset < total
651
659
  };
652
660
  }
653
- if (hasFilters && perPage !== Number.MAX_SAFE_INTEGER && perPage > 0) {
654
- if (direction === "ASC") {
655
- filteredMessages = filteredMessages.slice(offset, offset + perPage);
656
- } else {
657
- const start = Math.max(filteredMessages.length - offset - perPage, 0);
658
- const end = filteredMessages.length - offset;
659
- filteredMessages = filteredMessages.slice(start, end);
661
+ filteredThreadMessages.sort((a, b) => {
662
+ const timeA = new Date(a.createdAt).getTime();
663
+ const timeB = new Date(b.createdAt).getTime();
664
+ const timeDiff = direction === "ASC" ? timeA - timeB : timeB - timeA;
665
+ if (timeDiff === 0) {
666
+ return a.id.localeCompare(b.id);
660
667
  }
668
+ return timeDiff;
669
+ });
670
+ let paginatedMessages;
671
+ if (perPage === 0) {
672
+ paginatedMessages = [];
673
+ } else if (perPage === Number.MAX_SAFE_INTEGER) {
674
+ paginatedMessages = filteredThreadMessages;
675
+ } else {
676
+ paginatedMessages = filteredThreadMessages.slice(offset, offset + perPage);
661
677
  }
662
- const paginatedCount = hasFilters && perPage !== Number.MAX_SAFE_INTEGER && perPage > 0 ? filteredMessages.length : filteredMessages.length;
663
- try {
664
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
665
- const messageOrder = await this.getFullOrder(threadMessagesKey);
666
- const orderMap = new Map(messageOrder.map((id, index) => [id, index]));
667
- filteredMessages.sort((a, b) => {
668
- const indexA = orderMap.get(a.id);
669
- const indexB = orderMap.get(b.id);
670
- if (indexA !== void 0 && indexB !== void 0) {
671
- return direction === "ASC" ? indexA - indexB : indexB - indexA;
672
- }
673
- const timeA = new Date(a.createdAt).getTime();
674
- const timeB = new Date(b.createdAt).getTime();
675
- const timeDiff = direction === "ASC" ? timeA - timeB : timeB - timeA;
676
- if (timeDiff === 0) {
677
- return a.id.localeCompare(b.id);
678
- }
679
- return timeDiff;
680
- });
681
- } catch {
682
- filteredMessages.sort((a, b) => {
683
- const timeA = new Date(a.createdAt).getTime();
684
- const timeB = new Date(b.createdAt).getTime();
685
- const timeDiff = direction === "ASC" ? timeA - timeB : timeB - timeA;
686
- if (timeDiff === 0) {
687
- return a.id.localeCompare(b.id);
688
- }
689
- return timeDiff;
690
- });
678
+ let includedMessages = [];
679
+ if (include && include.length > 0) {
680
+ const includedMessageIds = /* @__PURE__ */ new Set();
681
+ await this.getIncludedMessagesWithContext(include, includedMessageIds);
682
+ const paginatedIds = new Set(paginatedMessages.map((m) => m.id));
683
+ const idsToFetch = Array.from(includedMessageIds).filter((id) => !paginatedIds.has(id));
684
+ if (idsToFetch.length > 0) {
685
+ includedMessages = await this.fetchAndParseMessagesFromMultipleThreads(idsToFetch, include, void 0);
686
+ }
687
+ }
688
+ const seenIds = /* @__PURE__ */ new Set();
689
+ const allMessages = [];
690
+ for (const msg of paginatedMessages) {
691
+ if (!seenIds.has(msg.id)) {
692
+ allMessages.push(msg);
693
+ seenIds.add(msg.id);
694
+ }
691
695
  }
696
+ for (const msg of includedMessages) {
697
+ if (!seenIds.has(msg.id)) {
698
+ allMessages.push(msg);
699
+ seenIds.add(msg.id);
700
+ }
701
+ }
702
+ allMessages.sort((a, b) => {
703
+ const timeA = new Date(a.createdAt).getTime();
704
+ const timeB = new Date(b.createdAt).getTime();
705
+ const timeDiff = direction === "ASC" ? timeA - timeB : timeB - timeA;
706
+ if (timeDiff === 0) {
707
+ return a.id.localeCompare(b.id);
708
+ }
709
+ return timeDiff;
710
+ });
711
+ let filteredMessages = allMessages;
712
+ const paginatedCount = paginatedMessages.length;
692
713
  if (total === 0 && filteredMessages.length === 0 && (!include || include.length === 0)) {
693
714
  return {
694
715
  messages: [],
@@ -703,7 +724,11 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
703
724
  type: message.type !== "v2" ? message.type : void 0,
704
725
  createdAt: storage.ensureDate(message.createdAt)
705
726
  }));
706
- const list = new agent.MessageList({ threadId, resourceId }).add(prepared, "memory");
727
+ const primaryThreadId = Array.isArray(threadId) ? threadId[0] : threadId;
728
+ const list = new agent.MessageList({ threadId: primaryThreadId, resourceId }).add(
729
+ prepared,
730
+ "memory"
731
+ );
707
732
  let finalMessages = list.get.all.db();
708
733
  finalMessages = finalMessages.sort((a, b) => {
709
734
  const isDateField = field === "createdAt" || field === "updatedAt";
@@ -719,16 +744,12 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
719
744
  const cmp = direction === "ASC" ? String(aVal).localeCompare(String(bVal)) : String(bVal).localeCompare(String(aVal));
720
745
  return cmp !== 0 ? cmp : a.id.localeCompare(b.id);
721
746
  });
722
- const returnedThreadMessageIds = new Set(finalMessages.filter((m) => m.threadId === threadId).map((m) => m.id));
747
+ const threadIdSet = new Set(threadIds);
748
+ const returnedThreadMessageIds = new Set(
749
+ finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
750
+ );
723
751
  const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
724
- let hasMore;
725
- if (perPageInput === false || allThreadMessagesReturned) {
726
- hasMore = false;
727
- } else if (direction === "ASC") {
728
- hasMore = offset + paginatedCount < total;
729
- } else {
730
- hasMore = total - offset - perPage > 0;
731
- }
752
+ const hasMore = perPageInput !== false && !allThreadMessagesReturned && offset + paginatedCount < total;
732
753
  return {
733
754
  messages: finalMessages,
734
755
  total,
@@ -742,9 +763,9 @@ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
742
763
  id: "CLOUDFLARE_STORAGE_LIST_MESSAGES_FAILED",
743
764
  domain: error.ErrorDomain.STORAGE,
744
765
  category: error.ErrorCategory.THIRD_PARTY,
745
- text: `Failed to list messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
766
+ text: `Failed to list messages for thread ${Array.isArray(threadId) ? threadId.join(",") : threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
746
767
  details: {
747
- threadId,
768
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
748
769
  resourceId: resourceId ?? ""
749
770
  }
750
771
  },
@@ -1496,17 +1517,7 @@ var StoreOperationsCloudflare = class extends storage.StoreOperations {
1496
1517
  }
1497
1518
  };
1498
1519
  function transformScoreRow(row) {
1499
- const deserialized = { ...row };
1500
- deserialized.input = storage.safelyParseJSON(row.input);
1501
- deserialized.output = storage.safelyParseJSON(row.output);
1502
- deserialized.scorer = storage.safelyParseJSON(row.scorer);
1503
- deserialized.preprocessStepResult = storage.safelyParseJSON(row.preprocessStepResult);
1504
- deserialized.analyzeStepResult = storage.safelyParseJSON(row.analyzeStepResult);
1505
- deserialized.metadata = storage.safelyParseJSON(row.metadata);
1506
- deserialized.additionalContext = storage.safelyParseJSON(row.additionalContext);
1507
- deserialized.requestContext = storage.safelyParseJSON(row.requestContext);
1508
- deserialized.entity = storage.safelyParseJSON(row.entity);
1509
- return deserialized;
1520
+ return storage.transformScoreRow(row);
1510
1521
  }
1511
1522
  var ScoresStorageCloudflare = class extends storage.ScoresStorage {
1512
1523
  operations;