@mastra/cloudflare 0.0.0-vector-sources-20250516175436 → 0.0.0-vector-query-tool-provider-options-20250828222356

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.cjs CHANGED
@@ -1,333 +1,581 @@
1
1
  'use strict';
2
2
 
3
+ var error = require('@mastra/core/error');
3
4
  var storage = require('@mastra/core/storage');
4
5
  var Cloudflare = require('cloudflare');
6
+ var agent = require('@mastra/core/agent');
5
7
 
6
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
9
 
8
10
  var Cloudflare__default = /*#__PURE__*/_interopDefault(Cloudflare);
9
11
 
10
12
  // src/storage/index.ts
11
-
12
- // src/storage/types.ts
13
- function isWorkersConfig(config) {
14
- return "bindings" in config;
15
- }
16
-
17
- // src/storage/index.ts
18
- var CloudflareStore = class extends storage.MastraStorage {
19
- client;
20
- accountId;
21
- namespacePrefix;
22
- bindings;
23
- validateWorkersConfig(config) {
24
- if (!isWorkersConfig(config)) {
25
- throw new Error("Invalid Workers API configuration");
26
- }
27
- if (!config.bindings) {
28
- throw new Error("KV bindings are required when using Workers Binding API");
29
- }
30
- const requiredTables = [storage.TABLE_THREADS, storage.TABLE_MESSAGES, storage.TABLE_WORKFLOW_SNAPSHOT, storage.TABLE_EVALS, storage.TABLE_TRACES];
31
- for (const table of requiredTables) {
32
- if (!(table in config.bindings)) {
33
- throw new Error(`Missing KV binding for table: ${table}`);
34
- }
35
- }
13
+ var LegacyEvalsStorageCloudflare = class extends storage.LegacyEvalsStorage {
14
+ operations;
15
+ constructor({ operations }) {
16
+ super();
17
+ this.operations = operations;
36
18
  }
37
- validateRestConfig(config) {
38
- if (isWorkersConfig(config)) {
39
- throw new Error("Invalid REST API configuration");
40
- }
41
- if (!config.accountId?.trim()) {
42
- throw new Error("accountId is required for REST API");
43
- }
44
- if (!config.apiToken?.trim()) {
45
- throw new Error("apiToken is required for REST API");
19
+ async getEvalsByAgentName(agentName, type) {
20
+ try {
21
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
22
+ const keyObjs = await this.operations.listKV(storage.TABLE_EVALS, { prefix: `${prefix}${storage.TABLE_EVALS}` });
23
+ const evals = [];
24
+ for (const { name: key } of keyObjs) {
25
+ const data = await this.operations.getKV(storage.TABLE_EVALS, key);
26
+ if (!data) continue;
27
+ if (data.agent_name !== agentName) continue;
28
+ if (type) {
29
+ const isTest = data.test_info !== null && data.test_info !== void 0;
30
+ const evalType = isTest ? "test" : "live";
31
+ if (evalType !== type) continue;
32
+ }
33
+ const mappedData = {
34
+ ...data,
35
+ runId: data.run_id,
36
+ testInfo: data.test_info
37
+ };
38
+ evals.push(mappedData);
39
+ }
40
+ evals.sort((a, b) => {
41
+ const aTime = new Date(a.createdAt || 0).getTime();
42
+ const bTime = new Date(b.createdAt || 0).getTime();
43
+ return bTime - aTime;
44
+ });
45
+ return evals;
46
+ } catch (error$1) {
47
+ throw new error.MastraError(
48
+ {
49
+ id: "CLOUDFLARE_STORAGE_GET_EVALS_BY_AGENT_NAME_FAILED",
50
+ domain: error.ErrorDomain.STORAGE,
51
+ category: error.ErrorCategory.THIRD_PARTY,
52
+ text: "Failed to get evals by agent name"
53
+ },
54
+ error$1
55
+ );
46
56
  }
47
57
  }
48
- constructor(config) {
49
- super({ name: "Cloudflare" });
58
+ async getEvals(options) {
50
59
  try {
51
- if (isWorkersConfig(config)) {
52
- this.validateWorkersConfig(config);
53
- this.bindings = config.bindings;
54
- this.namespacePrefix = config.keyPrefix?.trim() || "";
55
- this.logger.info("Using Cloudflare KV Workers Binding API");
56
- } else {
57
- this.validateRestConfig(config);
58
- this.accountId = config.accountId.trim();
59
- this.namespacePrefix = config.namespacePrefix?.trim() || "";
60
- this.client = new Cloudflare__default.default({
61
- apiToken: config.apiToken.trim()
62
- });
63
- this.logger.info("Using Cloudflare KV REST API");
60
+ const { agentName, type, page = 0, perPage = 100, dateRange } = options;
61
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
62
+ const keyObjs = await this.operations.listKV(storage.TABLE_EVALS, { prefix: `${prefix}${storage.TABLE_EVALS}` });
63
+ const evals = [];
64
+ for (const { name: key } of keyObjs) {
65
+ const data = await this.operations.getKV(storage.TABLE_EVALS, key);
66
+ if (!data) continue;
67
+ if (agentName && data.agent_name !== agentName) continue;
68
+ if (type) {
69
+ const isTest = data.test_info !== null && data.test_info !== void 0;
70
+ const evalType = isTest ? "test" : "live";
71
+ if (evalType !== type) continue;
72
+ }
73
+ if (dateRange?.start || dateRange?.end) {
74
+ const evalDate = new Date(data.createdAt || data.created_at || 0);
75
+ if (dateRange.start && evalDate < dateRange.start) continue;
76
+ if (dateRange.end && evalDate > dateRange.end) continue;
77
+ }
78
+ const mappedData = {
79
+ ...data,
80
+ runId: data.run_id,
81
+ testInfo: data.test_info
82
+ };
83
+ evals.push(mappedData);
64
84
  }
65
- } catch (error) {
66
- const message = error instanceof Error ? error.message : String(error);
67
- this.logger.error("Failed to initialize CloudflareStore:", { message });
68
- throw error;
85
+ evals.sort((a, b) => {
86
+ const aTime = new Date(a.createdAt || 0).getTime();
87
+ const bTime = new Date(b.createdAt || 0).getTime();
88
+ return bTime - aTime;
89
+ });
90
+ const start = page * perPage;
91
+ const end = start + perPage;
92
+ const paginatedEvals = evals.slice(start, end);
93
+ return {
94
+ page,
95
+ perPage,
96
+ total: evals.length,
97
+ hasMore: start + perPage < evals.length,
98
+ evals: paginatedEvals
99
+ };
100
+ } catch (error$1) {
101
+ throw new error.MastraError(
102
+ {
103
+ id: "CLOUDFLARE_STORAGE_GET_EVALS_FAILED",
104
+ domain: error.ErrorDomain.STORAGE,
105
+ category: error.ErrorCategory.THIRD_PARTY,
106
+ text: "Failed to get evals"
107
+ },
108
+ error$1
109
+ );
69
110
  }
70
111
  }
71
- getBinding(tableName) {
72
- if (!this.bindings) {
73
- throw new Error(`Cannot use Workers API binding for ${tableName}: Store initialized with REST API configuration`);
74
- }
75
- const binding = this.bindings[tableName];
76
- if (!binding) throw new Error(`No binding found for namespace ${tableName}`);
77
- return binding;
112
+ };
113
+ var MemoryStorageCloudflare = class extends storage.MemoryStorage {
114
+ operations;
115
+ constructor({ operations }) {
116
+ super();
117
+ this.operations = operations;
78
118
  }
79
- async listNamespaces() {
80
- if (this.bindings) {
119
+ ensureMetadata(metadata) {
120
+ if (!metadata) return void 0;
121
+ return typeof metadata === "string" ? JSON.parse(metadata) : metadata;
122
+ }
123
+ async getThreadById({ threadId }) {
124
+ const thread = await this.operations.load({ tableName: storage.TABLE_THREADS, keys: { id: threadId } });
125
+ if (!thread) return null;
126
+ try {
81
127
  return {
82
- result: Object.keys(this.bindings).map((name) => ({
83
- id: name,
84
- title: name,
85
- supports_url_encoding: true
86
- }))
128
+ ...thread,
129
+ createdAt: storage.ensureDate(thread.createdAt),
130
+ updatedAt: storage.ensureDate(thread.updatedAt),
131
+ metadata: this.ensureMetadata(thread.metadata)
87
132
  };
133
+ } catch (error$1) {
134
+ const mastraError = new error.MastraError(
135
+ {
136
+ id: "CLOUDFLARE_STORAGE_GET_THREAD_BY_ID_FAILED",
137
+ domain: error.ErrorDomain.STORAGE,
138
+ category: error.ErrorCategory.THIRD_PARTY,
139
+ details: {
140
+ threadId
141
+ }
142
+ },
143
+ error$1
144
+ );
145
+ this.logger?.trackException(mastraError);
146
+ this.logger?.error(mastraError.toString());
147
+ return null;
88
148
  }
89
- return await this.client.kv.namespaces.list({ account_id: this.accountId });
90
149
  }
91
- async getNamespaceValue(tableName, key) {
150
+ async getThreadsByResourceId({ resourceId }) {
92
151
  try {
93
- if (this.bindings) {
94
- const binding = this.getBinding(tableName);
95
- const result = await binding.getWithMetadata(key, "text");
96
- if (!result) return null;
97
- return JSON.stringify(result);
98
- } else {
99
- const namespaceId = await this.getNamespaceId(tableName);
100
- const response = await this.client.kv.namespaces.values.get(namespaceId, key, {
101
- account_id: this.accountId
102
- });
103
- return await response.text();
104
- }
105
- } catch (error) {
106
- if (error.message && error.message.includes("key not found")) {
107
- return null;
108
- }
109
- const message = error instanceof Error ? error.message : String(error);
110
- this.logger.error(`Failed to get value for ${tableName} ${key}:`, { message });
111
- throw error;
152
+ const keyList = await this.operations.listKV(storage.TABLE_THREADS);
153
+ const threads = await Promise.all(
154
+ keyList.map(async (keyObj) => {
155
+ try {
156
+ const data = await this.operations.getKV(storage.TABLE_THREADS, keyObj.name);
157
+ if (!data) return null;
158
+ const thread = typeof data === "string" ? JSON.parse(data) : data;
159
+ if (!thread || !thread.resourceId || thread.resourceId !== resourceId) return null;
160
+ return {
161
+ ...thread,
162
+ createdAt: storage.ensureDate(thread.createdAt),
163
+ updatedAt: storage.ensureDate(thread.updatedAt),
164
+ metadata: this.ensureMetadata(thread.metadata)
165
+ };
166
+ } catch (error$1) {
167
+ const mastraError = new error.MastraError(
168
+ {
169
+ id: "CLOUDFLARE_STORAGE_GET_THREADS_BY_RESOURCE_ID_FAILED",
170
+ domain: error.ErrorDomain.STORAGE,
171
+ category: error.ErrorCategory.THIRD_PARTY,
172
+ details: {
173
+ resourceId
174
+ }
175
+ },
176
+ error$1
177
+ );
178
+ this.logger?.trackException(mastraError);
179
+ this.logger?.error(mastraError.toString());
180
+ return null;
181
+ }
182
+ })
183
+ );
184
+ return threads.filter((thread) => thread !== null);
185
+ } catch (error$1) {
186
+ const mastraError = new error.MastraError(
187
+ {
188
+ id: "CLOUDFLARE_STORAGE_GET_THREADS_BY_RESOURCE_ID_FAILED",
189
+ domain: error.ErrorDomain.STORAGE,
190
+ category: error.ErrorCategory.THIRD_PARTY,
191
+ details: {
192
+ resourceId
193
+ }
194
+ },
195
+ error$1
196
+ );
197
+ this.logger?.trackException(mastraError);
198
+ this.logger?.error(mastraError.toString());
199
+ return [];
112
200
  }
113
201
  }
114
- async putNamespaceValue({
115
- tableName,
116
- key,
117
- value,
118
- metadata
119
- }) {
202
+ async getThreadsByResourceIdPaginated(args) {
120
203
  try {
121
- const serializedValue = this.safeSerialize(value);
122
- const serializedMetadata = metadata ? this.safeSerialize(metadata) : "";
123
- if (this.bindings) {
124
- const binding = this.getBinding(tableName);
125
- await binding.put(key, serializedValue, { metadata: serializedMetadata });
126
- } else {
127
- const namespaceId = await this.getNamespaceId(tableName);
128
- await this.client.kv.namespaces.values.update(namespaceId, key, {
129
- account_id: this.accountId,
130
- value: serializedValue,
131
- metadata: serializedMetadata
132
- });
204
+ const { resourceId, page = 0, perPage = 100 } = args;
205
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
206
+ const keyObjs = await this.operations.listKV(storage.TABLE_THREADS, { prefix: `${prefix}${storage.TABLE_THREADS}` });
207
+ const threads = [];
208
+ for (const { name: key } of keyObjs) {
209
+ const data = await this.operations.getKV(storage.TABLE_THREADS, key);
210
+ if (!data) continue;
211
+ if (data.resourceId !== resourceId) continue;
212
+ threads.push(data);
133
213
  }
134
- } catch (error) {
135
- const message = error instanceof Error ? error.message : String(error);
136
- this.logger.error(`Failed to put value for ${tableName} ${key}:`, { message });
137
- throw error;
138
- }
139
- }
140
- async deleteNamespaceValue(tableName, key) {
141
- if (this.bindings) {
142
- const binding = this.getBinding(tableName);
143
- await binding.delete(key);
144
- } else {
145
- const namespaceId = await this.getNamespaceId(tableName);
146
- await this.client.kv.namespaces.values.delete(namespaceId, key, {
147
- account_id: this.accountId
214
+ threads.sort((a, b) => {
215
+ const aTime = new Date(a.createdAt || 0).getTime();
216
+ const bTime = new Date(b.createdAt || 0).getTime();
217
+ return bTime - aTime;
148
218
  });
219
+ const start = page * perPage;
220
+ const end = start + perPage;
221
+ const paginatedThreads = threads.slice(start, end);
222
+ return {
223
+ page,
224
+ perPage,
225
+ total: threads.length,
226
+ hasMore: start + perPage < threads.length,
227
+ threads: paginatedThreads
228
+ };
229
+ } catch (error$1) {
230
+ throw new error.MastraError(
231
+ {
232
+ id: "CLOUDFLARE_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
233
+ domain: error.ErrorDomain.STORAGE,
234
+ category: error.ErrorCategory.THIRD_PARTY,
235
+ text: "Failed to get threads by resource ID with pagination"
236
+ },
237
+ error$1
238
+ );
149
239
  }
150
240
  }
151
- async listNamespaceKeys(tableName, options) {
241
+ async saveThread({ thread }) {
152
242
  try {
153
- if (this.bindings) {
154
- const binding = this.getBinding(tableName);
155
- const response = await binding.list({
156
- limit: options?.limit || 1e3,
157
- prefix: options?.prefix
158
- });
159
- return response.keys;
160
- } else {
161
- const namespaceId = await this.getNamespaceId(tableName);
162
- const response = await this.client.kv.namespaces.keys.list(namespaceId, {
163
- account_id: this.accountId,
164
- limit: options?.limit || 1e3,
165
- prefix: options?.prefix
166
- });
167
- return response.result;
168
- }
169
- } catch (error) {
170
- this.logger.error(`Failed to list keys for ${tableName}:`, error);
171
- throw new Error(`Failed to list keys: ${error.message}`);
243
+ await this.operations.insert({ tableName: storage.TABLE_THREADS, record: thread });
244
+ return thread;
245
+ } catch (error$1) {
246
+ throw new error.MastraError(
247
+ {
248
+ id: "CLOUDFLARE_STORAGE_SAVE_THREAD_FAILED",
249
+ domain: error.ErrorDomain.STORAGE,
250
+ category: error.ErrorCategory.THIRD_PARTY,
251
+ details: {
252
+ threadId: thread.id
253
+ }
254
+ },
255
+ error$1
256
+ );
172
257
  }
173
258
  }
174
- async createNamespaceById(title) {
175
- if (this.bindings) {
176
- return {
177
- id: title,
178
- // Use title as ID since that's what we need
259
+ async updateThread({
260
+ id,
261
+ title,
262
+ metadata
263
+ }) {
264
+ try {
265
+ const thread = await this.getThreadById({ threadId: id });
266
+ if (!thread) {
267
+ throw new Error(`Thread ${id} not found`);
268
+ }
269
+ const updatedThread = {
270
+ ...thread,
179
271
  title,
180
- supports_url_encoding: true
272
+ metadata: this.ensureMetadata({
273
+ ...thread.metadata ?? {},
274
+ ...metadata
275
+ }),
276
+ updatedAt: /* @__PURE__ */ new Date()
181
277
  };
278
+ await this.operations.insert({ tableName: storage.TABLE_THREADS, record: updatedThread });
279
+ return updatedThread;
280
+ } catch (error$1) {
281
+ throw new error.MastraError(
282
+ {
283
+ id: "CLOUDFLARE_STORAGE_UPDATE_THREAD_FAILED",
284
+ domain: error.ErrorDomain.STORAGE,
285
+ category: error.ErrorCategory.THIRD_PARTY,
286
+ details: {
287
+ threadId: id,
288
+ title
289
+ }
290
+ },
291
+ error$1
292
+ );
182
293
  }
183
- return await this.client.kv.namespaces.create({
184
- account_id: this.accountId,
185
- title
186
- });
187
294
  }
188
- async getNamespaceIdByName(namespaceName) {
295
+ getMessageKey(threadId, messageId) {
189
296
  try {
190
- const response = await this.listNamespaces();
191
- const namespace = response.result.find((ns) => ns.title === namespaceName);
192
- return namespace ? namespace.id : null;
297
+ return this.operations.getKey(storage.TABLE_MESSAGES, { threadId, id: messageId });
193
298
  } catch (error) {
194
- this.logger.error(`Failed to get namespace ID for ${namespaceName}:`, error);
195
- return null;
299
+ const message = error instanceof Error ? error.message : String(error);
300
+ this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
301
+ throw error;
196
302
  }
197
303
  }
198
- async createNamespace(namespaceName) {
304
+ getThreadMessagesKey(threadId) {
199
305
  try {
200
- const response = await this.createNamespaceById(namespaceName);
201
- return response.id;
306
+ return this.operations.getKey(storage.TABLE_MESSAGES, { threadId, id: "messages" });
202
307
  } catch (error) {
203
- if (error.message && error.message.includes("already exists")) {
204
- const namespaces = await this.listNamespaces();
205
- const namespace = namespaces.result.find((ns) => ns.title === namespaceName);
206
- if (namespace) return namespace.id;
207
- }
208
- this.logger.error("Error creating namespace:", error);
209
- throw new Error(`Failed to create namespace ${namespaceName}: ${error.message}`);
308
+ const message = error instanceof Error ? error.message : String(error);
309
+ this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { message });
310
+ throw error;
210
311
  }
211
312
  }
212
- async getOrCreateNamespaceId(namespaceName) {
213
- let namespaceId = await this.getNamespaceIdByName(namespaceName);
214
- if (!namespaceId) {
215
- namespaceId = await this.createNamespace(namespaceName);
313
+ async deleteThread({ threadId }) {
314
+ try {
315
+ const thread = await this.getThreadById({ threadId });
316
+ if (!thread) {
317
+ throw new Error(`Thread ${threadId} not found`);
318
+ }
319
+ const messageKeys = await this.operations.listKV(storage.TABLE_MESSAGES);
320
+ const threadMessageKeys = messageKeys.filter((key) => key.name.includes(`${storage.TABLE_MESSAGES}:${threadId}:`));
321
+ await Promise.all([
322
+ // Delete message order
323
+ this.operations.deleteKV(storage.TABLE_MESSAGES, this.getThreadMessagesKey(threadId)),
324
+ // Delete all messages
325
+ ...threadMessageKeys.map((key) => this.operations.deleteKV(storage.TABLE_MESSAGES, key.name)),
326
+ // Delete thread
327
+ this.operations.deleteKV(storage.TABLE_THREADS, this.operations.getKey(storage.TABLE_THREADS, { id: threadId }))
328
+ ]);
329
+ } catch (error$1) {
330
+ throw new error.MastraError(
331
+ {
332
+ id: "CLOUDFLARE_STORAGE_DELETE_THREAD_FAILED",
333
+ domain: error.ErrorDomain.STORAGE,
334
+ category: error.ErrorCategory.THIRD_PARTY,
335
+ details: {
336
+ threadId
337
+ }
338
+ },
339
+ error$1
340
+ );
216
341
  }
217
- return namespaceId;
218
342
  }
219
- async getNamespaceId(tableName) {
220
- const prefix = this.namespacePrefix ? `${this.namespacePrefix}_` : "";
343
+ async findMessageInAnyThread(messageId) {
221
344
  try {
222
- if (tableName === storage.TABLE_MESSAGES || tableName === storage.TABLE_THREADS) {
223
- return await this.getOrCreateNamespaceId(`${prefix}mastra_threads`);
224
- } else if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
225
- return await this.getOrCreateNamespaceId(`${prefix}mastra_workflows`);
226
- } else {
227
- return await this.getOrCreateNamespaceId(`${prefix}mastra_evals`);
345
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
346
+ const threadKeys = await this.operations.listKV(storage.TABLE_THREADS, { prefix: `${prefix}${storage.TABLE_THREADS}` });
347
+ for (const { name: threadKey } of threadKeys) {
348
+ const threadId = threadKey.split(":").pop();
349
+ if (!threadId || threadId === "messages") continue;
350
+ const messageKey = this.getMessageKey(threadId, messageId);
351
+ const message = await this.operations.getKV(storage.TABLE_MESSAGES, messageKey);
352
+ if (message) {
353
+ return { ...message, threadId };
354
+ }
228
355
  }
356
+ return null;
229
357
  } catch (error) {
230
- this.logger.error("Error fetching namespace ID:", error);
231
- throw new Error(`Failed to fetch namespace ID for table ${tableName}: ${error.message}`);
358
+ this.logger?.error(`Error finding message ${messageId} in any thread:`, error);
359
+ return null;
232
360
  }
233
361
  }
234
362
  /**
235
- * Helper to safely serialize data for KV storage
363
+ * Queue for serializing sorted order updates.
364
+ * Updates the sorted order for a given key. This operation is eventually consistent.
236
365
  */
237
- safeSerialize(data) {
238
- return typeof data === "string" ? data : JSON.stringify(data);
366
+ updateQueue = /* @__PURE__ */ new Map();
367
+ async updateSorting(threadMessages) {
368
+ return threadMessages.map((msg) => ({
369
+ message: msg,
370
+ // Use _index if available, otherwise timestamp, matching Upstash
371
+ score: msg._index !== void 0 ? msg._index : msg.createdAt.getTime()
372
+ })).sort((a, b) => a.score - b.score).map((item) => ({
373
+ id: item.message.id,
374
+ score: item.score
375
+ }));
239
376
  }
240
377
  /**
241
- * Helper to safely parse data from KV storage
378
+ * Updates the sorted order for a given key. This operation is eventually consistent.
379
+ * Note: Operations on the same orderKey are serialized using a queue to prevent
380
+ * concurrent updates from conflicting with each other.
242
381
  */
243
- safeParse(text) {
244
- if (!text) return null;
245
- try {
246
- const data = JSON.parse(text);
247
- if (data && typeof data === "object" && "value" in data) {
248
- if (typeof data.value === "string") {
249
- try {
250
- return JSON.parse(data.value);
251
- } catch {
252
- return data.value;
253
- }
382
+ async updateSortedMessages(orderKey, newEntries) {
383
+ const currentPromise = this.updateQueue.get(orderKey) || Promise.resolve();
384
+ const nextPromise = currentPromise.then(async () => {
385
+ try {
386
+ const currentOrder = await this.getSortedMessages(orderKey);
387
+ const orderMap = new Map(currentOrder.map((entry) => [entry.id, entry]));
388
+ for (const entry of newEntries) {
389
+ orderMap.set(entry.id, entry);
254
390
  }
255
- return null;
256
- }
257
- return data;
258
- } catch (error) {
259
- const message = error instanceof Error ? error.message : String(error);
260
- this.logger.error("Failed to parse text:", { message, text });
261
- return null;
262
- }
263
- }
264
- async putKV({
265
- tableName,
266
- key,
267
- value,
268
- metadata
269
- }) {
270
- try {
271
- await this.putNamespaceValue({ tableName, key, value, metadata });
272
- } catch (error) {
273
- this.logger.error(`Failed to put KV value for ${tableName}:${key}:`, error);
274
- throw new Error(`Failed to put KV value: ${error.message}`);
275
- }
391
+ const updatedOrder = Array.from(orderMap.values()).sort((a, b) => a.score - b.score);
392
+ await this.operations.putKV({
393
+ tableName: storage.TABLE_MESSAGES,
394
+ key: orderKey,
395
+ value: JSON.stringify(updatedOrder)
396
+ });
397
+ } catch (error) {
398
+ const message = error instanceof Error ? error.message : String(error);
399
+ this.logger.error(`Error updating sorted order for key ${orderKey}:`, { message });
400
+ throw error;
401
+ } finally {
402
+ if (this.updateQueue.get(orderKey) === nextPromise) {
403
+ this.updateQueue.delete(orderKey);
404
+ }
405
+ }
406
+ });
407
+ this.updateQueue.set(orderKey, nextPromise);
408
+ return nextPromise;
276
409
  }
277
- async getKV(tableName, key) {
410
+ async getSortedMessages(orderKey) {
411
+ const raw = await this.operations.getKV(storage.TABLE_MESSAGES, orderKey);
412
+ if (!raw) return [];
278
413
  try {
279
- const text = await this.getNamespaceValue(tableName, key);
280
- return this.safeParse(text);
281
- } catch (error) {
282
- this.logger.error(`Failed to get KV value for ${tableName}:${key}:`, error);
283
- throw new Error(`Failed to get KV value: ${error.message}`);
414
+ const arr = JSON.parse(typeof raw === "string" ? raw : JSON.stringify(raw));
415
+ return Array.isArray(arr) ? arr : [];
416
+ } catch (e) {
417
+ this.logger.error(`Error parsing order data for key ${orderKey}:`, { e });
418
+ return [];
284
419
  }
285
420
  }
286
- async deleteKV(tableName, key) {
421
+ async migrateMessage(messageId, fromThreadId, toThreadId) {
287
422
  try {
288
- await this.deleteNamespaceValue(tableName, key);
423
+ const oldMessageKey = this.getMessageKey(fromThreadId, messageId);
424
+ const message = await this.operations.getKV(storage.TABLE_MESSAGES, oldMessageKey);
425
+ if (!message) return;
426
+ const updatedMessage = {
427
+ ...message,
428
+ threadId: toThreadId
429
+ };
430
+ const newMessageKey = this.getMessageKey(toThreadId, messageId);
431
+ await this.operations.putKV({ tableName: storage.TABLE_MESSAGES, key: newMessageKey, value: updatedMessage });
432
+ const oldOrderKey = this.getThreadMessagesKey(fromThreadId);
433
+ const oldEntries = await this.getSortedMessages(oldOrderKey);
434
+ const filteredEntries = oldEntries.filter((entry) => entry.id !== messageId);
435
+ await this.updateSortedMessages(oldOrderKey, filteredEntries);
436
+ const newOrderKey = this.getThreadMessagesKey(toThreadId);
437
+ const newEntries = await this.getSortedMessages(newOrderKey);
438
+ const newEntry = { id: messageId, score: Date.now() };
439
+ newEntries.push(newEntry);
440
+ await this.updateSortedMessages(newOrderKey, newEntries);
441
+ await this.operations.deleteKV(storage.TABLE_MESSAGES, oldMessageKey);
289
442
  } catch (error) {
290
- this.logger.error(`Failed to delete KV value for ${tableName}:${key}:`, error);
291
- throw new Error(`Failed to delete KV value: ${error.message}`);
443
+ this.logger?.error(`Error migrating message ${messageId} from ${fromThreadId} to ${toThreadId}:`, error);
444
+ throw error;
292
445
  }
293
446
  }
294
- async listKV(tableName, options) {
447
+ async saveMessages(args) {
448
+ const { messages, format = "v1" } = args;
449
+ if (!Array.isArray(messages) || messages.length === 0) return [];
295
450
  try {
296
- return await this.listNamespaceKeys(tableName, options);
297
- } catch (error) {
298
- this.logger.error(`Failed to list KV for ${tableName}:`, error);
299
- throw new Error(`Failed to list KV: ${error.message}`);
451
+ const validatedMessages = messages.map((message, index) => {
452
+ const errors = [];
453
+ if (!message.id) errors.push("id is required");
454
+ if (!message.threadId) errors.push("threadId is required");
455
+ if (!message.content) errors.push("content is required");
456
+ if (!message.role) errors.push("role is required");
457
+ if (!message.createdAt) errors.push("createdAt is required");
458
+ if (message.resourceId === null || message.resourceId === void 0) errors.push("resourceId is required");
459
+ if (errors.length > 0) {
460
+ throw new Error(`Invalid message at index ${index}: ${errors.join(", ")}`);
461
+ }
462
+ return {
463
+ ...message,
464
+ createdAt: storage.ensureDate(message.createdAt),
465
+ type: message.type || "v2",
466
+ _index: index
467
+ };
468
+ }).filter((m) => !!m);
469
+ const messageMigrationTasks = [];
470
+ for (const message of validatedMessages) {
471
+ const existingMessage = await this.findMessageInAnyThread(message.id);
472
+ console.log(`Checking message ${message.id}: existing=${existingMessage?.threadId}, new=${message.threadId}`);
473
+ if (existingMessage && existingMessage.threadId && existingMessage.threadId !== message.threadId) {
474
+ console.log(`Migrating message ${message.id} from ${existingMessage.threadId} to ${message.threadId}`);
475
+ messageMigrationTasks.push(this.migrateMessage(message.id, existingMessage.threadId, message.threadId));
476
+ }
477
+ }
478
+ await Promise.all(messageMigrationTasks);
479
+ const messagesByThread = validatedMessages.reduce((acc, message) => {
480
+ if (message.threadId && !acc.has(message.threadId)) {
481
+ acc.set(message.threadId, []);
482
+ }
483
+ if (message.threadId) {
484
+ acc.get(message.threadId).push(message);
485
+ }
486
+ return acc;
487
+ }, /* @__PURE__ */ new Map());
488
+ await Promise.all(
489
+ Array.from(messagesByThread.entries()).map(async ([threadId, threadMessages]) => {
490
+ try {
491
+ const thread = await this.getThreadById({ threadId });
492
+ if (!thread) {
493
+ throw new Error(`Thread ${threadId} not found`);
494
+ }
495
+ await Promise.all(
496
+ threadMessages.map(async (message) => {
497
+ const key = this.getMessageKey(threadId, message.id);
498
+ const { _index, ...cleanMessage } = message;
499
+ const serializedMessage = {
500
+ ...cleanMessage,
501
+ createdAt: storage.serializeDate(cleanMessage.createdAt)
502
+ };
503
+ console.log(`Saving message ${message.id} with content:`, {
504
+ content: serializedMessage.content,
505
+ contentType: typeof serializedMessage.content,
506
+ isArray: Array.isArray(serializedMessage.content)
507
+ });
508
+ await this.operations.putKV({ tableName: storage.TABLE_MESSAGES, key, value: serializedMessage });
509
+ })
510
+ );
511
+ const orderKey = this.getThreadMessagesKey(threadId);
512
+ const entries = await this.updateSorting(threadMessages);
513
+ await this.updateSortedMessages(orderKey, entries);
514
+ const updatedThread = {
515
+ ...thread,
516
+ updatedAt: /* @__PURE__ */ new Date()
517
+ };
518
+ await this.operations.putKV({
519
+ tableName: storage.TABLE_THREADS,
520
+ key: this.operations.getKey(storage.TABLE_THREADS, { id: threadId }),
521
+ value: updatedThread
522
+ });
523
+ } catch (error$1) {
524
+ throw new error.MastraError(
525
+ {
526
+ id: "CLOUDFLARE_STORAGE_SAVE_MESSAGES_FAILED",
527
+ domain: error.ErrorDomain.STORAGE,
528
+ category: error.ErrorCategory.THIRD_PARTY,
529
+ details: {
530
+ threadId
531
+ }
532
+ },
533
+ error$1
534
+ );
535
+ }
536
+ })
537
+ );
538
+ const prepared = validatedMessages.map(
539
+ ({ _index, ...message }) => ({ ...message, type: message.type !== "v2" ? message.type : void 0 })
540
+ );
541
+ const list = new agent.MessageList().add(prepared, "memory");
542
+ if (format === `v2`) return list.get.all.v2();
543
+ return list.get.all.v1();
544
+ } catch (error$1) {
545
+ throw new error.MastraError(
546
+ {
547
+ id: "CLOUDFLARE_STORAGE_SAVE_MESSAGES_FAILED",
548
+ domain: error.ErrorDomain.STORAGE,
549
+ category: error.ErrorCategory.THIRD_PARTY
550
+ },
551
+ error$1
552
+ );
300
553
  }
301
554
  }
302
- /*---------------------------------------------------------------------------
303
- Sorted set simulation helpers for message ordering.
304
- We store an array of objects { id, score } as JSON under a dedicated key.
305
- ---------------------------------------------------------------------------*/
306
- async getSortedMessages(orderKey) {
307
- const raw = await this.getKV(storage.TABLE_MESSAGES, orderKey);
308
- if (!raw) return [];
309
- try {
310
- const arr = JSON.parse(typeof raw === "string" ? raw : JSON.stringify(raw));
311
- return Array.isArray(arr) ? arr : [];
312
- } catch (e) {
313
- this.logger.error(`Error parsing order data for key ${orderKey}:`, { e });
314
- return [];
315
- }
555
+ async getRank(orderKey, id) {
556
+ const order = await this.getSortedMessages(orderKey);
557
+ const index = order.findIndex((item) => item.id === id);
558
+ return index >= 0 ? index : null;
316
559
  }
317
- async updateSorting(threadMessages) {
318
- return threadMessages.map((msg) => ({
319
- message: msg,
320
- // Use _index if available, otherwise timestamp, matching Upstash
321
- score: msg._index !== void 0 ? msg._index : msg.createdAt.getTime()
322
- })).sort((a, b) => a.score - b.score).map((item) => ({
323
- id: item.message.id,
324
- score: item.score
325
- }));
560
+ async getRange(orderKey, start, end) {
561
+ const order = await this.getSortedMessages(orderKey);
562
+ const actualStart = start < 0 ? Math.max(0, order.length + start) : start;
563
+ const actualEnd = end < 0 ? order.length + end : Math.min(end, order.length - 1);
564
+ const sliced = order.slice(actualStart, actualEnd + 1);
565
+ return sliced.map((item) => item.id);
566
+ }
567
+ async getLastN(orderKey, n) {
568
+ return this.getRange(orderKey, -n, -1);
569
+ }
570
+ async getFullOrder(orderKey) {
571
+ return this.getRange(orderKey, 0, -1);
326
572
  }
327
573
  async getIncludedMessagesWithContext(threadId, include, messageIds) {
328
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
329
574
  await Promise.all(
330
575
  include.map(async (item) => {
576
+ const targetThreadId = item.threadId || threadId;
577
+ if (!targetThreadId) return;
578
+ const threadMessagesKey = this.getThreadMessagesKey(targetThreadId);
331
579
  messageIds.add(item.id);
332
580
  if (!item.withPreviousMessages && !item.withNextMessages) return;
333
581
  const rank = await this.getRank(threadMessagesKey, item.id);
@@ -357,14 +605,40 @@ var CloudflareStore = class extends storage.MastraStorage {
357
605
  console.log(`No message order found for thread ${threadId}, skipping latest messages`);
358
606
  }
359
607
  }
360
- async fetchAndParseMessages(threadId, messageIds) {
608
+ async fetchAndParseMessagesFromMultipleThreads(messageIds, include, targetThreadId) {
609
+ const messageIdToThreadId = /* @__PURE__ */ new Map();
610
+ if (include) {
611
+ for (const item of include) {
612
+ if (item.threadId) {
613
+ messageIdToThreadId.set(item.id, item.threadId);
614
+ }
615
+ }
616
+ }
361
617
  const messages = await Promise.all(
362
618
  messageIds.map(async (id) => {
363
619
  try {
620
+ let threadId = messageIdToThreadId.get(id);
621
+ if (!threadId) {
622
+ if (targetThreadId) {
623
+ threadId = targetThreadId;
624
+ } else {
625
+ const foundMessage = await this.findMessageInAnyThread(id);
626
+ if (foundMessage) {
627
+ threadId = foundMessage.threadId;
628
+ }
629
+ }
630
+ }
631
+ if (!threadId) return null;
364
632
  const key = this.getMessageKey(threadId, id);
365
- const data = await this.getKV(storage.TABLE_MESSAGES, key);
633
+ const data = await this.operations.getKV(storage.TABLE_MESSAGES, key);
366
634
  if (!data) return null;
367
- return typeof data === "string" ? JSON.parse(data) : data;
635
+ const parsed = typeof data === "string" ? JSON.parse(data) : data;
636
+ console.log(`Retrieved message ${id} from thread ${threadId} with content:`, {
637
+ content: parsed.content,
638
+ contentType: typeof parsed.content,
639
+ isArray: Array.isArray(parsed.content)
640
+ });
641
+ return parsed;
368
642
  } catch (error) {
369
643
  const message = error instanceof Error ? error.message : String(error);
370
644
  this.logger.error(`Error retrieving message ${id}:`, { message });
@@ -374,61 +648,424 @@ var CloudflareStore = class extends storage.MastraStorage {
374
648
  );
375
649
  return messages.filter((msg) => msg !== null);
376
650
  }
377
- /**
378
- * Queue for serializing sorted order updates.
379
- * Updates the sorted order for a given key. This operation is eventually consistent.
380
- */
381
- updateQueue = /* @__PURE__ */ new Map();
382
- /**
383
- * Updates the sorted order for a given key. This operation is eventually consistent.
384
- * Note: Operations on the same orderKey are serialized using a queue to prevent
385
- * concurrent updates from conflicting with each other.
386
- */
387
- async updateSortedMessages(orderKey, newEntries) {
388
- const currentPromise = this.updateQueue.get(orderKey) || Promise.resolve();
389
- const nextPromise = currentPromise.then(async () => {
651
+ async getMessages({
652
+ threadId,
653
+ resourceId,
654
+ selectBy,
655
+ format
656
+ }) {
657
+ console.log(`getMessages called with format: ${format}, threadId: ${threadId}`);
658
+ if (!threadId) throw new Error("threadId is required");
659
+ const actualFormat = format || "v1";
660
+ console.log(`Using format: ${actualFormat}`);
661
+ if (!threadId) throw new Error("threadId is required");
662
+ const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
663
+ const messageIds = /* @__PURE__ */ new Set();
664
+ if (limit === 0 && !selectBy?.include?.length) return [];
665
+ try {
666
+ await Promise.all([
667
+ selectBy?.include?.length ? this.getIncludedMessagesWithContext(threadId, selectBy.include, messageIds) : Promise.resolve(),
668
+ limit > 0 ? this.getRecentMessages(threadId, limit, messageIds) : Promise.resolve()
669
+ ]);
670
+ const targetThreadId = selectBy?.include?.length ? void 0 : threadId;
671
+ const messages = await this.fetchAndParseMessagesFromMultipleThreads(
672
+ Array.from(messageIds),
673
+ selectBy?.include,
674
+ targetThreadId
675
+ );
676
+ if (!messages.length) return [];
390
677
  try {
391
- const currentOrder = await this.getSortedMessages(orderKey);
392
- const orderMap = new Map(currentOrder.map((entry) => [entry.id, entry]));
393
- for (const entry of newEntries) {
394
- orderMap.set(entry.id, entry);
395
- }
396
- const updatedOrder = Array.from(orderMap.values()).sort((a, b) => a.score - b.score);
397
- await this.putKV({
398
- tableName: storage.TABLE_MESSAGES,
399
- key: orderKey,
400
- value: JSON.stringify(updatedOrder)
678
+ const threadMessagesKey = this.getThreadMessagesKey(threadId);
679
+ const messageOrder = await this.getFullOrder(threadMessagesKey);
680
+ const orderMap = new Map(messageOrder.map((id, index) => [id, index]));
681
+ messages.sort((a, b) => {
682
+ const indexA = orderMap.get(a.id);
683
+ const indexB = orderMap.get(b.id);
684
+ if (indexA !== void 0 && indexB !== void 0) return orderMap.get(a.id) - orderMap.get(b.id);
685
+ return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
401
686
  });
402
- } catch (error) {
403
- const message = error instanceof Error ? error.message : String(error);
404
- this.logger.error(`Error updating sorted order for key ${orderKey}:`, { message });
405
- throw error;
406
- } finally {
407
- if (this.updateQueue.get(orderKey) === nextPromise) {
408
- this.updateQueue.delete(orderKey);
687
+ } catch (error$1) {
688
+ const mastraError = new error.MastraError(
689
+ {
690
+ id: "CLOUDFLARE_STORAGE_SORT_MESSAGES_FAILED",
691
+ domain: error.ErrorDomain.STORAGE,
692
+ category: error.ErrorCategory.THIRD_PARTY,
693
+ text: `Error sorting messages for thread ${threadId} falling back to creation time`,
694
+ details: {
695
+ threadId
696
+ }
697
+ },
698
+ error$1
699
+ );
700
+ this.logger?.trackException(mastraError);
701
+ this.logger?.error(mastraError.toString());
702
+ messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
703
+ }
704
+ const prepared = messages.map(({ _index, ...message }) => ({
705
+ ...message,
706
+ type: message.type === `v2` ? void 0 : message.type,
707
+ createdAt: storage.ensureDate(message.createdAt)
708
+ }));
709
+ if (actualFormat === `v1`) {
710
+ console.log(`Processing ${prepared.length} messages for v1 format - returning directly without MessageList`);
711
+ return prepared.map((msg) => ({
712
+ ...msg,
713
+ createdAt: new Date(msg.createdAt)
714
+ }));
715
+ }
716
+ const list = new agent.MessageList({ threadId, resourceId }).add(prepared, "memory");
717
+ return list.get.all.v2();
718
+ } catch (error$1) {
719
+ const mastraError = new error.MastraError(
720
+ {
721
+ id: "CLOUDFLARE_STORAGE_GET_MESSAGES_FAILED",
722
+ domain: error.ErrorDomain.STORAGE,
723
+ category: error.ErrorCategory.THIRD_PARTY,
724
+ text: `Error retrieving messages for thread ${threadId}`,
725
+ details: {
726
+ threadId
727
+ }
728
+ },
729
+ error$1
730
+ );
731
+ this.logger?.trackException(mastraError);
732
+ this.logger?.error(mastraError.toString());
733
+ return [];
734
+ }
735
+ }
736
+ async getMessagesById({
737
+ messageIds,
738
+ format
739
+ }) {
740
+ if (messageIds.length === 0) return [];
741
+ try {
742
+ const messages = (await Promise.all(messageIds.map((id) => this.findMessageInAnyThread(id)))).filter(
743
+ (result) => !!result
744
+ );
745
+ const prepared = messages.map(({ _index, ...message }) => ({
746
+ ...message,
747
+ ...message.type !== `v2` && { type: message.type },
748
+ createdAt: storage.ensureDate(message.createdAt)
749
+ }));
750
+ const list = new agent.MessageList().add(prepared, "memory");
751
+ if (format === `v1`) return list.get.all.v1();
752
+ return list.get.all.v2();
753
+ } catch (error$1) {
754
+ const mastraError = new error.MastraError(
755
+ {
756
+ id: "CLOUDFLARE_STORAGE_GET_MESSAGES_BY_ID_FAILED",
757
+ domain: error.ErrorDomain.STORAGE,
758
+ category: error.ErrorCategory.THIRD_PARTY,
759
+ text: `Error retrieving messages by ID`,
760
+ details: {
761
+ messageIds: JSON.stringify(messageIds)
762
+ }
763
+ },
764
+ error$1
765
+ );
766
+ this.logger?.trackException(mastraError);
767
+ this.logger?.error(mastraError.toString());
768
+ return [];
769
+ }
770
+ }
771
+ async getMessagesPaginated(args) {
772
+ try {
773
+ const { threadId, selectBy, format = "v1" } = args;
774
+ const { page = 0, perPage = 100 } = selectBy?.pagination || {};
775
+ const messages = format === "v2" ? await this.getMessages({ threadId, selectBy, format: "v2" }) : await this.getMessages({ threadId, selectBy, format: "v1" });
776
+ let filteredMessages = messages;
777
+ if (selectBy?.pagination?.dateRange) {
778
+ const { start: dateStart, end: dateEnd } = selectBy.pagination.dateRange;
779
+ filteredMessages = messages.filter((message) => {
780
+ const messageDate = new Date(message.createdAt);
781
+ if (dateStart && messageDate < dateStart) return false;
782
+ if (dateEnd && messageDate > dateEnd) return false;
783
+ return true;
784
+ });
785
+ }
786
+ const start = page * perPage;
787
+ const end = start + perPage;
788
+ const paginatedMessages = filteredMessages.slice(start, end);
789
+ return {
790
+ page,
791
+ perPage,
792
+ total: filteredMessages.length,
793
+ hasMore: start + perPage < filteredMessages.length,
794
+ messages: paginatedMessages
795
+ };
796
+ } catch (error$1) {
797
+ throw new error.MastraError(
798
+ {
799
+ id: "CLOUDFLARE_STORAGE_GET_MESSAGES_PAGINATED_FAILED",
800
+ domain: error.ErrorDomain.STORAGE,
801
+ category: error.ErrorCategory.THIRD_PARTY,
802
+ text: "Failed to get messages with pagination"
803
+ },
804
+ error$1
805
+ );
806
+ }
807
+ }
808
+ async updateMessages(args) {
809
+ try {
810
+ const { messages } = args;
811
+ const updatedMessages = [];
812
+ for (const messageUpdate of messages) {
813
+ const { id, content, ...otherFields } = messageUpdate;
814
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
815
+ const keyObjs = await this.operations.listKV(storage.TABLE_MESSAGES, { prefix: `${prefix}${storage.TABLE_MESSAGES}` });
816
+ let existingMessage = null;
817
+ let messageKey = "";
818
+ for (const { name: key } of keyObjs) {
819
+ const data = await this.operations.getKV(storage.TABLE_MESSAGES, key);
820
+ if (data && data.id === id) {
821
+ existingMessage = data;
822
+ messageKey = key;
823
+ break;
824
+ }
825
+ }
826
+ if (!existingMessage) {
827
+ continue;
828
+ }
829
+ const updatedMessage = {
830
+ ...existingMessage,
831
+ ...otherFields,
832
+ id
833
+ };
834
+ if (content) {
835
+ if (content.metadata !== void 0) {
836
+ updatedMessage.content = {
837
+ ...updatedMessage.content,
838
+ metadata: {
839
+ ...updatedMessage.content?.metadata,
840
+ ...content.metadata
841
+ }
842
+ };
843
+ }
844
+ if (content.content !== void 0) {
845
+ updatedMessage.content = {
846
+ ...updatedMessage.content,
847
+ content: content.content
848
+ };
849
+ }
850
+ }
851
+ if ("threadId" in messageUpdate && messageUpdate.threadId && messageUpdate.threadId !== existingMessage.threadId) {
852
+ await this.operations.deleteKV(storage.TABLE_MESSAGES, messageKey);
853
+ updatedMessage.threadId = messageUpdate.threadId;
854
+ const newMessageKey = this.getMessageKey(messageUpdate.threadId, id);
855
+ await this.operations.putKV({
856
+ tableName: storage.TABLE_MESSAGES,
857
+ key: newMessageKey,
858
+ value: updatedMessage
859
+ });
860
+ if (existingMessage.threadId) {
861
+ const sourceOrderKey = this.getThreadMessagesKey(existingMessage.threadId);
862
+ const sourceEntries = await this.getSortedMessages(sourceOrderKey);
863
+ const filteredEntries = sourceEntries.filter((entry) => entry.id !== id);
864
+ await this.updateSortedMessages(sourceOrderKey, filteredEntries);
865
+ }
866
+ const destOrderKey = this.getThreadMessagesKey(messageUpdate.threadId);
867
+ const destEntries = await this.getSortedMessages(destOrderKey);
868
+ const newEntry = { id, score: Date.now() };
869
+ destEntries.push(newEntry);
870
+ await this.updateSortedMessages(destOrderKey, destEntries);
871
+ } else {
872
+ await this.operations.putKV({
873
+ tableName: storage.TABLE_MESSAGES,
874
+ key: messageKey,
875
+ value: updatedMessage
876
+ });
877
+ }
878
+ const threadsToUpdate = /* @__PURE__ */ new Set();
879
+ if (updatedMessage.threadId) {
880
+ threadsToUpdate.add(updatedMessage.threadId);
881
+ }
882
+ if ("threadId" in messageUpdate && messageUpdate.threadId && messageUpdate.threadId !== existingMessage.threadId) {
883
+ if (existingMessage.threadId) {
884
+ threadsToUpdate.add(existingMessage.threadId);
885
+ }
886
+ threadsToUpdate.add(messageUpdate.threadId);
887
+ }
888
+ for (const threadId of threadsToUpdate) {
889
+ const thread = await this.getThreadById({ threadId });
890
+ if (thread) {
891
+ const updatedThread = {
892
+ ...thread,
893
+ updatedAt: /* @__PURE__ */ new Date()
894
+ };
895
+ await this.operations.putKV({
896
+ tableName: storage.TABLE_THREADS,
897
+ key: this.operations.getKey(storage.TABLE_THREADS, { id: threadId }),
898
+ value: updatedThread
899
+ });
900
+ }
409
901
  }
902
+ updatedMessages.push(updatedMessage);
410
903
  }
411
- });
412
- this.updateQueue.set(orderKey, nextPromise);
413
- return nextPromise;
904
+ return updatedMessages;
905
+ } catch (error$1) {
906
+ throw new error.MastraError(
907
+ {
908
+ id: "CLOUDFLARE_STORAGE_UPDATE_MESSAGES_FAILED",
909
+ domain: error.ErrorDomain.STORAGE,
910
+ category: error.ErrorCategory.THIRD_PARTY,
911
+ text: "Failed to update messages"
912
+ },
913
+ error$1
914
+ );
915
+ }
916
+ }
917
+ async getResourceById({ resourceId }) {
918
+ try {
919
+ const data = await this.operations.getKV(storage.TABLE_RESOURCES, resourceId);
920
+ if (!data) return null;
921
+ const resource = typeof data === "string" ? JSON.parse(data) : data;
922
+ return {
923
+ ...resource,
924
+ createdAt: storage.ensureDate(resource.createdAt),
925
+ updatedAt: storage.ensureDate(resource.updatedAt),
926
+ metadata: this.ensureMetadata(resource.metadata)
927
+ };
928
+ } catch (error$1) {
929
+ const mastraError = new error.MastraError(
930
+ {
931
+ id: "CLOUDFLARE_STORAGE_GET_RESOURCE_BY_ID_FAILED",
932
+ domain: error.ErrorDomain.STORAGE,
933
+ category: error.ErrorCategory.THIRD_PARTY,
934
+ details: {
935
+ resourceId
936
+ }
937
+ },
938
+ error$1
939
+ );
940
+ this.logger?.trackException(mastraError);
941
+ this.logger?.error(mastraError.toString());
942
+ return null;
943
+ }
944
+ }
945
+ async saveResource({ resource }) {
946
+ try {
947
+ const resourceToSave = {
948
+ ...resource,
949
+ metadata: resource.metadata ? JSON.stringify(resource.metadata) : null
950
+ };
951
+ await this.operations.putKV({
952
+ tableName: storage.TABLE_RESOURCES,
953
+ key: resource.id,
954
+ value: resourceToSave
955
+ });
956
+ return resource;
957
+ } catch (error$1) {
958
+ throw new error.MastraError(
959
+ {
960
+ id: "CLOUDFLARE_STORAGE_SAVE_RESOURCE_FAILED",
961
+ domain: error.ErrorDomain.STORAGE,
962
+ category: error.ErrorCategory.THIRD_PARTY,
963
+ details: {
964
+ resourceId: resource.id
965
+ }
966
+ },
967
+ error$1
968
+ );
969
+ }
970
+ }
971
+ async updateResource({
972
+ resourceId,
973
+ workingMemory,
974
+ metadata
975
+ }) {
976
+ const existingResource = await this.getResourceById({ resourceId });
977
+ if (!existingResource) {
978
+ const newResource = {
979
+ id: resourceId,
980
+ workingMemory,
981
+ metadata: metadata || {},
982
+ createdAt: /* @__PURE__ */ new Date(),
983
+ updatedAt: /* @__PURE__ */ new Date()
984
+ };
985
+ return this.saveResource({ resource: newResource });
986
+ }
987
+ const updatedAt = /* @__PURE__ */ new Date();
988
+ const updatedResource = {
989
+ ...existingResource,
990
+ workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
991
+ metadata: {
992
+ ...existingResource.metadata,
993
+ ...metadata
994
+ },
995
+ updatedAt
996
+ };
997
+ return this.saveResource({ resource: updatedResource });
998
+ }
999
+ };
1000
+ var StoreOperationsCloudflare = class extends storage.StoreOperations {
1001
+ bindings;
1002
+ client;
1003
+ accountId;
1004
+ namespacePrefix;
1005
+ constructor({
1006
+ namespacePrefix,
1007
+ bindings,
1008
+ client,
1009
+ accountId
1010
+ }) {
1011
+ super();
1012
+ this.bindings = bindings;
1013
+ this.namespacePrefix = namespacePrefix;
1014
+ this.client = client;
1015
+ this.accountId = accountId;
1016
+ }
1017
+ async hasColumn() {
1018
+ return true;
414
1019
  }
415
- async getRank(orderKey, id) {
416
- const order = await this.getSortedMessages(orderKey);
417
- const index = order.findIndex((item) => item.id === id);
418
- return index >= 0 ? index : null;
1020
+ async alterTable(_args) {
419
1021
  }
420
- async getRange(orderKey, start, end) {
421
- const order = await this.getSortedMessages(orderKey);
422
- const actualStart = start < 0 ? Math.max(0, order.length + start) : start;
423
- const actualEnd = end < 0 ? order.length + end : Math.min(end, order.length - 1);
424
- const sliced = order.slice(actualStart, actualEnd + 1);
425
- return sliced.map((item) => item.id);
1022
+ async clearTable({ tableName }) {
1023
+ try {
1024
+ const keys = await this.listKV(tableName);
1025
+ if (keys.length > 0) {
1026
+ await Promise.all(keys.map((keyObj) => this.deleteKV(tableName, keyObj.name)));
1027
+ }
1028
+ } catch (error$1) {
1029
+ throw new error.MastraError(
1030
+ {
1031
+ id: "CLOUDFLARE_STORAGE_CLEAR_TABLE_FAILED",
1032
+ domain: error.ErrorDomain.STORAGE,
1033
+ category: error.ErrorCategory.THIRD_PARTY,
1034
+ details: {
1035
+ tableName
1036
+ }
1037
+ },
1038
+ error$1
1039
+ );
1040
+ }
426
1041
  }
427
- async getLastN(orderKey, n) {
428
- return this.getRange(orderKey, -n, -1);
1042
+ async dropTable({ tableName }) {
1043
+ try {
1044
+ const keys = await this.listKV(tableName);
1045
+ if (keys.length > 0) {
1046
+ await Promise.all(keys.map((keyObj) => this.deleteKV(tableName, keyObj.name)));
1047
+ }
1048
+ } catch (error$1) {
1049
+ throw new error.MastraError(
1050
+ {
1051
+ id: "CLOUDFLARE_STORAGE_DROP_TABLE_FAILED",
1052
+ domain: error.ErrorDomain.STORAGE,
1053
+ category: error.ErrorCategory.THIRD_PARTY,
1054
+ details: {
1055
+ tableName
1056
+ }
1057
+ },
1058
+ error$1
1059
+ );
1060
+ }
429
1061
  }
430
- async getFullOrder(orderKey) {
431
- return this.getRange(orderKey, 0, -1);
1062
+ getBinding(tableName) {
1063
+ if (!this.bindings) {
1064
+ throw new Error(`Cannot use Workers API binding for ${tableName}: Store initialized with REST API configuration`);
1065
+ }
1066
+ const binding = this.bindings[tableName];
1067
+ if (!binding) throw new Error(`No binding found for namespace ${tableName}`);
1068
+ return binding;
432
1069
  }
433
1070
  getKey(tableName, record) {
434
1071
  const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
@@ -440,10 +1077,10 @@ var CloudflareStore = class extends storage.MastraStorage {
440
1077
  if (!record.threadId || !record.id) throw new Error("Thread ID and Message ID are required");
441
1078
  return `${prefix}${tableName}:${record.threadId}:${record.id}`;
442
1079
  case storage.TABLE_WORKFLOW_SNAPSHOT:
443
- if (!record.namespace || !record.workflow_name || !record.run_id) {
444
- throw new Error("Namespace, workflow name, and run ID are required");
1080
+ if (!record.workflow_name || !record.run_id) {
1081
+ throw new Error("Workflow name, and run ID are required");
445
1082
  }
446
- let key = `${prefix}${tableName}:${record.namespace}:${record.workflow_name}:${record.run_id}`;
1083
+ let key = `${prefix}${tableName}:${record.workflow_name}:${record.run_id}`;
447
1084
  if (record.resourceId) {
448
1085
  key = `${key}:${record.resourceId}`;
449
1086
  }
@@ -451,6 +1088,13 @@ var CloudflareStore = class extends storage.MastraStorage {
451
1088
  case storage.TABLE_TRACES:
452
1089
  if (!record.id) throw new Error("Trace ID is required");
453
1090
  return `${prefix}${tableName}:${record.id}`;
1091
+ case storage.TABLE_EVALS:
1092
+ const evalId = record.id || record.run_id;
1093
+ if (!evalId) throw new Error("Eval ID or run_id is required");
1094
+ return `${prefix}${tableName}:${evalId}`;
1095
+ case storage.TABLE_SCORERS:
1096
+ if (!record.id) throw new Error("Score ID is required");
1097
+ return `${prefix}${tableName}:${record.id}`;
454
1098
  default:
455
1099
  throw new Error(`Unsupported table: ${tableName}`);
456
1100
  }
@@ -459,6 +1103,146 @@ var CloudflareStore = class extends storage.MastraStorage {
459
1103
  const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
460
1104
  return `${prefix}schema:${tableName}`;
461
1105
  }
1106
+ /**
1107
+ * Helper to safely parse data from KV storage
1108
+ */
1109
+ safeParse(text) {
1110
+ if (!text) return null;
1111
+ try {
1112
+ const data = JSON.parse(text);
1113
+ if (data && typeof data === "object" && "value" in data) {
1114
+ if (typeof data.value === "string") {
1115
+ try {
1116
+ return JSON.parse(data.value);
1117
+ } catch {
1118
+ return data.value;
1119
+ }
1120
+ }
1121
+ return null;
1122
+ }
1123
+ return data;
1124
+ } catch (error) {
1125
+ const message = error instanceof Error ? error.message : String(error);
1126
+ this.logger.error("Failed to parse text:", { message, text });
1127
+ return null;
1128
+ }
1129
+ }
1130
+ async createNamespaceById(title) {
1131
+ if (this.bindings) {
1132
+ return {
1133
+ id: title,
1134
+ // Use title as ID since that's what we need
1135
+ title,
1136
+ supports_url_encoding: true
1137
+ };
1138
+ }
1139
+ return await this.client.kv.namespaces.create({
1140
+ account_id: this.accountId,
1141
+ title
1142
+ });
1143
+ }
1144
+ async createNamespace(namespaceName) {
1145
+ try {
1146
+ const response = await this.createNamespaceById(namespaceName);
1147
+ return response.id;
1148
+ } catch (error) {
1149
+ if (error.message && error.message.includes("already exists")) {
1150
+ const namespaces = await this.listNamespaces();
1151
+ const namespace = namespaces.result.find((ns) => ns.title === namespaceName);
1152
+ if (namespace) return namespace.id;
1153
+ }
1154
+ this.logger.error("Error creating namespace:", error);
1155
+ throw new Error(`Failed to create namespace ${namespaceName}: ${error.message}`);
1156
+ }
1157
+ }
1158
+ async listNamespaces() {
1159
+ if (this.bindings) {
1160
+ return {
1161
+ result: Object.keys(this.bindings).map((name) => ({
1162
+ id: name,
1163
+ title: name,
1164
+ supports_url_encoding: true
1165
+ }))
1166
+ };
1167
+ }
1168
+ let allNamespaces = [];
1169
+ let currentPage = 1;
1170
+ const perPage = 50;
1171
+ let morePagesExist = true;
1172
+ while (morePagesExist) {
1173
+ const response = await this.client.kv.namespaces.list({
1174
+ account_id: this.accountId,
1175
+ page: currentPage,
1176
+ per_page: perPage
1177
+ });
1178
+ if (response.result) {
1179
+ allNamespaces = allNamespaces.concat(response.result);
1180
+ }
1181
+ morePagesExist = response.result ? response.result.length === perPage : false;
1182
+ if (morePagesExist) {
1183
+ currentPage++;
1184
+ }
1185
+ }
1186
+ return { result: allNamespaces };
1187
+ }
1188
+ async getNamespaceIdByName(namespaceName) {
1189
+ try {
1190
+ const response = await this.listNamespaces();
1191
+ const namespace = response.result.find((ns) => ns.title === namespaceName);
1192
+ return namespace ? namespace.id : null;
1193
+ } catch (error) {
1194
+ this.logger.error(`Failed to get namespace ID for ${namespaceName}:`, error);
1195
+ return null;
1196
+ }
1197
+ }
1198
+ async getOrCreateNamespaceId(namespaceName) {
1199
+ let namespaceId = await this.getNamespaceIdByName(namespaceName);
1200
+ if (!namespaceId) {
1201
+ namespaceId = await this.createNamespace(namespaceName);
1202
+ }
1203
+ return namespaceId;
1204
+ }
1205
+ async getNamespaceId(tableName) {
1206
+ const prefix = this.namespacePrefix ? `${this.namespacePrefix}_` : "";
1207
+ try {
1208
+ return await this.getOrCreateNamespaceId(`${prefix}${tableName}`);
1209
+ } catch (error) {
1210
+ this.logger.error("Error fetching namespace ID:", error);
1211
+ throw new Error(`Failed to fetch namespace ID for table ${tableName}: ${error.message}`);
1212
+ }
1213
+ }
1214
+ async getNamespaceValue(tableName, key) {
1215
+ try {
1216
+ if (this.bindings) {
1217
+ const binding = this.getBinding(tableName);
1218
+ const result = await binding.getWithMetadata(key, "text");
1219
+ if (!result) return null;
1220
+ return JSON.stringify(result);
1221
+ } else {
1222
+ const namespaceId = await this.getNamespaceId(tableName);
1223
+ const response = await this.client.kv.namespaces.values.get(namespaceId, key, {
1224
+ account_id: this.accountId
1225
+ });
1226
+ return await response.text();
1227
+ }
1228
+ } catch (error) {
1229
+ if (error.message && error.message.includes("key not found")) {
1230
+ return null;
1231
+ }
1232
+ const message = error instanceof Error ? error.message : String(error);
1233
+ this.logger.error(`Failed to get value for ${tableName} ${key}:`, { message });
1234
+ throw error;
1235
+ }
1236
+ }
1237
+ async getKV(tableName, key) {
1238
+ try {
1239
+ const text = await this.getNamespaceValue(tableName, key);
1240
+ return this.safeParse(text);
1241
+ } catch (error) {
1242
+ this.logger.error(`Failed to get KV value for ${tableName}:${key}:`, error);
1243
+ throw new Error(`Failed to get KV value: ${error.message}`);
1244
+ }
1245
+ }
462
1246
  async getTableSchema(tableName) {
463
1247
  try {
464
1248
  const schemaKey = this.getSchemaKey(tableName);
@@ -538,7 +1322,7 @@ var CloudflareStore = class extends storage.MastraStorage {
538
1322
  }
539
1323
  break;
540
1324
  case storage.TABLE_WORKFLOW_SNAPSHOT:
541
- if (!("namespace" in recordTyped) || !("workflow_name" in recordTyped) || !("run_id" in recordTyped)) {
1325
+ if (!("workflow_name" in recordTyped) || !("run_id" in recordTyped)) {
542
1326
  throw new Error("Workflow record missing required fields");
543
1327
  }
544
1328
  break;
@@ -547,6 +1331,16 @@ var CloudflareStore = class extends storage.MastraStorage {
547
1331
  throw new Error("Trace record missing required fields");
548
1332
  }
549
1333
  break;
1334
+ case storage.TABLE_EVALS:
1335
+ if (!("agent_name" in recordTyped) || !("run_id" in recordTyped)) {
1336
+ throw new Error("Eval record missing required fields");
1337
+ }
1338
+ break;
1339
+ case storage.TABLE_SCORERS:
1340
+ if (!("id" in recordTyped) || !("scorerId" in recordTyped)) {
1341
+ throw new Error("Score record missing required fields");
1342
+ }
1343
+ break;
550
1344
  default:
551
1345
  throw new Error(`Unknown table type: ${tableName}`);
552
1346
  }
@@ -556,501 +1350,664 @@ var CloudflareStore = class extends storage.MastraStorage {
556
1350
  throw error;
557
1351
  }
558
1352
  }
559
- ensureDate(date) {
560
- if (!date) return void 0;
561
- return date instanceof Date ? date : new Date(date);
562
- }
563
- serializeDate(date) {
564
- if (!date) return void 0;
565
- const dateObj = this.ensureDate(date);
566
- return dateObj?.toISOString();
1353
+ async insert({ tableName, record }) {
1354
+ try {
1355
+ const key = this.getKey(tableName, record);
1356
+ const processedRecord = {
1357
+ ...record,
1358
+ createdAt: record.createdAt ? storage.serializeDate(record.createdAt) : void 0,
1359
+ updatedAt: record.updatedAt ? storage.serializeDate(record.updatedAt) : void 0,
1360
+ metadata: record.metadata ? JSON.stringify(record.metadata) : ""
1361
+ };
1362
+ await this.validateRecord(processedRecord, tableName);
1363
+ await this.putKV({ tableName, key, value: processedRecord });
1364
+ } catch (error$1) {
1365
+ throw new error.MastraError(
1366
+ {
1367
+ id: "CLOUDFLARE_STORAGE_INSERT_FAILED",
1368
+ domain: error.ErrorDomain.STORAGE,
1369
+ category: error.ErrorCategory.THIRD_PARTY,
1370
+ details: {
1371
+ tableName
1372
+ }
1373
+ },
1374
+ error$1
1375
+ );
1376
+ }
567
1377
  }
568
1378
  ensureMetadata(metadata) {
569
1379
  if (!metadata) return {};
570
1380
  return typeof metadata === "string" ? JSON.parse(metadata) : metadata;
571
1381
  }
572
- async createTable({
573
- tableName,
574
- schema
575
- }) {
1382
+ async load({ tableName, keys }) {
576
1383
  try {
577
- const schemaKey = this.getSchemaKey(tableName);
578
- const metadata = {
579
- type: "table_schema",
580
- tableName,
581
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
1384
+ const key = this.getKey(tableName, keys);
1385
+ const data = await this.getKV(tableName, key);
1386
+ if (!data) return null;
1387
+ const processed = {
1388
+ ...data,
1389
+ createdAt: storage.ensureDate(data.createdAt),
1390
+ updatedAt: storage.ensureDate(data.updatedAt),
1391
+ metadata: this.ensureMetadata(data.metadata)
582
1392
  };
583
- await this.putKV({ tableName, key: schemaKey, value: schema, metadata });
584
- } catch (error) {
585
- this.logger.error(`Failed to store schema for ${tableName}:`, error);
586
- throw new Error(`Failed to store schema: ${error.message}`);
1393
+ return processed;
1394
+ } catch (error$1) {
1395
+ const mastraError = new error.MastraError(
1396
+ {
1397
+ id: "CLOUDFLARE_STORAGE_LOAD_FAILED",
1398
+ domain: error.ErrorDomain.STORAGE,
1399
+ category: error.ErrorCategory.THIRD_PARTY,
1400
+ details: {
1401
+ tableName
1402
+ }
1403
+ },
1404
+ error$1
1405
+ );
1406
+ this.logger?.trackException(mastraError);
1407
+ this.logger?.error(mastraError.toString());
1408
+ return null;
587
1409
  }
588
1410
  }
589
- async clearTable({ tableName }) {
590
- const keys = await this.listKV(tableName);
591
- if (keys.length > 0) {
592
- await Promise.all(keys.map((keyObj) => this.deleteKV(tableName, keyObj.name)));
1411
+ async batchInsert(input) {
1412
+ if (!input.records || input.records.length === 0) return;
1413
+ try {
1414
+ await Promise.all(
1415
+ input.records.map(async (record) => {
1416
+ const key = this.getKey(input.tableName, record);
1417
+ const processedRecord = {
1418
+ ...record,
1419
+ createdAt: record.createdAt ? storage.serializeDate(record.createdAt) : void 0,
1420
+ updatedAt: record.updatedAt ? storage.serializeDate(record.updatedAt) : void 0,
1421
+ metadata: record.metadata ? JSON.stringify(record.metadata) : void 0
1422
+ };
1423
+ await this.putKV({ tableName: input.tableName, key, value: processedRecord });
1424
+ })
1425
+ );
1426
+ } catch (error$1) {
1427
+ throw new error.MastraError(
1428
+ {
1429
+ id: "CLOUDFLARE_STORAGE_BATCH_INSERT_FAILED",
1430
+ domain: error.ErrorDomain.STORAGE,
1431
+ category: error.ErrorCategory.THIRD_PARTY,
1432
+ text: `Error in batch insert for table ${input.tableName}`,
1433
+ details: {
1434
+ tableName: input.tableName
1435
+ }
1436
+ },
1437
+ error$1
1438
+ );
593
1439
  }
594
1440
  }
595
- async insert({
1441
+ /**
1442
+ * Helper to safely serialize data for KV storage
1443
+ */
1444
+ safeSerialize(data) {
1445
+ return typeof data === "string" ? data : JSON.stringify(data);
1446
+ }
1447
+ async putNamespaceValue({
596
1448
  tableName,
597
- record
1449
+ key,
1450
+ value,
1451
+ metadata
598
1452
  }) {
599
1453
  try {
600
- const key = this.getKey(tableName, record);
601
- const processedRecord = {
602
- ...record,
603
- createdAt: record.createdAt ? this.serializeDate(record.createdAt) : void 0,
604
- updatedAt: record.updatedAt ? this.serializeDate(record.updatedAt) : void 0,
605
- metadata: record.metadata ? JSON.stringify(record.metadata) : ""
606
- };
607
- await this.validateRecord(processedRecord, tableName);
608
- await this.putKV({ tableName, key, value: processedRecord });
1454
+ const serializedValue = this.safeSerialize(value);
1455
+ const serializedMetadata = metadata ? this.safeSerialize(metadata) : "";
1456
+ if (this.bindings) {
1457
+ const binding = this.getBinding(tableName);
1458
+ await binding.put(key, serializedValue, { metadata: serializedMetadata });
1459
+ } else {
1460
+ const namespaceId = await this.getNamespaceId(tableName);
1461
+ await this.client.kv.namespaces.values.update(namespaceId, key, {
1462
+ account_id: this.accountId,
1463
+ value: serializedValue,
1464
+ metadata: serializedMetadata
1465
+ });
1466
+ }
1467
+ } catch (error) {
1468
+ const message = error instanceof Error ? error.message : String(error);
1469
+ this.logger.error(`Failed to put value for ${tableName} ${key}:`, { message });
1470
+ throw error;
1471
+ }
1472
+ }
1473
+ async putKV({
1474
+ tableName,
1475
+ key,
1476
+ value,
1477
+ metadata
1478
+ }) {
1479
+ try {
1480
+ await this.putNamespaceValue({ tableName, key, value, metadata });
609
1481
  } catch (error) {
610
- const message = error instanceof Error ? error.message : String(error);
611
- this.logger.error(`Failed to insert record for ${tableName}:`, { message });
612
- throw error;
1482
+ this.logger.error(`Failed to put KV value for ${tableName}:${key}:`, error);
1483
+ throw new Error(`Failed to put KV value: ${error.message}`);
613
1484
  }
614
1485
  }
615
- async load({ tableName, keys }) {
1486
+ async createTable({
1487
+ tableName,
1488
+ schema
1489
+ }) {
616
1490
  try {
617
- const key = this.getKey(tableName, keys);
618
- const data = await this.getKV(tableName, key);
619
- if (!data) return null;
620
- const processed = {
621
- ...data,
622
- createdAt: this.ensureDate(data.createdAt),
623
- updatedAt: this.ensureDate(data.updatedAt),
624
- metadata: this.ensureMetadata(data.metadata)
1491
+ const schemaKey = this.getSchemaKey(tableName);
1492
+ const metadata = {
1493
+ type: "table_schema",
1494
+ tableName,
1495
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
625
1496
  };
626
- return processed;
627
- } catch (error) {
628
- this.logger.error(`Failed to load data for ${tableName}:`, {
629
- error: error instanceof Error ? error.message : String(error)
630
- });
631
- return null;
1497
+ await this.putKV({ tableName, key: schemaKey, value: schema, metadata });
1498
+ } catch (error$1) {
1499
+ throw new error.MastraError(
1500
+ {
1501
+ id: "CLOUDFLARE_STORAGE_CREATE_TABLE_FAILED",
1502
+ domain: error.ErrorDomain.STORAGE,
1503
+ category: error.ErrorCategory.THIRD_PARTY,
1504
+ details: {
1505
+ tableName
1506
+ }
1507
+ },
1508
+ error$1
1509
+ );
632
1510
  }
633
1511
  }
634
- async getThreadById({ threadId }) {
635
- const thread = await this.load({ tableName: storage.TABLE_THREADS, keys: { id: threadId } });
636
- if (!thread) return null;
1512
+ async listNamespaceKeys(tableName, options) {
637
1513
  try {
638
- return {
639
- ...thread,
640
- createdAt: this.ensureDate(thread.createdAt),
641
- updatedAt: this.ensureDate(thread.updatedAt),
642
- metadata: this.ensureMetadata(thread.metadata)
643
- };
644
- } catch (error) {
645
- this.logger.error(`Error processing thread ${threadId}:`, {
646
- error: error instanceof Error ? error.message : String(error)
1514
+ if (this.bindings) {
1515
+ const binding = this.getBinding(tableName);
1516
+ const response = await binding.list({
1517
+ limit: options?.limit || 1e3,
1518
+ prefix: options?.prefix
1519
+ });
1520
+ return response.keys;
1521
+ } else {
1522
+ const namespaceId = await this.getNamespaceId(tableName);
1523
+ const response = await this.client.kv.namespaces.keys.list(namespaceId, {
1524
+ account_id: this.accountId,
1525
+ limit: options?.limit || 1e3,
1526
+ prefix: options?.prefix
1527
+ });
1528
+ return response.result;
1529
+ }
1530
+ } catch (error$1) {
1531
+ throw new error.MastraError(
1532
+ {
1533
+ id: "CLOUDFLARE_STORAGE_LIST_NAMESPACE_KEYS_FAILED",
1534
+ domain: error.ErrorDomain.STORAGE,
1535
+ category: error.ErrorCategory.THIRD_PARTY,
1536
+ details: {
1537
+ tableName
1538
+ }
1539
+ },
1540
+ error$1
1541
+ );
1542
+ }
1543
+ }
1544
+ async deleteNamespaceValue(tableName, key) {
1545
+ if (this.bindings) {
1546
+ const binding = this.getBinding(tableName);
1547
+ await binding.delete(key);
1548
+ } else {
1549
+ const namespaceId = await this.getNamespaceId(tableName);
1550
+ await this.client.kv.namespaces.values.delete(namespaceId, key, {
1551
+ account_id: this.accountId
647
1552
  });
648
- return null;
649
1553
  }
650
1554
  }
651
- async getThreadsByResourceId({ resourceId }) {
1555
+ async deleteKV(tableName, key) {
652
1556
  try {
653
- const keyList = await this.listKV(storage.TABLE_THREADS);
654
- const threads = await Promise.all(
655
- keyList.map(async (keyObj) => {
656
- try {
657
- const data = await this.getKV(storage.TABLE_THREADS, keyObj.name);
658
- if (!data) return null;
659
- const thread = typeof data === "string" ? JSON.parse(data) : data;
660
- if (!thread || !thread.resourceId || thread.resourceId !== resourceId) return null;
661
- return {
662
- ...thread,
663
- createdAt: this.ensureDate(thread.createdAt),
664
- updatedAt: this.ensureDate(thread.updatedAt),
665
- metadata: this.ensureMetadata(thread.metadata)
666
- };
667
- } catch (error) {
668
- const message = error instanceof Error ? error.message : String(error);
669
- this.logger.error(`Error processing thread from key ${keyObj.name}:`, { message });
670
- return null;
671
- }
672
- })
673
- );
674
- return threads.filter((thread) => thread !== null);
1557
+ await this.deleteNamespaceValue(tableName, key);
675
1558
  } catch (error) {
676
- const message = error instanceof Error ? error.message : String(error);
677
- this.logger.error(`Error getting threads for resourceId ${resourceId}:`, { message });
678
- return [];
1559
+ this.logger.error(`Failed to delete KV value for ${tableName}:${key}:`, error);
1560
+ throw new Error(`Failed to delete KV value: ${error.message}`);
679
1561
  }
680
1562
  }
681
- async saveThread({ thread }) {
1563
+ async listKV(tableName, options) {
682
1564
  try {
683
- await this.insert({ tableName: storage.TABLE_THREADS, record: thread });
684
- return thread;
1565
+ return await this.listNamespaceKeys(tableName, options);
685
1566
  } catch (error) {
686
- const message = error instanceof Error ? error.message : String(error);
687
- this.logger.error("Error saving thread:", { message });
688
- throw error;
1567
+ this.logger.error(`Failed to list KV for ${tableName}:`, error);
1568
+ throw new Error(`Failed to list KV: ${error.message}`);
689
1569
  }
690
1570
  }
691
- async updateThread({
692
- id,
693
- title,
694
- metadata
695
- }) {
1571
+ };
1572
+ function transformScoreRow(row) {
1573
+ const deserialized = { ...row };
1574
+ deserialized.input = storage.safelyParseJSON(row.input);
1575
+ deserialized.output = storage.safelyParseJSON(row.output);
1576
+ deserialized.scorer = storage.safelyParseJSON(row.scorer);
1577
+ deserialized.preprocessStepResult = storage.safelyParseJSON(row.preprocessStepResult);
1578
+ deserialized.analyzeStepResult = storage.safelyParseJSON(row.analyzeStepResult);
1579
+ deserialized.metadata = storage.safelyParseJSON(row.metadata);
1580
+ deserialized.additionalContext = storage.safelyParseJSON(row.additionalContext);
1581
+ deserialized.runtimeContext = storage.safelyParseJSON(row.runtimeContext);
1582
+ deserialized.entity = storage.safelyParseJSON(row.entity);
1583
+ return deserialized;
1584
+ }
1585
+ var ScoresStorageCloudflare = class extends storage.ScoresStorage {
1586
+ operations;
1587
+ constructor({ operations }) {
1588
+ super();
1589
+ this.operations = operations;
1590
+ }
1591
+ async getScoreById({ id }) {
696
1592
  try {
697
- const thread = await this.getThreadById({ threadId: id });
698
- if (!thread) {
699
- throw new Error(`Thread ${id} not found`);
1593
+ const score = await this.operations.getKV(storage.TABLE_SCORERS, id);
1594
+ if (!score) {
1595
+ return null;
700
1596
  }
701
- const updatedThread = {
702
- ...thread,
703
- title,
704
- metadata: this.ensureMetadata({
705
- ...thread.metadata ?? {},
706
- ...metadata
707
- }),
708
- updatedAt: /* @__PURE__ */ new Date()
709
- };
710
- await this.insert({ tableName: storage.TABLE_THREADS, record: updatedThread });
711
- return updatedThread;
712
- } catch (error) {
713
- const message = error instanceof Error ? error.message : String(error);
714
- this.logger.error(`Error updating thread ${id}:`, { message });
715
- throw error;
1597
+ return transformScoreRow(score);
1598
+ } catch (error$1) {
1599
+ const mastraError = new error.MastraError(
1600
+ {
1601
+ id: "CLOUDFLARE_STORAGE_SCORES_GET_SCORE_BY_ID_FAILED",
1602
+ domain: error.ErrorDomain.STORAGE,
1603
+ category: error.ErrorCategory.THIRD_PARTY,
1604
+ text: `Failed to get score by id: ${id}`
1605
+ },
1606
+ error$1
1607
+ );
1608
+ this.logger.trackException(mastraError);
1609
+ this.logger.error(mastraError.toString());
1610
+ return null;
716
1611
  }
717
1612
  }
718
- async deleteThread({ threadId }) {
1613
+ async saveScore(score) {
719
1614
  try {
720
- const thread = await this.getThreadById({ threadId });
721
- if (!thread) {
722
- throw new Error(`Thread ${threadId} not found`);
1615
+ const id = crypto.randomUUID();
1616
+ const { input, ...rest } = score;
1617
+ const serializedRecord = {};
1618
+ for (const [key, value] of Object.entries(rest)) {
1619
+ if (value !== null && value !== void 0) {
1620
+ if (typeof value === "object") {
1621
+ serializedRecord[key] = JSON.stringify(value);
1622
+ } else {
1623
+ serializedRecord[key] = value;
1624
+ }
1625
+ } else {
1626
+ serializedRecord[key] = null;
1627
+ }
723
1628
  }
724
- const messageKeys = await this.listKV(storage.TABLE_MESSAGES);
725
- const threadMessageKeys = messageKeys.filter((key) => key.name.includes(`${storage.TABLE_MESSAGES}:${threadId}:`));
726
- await Promise.all([
727
- // Delete message order
728
- this.deleteKV(storage.TABLE_MESSAGES, this.getThreadMessagesKey(threadId)),
729
- // Delete all messages
730
- ...threadMessageKeys.map((key) => this.deleteKV(storage.TABLE_MESSAGES, key.name)),
731
- // Delete thread
732
- this.deleteKV(storage.TABLE_THREADS, this.getKey(storage.TABLE_THREADS, { id: threadId }))
733
- ]);
734
- } catch (error) {
735
- const message = error instanceof Error ? error.message : String(error);
736
- this.logger.error(`Error deleting thread ${threadId}:`, { message });
737
- throw error;
1629
+ serializedRecord.id = id;
1630
+ serializedRecord.createdAt = (/* @__PURE__ */ new Date()).toISOString();
1631
+ serializedRecord.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1632
+ await this.operations.putKV({
1633
+ tableName: storage.TABLE_SCORERS,
1634
+ key: id,
1635
+ value: serializedRecord
1636
+ });
1637
+ const scoreFromDb = await this.getScoreById({ id: score.id });
1638
+ return { score: scoreFromDb };
1639
+ } catch (error$1) {
1640
+ const mastraError = new error.MastraError(
1641
+ {
1642
+ id: "CLOUDFLARE_STORAGE_SCORES_SAVE_SCORE_FAILED",
1643
+ domain: error.ErrorDomain.STORAGE,
1644
+ category: error.ErrorCategory.THIRD_PARTY,
1645
+ text: `Failed to save score: ${score.id}`
1646
+ },
1647
+ error$1
1648
+ );
1649
+ this.logger.trackException(mastraError);
1650
+ this.logger.error(mastraError.toString());
1651
+ throw mastraError;
738
1652
  }
739
1653
  }
740
- getMessageKey(threadId, messageId) {
1654
+ async getScoresByScorerId({
1655
+ scorerId,
1656
+ entityId,
1657
+ entityType,
1658
+ source,
1659
+ pagination
1660
+ }) {
741
1661
  try {
742
- return this.getKey(storage.TABLE_MESSAGES, { threadId, id: messageId });
743
- } catch (error) {
744
- const message = error instanceof Error ? error.message : String(error);
745
- this.logger.error(`Error getting message key for thread ${threadId} and message ${messageId}:`, { message });
746
- throw error;
1662
+ const keys = await this.operations.listKV(storage.TABLE_SCORERS);
1663
+ const scores = [];
1664
+ for (const { name: key } of keys) {
1665
+ const score = await this.operations.getKV(storage.TABLE_SCORERS, key);
1666
+ if (entityId && score.entityId !== entityId) {
1667
+ continue;
1668
+ }
1669
+ if (entityType && score.entityType !== entityType) {
1670
+ continue;
1671
+ }
1672
+ if (source && score.source !== source) {
1673
+ continue;
1674
+ }
1675
+ if (score && score.scorerId === scorerId) {
1676
+ scores.push(transformScoreRow(score));
1677
+ }
1678
+ }
1679
+ scores.sort((a, b) => {
1680
+ const dateA = new Date(a.createdAt || 0).getTime();
1681
+ const dateB = new Date(b.createdAt || 0).getTime();
1682
+ return dateB - dateA;
1683
+ });
1684
+ const total = scores.length;
1685
+ const start = pagination.page * pagination.perPage;
1686
+ const end = start + pagination.perPage;
1687
+ const pagedScores = scores.slice(start, end);
1688
+ return {
1689
+ pagination: {
1690
+ total,
1691
+ page: pagination.page,
1692
+ perPage: pagination.perPage,
1693
+ hasMore: end < total
1694
+ },
1695
+ scores: pagedScores
1696
+ };
1697
+ } catch (error$1) {
1698
+ const mastraError = new error.MastraError(
1699
+ {
1700
+ id: "CLOUDFLARE_STORAGE_SCORES_GET_SCORES_BY_SCORER_ID_FAILED",
1701
+ domain: error.ErrorDomain.STORAGE,
1702
+ category: error.ErrorCategory.THIRD_PARTY,
1703
+ text: `Failed to get scores by scorer id: ${scorerId}`
1704
+ },
1705
+ error$1
1706
+ );
1707
+ this.logger?.trackException(mastraError);
1708
+ this.logger?.error(mastraError.toString());
1709
+ return { pagination: { total: 0, page: 0, perPage: 100, hasMore: false }, scores: [] };
747
1710
  }
748
1711
  }
749
- getThreadMessagesKey(threadId) {
1712
+ async getScoresByRunId({
1713
+ runId,
1714
+ pagination
1715
+ }) {
750
1716
  try {
751
- return this.getKey(storage.TABLE_MESSAGES, { threadId, id: "messages" });
752
- } catch (error) {
753
- const message = error instanceof Error ? error.message : String(error);
754
- this.logger.error(`Error getting thread messages key for thread ${threadId}:`, { message });
755
- throw error;
1717
+ const keys = await this.operations.listKV(storage.TABLE_SCORERS);
1718
+ const scores = [];
1719
+ for (const { name: key } of keys) {
1720
+ const score = await this.operations.getKV(storage.TABLE_SCORERS, key);
1721
+ if (score && score.runId === runId) {
1722
+ scores.push(transformScoreRow(score));
1723
+ }
1724
+ }
1725
+ scores.sort((a, b) => {
1726
+ const dateA = new Date(a.createdAt || 0).getTime();
1727
+ const dateB = new Date(b.createdAt || 0).getTime();
1728
+ return dateB - dateA;
1729
+ });
1730
+ const total = scores.length;
1731
+ const start = pagination.page * pagination.perPage;
1732
+ const end = start + pagination.perPage;
1733
+ const pagedScores = scores.slice(start, end);
1734
+ return {
1735
+ pagination: {
1736
+ total,
1737
+ page: pagination.page,
1738
+ perPage: pagination.perPage,
1739
+ hasMore: end < total
1740
+ },
1741
+ scores: pagedScores
1742
+ };
1743
+ } catch (error$1) {
1744
+ const mastraError = new error.MastraError(
1745
+ {
1746
+ id: "CLOUDFLARE_STORAGE_SCORES_GET_SCORES_BY_RUN_ID_FAILED",
1747
+ domain: error.ErrorDomain.STORAGE,
1748
+ category: error.ErrorCategory.THIRD_PARTY,
1749
+ text: `Failed to get scores by run id: ${runId}`
1750
+ },
1751
+ error$1
1752
+ );
1753
+ this.logger.trackException(mastraError);
1754
+ this.logger.error(mastraError.toString());
1755
+ return { pagination: { total: 0, page: 0, perPage: 100, hasMore: false }, scores: [] };
756
1756
  }
757
1757
  }
758
- async saveMessages({ messages }) {
759
- if (!Array.isArray(messages) || messages.length === 0) return [];
1758
+ async getScoresByEntityId({
1759
+ entityId,
1760
+ entityType,
1761
+ pagination
1762
+ }) {
760
1763
  try {
761
- const validatedMessages = messages.map((message, index) => {
762
- const errors = [];
763
- if (!message.id) errors.push("id is required");
764
- if (!message.threadId) errors.push("threadId is required");
765
- if (!message.content) errors.push("content is required");
766
- if (!message.role) errors.push("role is required");
767
- if (!message.createdAt) errors.push("createdAt is required");
768
- if (errors.length > 0) {
769
- throw new Error(`Invalid message at index ${index}: ${errors.join(", ")}`);
1764
+ const keys = await this.operations.listKV(storage.TABLE_SCORERS);
1765
+ const scores = [];
1766
+ for (const { name: key } of keys) {
1767
+ const score = await this.operations.getKV(storage.TABLE_SCORERS, key);
1768
+ if (score && score.entityId === entityId && score.entityType === entityType) {
1769
+ scores.push(transformScoreRow(score));
770
1770
  }
771
- return {
772
- ...message,
773
- createdAt: this.ensureDate(message.createdAt),
774
- type: message.type || "text",
775
- _index: index
776
- };
1771
+ }
1772
+ scores.sort((a, b) => {
1773
+ const dateA = new Date(a.createdAt || 0).getTime();
1774
+ const dateB = new Date(b.createdAt || 0).getTime();
1775
+ return dateB - dateA;
777
1776
  });
778
- const messagesByThread = validatedMessages.reduce((acc, message) => {
779
- if (!acc.has(message.threadId)) {
780
- acc.set(message.threadId, []);
781
- }
782
- acc.get(message.threadId).push(message);
783
- return acc;
784
- }, /* @__PURE__ */ new Map());
785
- await Promise.all(
786
- Array.from(messagesByThread.entries()).map(async ([threadId, threadMessages]) => {
787
- try {
788
- const thread = await this.getThreadById({ threadId });
789
- if (!thread) {
790
- throw new Error(`Thread ${threadId} not found`);
791
- }
792
- await Promise.all(
793
- threadMessages.map(async (message) => {
794
- const key = await this.getMessageKey(threadId, message.id);
795
- const { _index, ...cleanMessage } = message;
796
- const serializedMessage = {
797
- ...cleanMessage,
798
- createdAt: this.serializeDate(cleanMessage.createdAt)
799
- };
800
- await this.putKV({ tableName: storage.TABLE_MESSAGES, key, value: serializedMessage });
801
- })
802
- );
803
- const orderKey = this.getThreadMessagesKey(threadId);
804
- const entries = await this.updateSorting(threadMessages);
805
- await this.updateSortedMessages(orderKey, entries);
806
- } catch (error) {
807
- const errorMessage = error instanceof Error ? error.message : String(error);
808
- this.logger.error(`Error processing messages for thread ${threadId}: ${errorMessage}`);
809
- throw error;
810
- }
811
- })
1777
+ const total = scores.length;
1778
+ const start = pagination.page * pagination.perPage;
1779
+ const end = start + pagination.perPage;
1780
+ const pagedScores = scores.slice(start, end);
1781
+ return {
1782
+ pagination: {
1783
+ total,
1784
+ page: pagination.page,
1785
+ perPage: pagination.perPage,
1786
+ hasMore: end < total
1787
+ },
1788
+ scores: pagedScores
1789
+ };
1790
+ } catch (error$1) {
1791
+ const mastraError = new error.MastraError(
1792
+ {
1793
+ id: "CLOUDFLARE_STORAGE_SCORES_GET_SCORES_BY_ENTITY_ID_FAILED",
1794
+ domain: error.ErrorDomain.STORAGE,
1795
+ category: error.ErrorCategory.THIRD_PARTY,
1796
+ text: `Failed to get scores by entity id: ${entityId}, type: ${entityType}`
1797
+ },
1798
+ error$1
812
1799
  );
813
- return validatedMessages.map(({ _index, ...message }) => message);
814
- } catch (error) {
815
- const errorMessage = error instanceof Error ? error.message : String(error);
816
- this.logger.error(`Error saving messages: ${errorMessage}`);
817
- throw error;
1800
+ this.logger.trackException(mastraError);
1801
+ this.logger.error(mastraError.toString());
1802
+ return { pagination: { total: 0, page: 0, perPage: 100, hasMore: false }, scores: [] };
818
1803
  }
819
1804
  }
820
- async getMessages({ threadId, selectBy }) {
821
- if (!threadId) throw new Error("threadId is required");
822
- let limit = 40;
823
- if (typeof selectBy?.last === "number") {
824
- limit = Math.max(0, selectBy.last);
825
- } else if (selectBy?.last === false) {
826
- limit = 0;
1805
+ };
1806
+ var TracesStorageCloudflare = class extends storage.TracesStorage {
1807
+ operations;
1808
+ constructor({ operations }) {
1809
+ super();
1810
+ this.operations = operations;
1811
+ }
1812
+ async getTraces(args) {
1813
+ const paginatedArgs = {
1814
+ name: args.name,
1815
+ scope: args.scope,
1816
+ page: args.page,
1817
+ perPage: args.perPage,
1818
+ attributes: args.attributes,
1819
+ filters: args.filters,
1820
+ dateRange: args.fromDate || args.toDate ? {
1821
+ start: args.fromDate,
1822
+ end: args.toDate
1823
+ } : void 0
1824
+ };
1825
+ try {
1826
+ const result = await this.getTracesPaginated(paginatedArgs);
1827
+ return result.traces;
1828
+ } catch (error$1) {
1829
+ throw new error.MastraError(
1830
+ {
1831
+ id: "CLOUDFLARE_STORAGE_GET_TRACES_ERROR",
1832
+ domain: error.ErrorDomain.STORAGE,
1833
+ category: error.ErrorCategory.THIRD_PARTY,
1834
+ text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
1835
+ details: {
1836
+ name: args.name ?? "",
1837
+ scope: args.scope ?? ""
1838
+ }
1839
+ },
1840
+ error$1
1841
+ );
827
1842
  }
828
- const messageIds = /* @__PURE__ */ new Set();
829
- if (limit === 0 && !selectBy?.include?.length) return [];
1843
+ }
1844
+ async getTracesPaginated(args) {
830
1845
  try {
831
- await Promise.all([
832
- selectBy?.include?.length ? this.getIncludedMessagesWithContext(threadId, selectBy.include, messageIds) : Promise.resolve(),
833
- limit > 0 && !selectBy?.include?.length ? this.getRecentMessages(threadId, limit, messageIds) : Promise.resolve()
834
- ]);
835
- const messages = await this.fetchAndParseMessages(threadId, Array.from(messageIds));
836
- if (!messages.length) return [];
837
- try {
838
- const threadMessagesKey = this.getThreadMessagesKey(threadId);
839
- const messageOrder = await this.getFullOrder(threadMessagesKey);
840
- const orderMap = new Map(messageOrder.map((id, index) => [id, index]));
841
- messages.sort((a, b) => {
842
- const indexA = orderMap.get(a.id);
843
- const indexB = orderMap.get(b.id);
844
- if (indexA !== void 0 && indexB !== void 0) return orderMap.get(a.id) - orderMap.get(b.id);
845
- return new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime();
846
- });
847
- } catch (error) {
848
- const errorMessage = error instanceof Error ? error.message : String(error);
849
- this.logger.warn(`Error sorting messages, falling back to creation time: ${errorMessage}`);
850
- messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1846
+ const { name, scope, attributes, filters, page = 0, perPage = 100, dateRange } = args;
1847
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
1848
+ const keyObjs = await this.operations.listKV(storage.TABLE_TRACES, { prefix: `${prefix}${storage.TABLE_TRACES}` });
1849
+ const traces = [];
1850
+ for (const { name: key } of keyObjs) {
1851
+ try {
1852
+ const data = await this.operations.getKV(storage.TABLE_TRACES, key);
1853
+ if (!data) continue;
1854
+ if (name && data.name !== name) continue;
1855
+ if (scope && data.scope !== scope) continue;
1856
+ if (attributes) {
1857
+ const dataAttributes = data.attributes || {};
1858
+ let shouldSkip = false;
1859
+ for (const [key2, value] of Object.entries(attributes)) {
1860
+ if (dataAttributes[key2] !== value) {
1861
+ shouldSkip = true;
1862
+ break;
1863
+ }
1864
+ }
1865
+ if (shouldSkip) continue;
1866
+ }
1867
+ if (dateRange?.start || dateRange?.end) {
1868
+ const traceDate = new Date(data.createdAt || 0);
1869
+ if (dateRange.start && traceDate < dateRange.start) continue;
1870
+ if (dateRange.end && traceDate > dateRange.end) continue;
1871
+ }
1872
+ if (filters) {
1873
+ let shouldSkip = false;
1874
+ for (const [key2, value] of Object.entries(filters)) {
1875
+ if (data[key2] !== value) {
1876
+ shouldSkip = true;
1877
+ break;
1878
+ }
1879
+ }
1880
+ if (shouldSkip) continue;
1881
+ }
1882
+ traces.push(data);
1883
+ } catch (err) {
1884
+ this.logger.error("Failed to parse trace:", { key, error: err });
1885
+ }
851
1886
  }
852
- return messages.map(({ _index, ...message }) => ({
853
- ...message,
854
- createdAt: this.ensureDate(message.createdAt)
855
- }));
856
- } catch (error) {
857
- const errorMessage = error instanceof Error ? error.message : String(error);
858
- this.logger.error(`Error retrieving messages for thread ${threadId}: ${errorMessage}`);
859
- return [];
1887
+ traces.sort((a, b) => {
1888
+ const aTime = new Date(a.createdAt || 0).getTime();
1889
+ const bTime = new Date(b.createdAt || 0).getTime();
1890
+ return bTime - aTime;
1891
+ });
1892
+ const total = traces.length;
1893
+ const start = page * perPage;
1894
+ const end = start + perPage;
1895
+ const pagedTraces = traces.slice(start, end);
1896
+ return {
1897
+ traces: pagedTraces,
1898
+ total,
1899
+ page,
1900
+ perPage,
1901
+ hasMore: end < total
1902
+ };
1903
+ } catch (error$1) {
1904
+ const mastraError = new error.MastraError(
1905
+ {
1906
+ id: "CLOUDFLARE_STORAGE_GET_TRACES_PAGINATED_FAILED",
1907
+ domain: error.ErrorDomain.STORAGE,
1908
+ category: error.ErrorCategory.THIRD_PARTY,
1909
+ text: "Error getting traces with pagination"
1910
+ },
1911
+ error$1
1912
+ );
1913
+ this.logger.trackException?.(mastraError);
1914
+ this.logger.error(mastraError.toString());
1915
+ return { traces: [], total: 0, page: 0, perPage: 100, hasMore: false };
860
1916
  }
861
1917
  }
1918
+ async batchTraceInsert({ records }) {
1919
+ this.logger.debug("Batch inserting traces", { count: records.length });
1920
+ await this.operations.batchInsert({
1921
+ tableName: storage.TABLE_TRACES,
1922
+ records
1923
+ });
1924
+ }
1925
+ };
1926
+ var WorkflowsStorageCloudflare = class extends storage.WorkflowsStorage {
1927
+ operations;
1928
+ constructor({ operations }) {
1929
+ super();
1930
+ this.operations = operations;
1931
+ }
862
1932
  validateWorkflowParams(params) {
863
- const { namespace, workflowName, runId } = params;
864
- if (!namespace || !workflowName || !runId) {
1933
+ const { workflowName, runId } = params;
1934
+ if (!workflowName || !runId) {
865
1935
  throw new Error("Invalid workflow snapshot parameters");
866
1936
  }
867
1937
  }
868
- validateWorkflowState(state) {
869
- if (!state?.runId || !state?.value || !state?.context?.steps || !state?.context?.triggerData || !state?.context?.attempts || !state?.activePaths) {
870
- throw new Error("Invalid workflow state structure");
871
- }
872
- }
873
- normalizeSteps(steps) {
874
- const normalizedSteps = {};
875
- for (const [stepId, step] of Object.entries(steps)) {
876
- normalizedSteps[stepId] = {
877
- status: step.status,
878
- payload: step.payload || step.result,
879
- error: step.error
880
- };
881
- }
882
- return normalizedSteps;
1938
+ updateWorkflowResults({
1939
+ // workflowName,
1940
+ // runId,
1941
+ // stepId,
1942
+ // result,
1943
+ // runtimeContext,
1944
+ }) {
1945
+ throw new Error("Method not implemented.");
883
1946
  }
884
- normalizeWorkflowState(data) {
885
- const steps = data.context?.stepResults || data.context?.steps || {};
886
- return {
887
- runId: data.runId,
888
- value: data.value,
889
- context: {
890
- steps: this.normalizeSteps(steps),
891
- triggerData: data.context?.triggerData || {},
892
- attempts: data.context?.attempts || {}
893
- },
894
- suspendedPaths: data.suspendedPaths || {},
895
- activePaths: data.activePaths || [],
896
- timestamp: data.timestamp || Date.now()
897
- };
1947
+ updateWorkflowState({
1948
+ // workflowName,
1949
+ // runId,
1950
+ // opts,
1951
+ }) {
1952
+ throw new Error("Method not implemented.");
898
1953
  }
899
1954
  async persistWorkflowSnapshot(params) {
900
1955
  try {
901
- this.validateWorkflowParams(params);
902
- const { namespace, workflowName, runId, snapshot } = params;
903
- const normalizedState = this.normalizeWorkflowState(snapshot);
904
- this.validateWorkflowState(normalizedState);
905
- await this.insert({
1956
+ const { workflowName, runId, snapshot } = params;
1957
+ await this.operations.putKV({
906
1958
  tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
907
- record: {
908
- namespace,
1959
+ key: this.operations.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { workflow_name: workflowName, run_id: runId }),
1960
+ value: {
909
1961
  workflow_name: workflowName,
910
1962
  run_id: runId,
911
- snapshot: normalizedState,
1963
+ snapshot: typeof snapshot === "string" ? snapshot : JSON.stringify(snapshot),
912
1964
  createdAt: /* @__PURE__ */ new Date(),
913
1965
  updatedAt: /* @__PURE__ */ new Date()
914
1966
  }
915
1967
  });
916
- } catch (error) {
917
- const message = error instanceof Error ? error.message : String(error);
918
- this.logger.error("Error persisting workflow snapshot:", { message });
919
- throw error;
1968
+ } catch (error$1) {
1969
+ throw new error.MastraError(
1970
+ {
1971
+ id: "CLOUDFLARE_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1972
+ domain: error.ErrorDomain.STORAGE,
1973
+ category: error.ErrorCategory.THIRD_PARTY,
1974
+ text: `Error persisting workflow snapshot for workflow ${params.workflowName}, run ${params.runId}`,
1975
+ details: {
1976
+ workflowName: params.workflowName,
1977
+ runId: params.runId
1978
+ }
1979
+ },
1980
+ error$1
1981
+ );
920
1982
  }
921
1983
  }
922
1984
  async loadWorkflowSnapshot(params) {
923
1985
  try {
924
1986
  this.validateWorkflowParams(params);
925
- const { namespace, workflowName, runId } = params;
926
- const key = this.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { namespace, workflow_name: workflowName, run_id: runId });
927
- const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
1987
+ const { workflowName, runId } = params;
1988
+ const key = this.operations.getKey(storage.TABLE_WORKFLOW_SNAPSHOT, { workflow_name: workflowName, run_id: runId });
1989
+ const data = await this.operations.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
928
1990
  if (!data) return null;
929
- const state = this.normalizeWorkflowState(data.snapshot || data);
930
- this.validateWorkflowState(state);
931
- return state;
932
- } catch (error) {
933
- this.logger.error("Error loading workflow snapshot:", {
934
- error: error instanceof Error ? error.message : String(error)
935
- });
936
- return null;
937
- }
938
- }
939
- async batchInsert(input) {
940
- if (!input.records || input.records.length === 0) return;
941
- try {
942
- await Promise.all(
943
- input.records.map(async (record) => {
944
- const key = this.getKey(input.tableName, record);
945
- const processedRecord = {
946
- ...record,
947
- createdAt: record.createdAt ? this.serializeDate(record.createdAt) : void 0,
948
- updatedAt: record.updatedAt ? this.serializeDate(record.updatedAt) : void 0,
949
- metadata: record.metadata ? JSON.stringify(record.metadata) : void 0
950
- };
951
- await this.putKV({ tableName: input.tableName, key, value: processedRecord });
952
- })
953
- );
954
- } catch (error) {
955
- const message = error instanceof Error ? error.message : String(error);
956
- this.logger.error("Error in batch insert:", { message });
957
- throw error;
958
- }
959
- }
960
- async getTraces({
961
- name,
962
- scope,
963
- page = 0,
964
- perPage = 100,
965
- attributes,
966
- fromDate,
967
- toDate
968
- }) {
969
- try {
970
- let keys;
971
- if (this.bindings) {
972
- keys = (await this.listKV(storage.TABLE_TRACES))?.map((k) => k.name) || [];
973
- } else {
974
- const namespaceId = await this.getNamespaceId(storage.TABLE_TRACES);
975
- const result = await this.client.kv.namespaces.keys.list(namespaceId, {
976
- prefix: "",
977
- limit: 1e3,
978
- account_id: this.accountId
979
- });
980
- keys = result.result?.map((k) => k.name) || [];
981
- }
982
- const traceRecords = await Promise.all(
983
- keys.map(async (key) => {
984
- const record = await this.getKV(storage.TABLE_TRACES, key);
985
- if (!record) return null;
986
- return record;
987
- })
988
- );
989
- let filteredTraces = traceRecords.filter(
990
- (record) => record !== null && typeof record === "object"
1991
+ const snapshotData = typeof data.snapshot === "string" ? JSON.parse(data.snapshot) : data.snapshot;
1992
+ return snapshotData;
1993
+ } catch (error$1) {
1994
+ const mastraError = new error.MastraError(
1995
+ {
1996
+ id: "CLOUDFLARE_STORAGE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1997
+ domain: error.ErrorDomain.STORAGE,
1998
+ category: error.ErrorCategory.THIRD_PARTY,
1999
+ text: `Error loading workflow snapshot for workflow ${params.workflowName}, run ${params.runId}`,
2000
+ details: {
2001
+ workflowName: params.workflowName,
2002
+ runId: params.runId
2003
+ }
2004
+ },
2005
+ error$1
991
2006
  );
992
- if (name) {
993
- filteredTraces = filteredTraces.filter((record) => record.name?.toLowerCase().startsWith(name.toLowerCase()));
994
- }
995
- if (scope) {
996
- filteredTraces = filteredTraces.filter((record) => record.scope === scope);
997
- }
998
- if (attributes) {
999
- filteredTraces = filteredTraces.filter((record) => {
1000
- if (!record.attributes) return false;
1001
- const recordAttrs = this.parseJSON(record.attributes);
1002
- if (!recordAttrs) return false;
1003
- return Object.entries(attributes).every(([key, value]) => recordAttrs[key] === value);
1004
- });
1005
- }
1006
- if (fromDate) {
1007
- filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() >= fromDate.getTime());
1008
- }
1009
- if (toDate) {
1010
- filteredTraces = filteredTraces.filter((record) => new Date(record.createdAt).getTime() <= toDate.getTime());
1011
- }
1012
- filteredTraces.sort((a, b) => {
1013
- const dateA = new Date(a.createdAt).getTime();
1014
- const dateB = new Date(b.createdAt).getTime();
1015
- return dateB - dateA;
1016
- });
1017
- const start = page * perPage;
1018
- const end = start + perPage;
1019
- const paginatedTraces = filteredTraces.slice(start, end);
1020
- return paginatedTraces.map((record) => ({
1021
- id: record.id,
1022
- parentSpanId: record.parentSpanId,
1023
- traceId: record.traceId,
1024
- name: record.name,
1025
- scope: record.scope,
1026
- kind: record.kind,
1027
- status: this.parseJSON(record.status),
1028
- events: this.parseJSON(record.events) || [],
1029
- links: this.parseJSON(record.links) || [],
1030
- attributes: this.parseJSON(record?.attributes) || {},
1031
- startTime: record.startTime,
1032
- endTime: record.endTime,
1033
- other: this.parseJSON(record.other) || {},
1034
- createdAt: record.createdAt
1035
- }));
1036
- } catch (error) {
1037
- const message = error instanceof Error ? error.message : String(error);
1038
- this.logger.error("Failed to get traces:", { message });
1039
- return [];
1040
- }
1041
- }
1042
- parseJSON(value) {
1043
- if (typeof value === "string") {
1044
- try {
1045
- return JSON.parse(value);
1046
- } catch {
1047
- return value;
1048
- }
2007
+ this.logger.trackException?.(mastraError);
2008
+ this.logger.error(mastraError.toString());
2009
+ return null;
1049
2010
  }
1050
- return value;
1051
- }
1052
- getEvalsByAgentName(_agentName, _type) {
1053
- throw new Error("Method not implemented.");
1054
2011
  }
1055
2012
  parseWorkflowRun(row) {
1056
2013
  let parsedSnapshot = row.snapshot;
@@ -1065,28 +2022,24 @@ var CloudflareStore = class extends storage.MastraStorage {
1065
2022
  workflowName: row.workflow_name,
1066
2023
  runId: row.run_id,
1067
2024
  snapshot: parsedSnapshot,
1068
- createdAt: this.ensureDate(row.createdAt),
1069
- updatedAt: this.ensureDate(row.updatedAt),
2025
+ createdAt: storage.ensureDate(row.createdAt),
2026
+ updatedAt: storage.ensureDate(row.updatedAt),
1070
2027
  resourceId: row.resourceId
1071
2028
  };
1072
2029
  }
1073
2030
  buildWorkflowSnapshotPrefix({
1074
- namespace,
1075
2031
  workflowName,
1076
2032
  runId,
1077
2033
  resourceId
1078
2034
  }) {
1079
- const prefix = this.namespacePrefix ? `${this.namespacePrefix}:` : "";
2035
+ const prefix = this.operations.namespacePrefix ? `${this.operations.namespacePrefix}:` : "";
1080
2036
  let key = `${prefix}${storage.TABLE_WORKFLOW_SNAPSHOT}`;
1081
- if (namespace) key += `:${namespace}`;
1082
2037
  if (workflowName) key += `:${workflowName}`;
1083
2038
  if (runId) key += `:${runId}`;
1084
2039
  if (resourceId) key += `:${resourceId}`;
1085
- if (!resourceId && (runId || workflowName || namespace)) key += ":";
1086
2040
  return key;
1087
2041
  }
1088
2042
  async getWorkflowRuns({
1089
- namespace,
1090
2043
  workflowName,
1091
2044
  limit = 20,
1092
2045
  offset = 0,
@@ -1095,28 +2048,32 @@ var CloudflareStore = class extends storage.MastraStorage {
1095
2048
  toDate
1096
2049
  } = {}) {
1097
2050
  try {
1098
- const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName });
1099
- const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
2051
+ const prefix = this.buildWorkflowSnapshotPrefix({ workflowName });
2052
+ const keyObjs = await this.operations.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
1100
2053
  const runs = [];
1101
2054
  for (const { name: key } of keyObjs) {
1102
2055
  const parts = key.split(":");
1103
2056
  const idx = parts.indexOf(storage.TABLE_WORKFLOW_SNAPSHOT);
1104
- if (idx === -1 || parts.length < idx + 4) continue;
1105
- const ns = parts[idx + 1];
1106
- const wfName = parts[idx + 2];
1107
- const keyResourceId = parts.length > idx + 4 ? parts[idx + 4] : void 0;
1108
- if (namespace && ns !== namespace || workflowName && wfName !== workflowName) continue;
1109
- if (resourceId && keyResourceId && keyResourceId !== resourceId) continue;
1110
- const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
2057
+ if (idx === -1 || parts.length < idx + 3) continue;
2058
+ const wfName = parts[idx + 1];
2059
+ const keyResourceId = parts.length > idx + 3 ? parts[idx + 3] : void 0;
2060
+ if (workflowName && wfName !== workflowName) continue;
2061
+ if (resourceId && keyResourceId !== resourceId) continue;
2062
+ const data = await this.operations.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
1111
2063
  if (!data) continue;
1112
2064
  try {
1113
- if (resourceId && data.resourceId && data.resourceId !== resourceId) continue;
1114
- const createdAt = this.ensureDate(data.createdAt);
2065
+ if (resourceId && !keyResourceId) continue;
2066
+ const createdAt = storage.ensureDate(data.createdAt);
1115
2067
  if (fromDate && createdAt && createdAt < fromDate) continue;
1116
2068
  if (toDate && createdAt && createdAt > toDate) continue;
1117
- const state = this.normalizeWorkflowState(data.snapshot || data);
1118
- this.validateWorkflowState(state);
1119
- const run = this.parseWorkflowRun({ ...data, snapshot: state });
2069
+ const snapshotData = typeof data.snapshot === "string" ? JSON.parse(data.snapshot) : data.snapshot;
2070
+ const resourceIdToUse = keyResourceId || data.resourceId;
2071
+ const run = this.parseWorkflowRun({
2072
+ ...data,
2073
+ workflow_name: wfName,
2074
+ resourceId: resourceIdToUse,
2075
+ snapshot: snapshotData
2076
+ });
1120
2077
  runs.push(run);
1121
2078
  } catch (err) {
1122
2079
  this.logger.error("Failed to parse workflow snapshot:", { key, error: err });
@@ -1132,38 +2089,355 @@ var CloudflareStore = class extends storage.MastraStorage {
1132
2089
  runs: pagedRuns,
1133
2090
  total: runs.length
1134
2091
  };
1135
- } catch (error) {
1136
- const message = error instanceof Error ? error.message : String(error);
1137
- this.logger.error("Error in getWorkflowRuns:", { message });
2092
+ } catch (error$1) {
2093
+ const mastraError = new error.MastraError(
2094
+ {
2095
+ id: "CLOUDFLARE_STORAGE_GET_WORKFLOW_RUNS_FAILED",
2096
+ domain: error.ErrorDomain.STORAGE,
2097
+ category: error.ErrorCategory.THIRD_PARTY
2098
+ },
2099
+ error$1
2100
+ );
2101
+ this.logger.trackException?.(mastraError);
2102
+ this.logger.error(mastraError.toString());
1138
2103
  return { runs: [], total: 0 };
1139
2104
  }
1140
2105
  }
1141
2106
  async getWorkflowRunById({
1142
- namespace,
1143
2107
  runId,
1144
2108
  workflowName
1145
2109
  }) {
1146
2110
  try {
1147
- if (!runId || !workflowName || !namespace) {
1148
- throw new Error("runId, workflowName, and namespace are required");
2111
+ if (!runId || !workflowName) {
2112
+ throw new Error("runId, workflowName, are required");
1149
2113
  }
1150
- const prefix = this.buildWorkflowSnapshotPrefix({ namespace, workflowName, runId });
1151
- const keyObjs = await this.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
2114
+ const prefix = this.buildWorkflowSnapshotPrefix({ workflowName, runId });
2115
+ const keyObjs = await this.operations.listKV(storage.TABLE_WORKFLOW_SNAPSHOT, { prefix });
1152
2116
  if (!keyObjs.length) return null;
1153
- const key = keyObjs[0]?.name;
1154
- const data = await this.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, key);
2117
+ const exactKey = keyObjs.find((k) => {
2118
+ const parts = k.name.split(":");
2119
+ const idx = parts.indexOf(storage.TABLE_WORKFLOW_SNAPSHOT);
2120
+ if (idx === -1 || parts.length < idx + 3) return false;
2121
+ const wfName = parts[idx + 1];
2122
+ const rId = parts[idx + 2];
2123
+ return wfName === workflowName && rId === runId;
2124
+ });
2125
+ if (!exactKey) return null;
2126
+ const data = await this.operations.getKV(storage.TABLE_WORKFLOW_SNAPSHOT, exactKey.name);
1155
2127
  if (!data) return null;
1156
- const state = this.normalizeWorkflowState(data.snapshot || data);
1157
- this.validateWorkflowState(state);
1158
- return this.parseWorkflowRun({ ...data, snapshot: state });
1159
- } catch (error) {
1160
- const message = error instanceof Error ? error.message : String(error);
1161
- this.logger.error("Error in getWorkflowRunById:", { message });
2128
+ const snapshotData = typeof data.snapshot === "string" ? JSON.parse(data.snapshot) : data.snapshot;
2129
+ return this.parseWorkflowRun({ ...data, snapshot: snapshotData });
2130
+ } catch (error$1) {
2131
+ const mastraError = new error.MastraError(
2132
+ {
2133
+ id: "CLOUDFLARE_STORAGE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2134
+ domain: error.ErrorDomain.STORAGE,
2135
+ category: error.ErrorCategory.THIRD_PARTY,
2136
+ details: {
2137
+ workflowName,
2138
+ runId
2139
+ }
2140
+ },
2141
+ error$1
2142
+ );
2143
+ this.logger.trackException?.(mastraError);
2144
+ this.logger.error(mastraError.toString());
1162
2145
  return null;
1163
2146
  }
1164
2147
  }
2148
+ };
2149
+
2150
+ // src/storage/types.ts
2151
+ function isWorkersConfig(config) {
2152
+ return "bindings" in config;
2153
+ }
2154
+
2155
+ // src/storage/index.ts
2156
+ var CloudflareStore = class extends storage.MastraStorage {
2157
+ stores;
2158
+ client;
2159
+ accountId;
2160
+ namespacePrefix;
2161
+ bindings;
2162
+ validateWorkersConfig(config) {
2163
+ if (!isWorkersConfig(config)) {
2164
+ throw new Error("Invalid Workers API configuration");
2165
+ }
2166
+ if (!config.bindings) {
2167
+ throw new Error("KV bindings are required when using Workers Binding API");
2168
+ }
2169
+ const requiredTables = [
2170
+ storage.TABLE_THREADS,
2171
+ storage.TABLE_MESSAGES,
2172
+ storage.TABLE_WORKFLOW_SNAPSHOT,
2173
+ storage.TABLE_EVALS,
2174
+ storage.TABLE_SCORERS,
2175
+ storage.TABLE_TRACES
2176
+ ];
2177
+ for (const table of requiredTables) {
2178
+ if (!(table in config.bindings)) {
2179
+ throw new Error(`Missing KV binding for table: ${table}`);
2180
+ }
2181
+ }
2182
+ }
2183
+ validateRestConfig(config) {
2184
+ if (isWorkersConfig(config)) {
2185
+ throw new Error("Invalid REST API configuration");
2186
+ }
2187
+ if (!config.accountId?.trim()) {
2188
+ throw new Error("accountId is required for REST API");
2189
+ }
2190
+ if (!config.apiToken?.trim()) {
2191
+ throw new Error("apiToken is required for REST API");
2192
+ }
2193
+ }
2194
+ constructor(config) {
2195
+ super({ name: "Cloudflare" });
2196
+ try {
2197
+ if (isWorkersConfig(config)) {
2198
+ this.validateWorkersConfig(config);
2199
+ this.bindings = config.bindings;
2200
+ this.namespacePrefix = config.keyPrefix?.trim() || "";
2201
+ this.logger.info("Using Cloudflare KV Workers Binding API");
2202
+ } else {
2203
+ this.validateRestConfig(config);
2204
+ this.accountId = config.accountId.trim();
2205
+ this.namespacePrefix = config.namespacePrefix?.trim() || "";
2206
+ this.client = new Cloudflare__default.default({
2207
+ apiToken: config.apiToken.trim()
2208
+ });
2209
+ this.logger.info("Using Cloudflare KV REST API");
2210
+ }
2211
+ const operations = new StoreOperationsCloudflare({
2212
+ accountId: this.accountId,
2213
+ client: this.client,
2214
+ namespacePrefix: this.namespacePrefix,
2215
+ bindings: this.bindings
2216
+ });
2217
+ const legacyEvals = new LegacyEvalsStorageCloudflare({
2218
+ operations
2219
+ });
2220
+ const workflows = new WorkflowsStorageCloudflare({
2221
+ operations
2222
+ });
2223
+ const traces = new TracesStorageCloudflare({
2224
+ operations
2225
+ });
2226
+ const memory = new MemoryStorageCloudflare({
2227
+ operations
2228
+ });
2229
+ const scores = new ScoresStorageCloudflare({
2230
+ operations
2231
+ });
2232
+ this.stores = {
2233
+ operations,
2234
+ legacyEvals,
2235
+ workflows,
2236
+ traces,
2237
+ memory,
2238
+ scores
2239
+ };
2240
+ } catch (error$1) {
2241
+ throw new error.MastraError(
2242
+ {
2243
+ id: "CLOUDFLARE_STORAGE_INIT_FAILED",
2244
+ domain: error.ErrorDomain.STORAGE,
2245
+ category: error.ErrorCategory.THIRD_PARTY
2246
+ },
2247
+ error$1
2248
+ );
2249
+ }
2250
+ }
2251
+ async createTable({
2252
+ tableName,
2253
+ schema
2254
+ }) {
2255
+ return this.stores.operations.createTable({ tableName, schema });
2256
+ }
2257
+ async alterTable(_args) {
2258
+ return this.stores.operations.alterTable(_args);
2259
+ }
2260
+ async clearTable({ tableName }) {
2261
+ return this.stores.operations.clearTable({ tableName });
2262
+ }
2263
+ async dropTable({ tableName }) {
2264
+ return this.stores.operations.dropTable({ tableName });
2265
+ }
2266
+ async insert({
2267
+ tableName,
2268
+ record
2269
+ }) {
2270
+ return this.stores.operations.insert({ tableName, record });
2271
+ }
2272
+ async load({ tableName, keys }) {
2273
+ return this.stores.operations.load({ tableName, keys });
2274
+ }
2275
+ async getThreadById({ threadId }) {
2276
+ return this.stores.memory.getThreadById({ threadId });
2277
+ }
2278
+ async getThreadsByResourceId({ resourceId }) {
2279
+ return this.stores.memory.getThreadsByResourceId({ resourceId });
2280
+ }
2281
+ async saveThread({ thread }) {
2282
+ return this.stores.memory.saveThread({ thread });
2283
+ }
2284
+ async updateThread({
2285
+ id,
2286
+ title,
2287
+ metadata
2288
+ }) {
2289
+ return this.stores.memory.updateThread({ id, title, metadata });
2290
+ }
2291
+ async deleteThread({ threadId }) {
2292
+ return this.stores.memory.deleteThread({ threadId });
2293
+ }
2294
+ async saveMessages(args) {
2295
+ return this.stores.memory.saveMessages(args);
2296
+ }
2297
+ async getMessages({
2298
+ threadId,
2299
+ resourceId,
2300
+ selectBy,
2301
+ format
2302
+ }) {
2303
+ return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
2304
+ }
2305
+ async updateWorkflowResults({
2306
+ workflowName,
2307
+ runId,
2308
+ stepId,
2309
+ result,
2310
+ runtimeContext
2311
+ }) {
2312
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
2313
+ }
2314
+ async updateWorkflowState({
2315
+ workflowName,
2316
+ runId,
2317
+ opts
2318
+ }) {
2319
+ return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
2320
+ }
2321
+ async getMessagesById({
2322
+ messageIds,
2323
+ format
2324
+ }) {
2325
+ return this.stores.memory.getMessagesById({ messageIds, format });
2326
+ }
2327
+ async persistWorkflowSnapshot(params) {
2328
+ return this.stores.workflows.persistWorkflowSnapshot(params);
2329
+ }
2330
+ async loadWorkflowSnapshot(params) {
2331
+ return this.stores.workflows.loadWorkflowSnapshot(params);
2332
+ }
2333
+ async batchInsert(input) {
2334
+ return this.stores.operations.batchInsert(input);
2335
+ }
2336
+ async getTraces({
2337
+ name,
2338
+ scope,
2339
+ page = 0,
2340
+ perPage = 100,
2341
+ attributes,
2342
+ fromDate,
2343
+ toDate
2344
+ }) {
2345
+ return this.stores.traces.getTraces({
2346
+ name,
2347
+ scope,
2348
+ page,
2349
+ perPage,
2350
+ attributes,
2351
+ fromDate,
2352
+ toDate
2353
+ });
2354
+ }
2355
+ async getEvalsByAgentName(agentName, type) {
2356
+ return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
2357
+ }
2358
+ async getEvals(options) {
2359
+ return this.stores.legacyEvals.getEvals(options);
2360
+ }
2361
+ async getWorkflowRuns({
2362
+ workflowName,
2363
+ limit = 20,
2364
+ offset = 0,
2365
+ resourceId,
2366
+ fromDate,
2367
+ toDate
2368
+ } = {}) {
2369
+ return this.stores.workflows.getWorkflowRuns({
2370
+ workflowName,
2371
+ limit,
2372
+ offset,
2373
+ resourceId,
2374
+ fromDate,
2375
+ toDate
2376
+ });
2377
+ }
2378
+ async getWorkflowRunById({
2379
+ runId,
2380
+ workflowName
2381
+ }) {
2382
+ return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
2383
+ }
2384
+ async getTracesPaginated(args) {
2385
+ return this.stores.traces.getTracesPaginated(args);
2386
+ }
2387
+ async getThreadsByResourceIdPaginated(args) {
2388
+ return this.stores.memory.getThreadsByResourceIdPaginated(args);
2389
+ }
2390
+ async getMessagesPaginated(args) {
2391
+ return this.stores.memory.getMessagesPaginated(args);
2392
+ }
2393
+ async updateMessages(args) {
2394
+ return this.stores.memory.updateMessages(args);
2395
+ }
2396
+ async getScoreById({ id }) {
2397
+ return this.stores.scores.getScoreById({ id });
2398
+ }
2399
+ async saveScore(score) {
2400
+ return this.stores.scores.saveScore(score);
2401
+ }
2402
+ async getScoresByRunId({
2403
+ runId,
2404
+ pagination
2405
+ }) {
2406
+ return this.stores.scores.getScoresByRunId({ runId, pagination });
2407
+ }
2408
+ async getScoresByEntityId({
2409
+ entityId,
2410
+ entityType,
2411
+ pagination
2412
+ }) {
2413
+ return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
2414
+ }
2415
+ async getScoresByScorerId({
2416
+ scorerId,
2417
+ entityId,
2418
+ entityType,
2419
+ source,
2420
+ pagination
2421
+ }) {
2422
+ return this.stores.scores.getScoresByScorerId({ scorerId, entityId, entityType, source, pagination });
2423
+ }
2424
+ async getResourceById({ resourceId }) {
2425
+ return this.stores.memory.getResourceById({ resourceId });
2426
+ }
2427
+ async saveResource({ resource }) {
2428
+ return this.stores.memory.saveResource({ resource });
2429
+ }
2430
+ async updateResource({
2431
+ resourceId,
2432
+ workingMemory,
2433
+ metadata
2434
+ }) {
2435
+ return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
2436
+ }
1165
2437
  async close() {
1166
2438
  }
1167
2439
  };
1168
2440
 
1169
2441
  exports.CloudflareStore = CloudflareStore;
2442
+ //# sourceMappingURL=index.cjs.map
2443
+ //# sourceMappingURL=index.cjs.map