@mastra/cloudflare 0.13.2 → 0.13.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/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_EVALS, TABLE_SCORERS, TABLE_TRACES, StoreOperations, serializeDate, ensureDate, LegacyEvalsStorage, WorkflowsStorage, TracesStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES, ScoresStorage, safelyParseJSON } from '@mastra/core/storage';
2
+ import { MastraStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_WORKFLOW_SNAPSHOT, TABLE_EVALS, TABLE_SCORERS, TABLE_TRACES, StoreOperations, serializeDate, ensureDate, LegacyEvalsStorage, WorkflowsStorage, TracesStorage, MemoryStorage, resolveMessageLimit, TABLE_RESOURCES, ScoresStorage, SCORERS_SCHEMA, safelyParseJSON } 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/scores';
@@ -115,6 +115,17 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
115
115
  if (!metadata) return void 0;
116
116
  return typeof metadata === "string" ? JSON.parse(metadata) : metadata;
117
117
  }
118
+ /**
119
+ * Summarizes message content without exposing raw data (for logging).
120
+ * Returns type, length, and keys only to prevent PII leakage.
121
+ */
122
+ summarizeMessageContent(content) {
123
+ if (!content) return { type: "undefined" };
124
+ if (typeof content === "string") return { type: "string", length: content.length };
125
+ if (Array.isArray(content)) return { type: "array", length: content.length };
126
+ if (typeof content === "object") return { type: "object", keys: Object.keys(content) };
127
+ return { type: typeof content };
128
+ }
118
129
  async getThreadById({ threadId }) {
119
130
  const thread = await this.operations.load({ tableName: TABLE_THREADS, keys: { id: threadId } });
120
131
  if (!thread) return null;
@@ -292,7 +303,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
292
303
  return this.operations.getKey(TABLE_MESSAGES, { threadId, id: messageId });
293
304
  } catch (error) {
294
305
  const message = error instanceof Error ? error.message : String(error);
295
- this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
306
+ this.logger?.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
296
307
  throw error;
297
308
  }
298
309
  }
@@ -301,7 +312,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
301
312
  return this.operations.getKey(TABLE_MESSAGES, { threadId, id: "messages" });
302
313
  } catch (error) {
303
314
  const message = error instanceof Error ? error.message : String(error);
304
- this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { message });
315
+ this.logger?.error(`Error getting thread messages key for thread ${threadId}:`, { message });
305
316
  throw error;
306
317
  }
307
318
  }
@@ -391,7 +402,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
391
402
  });
392
403
  } catch (error) {
393
404
  const message = error instanceof Error ? error.message : String(error);
394
- this.logger.error(`Error updating sorted order for key ${orderKey}:`, { message });
405
+ this.logger?.error(`Error updating sorted order for key ${orderKey}:`, { message });
395
406
  throw error;
396
407
  } finally {
397
408
  if (this.updateQueue.get(orderKey) === nextPromise) {
@@ -409,7 +420,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
409
420
  const arr = JSON.parse(typeof raw === "string" ? raw : JSON.stringify(raw));
410
421
  return Array.isArray(arr) ? arr : [];
411
422
  } catch (e) {
412
- this.logger.error(`Error parsing order data for key ${orderKey}:`, { e });
423
+ this.logger?.error(`Error parsing order data for key ${orderKey}:`, { e });
413
424
  return [];
414
425
  }
415
426
  }
@@ -464,9 +475,11 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
464
475
  const messageMigrationTasks = [];
465
476
  for (const message of validatedMessages) {
466
477
  const existingMessage = await this.findMessageInAnyThread(message.id);
467
- console.info(`Checking message ${message.id}: existing=${existingMessage?.threadId}, new=${message.threadId}`);
478
+ this.logger?.debug(
479
+ `Checking message ${message.id}: existing=${existingMessage?.threadId}, new=${message.threadId}`
480
+ );
468
481
  if (existingMessage && existingMessage.threadId && existingMessage.threadId !== message.threadId) {
469
- console.info(`Migrating message ${message.id} from ${existingMessage.threadId} to ${message.threadId}`);
482
+ this.logger?.debug(`Migrating message ${message.id} from ${existingMessage.threadId} to ${message.threadId}`);
470
483
  messageMigrationTasks.push(this.migrateMessage(message.id, existingMessage.threadId, message.threadId));
471
484
  }
472
485
  }
