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