@@ -495,10 +508,8 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
495
508
  ...cleanMessage,
496
509
  createdAt: serializeDate(cleanMessage.createdAt)
497
510
  };
498
- console.info(`Saving message ${message.id} with content:`, {
499
- content: serializedMessage.content,
500
- contentType: typeof serializedMessage.content,
501
- isArray: Array.isArray(serializedMessage.content)
511
+ this.logger?.debug(`Saving message ${message.id}`, {
512
+ contentSummary: this.summarizeMessageContent(serializedMessage.content)
502
513
  });
503
514
  await this.operations.putKV({ tableName: TABLE_MESSAGES, key, value: serializedMessage });
504
515
  })
@@ -562,9 +573,6 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
562
573
  async getLastN(orderKey, n) {
563
574
  return this.getRange(orderKey, -n, -1);
564
575
  }
565
- async getFullOrder(orderKey) {
566
- return this.getRange(orderKey, 0, -1);
567
- }
568
576
  async getIncludedMessagesWithContext(threadId, include, messageIds) {
569
577
  await Promise.all(
570
578
  include.map(async (item) => {
@@ -598,7 +606,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
598
606
  const latestIds = await this.getLastN(threadMessagesKey, limit);
599
607
  latestIds.forEach((id) => messageIds.add(id));
600
608
  } catch {
601
- console.info(`No message order found for thread ${threadId}, skipping latest messages`);
609
+ this.logger?.debug(`No message order found for thread ${threadId}, skipping latest messages`);
602
610
  }
603
611
  }
604
612
  async fetchAndParseMessagesFromMultipleThreads(messageIds, include, targetThreadId) {
@@ -629,15 +637,13 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
629
637
  const data = await this.operations.getKV(TABLE_MESSAGES, key);
630
638
  if (!data) return null;
631
639
  const parsed = typeof data === "string" ? JSON.parse(data) : data;
632
- console.info(`Retrieved message ${id} from thread ${threadId} with content:`, {
633
- content: parsed.content,
634
- contentType: typeof parsed.content,
635
- isArray: Array.isArray(parsed.content)
640
+ this.logger?.debug(`Retrieved message ${id} from thread ${threadId}`, {
641
+ contentSummary: this.summarizeMessageContent(parsed.content)
636
642
  });
637
643
  return parsed;
638
644
  } catch (error) {
639
645
  const message = error instanceof Error ? error.message : String(error);
640
- this.logger.error(`Error retrieving message ${id}:`, { message });
646
+ this.logger?.error(`Error retrieving message ${id}:`, { message });
641
647
  return null;
642
648
  }
643
649
  })
@@ -669,33 +675,7 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
669
675
  targetThreadId
670
676
  );
671
677
  if (!messages.length) return [];
672
- try {
673
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
674
- const messageOrder = await this.getFullOrder(threadMessagesKey);
675
- const orderMap = new Map(messageOrder.map((id, index) => [id, index]));
676
- messages.sort((a, b) => {
677
- const indexA = orderMap.get(a.id);
678
- const indexB = orderMap.get(b.id);
679
- if (indexA !== void 0 && indexB !== void 0) return orderMap.get(a.id) - orderMap.get(b.id);
680
- return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
681
- });
682
- } catch (error) {
683
- const mastraError = new MastraError(
684
- {
685
- id: "CLOUDFLARE_STORAGE_SORT_MESSAGES_FAILED",
686
- domain: ErrorDomain.STORAGE,
687
- category: ErrorCategory.THIRD_PARTY,
688
- text: `Error sorting messages for thread ${threadId} falling back to creation time`,
689
- details: {
690
- threadId
691
- }
692
- },
693
- error
694
- );
695
- this.logger?.trackException(mastraError);
696
- this.logger?.error(mastraError.toString());
697
- messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
698
- }
678
+ messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
699
679
  const prepared = messages.map(({ _index, ...message }) => ({
700
680
  ...message,
701
681
  type: message.type === `v2` ? void 0 : message.type,
@@ -769,26 +749,49 @@ var MemoryStorageCloudflare = class extends MemoryStorage {
769
749
  const { page = 0, perPage = 100 } = selectBy?.pagination || {};
770
750
  try {
771
751
  if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
772
- const messages = format === "v2" ? await this.getMessages({ threadId, selectBy, format: "v2" }) : await this.getMessages({ threadId, selectBy, format: "v1" });
773
- let filteredMessages = messages;
752
+ const includedMessages = [];
753
+ if (selectBy?.include?.length) {
754
+ const includeOnlySelectBy = { ...selectBy, last: 0 };
755
+ const included = format === "v2" ? await this.getMessages({ threadId, selectBy: includeOnlySelectBy, format: "v2" }) : await this.getMessages({ threadId, selectBy: includeOnlySelectBy, format: "v1" });
756
+ includedMessages.push(...included);
757
+ }
758
+ const threadOnlySelectBy = selectBy ? { ...selectBy, include: void 0 } : void 0;
759
+ const threadMessages = format === "v2" ? await this.getMessages({ threadId, selectBy: threadOnlySelectBy, format: "v2" }) : await this.getMessages({ threadId, selectBy: threadOnlySelectBy, format: "v1" });
760
+ let filteredMessages = threadMessages;
774
761
  if (selectBy?.pagination?.dateRange) {
775
762
  const { start: dateStart, end: dateEnd } = selectBy.pagination.dateRange;
776
- filteredMessages = messages.filter((message) => {
763
+ filteredMessages = threadMessages.filter((message) => {
777
764
  const messageDate = new Date(message.createdAt);
778
765
  if (dateStart && messageDate < dateStart) return false;
779
766
  if (dateEnd && messageDate > dateEnd) return false;
780
767
  return true;
781
768
  });
782
769
  }
770
+ const total = filteredMessages.length;
783
771
  const start = page * perPage;
784
772
  const end = start + perPage;
785
773
  const paginatedMessages = filteredMessages.slice(start, end);
774
+ const seenIds = /* @__PURE__ */ new Set();
775
+ const combinedMessages = [];
776
+ for (const msg of paginatedMessages) {
777
+ if (!seenIds.has(msg.id)) {
778
+ combinedMessages.push(msg);
779
+ seenIds.add(msg.id);
780
+ }
781
+ }
782
+ for (const msg of includedMessages) {
783
+ if (!seenIds.has(msg.id)) {
784
+ combinedMessages.push(msg);
785
+ seenIds.add(msg.id);
786
+ }
787
+ }
788
+ combinedMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
786
789
  return {
787
790
  page,
788
791
  perPage,
789
- total: filteredMessages.length,
790
- hasMore: start + perPage < filteredMessages.length,
791
- messages: paginatedMessages
792
+ total,
793
+ hasMore: start + perPage < total,
794
+ messages: combinedMessages
792
795
  };
793
796
  } catch (error) {
794
797
  const mastraError = new MastraError(
@@ -1574,17 +1577,21 @@ var StoreOperationsCloudflare = class extends StoreOperations {
1574
1577
  }
1575
1578
  };
1576
1579
  function transformScoreRow(row) {
1577
- const deserialized = { ...row };
1578
- deserialized.input = safelyParseJSON(row.input);
1579
- deserialized.output = safelyParseJSON(row.output);
1580
- deserialized.scorer = safelyParseJSON(row.scorer);
1581
- deserialized.preprocessStepResult = safelyParseJSON(row.preprocessStepResult);
1582
- deserialized.analyzeStepResult = safelyParseJSON(row.analyzeStepResult);
1583
- deserialized.metadata = safelyParseJSON(row.metadata);
1584
- deserialized.additionalContext = safelyParseJSON(row.additionalContext);
1585
- deserialized.runtimeContext = safelyParseJSON(row.runtimeContext);
1586
- deserialized.entity = safelyParseJSON(row.entity);
1587
- return deserialized;
1580
+ const result = {};
1581
+ for (const [key, columnSchema] of Object.entries(SCORERS_SCHEMA)) {
1582
+ const value = row[key];
1583
+ if (value == null) {
1584
+ continue;
1585
+ }
1586
+ if (columnSchema.type === "jsonb") {
1587
+ result[key] = safelyParseJSON(value);
1588
+ } else if (columnSchema.type === "timestamp") {
1589
+ result[key] = new Date(value);
1590
+ } else {
1591
+ result[key] = value;
1592
+ }
1593
+ }
1594
+ return result;
1588
1595
  }
1589
1596
  var ScoresStorageCloudflare = class extends ScoresStorage {
1590
1597
  operations;