@mastra/cloudflare-d1 0.0.0-separate-trace-data-from-component-20250501141108 → 0.0.0-share-agent-metadata-with-cloud-20250718110128
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/LICENSE.md +11 -42
- package/README.md +15 -0
- package/dist/_tsup-dts-rollup.d.cts +145 -52
- package/dist/_tsup-dts-rollup.d.ts +145 -52
- package/dist/index.cjs +844 -239
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +826 -221
- package/package.json +17 -13
package/dist/index.cjs
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var agent = require('@mastra/core/agent');
|
|
4
|
+
var error = require('@mastra/core/error');
|
|
3
5
|
var storage = require('@mastra/core/storage');
|
|
4
6
|
var Cloudflare = require('cloudflare');
|
|
7
|
+
var utils = require('@mastra/core/utils');
|
|
5
8
|
|
|
6
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
10
|
|
|
8
11
|
var Cloudflare__default = /*#__PURE__*/_interopDefault(Cloudflare);
|
|
9
12
|
|
|
10
13
|
// src/storage/index.ts
|
|
11
|
-
|
|
12
|
-
// src/storage/sql-builder.ts
|
|
13
14
|
var SqlBuilder = class {
|
|
14
15
|
sql = "";
|
|
15
16
|
params = [];
|
|
@@ -19,12 +20,15 @@ var SqlBuilder = class {
|
|
|
19
20
|
if (!columns || Array.isArray(columns) && columns.length === 0) {
|
|
20
21
|
this.sql = "SELECT *";
|
|
21
22
|
} else {
|
|
22
|
-
|
|
23
|
+
const cols = Array.isArray(columns) ? columns : [columns];
|
|
24
|
+
const parsedCols = cols.map((col) => parseSelectIdentifier(col));
|
|
25
|
+
this.sql = `SELECT ${parsedCols.join(", ")}`;
|
|
23
26
|
}
|
|
24
27
|
return this;
|
|
25
28
|
}
|
|
26
29
|
from(table) {
|
|
27
|
-
|
|
30
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
31
|
+
this.sql += ` FROM ${parsedTableName}`;
|
|
28
32
|
return this;
|
|
29
33
|
}
|
|
30
34
|
/**
|
|
@@ -61,7 +65,11 @@ var SqlBuilder = class {
|
|
|
61
65
|
return this;
|
|
62
66
|
}
|
|
63
67
|
orderBy(column, direction = "ASC") {
|
|
64
|
-
|
|
68
|
+
const parsedColumn = utils.parseSqlIdentifier(column, "column name");
|
|
69
|
+
if (!["ASC", "DESC"].includes(direction)) {
|
|
70
|
+
throw new Error(`Invalid sort direction: ${direction}`);
|
|
71
|
+
}
|
|
72
|
+
this.sql += ` ORDER BY ${parsedColumn} ${direction}`;
|
|
65
73
|
return this;
|
|
66
74
|
}
|
|
67
75
|
limit(count) {
|
|
@@ -87,27 +95,33 @@ var SqlBuilder = class {
|
|
|
87
95
|
* @param updateMap Object mapping columns to update to their new value (e.g. { name: 'excluded.name' })
|
|
88
96
|
*/
|
|
89
97
|
insert(table, columns, values, conflictColumns, updateMap) {
|
|
90
|
-
const
|
|
98
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
99
|
+
const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
100
|
+
const placeholders = parsedColumns.map(() => "?").join(", ");
|
|
91
101
|
if (conflictColumns && updateMap) {
|
|
102
|
+
const parsedConflictColumns = conflictColumns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
92
103
|
const updateClause = Object.entries(updateMap).map(([col, expr]) => `${col} = ${expr}`).join(", ");
|
|
93
|
-
this.sql = `INSERT INTO ${
|
|
104
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${parsedConflictColumns.join(", ")}) DO UPDATE SET ${updateClause}`;
|
|
94
105
|
this.params.push(...values);
|
|
95
106
|
return this;
|
|
96
107
|
}
|
|
97
|
-
this.sql = `INSERT INTO ${
|
|
108
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders})`;
|
|
98
109
|
this.params.push(...values);
|
|
99
110
|
return this;
|
|
100
111
|
}
|
|
101
112
|
// Update operations
|
|
102
113
|
update(table, columns, values) {
|
|
103
|
-
const
|
|
104
|
-
|
|
114
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
115
|
+
const parsedColumns = columns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
116
|
+
const setClause = parsedColumns.map((col) => `${col} = ?`).join(", ");
|
|
117
|
+
this.sql = `UPDATE ${parsedTableName} SET ${setClause}`;
|
|
105
118
|
this.params.push(...values);
|
|
106
119
|
return this;
|
|
107
120
|
}
|
|
108
121
|
// Delete operations
|
|
109
122
|
delete(table) {
|
|
110
|
-
|
|
123
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
124
|
+
this.sql = `DELETE FROM ${parsedTableName}`;
|
|
111
125
|
return this;
|
|
112
126
|
}
|
|
113
127
|
/**
|
|
@@ -118,9 +132,16 @@ var SqlBuilder = class {
|
|
|
118
132
|
* @returns The builder instance
|
|
119
133
|
*/
|
|
120
134
|
createTable(table, columnDefinitions, tableConstraints) {
|
|
121
|
-
const
|
|
135
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
136
|
+
const parsedColumnDefinitions = columnDefinitions.map((def) => {
|
|
137
|
+
const colName = def.split(/\s+/)[0];
|
|
138
|
+
if (!colName) throw new Error("Empty column name in definition");
|
|
139
|
+
utils.parseSqlIdentifier(colName, "column name");
|
|
140
|
+
return def;
|
|
141
|
+
});
|
|
142
|
+
const columns = parsedColumnDefinitions.join(", ");
|
|
122
143
|
const constraints = tableConstraints && tableConstraints.length > 0 ? ", " + tableConstraints.join(", ") : "";
|
|
123
|
-
this.sql = `CREATE TABLE IF NOT EXISTS ${
|
|
144
|
+
this.sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns}${constraints})`;
|
|
124
145
|
return this;
|
|
125
146
|
}
|
|
126
147
|
/**
|
|
@@ -143,13 +164,10 @@ var SqlBuilder = class {
|
|
|
143
164
|
* @returns The builder instance
|
|
144
165
|
*/
|
|
145
166
|
createIndex(indexName, tableName, columnName, indexType = "") {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
raw(sql, ...params) {
|
|
151
|
-
this.sql = sql;
|
|
152
|
-
this.params.push(...params);
|
|
167
|
+
const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
|
|
168
|
+
const parsedTableName = utils.parseSqlIdentifier(tableName, "table name");
|
|
169
|
+
const parsedColumnName = utils.parseSqlIdentifier(columnName, "column name");
|
|
170
|
+
this.sql = `CREATE ${indexType ? indexType + " " : ""}INDEX IF NOT EXISTS ${parsedIndexName} ON ${parsedTableName}(${parsedColumnName})`;
|
|
153
171
|
return this;
|
|
154
172
|
}
|
|
155
173
|
/**
|
|
@@ -159,11 +177,12 @@ var SqlBuilder = class {
|
|
|
159
177
|
* @param exact If true, will not add % wildcards
|
|
160
178
|
*/
|
|
161
179
|
like(column, value, exact = false) {
|
|
180
|
+
const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
|
|
162
181
|
const likeValue = exact ? value : `%${value}%`;
|
|
163
182
|
if (this.whereAdded) {
|
|
164
|
-
this.sql += ` AND ${
|
|
183
|
+
this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
165
184
|
} else {
|
|
166
|
-
this.sql += ` WHERE ${
|
|
185
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
167
186
|
this.whereAdded = true;
|
|
168
187
|
}
|
|
169
188
|
this.params.push(likeValue);
|
|
@@ -176,11 +195,13 @@ var SqlBuilder = class {
|
|
|
176
195
|
* @param value The value to match
|
|
177
196
|
*/
|
|
178
197
|
jsonLike(column, key, value) {
|
|
179
|
-
const
|
|
198
|
+
const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
|
|
199
|
+
const parsedKey = utils.parseSqlIdentifier(key, "key name");
|
|
200
|
+
const jsonPattern = `%"${parsedKey}":"${value}"%`;
|
|
180
201
|
if (this.whereAdded) {
|
|
181
|
-
this.sql += ` AND ${
|
|
202
|
+
this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
182
203
|
} else {
|
|
183
|
-
this.sql += ` WHERE ${
|
|
204
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
184
205
|
this.whereAdded = true;
|
|
185
206
|
}
|
|
186
207
|
this.params.push(jsonPattern);
|
|
@@ -210,6 +231,15 @@ var SqlBuilder = class {
|
|
|
210
231
|
function createSqlBuilder() {
|
|
211
232
|
return new SqlBuilder();
|
|
212
233
|
}
|
|
234
|
+
var SQL_IDENTIFIER_PATTERN = /^[a-zA-Z0-9_]+(\s+AS\s+[a-zA-Z0-9_]+)?$/;
|
|
235
|
+
function parseSelectIdentifier(column) {
|
|
236
|
+
if (column !== "*" && !SQL_IDENTIFIER_PATTERN.test(column)) {
|
|
237
|
+
throw new Error(
|
|
238
|
+
`Invalid column name: "${column}". Must be "*" or a valid identifier (letters, numbers, underscores), optionally with "AS alias".`
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
return column;
|
|
242
|
+
}
|
|
213
243
|
|
|
214
244
|
// src/storage/index.ts
|
|
215
245
|
function isArrayOfRecords(value) {
|
|
@@ -217,8 +247,6 @@ function isArrayOfRecords(value) {
|
|
|
217
247
|
}
|
|
218
248
|
var D1Store = class extends storage.MastraStorage {
|
|
219
249
|
client;
|
|
220
|
-
accountId;
|
|
221
|
-
databaseId;
|
|
222
250
|
binding;
|
|
223
251
|
// D1Database binding
|
|
224
252
|
tablePrefix;
|
|
@@ -227,24 +255,52 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
227
255
|
* @param config Configuration for D1 access (either REST API or Workers Binding API)
|
|
228
256
|
*/
|
|
229
257
|
constructor(config) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
throw new Error("D1 binding is required when using Workers Binding API");
|
|
258
|
+
try {
|
|
259
|
+
super({ name: "D1" });
|
|
260
|
+
if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) {
|
|
261
|
+
throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
|
|
235
262
|
}
|
|
236
|
-
this.
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
263
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
264
|
+
if ("binding" in config) {
|
|
265
|
+
if (!config.binding) {
|
|
266
|
+
throw new Error("D1 binding is required when using Workers Binding API");
|
|
267
|
+
}
|
|
268
|
+
this.binding = config.binding;
|
|
269
|
+
this.logger.info("Using D1 Workers Binding API");
|
|
270
|
+
} else if ("client" in config) {
|
|
271
|
+
if (!config.client) {
|
|
272
|
+
throw new Error("D1 client is required when using D1ClientConfig");
|
|
273
|
+
}
|
|
274
|
+
this.client = config.client;
|
|
275
|
+
this.logger.info("Using D1 Client");
|
|
276
|
+
} else {
|
|
277
|
+
if (!config.accountId || !config.databaseId || !config.apiToken) {
|
|
278
|
+
throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
279
|
+
}
|
|
280
|
+
const cfClient = new Cloudflare__default.default({
|
|
281
|
+
apiToken: config.apiToken
|
|
282
|
+
});
|
|
283
|
+
this.client = {
|
|
284
|
+
query: ({ sql, params }) => {
|
|
285
|
+
return cfClient.d1.database.query(config.databaseId, {
|
|
286
|
+
account_id: config.accountId,
|
|
287
|
+
sql,
|
|
288
|
+
params
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
this.logger.info("Using D1 REST API");
|
|
241
293
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
294
|
+
} catch (error$1) {
|
|
295
|
+
throw new error.MastraError(
|
|
296
|
+
{
|
|
297
|
+
id: "CLOUDFLARE_D1_STORAGE_INITIALIZATION_ERROR",
|
|
298
|
+
domain: error.ErrorDomain.STORAGE,
|
|
299
|
+
category: error.ErrorCategory.SYSTEM,
|
|
300
|
+
text: "Error initializing D1Store"
|
|
301
|
+
},
|
|
302
|
+
error$1
|
|
303
|
+
);
|
|
248
304
|
}
|
|
249
305
|
}
|
|
250
306
|
// Helper method to get the full table name with prefix
|
|
@@ -254,30 +310,6 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
254
310
|
formatSqlParams(params) {
|
|
255
311
|
return params.map((p) => p === void 0 || p === null ? null : p);
|
|
256
312
|
}
|
|
257
|
-
// Helper method to create SQL indexes for better query performance
|
|
258
|
-
async createIndexIfNotExists(tableName, columnName, indexType = "") {
|
|
259
|
-
const fullTableName = this.getTableName(tableName);
|
|
260
|
-
const indexName = `idx_${tableName}_${columnName}`;
|
|
261
|
-
try {
|
|
262
|
-
const checkQuery = createSqlBuilder().checkIndexExists(indexName, fullTableName);
|
|
263
|
-
const { sql: checkSql, params: checkParams } = checkQuery.build();
|
|
264
|
-
const indexExists = await this.executeQuery({
|
|
265
|
-
sql: checkSql,
|
|
266
|
-
params: checkParams,
|
|
267
|
-
first: true
|
|
268
|
-
});
|
|
269
|
-
if (!indexExists) {
|
|
270
|
-
const createQuery = createSqlBuilder().createIndex(indexName, fullTableName, columnName, indexType);
|
|
271
|
-
const { sql: createSql, params: createParams } = createQuery.build();
|
|
272
|
-
await this.executeQuery({ sql: createSql, params: createParams });
|
|
273
|
-
this.logger.debug(`Created index ${indexName} on ${fullTableName}(${columnName})`);
|
|
274
|
-
}
|
|
275
|
-
} catch (error) {
|
|
276
|
-
this.logger.error(`Error creating index on ${fullTableName}(${columnName}):`, {
|
|
277
|
-
message: error instanceof Error ? error.message : String(error)
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
313
|
async executeWorkersBindingQuery({
|
|
282
314
|
sql,
|
|
283
315
|
params = [],
|
|
@@ -330,12 +362,11 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
330
362
|
params = [],
|
|
331
363
|
first = false
|
|
332
364
|
}) {
|
|
333
|
-
if (!this.client
|
|
365
|
+
if (!this.client) {
|
|
334
366
|
throw new Error("Missing required REST API configuration");
|
|
335
367
|
}
|
|
336
368
|
try {
|
|
337
|
-
const response = await this.client.
|
|
338
|
-
account_id: this.accountId,
|
|
369
|
+
const response = await this.client.query({
|
|
339
370
|
sql,
|
|
340
371
|
params: this.formatSqlParams(params)
|
|
341
372
|
});
|
|
@@ -366,7 +397,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
366
397
|
this.logger.debug("Executing SQL query", { sql, params, first });
|
|
367
398
|
if (this.binding) {
|
|
368
399
|
return this.executeWorkersBindingQuery({ sql, params, first });
|
|
369
|
-
} else if (this.client
|
|
400
|
+
} else if (this.client) {
|
|
370
401
|
return this.executeRestQuery({ sql, params, first });
|
|
371
402
|
} else {
|
|
372
403
|
throw new Error("No valid D1 configuration provided");
|
|
@@ -381,34 +412,25 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
381
412
|
throw new Error(`D1 query error: ${error.message}`);
|
|
382
413
|
}
|
|
383
414
|
}
|
|
384
|
-
// Helper to
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
return
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
415
|
+
// Helper to get existing table columns
|
|
416
|
+
async getTableColumns(tableName) {
|
|
417
|
+
try {
|
|
418
|
+
const sql = `PRAGMA table_info(${tableName})`;
|
|
419
|
+
const result = await this.executeQuery({ sql, params: [] });
|
|
420
|
+
if (!result || !Array.isArray(result)) {
|
|
421
|
+
return [];
|
|
422
|
+
}
|
|
423
|
+
return result.map((row) => ({
|
|
424
|
+
name: row.name,
|
|
425
|
+
type: row.type
|
|
426
|
+
}));
|
|
427
|
+
} catch (error) {
|
|
428
|
+
this.logger.error(`Error getting table columns for ${tableName}:`, {
|
|
429
|
+
message: error instanceof Error ? error.message : String(error)
|
|
430
|
+
});
|
|
431
|
+
return [];
|
|
401
432
|
}
|
|
402
433
|
}
|
|
403
|
-
ensureDate(date) {
|
|
404
|
-
if (!date) return void 0;
|
|
405
|
-
return date instanceof Date ? date : new Date(date);
|
|
406
|
-
}
|
|
407
|
-
serializeDate(date) {
|
|
408
|
-
if (!date) return void 0;
|
|
409
|
-
const dateObj = this.ensureDate(date);
|
|
410
|
-
return dateObj?.toISOString();
|
|
411
|
-
}
|
|
412
434
|
// Helper to serialize objects to JSON strings
|
|
413
435
|
serializeValue(value) {
|
|
414
436
|
if (value === null || value === void 0) return null;
|
|
@@ -442,6 +464,18 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
442
464
|
}
|
|
443
465
|
return value;
|
|
444
466
|
}
|
|
467
|
+
getSqlType(type) {
|
|
468
|
+
switch (type) {
|
|
469
|
+
case "bigint":
|
|
470
|
+
return "INTEGER";
|
|
471
|
+
// SQLite uses INTEGER for all integer sizes
|
|
472
|
+
case "jsonb":
|
|
473
|
+
return "TEXT";
|
|
474
|
+
// Store JSON as TEXT in SQLite
|
|
475
|
+
default:
|
|
476
|
+
return super.getSqlType(type);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
445
479
|
async createTable({
|
|
446
480
|
tableName,
|
|
447
481
|
schema
|
|
@@ -457,16 +491,64 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
457
491
|
if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
|
|
458
492
|
tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
459
493
|
}
|
|
460
|
-
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
461
|
-
const { sql, params } = query.build();
|
|
462
494
|
try {
|
|
495
|
+
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
496
|
+
const { sql, params } = query.build();
|
|
463
497
|
await this.executeQuery({ sql, params });
|
|
464
498
|
this.logger.debug(`Created table ${fullTableName}`);
|
|
465
|
-
} catch (error) {
|
|
499
|
+
} catch (error$1) {
|
|
466
500
|
this.logger.error(`Error creating table ${fullTableName}:`, {
|
|
467
|
-
message: error instanceof Error ? error.message : String(error)
|
|
501
|
+
message: error$1 instanceof Error ? error$1.message : String(error$1)
|
|
468
502
|
});
|
|
469
|
-
throw new
|
|
503
|
+
throw new error.MastraError(
|
|
504
|
+
{
|
|
505
|
+
id: "CLOUDFLARE_D1_STORAGE_CREATE_TABLE_ERROR",
|
|
506
|
+
domain: error.ErrorDomain.STORAGE,
|
|
507
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
508
|
+
text: `Failed to create table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
509
|
+
details: { tableName }
|
|
510
|
+
},
|
|
511
|
+
error$1
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Alters table schema to add columns if they don't exist
|
|
517
|
+
* @param tableName Name of the table
|
|
518
|
+
* @param schema Schema of the table
|
|
519
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
520
|
+
*/
|
|
521
|
+
async alterTable({
|
|
522
|
+
tableName,
|
|
523
|
+
schema,
|
|
524
|
+
ifNotExists
|
|
525
|
+
}) {
|
|
526
|
+
const fullTableName = this.getTableName(tableName);
|
|
527
|
+
try {
|
|
528
|
+
const existingColumns = await this.getTableColumns(fullTableName);
|
|
529
|
+
const existingColumnNames = new Set(existingColumns.map((col) => col.name.toLowerCase()));
|
|
530
|
+
for (const columnName of ifNotExists) {
|
|
531
|
+
if (!existingColumnNames.has(columnName.toLowerCase()) && schema[columnName]) {
|
|
532
|
+
const columnDef = schema[columnName];
|
|
533
|
+
const sqlType = this.getSqlType(columnDef.type);
|
|
534
|
+
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
535
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
536
|
+
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
537
|
+
await this.executeQuery({ sql: alterSql, params: [] });
|
|
538
|
+
this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
} catch (error$1) {
|
|
542
|
+
throw new error.MastraError(
|
|
543
|
+
{
|
|
544
|
+
id: "CLOUDFLARE_D1_STORAGE_ALTER_TABLE_ERROR",
|
|
545
|
+
domain: error.ErrorDomain.STORAGE,
|
|
546
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
547
|
+
text: `Failed to alter table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
548
|
+
details: { tableName }
|
|
549
|
+
},
|
|
550
|
+
error$1
|
|
551
|
+
);
|
|
470
552
|
}
|
|
471
553
|
}
|
|
472
554
|
async clearTable({ tableName }) {
|
|
@@ -476,11 +558,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
476
558
|
const { sql, params } = query.build();
|
|
477
559
|
await this.executeQuery({ sql, params });
|
|
478
560
|
this.logger.debug(`Cleared table ${fullTableName}`);
|
|
479
|
-
} catch (error) {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
561
|
+
} catch (error$1) {
|
|
562
|
+
throw new error.MastraError(
|
|
563
|
+
{
|
|
564
|
+
id: "CLOUDFLARE_D1_STORAGE_CLEAR_TABLE_ERROR",
|
|
565
|
+
domain: error.ErrorDomain.STORAGE,
|
|
566
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
567
|
+
text: `Failed to clear table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
568
|
+
details: { tableName }
|
|
569
|
+
},
|
|
570
|
+
error$1
|
|
571
|
+
);
|
|
484
572
|
}
|
|
485
573
|
}
|
|
486
574
|
async processRecord(record) {
|
|
@@ -499,10 +587,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
499
587
|
const { sql, params } = query.build();
|
|
500
588
|
try {
|
|
501
589
|
await this.executeQuery({ sql, params });
|
|
502
|
-
} catch (error) {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
590
|
+
} catch (error$1) {
|
|
591
|
+
throw new error.MastraError(
|
|
592
|
+
{
|
|
593
|
+
id: "CLOUDFLARE_D1_STORAGE_INSERT_ERROR",
|
|
594
|
+
domain: error.ErrorDomain.STORAGE,
|
|
595
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
596
|
+
text: `Failed to insert into ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
597
|
+
details: { tableName }
|
|
598
|
+
},
|
|
599
|
+
error$1
|
|
600
|
+
);
|
|
506
601
|
}
|
|
507
602
|
}
|
|
508
603
|
async load({ tableName, keys }) {
|
|
@@ -527,11 +622,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
527
622
|
processedResult[key] = this.deserializeValue(value);
|
|
528
623
|
}
|
|
529
624
|
return processedResult;
|
|
530
|
-
} catch (error) {
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
625
|
+
} catch (error$1) {
|
|
626
|
+
throw new error.MastraError(
|
|
627
|
+
{
|
|
628
|
+
id: "CLOUDFLARE_D1_STORAGE_LOAD_ERROR",
|
|
629
|
+
domain: error.ErrorDomain.STORAGE,
|
|
630
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
631
|
+
text: `Failed to load from ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
632
|
+
details: { tableName }
|
|
633
|
+
},
|
|
634
|
+
error$1
|
|
635
|
+
);
|
|
535
636
|
}
|
|
536
637
|
}
|
|
537
638
|
async getThreadById({ threadId }) {
|
|
@@ -547,13 +648,25 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
547
648
|
updatedAt: this.ensureDate(thread.updatedAt),
|
|
548
649
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
549
650
|
};
|
|
550
|
-
} catch (error) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
651
|
+
} catch (error$1) {
|
|
652
|
+
const mastraError = new error.MastraError(
|
|
653
|
+
{
|
|
654
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREAD_BY_ID_ERROR",
|
|
655
|
+
domain: error.ErrorDomain.STORAGE,
|
|
656
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
657
|
+
text: `Error processing thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
658
|
+
details: { threadId }
|
|
659
|
+
},
|
|
660
|
+
error$1
|
|
661
|
+
);
|
|
662
|
+
this.logger?.error(mastraError.toString());
|
|
663
|
+
this.logger?.trackException(mastraError);
|
|
554
664
|
return null;
|
|
555
665
|
}
|
|
556
666
|
}
|
|
667
|
+
/**
|
|
668
|
+
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
669
|
+
*/
|
|
557
670
|
async getThreadsByResourceId({ resourceId }) {
|
|
558
671
|
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
559
672
|
try {
|
|
@@ -566,13 +679,67 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
566
679
|
updatedAt: this.ensureDate(thread.updatedAt),
|
|
567
680
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
568
681
|
}));
|
|
569
|
-
} catch (error) {
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
682
|
+
} catch (error$1) {
|
|
683
|
+
const mastraError = new error.MastraError(
|
|
684
|
+
{
|
|
685
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREADS_BY_RESOURCE_ID_ERROR",
|
|
686
|
+
domain: error.ErrorDomain.STORAGE,
|
|
687
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
688
|
+
text: `Error getting threads by resourceId ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
689
|
+
details: { resourceId }
|
|
690
|
+
},
|
|
691
|
+
error$1
|
|
692
|
+
);
|
|
693
|
+
this.logger?.error(mastraError.toString());
|
|
694
|
+
this.logger?.trackException(mastraError);
|
|
573
695
|
return [];
|
|
574
696
|
}
|
|
575
697
|
}
|
|
698
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
699
|
+
const { resourceId, page, perPage } = args;
|
|
700
|
+
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
701
|
+
const mapRowToStorageThreadType = (row) => ({
|
|
702
|
+
...row,
|
|
703
|
+
createdAt: this.ensureDate(row.createdAt),
|
|
704
|
+
updatedAt: this.ensureDate(row.updatedAt),
|
|
705
|
+
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
|
|
706
|
+
});
|
|
707
|
+
try {
|
|
708
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("resourceId = ?", resourceId);
|
|
709
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
710
|
+
const total = Number(countResult?.[0]?.count ?? 0);
|
|
711
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("resourceId = ?", resourceId).orderBy("createdAt", "DESC").limit(perPage).offset(page * perPage);
|
|
712
|
+
const results = await this.executeQuery(selectQuery.build());
|
|
713
|
+
const threads = results.map(mapRowToStorageThreadType);
|
|
714
|
+
return {
|
|
715
|
+
threads,
|
|
716
|
+
total,
|
|
717
|
+
page,
|
|
718
|
+
perPage,
|
|
719
|
+
hasMore: page * perPage + threads.length < total
|
|
720
|
+
};
|
|
721
|
+
} catch (error$1) {
|
|
722
|
+
const mastraError = new error.MastraError(
|
|
723
|
+
{
|
|
724
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_ERROR",
|
|
725
|
+
domain: error.ErrorDomain.STORAGE,
|
|
726
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
727
|
+
text: `Error getting threads by resourceId ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
728
|
+
details: { resourceId }
|
|
729
|
+
},
|
|
730
|
+
error$1
|
|
731
|
+
);
|
|
732
|
+
this.logger?.error(mastraError.toString());
|
|
733
|
+
this.logger?.trackException(mastraError);
|
|
734
|
+
return {
|
|
735
|
+
threads: [],
|
|
736
|
+
total: 0,
|
|
737
|
+
page,
|
|
738
|
+
perPage,
|
|
739
|
+
hasMore: false
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
}
|
|
576
743
|
async saveThread({ thread }) {
|
|
577
744
|
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
578
745
|
const threadToSave = {
|
|
@@ -598,10 +765,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
598
765
|
try {
|
|
599
766
|
await this.executeQuery({ sql, params });
|
|
600
767
|
return thread;
|
|
601
|
-
} catch (error) {
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
768
|
+
} catch (error$1) {
|
|
769
|
+
throw new error.MastraError(
|
|
770
|
+
{
|
|
771
|
+
id: "CLOUDFLARE_D1_STORAGE_SAVE_THREAD_ERROR",
|
|
772
|
+
domain: error.ErrorDomain.STORAGE,
|
|
773
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
774
|
+
text: `Failed to save thread to ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
775
|
+
details: { threadId: thread.id }
|
|
776
|
+
},
|
|
777
|
+
error$1
|
|
778
|
+
);
|
|
605
779
|
}
|
|
606
780
|
}
|
|
607
781
|
async updateThread({
|
|
@@ -610,19 +784,19 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
610
784
|
metadata
|
|
611
785
|
}) {
|
|
612
786
|
const thread = await this.getThreadById({ threadId: id });
|
|
613
|
-
if (!thread) {
|
|
614
|
-
throw new Error(`Thread ${id} not found`);
|
|
615
|
-
}
|
|
616
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
617
|
-
const mergedMetadata = {
|
|
618
|
-
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
619
|
-
...metadata
|
|
620
|
-
};
|
|
621
|
-
const columns = ["title", "metadata", "updatedAt"];
|
|
622
|
-
const values = [title, JSON.stringify(mergedMetadata), (/* @__PURE__ */ new Date()).toISOString()];
|
|
623
|
-
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
|
|
624
|
-
const { sql, params } = query.build();
|
|
625
787
|
try {
|
|
788
|
+
if (!thread) {
|
|
789
|
+
throw new Error(`Thread ${id} not found`);
|
|
790
|
+
}
|
|
791
|
+
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
792
|
+
const mergedMetadata = {
|
|
793
|
+
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
794
|
+
...metadata
|
|
795
|
+
};
|
|
796
|
+
const columns = ["title", "metadata", "updatedAt"];
|
|
797
|
+
const values = [title, JSON.stringify(mergedMetadata), (/* @__PURE__ */ new Date()).toISOString()];
|
|
798
|
+
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
|
|
799
|
+
const { sql, params } = query.build();
|
|
626
800
|
await this.executeQuery({ sql, params });
|
|
627
801
|
return {
|
|
628
802
|
...thread,
|
|
@@ -633,10 +807,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
633
807
|
},
|
|
634
808
|
updatedAt: /* @__PURE__ */ new Date()
|
|
635
809
|
};
|
|
636
|
-
} catch (error) {
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
810
|
+
} catch (error$1) {
|
|
811
|
+
throw new error.MastraError(
|
|
812
|
+
{
|
|
813
|
+
id: "CLOUDFLARE_D1_STORAGE_UPDATE_THREAD_ERROR",
|
|
814
|
+
domain: error.ErrorDomain.STORAGE,
|
|
815
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
816
|
+
text: `Failed to update thread ${id}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
817
|
+
details: { threadId: id }
|
|
818
|
+
},
|
|
819
|
+
error$1
|
|
820
|
+
);
|
|
640
821
|
}
|
|
641
822
|
}
|
|
642
823
|
async deleteThread({ threadId }) {
|
|
@@ -649,23 +830,36 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
649
830
|
const deleteMessagesQuery = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId);
|
|
650
831
|
const { sql: messagesSql, params: messagesParams } = deleteMessagesQuery.build();
|
|
651
832
|
await this.executeQuery({ sql: messagesSql, params: messagesParams });
|
|
652
|
-
} catch (error) {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
833
|
+
} catch (error$1) {
|
|
834
|
+
throw new error.MastraError(
|
|
835
|
+
{
|
|
836
|
+
id: "CLOUDFLARE_D1_STORAGE_DELETE_THREAD_ERROR",
|
|
837
|
+
domain: error.ErrorDomain.STORAGE,
|
|
838
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
839
|
+
text: `Failed to delete thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
840
|
+
details: { threadId }
|
|
841
|
+
},
|
|
842
|
+
error$1
|
|
843
|
+
);
|
|
657
844
|
}
|
|
658
845
|
}
|
|
659
|
-
|
|
660
|
-
|
|
846
|
+
async saveMessages(args) {
|
|
847
|
+
const { messages, format = "v1" } = args;
|
|
661
848
|
if (messages.length === 0) return [];
|
|
662
849
|
try {
|
|
663
850
|
const now = /* @__PURE__ */ new Date();
|
|
851
|
+
const threadId = messages[0]?.threadId;
|
|
664
852
|
for (const [i, message] of messages.entries()) {
|
|
665
853
|
if (!message.id) throw new Error(`Message at index ${i} missing id`);
|
|
666
|
-
if (!message.threadId)
|
|
667
|
-
|
|
668
|
-
|
|
854
|
+
if (!message.threadId) {
|
|
855
|
+
throw new Error(`Message at index ${i} missing threadId`);
|
|
856
|
+
}
|
|
857
|
+
if (!message.content) {
|
|
858
|
+
throw new Error(`Message at index ${i} missing content`);
|
|
859
|
+
}
|
|
860
|
+
if (!message.role) {
|
|
861
|
+
throw new Error(`Message at index ${i} missing role`);
|
|
862
|
+
}
|
|
669
863
|
const thread = await this.getThreadById({ threadId: message.threadId });
|
|
670
864
|
if (!thread) {
|
|
671
865
|
throw new Error(`Thread ${message.threadId} not found`);
|
|
@@ -679,36 +873,49 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
679
873
|
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
680
874
|
createdAt: createdAt.toISOString(),
|
|
681
875
|
role: message.role,
|
|
682
|
-
type: message.type
|
|
876
|
+
type: message.type || "v2",
|
|
877
|
+
resourceId: message.resourceId
|
|
683
878
|
};
|
|
684
879
|
});
|
|
685
|
-
await
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
880
|
+
await Promise.all([
|
|
881
|
+
this.batchUpsert({
|
|
882
|
+
tableName: storage.TABLE_MESSAGES,
|
|
883
|
+
records: messagesToInsert
|
|
884
|
+
}),
|
|
885
|
+
// Update thread's updatedAt timestamp
|
|
886
|
+
this.executeQuery({
|
|
887
|
+
sql: `UPDATE ${this.getTableName(storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
|
|
888
|
+
params: [now.toISOString(), threadId]
|
|
889
|
+
})
|
|
890
|
+
]);
|
|
689
891
|
this.logger.debug(`Saved ${messages.length} messages`);
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
892
|
+
const list = new agent.MessageList().add(messages, "memory");
|
|
893
|
+
if (format === `v2`) return list.get.all.v2();
|
|
894
|
+
return list.get.all.v1();
|
|
895
|
+
} catch (error$1) {
|
|
896
|
+
throw new error.MastraError(
|
|
897
|
+
{
|
|
898
|
+
id: "CLOUDFLARE_D1_STORAGE_SAVE_MESSAGES_ERROR",
|
|
899
|
+
domain: error.ErrorDomain.STORAGE,
|
|
900
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
901
|
+
text: `Failed to save messages: ${error$1 instanceof Error ? error$1.message : String(error$1)}`
|
|
902
|
+
},
|
|
903
|
+
error$1
|
|
904
|
+
);
|
|
694
905
|
}
|
|
695
906
|
}
|
|
696
|
-
async
|
|
697
|
-
const
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
const prevMax = Math.max(...include.map((i) => i.withPreviousMessages || 0));
|
|
704
|
-
const nextMax = Math.max(...include.map((i) => i.withNextMessages || 0));
|
|
705
|
-
const includeIds = include.map((i) => i.id);
|
|
706
|
-
const sql2 = `
|
|
907
|
+
async _getIncludedMessages(threadId, selectBy) {
|
|
908
|
+
const include = selectBy?.include;
|
|
909
|
+
if (!include) return null;
|
|
910
|
+
const prevMax = Math.max(...include.map((i) => i.withPreviousMessages || 0));
|
|
911
|
+
const nextMax = Math.max(...include.map((i) => i.withNextMessages || 0));
|
|
912
|
+
const includeIds = include.map((i) => i.id);
|
|
913
|
+
const sql = `
|
|
707
914
|
WITH ordered_messages AS (
|
|
708
915
|
SELECT
|
|
709
916
|
*,
|
|
710
917
|
ROW_NUMBER() OVER (ORDER BY createdAt DESC) AS row_num
|
|
711
|
-
FROM ${
|
|
918
|
+
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
712
919
|
WHERE thread_id = ?
|
|
713
920
|
)
|
|
714
921
|
SELECT
|
|
@@ -717,7 +924,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
717
924
|
m.role,
|
|
718
925
|
m.type,
|
|
719
926
|
m.createdAt,
|
|
720
|
-
m.thread_id AS
|
|
927
|
+
m.thread_id AS threadId
|
|
721
928
|
FROM ordered_messages m
|
|
722
929
|
WHERE m.id IN (${includeIds.map(() => "?").join(",")})
|
|
723
930
|
OR EXISTS (
|
|
@@ -731,20 +938,41 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
731
938
|
)
|
|
732
939
|
ORDER BY m.createdAt DESC
|
|
733
940
|
`;
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
941
|
+
const params = [
|
|
942
|
+
threadId,
|
|
943
|
+
...includeIds,
|
|
944
|
+
// for m.id IN (...)
|
|
945
|
+
...includeIds,
|
|
946
|
+
// for target.id IN (...)
|
|
947
|
+
prevMax,
|
|
948
|
+
nextMax
|
|
949
|
+
];
|
|
950
|
+
const messages = await this.executeQuery({ sql, params });
|
|
951
|
+
return messages;
|
|
952
|
+
}
|
|
953
|
+
async getMessages({
|
|
954
|
+
threadId,
|
|
955
|
+
selectBy,
|
|
956
|
+
format
|
|
957
|
+
}) {
|
|
958
|
+
const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
959
|
+
const limit = this.resolveMessageLimit({
|
|
960
|
+
last: selectBy?.last,
|
|
961
|
+
defaultLimit: 40
|
|
962
|
+
});
|
|
963
|
+
const include = selectBy?.include || [];
|
|
964
|
+
const messages = [];
|
|
965
|
+
try {
|
|
966
|
+
if (include.length) {
|
|
967
|
+
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
744
968
|
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
745
969
|
}
|
|
746
970
|
const excludeIds = messages.map((m) => m.id);
|
|
747
|
-
|
|
971
|
+
const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId"]).from(fullTableName).where("thread_id = ?", threadId);
|
|
972
|
+
if (excludeIds.length > 0) {
|
|
973
|
+
query.andWhere(`id NOT IN (${excludeIds.map(() => "?").join(",")})`, ...excludeIds);
|
|
974
|
+
}
|
|
975
|
+
query.orderBy("createdAt", "DESC").limit(limit);
|
|
748
976
|
const { sql, params } = query.build();
|
|
749
977
|
const result = await this.executeQuery({ sql, params });
|
|
750
978
|
if (Array.isArray(result)) messages.push(...result);
|
|
@@ -758,18 +986,92 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
758
986
|
const processedMessages = messages.map((message) => {
|
|
759
987
|
const processedMsg = {};
|
|
760
988
|
for (const [key, value] of Object.entries(message)) {
|
|
989
|
+
if (key === `type` && value === `v2`) continue;
|
|
761
990
|
processedMsg[key] = this.deserializeValue(value);
|
|
762
991
|
}
|
|
763
992
|
return processedMsg;
|
|
764
993
|
});
|
|
765
994
|
this.logger.debug(`Retrieved ${messages.length} messages for thread ${threadId}`);
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
995
|
+
const list = new agent.MessageList().add(processedMessages, "memory");
|
|
996
|
+
if (format === `v2`) return list.get.all.v2();
|
|
997
|
+
return list.get.all.v1();
|
|
998
|
+
} catch (error$1) {
|
|
999
|
+
const mastraError = new error.MastraError(
|
|
1000
|
+
{
|
|
1001
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_MESSAGES_ERROR",
|
|
1002
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1003
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1004
|
+
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1005
|
+
details: { threadId }
|
|
1006
|
+
},
|
|
1007
|
+
error$1
|
|
1008
|
+
);
|
|
1009
|
+
this.logger?.error(mastraError.toString());
|
|
1010
|
+
this.logger?.trackException(mastraError);
|
|
1011
|
+
throw mastraError;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
async getMessagesPaginated({
|
|
1015
|
+
threadId,
|
|
1016
|
+
selectBy,
|
|
1017
|
+
format
|
|
1018
|
+
}) {
|
|
1019
|
+
const { dateRange, page = 0, perPage = 40 } = selectBy?.pagination || {};
|
|
1020
|
+
const { start: fromDate, end: toDate } = dateRange || {};
|
|
1021
|
+
const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
1022
|
+
const messages = [];
|
|
1023
|
+
try {
|
|
1024
|
+
if (selectBy?.include?.length) {
|
|
1025
|
+
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
1026
|
+
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
1027
|
+
}
|
|
1028
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("thread_id = ?", threadId);
|
|
1029
|
+
if (fromDate) {
|
|
1030
|
+
countQuery.andWhere("createdAt >= ?", this.serializeDate(fromDate));
|
|
1031
|
+
}
|
|
1032
|
+
if (toDate) {
|
|
1033
|
+
countQuery.andWhere("createdAt <= ?", this.serializeDate(toDate));
|
|
1034
|
+
}
|
|
1035
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
1036
|
+
const total = Number(countResult[0]?.count ?? 0);
|
|
1037
|
+
const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId"]).from(fullTableName).where("thread_id = ?", threadId);
|
|
1038
|
+
if (fromDate) {
|
|
1039
|
+
query.andWhere("createdAt >= ?", this.serializeDate(fromDate));
|
|
1040
|
+
}
|
|
1041
|
+
if (toDate) {
|
|
1042
|
+
query.andWhere("createdAt <= ?", this.serializeDate(toDate));
|
|
1043
|
+
}
|
|
1044
|
+
query.orderBy("createdAt", "DESC").limit(perPage).offset(page * perPage);
|
|
1045
|
+
const results = await this.executeQuery(query.build());
|
|
1046
|
+
const list = new agent.MessageList().add(results, "memory");
|
|
1047
|
+
messages.push(...format === `v2` ? list.get.all.v2() : list.get.all.v1());
|
|
1048
|
+
return {
|
|
1049
|
+
messages,
|
|
1050
|
+
total,
|
|
1051
|
+
page,
|
|
1052
|
+
perPage,
|
|
1053
|
+
hasMore: page * perPage + messages.length < total
|
|
1054
|
+
};
|
|
1055
|
+
} catch (error$1) {
|
|
1056
|
+
const mastraError = new error.MastraError(
|
|
1057
|
+
{
|
|
1058
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_MESSAGES_PAGINATED_ERROR",
|
|
1059
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1060
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1061
|
+
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1062
|
+
details: { threadId }
|
|
1063
|
+
},
|
|
1064
|
+
error$1
|
|
1065
|
+
);
|
|
1066
|
+
this.logger?.error(mastraError.toString());
|
|
1067
|
+
this.logger?.trackException(mastraError);
|
|
1068
|
+
return {
|
|
1069
|
+
messages: [],
|
|
1070
|
+
total: 0,
|
|
1071
|
+
page,
|
|
1072
|
+
perPage,
|
|
1073
|
+
hasMore: false
|
|
1074
|
+
};
|
|
773
1075
|
}
|
|
774
1076
|
}
|
|
775
1077
|
async persistWorkflowSnapshot({
|
|
@@ -806,24 +1108,43 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
806
1108
|
const { sql, params } = query.build();
|
|
807
1109
|
try {
|
|
808
1110
|
await this.executeQuery({ sql, params });
|
|
809
|
-
} catch (error) {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
1111
|
+
} catch (error$1) {
|
|
1112
|
+
throw new error.MastraError(
|
|
1113
|
+
{
|
|
1114
|
+
id: "CLOUDFLARE_D1_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_ERROR",
|
|
1115
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1116
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1117
|
+
text: `Failed to persist workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1118
|
+
details: { workflowName, runId }
|
|
1119
|
+
},
|
|
1120
|
+
error$1
|
|
1121
|
+
);
|
|
814
1122
|
}
|
|
815
1123
|
}
|
|
816
1124
|
async loadWorkflowSnapshot(params) {
|
|
817
1125
|
const { workflowName, runId } = params;
|
|
818
1126
|
this.logger.debug("Loading workflow snapshot", { workflowName, runId });
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1127
|
+
try {
|
|
1128
|
+
const d = await this.load({
|
|
1129
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
1130
|
+
keys: {
|
|
1131
|
+
workflow_name: workflowName,
|
|
1132
|
+
run_id: runId
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
return d ? d.snapshot : null;
|
|
1136
|
+
} catch (error$1) {
|
|
1137
|
+
throw new error.MastraError(
|
|
1138
|
+
{
|
|
1139
|
+
id: "CLOUDFLARE_D1_STORAGE_LOAD_WORKFLOW_SNAPSHOT_ERROR",
|
|
1140
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1141
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1142
|
+
text: `Failed to load workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1143
|
+
details: { workflowName, runId }
|
|
1144
|
+
},
|
|
1145
|
+
error$1
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
827
1148
|
}
|
|
828
1149
|
/**
|
|
829
1150
|
* Insert multiple records in a batch operation
|
|
@@ -857,19 +1178,85 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
857
1178
|
);
|
|
858
1179
|
}
|
|
859
1180
|
this.logger.debug(`Successfully batch inserted ${records.length} records into ${tableName}`);
|
|
860
|
-
} catch (error) {
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
1181
|
+
} catch (error$1) {
|
|
1182
|
+
throw new error.MastraError(
|
|
1183
|
+
{
|
|
1184
|
+
id: "CLOUDFLARE_D1_STORAGE_BATCH_INSERT_ERROR",
|
|
1185
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1186
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1187
|
+
text: `Failed to batch insert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1188
|
+
details: { tableName }
|
|
1189
|
+
},
|
|
1190
|
+
error$1
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
/**
|
|
1195
|
+
* Upsert multiple records in a batch operation
|
|
1196
|
+
* @param tableName The table to insert into
|
|
1197
|
+
* @param records The records to insert
|
|
1198
|
+
*/
|
|
1199
|
+
async batchUpsert({
|
|
1200
|
+
tableName,
|
|
1201
|
+
records
|
|
1202
|
+
}) {
|
|
1203
|
+
if (records.length === 0) return;
|
|
1204
|
+
const fullTableName = this.getTableName(tableName);
|
|
1205
|
+
try {
|
|
1206
|
+
const batchSize = 50;
|
|
1207
|
+
for (let i = 0; i < records.length; i += batchSize) {
|
|
1208
|
+
const batch = records.slice(i, i + batchSize);
|
|
1209
|
+
const recordsToInsert = batch;
|
|
1210
|
+
if (recordsToInsert.length > 0) {
|
|
1211
|
+
const firstRecord = recordsToInsert[0];
|
|
1212
|
+
const columns = Object.keys(firstRecord || {});
|
|
1213
|
+
for (const record of recordsToInsert) {
|
|
1214
|
+
const values = columns.map((col) => {
|
|
1215
|
+
if (!record) return null;
|
|
1216
|
+
const value = typeof col === "string" ? record[col] : null;
|
|
1217
|
+
return this.serializeValue(value);
|
|
1218
|
+
});
|
|
1219
|
+
const recordToUpsert = columns.reduce(
|
|
1220
|
+
(acc, col) => {
|
|
1221
|
+
if (col !== "createdAt") acc[col] = `excluded.${col}`;
|
|
1222
|
+
return acc;
|
|
1223
|
+
},
|
|
1224
|
+
{}
|
|
1225
|
+
);
|
|
1226
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert);
|
|
1227
|
+
const { sql, params } = query.build();
|
|
1228
|
+
await this.executeQuery({ sql, params });
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
this.logger.debug(
|
|
1232
|
+
`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
|
|
1236
|
+
} catch (error$1) {
|
|
1237
|
+
throw new error.MastraError(
|
|
1238
|
+
{
|
|
1239
|
+
id: "CLOUDFLARE_D1_STORAGE_BATCH_UPSERT_ERROR",
|
|
1240
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1241
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1242
|
+
text: `Failed to batch upsert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1243
|
+
details: { tableName }
|
|
1244
|
+
},
|
|
1245
|
+
error$1
|
|
1246
|
+
);
|
|
865
1247
|
}
|
|
866
1248
|
}
|
|
1249
|
+
/**
|
|
1250
|
+
* @deprecated use getTracesPaginated instead
|
|
1251
|
+
*/
|
|
867
1252
|
async getTraces({
|
|
868
1253
|
name,
|
|
869
1254
|
scope,
|
|
870
1255
|
page,
|
|
871
1256
|
perPage,
|
|
872
|
-
attributes
|
|
1257
|
+
attributes,
|
|
1258
|
+
fromDate,
|
|
1259
|
+
toDate
|
|
873
1260
|
}) {
|
|
874
1261
|
const fullTableName = this.getTableName(storage.TABLE_TRACES);
|
|
875
1262
|
try {
|
|
@@ -885,22 +1272,114 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
885
1272
|
query.jsonLike("attributes", key, value);
|
|
886
1273
|
}
|
|
887
1274
|
}
|
|
888
|
-
|
|
1275
|
+
if (fromDate) {
|
|
1276
|
+
query.andWhere("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
1277
|
+
}
|
|
1278
|
+
if (toDate) {
|
|
1279
|
+
query.andWhere("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
1280
|
+
}
|
|
1281
|
+
query.orderBy("startTime", "DESC").limit(perPage).offset(page * perPage);
|
|
889
1282
|
const { sql, params } = query.build();
|
|
890
1283
|
const results = await this.executeQuery({ sql, params });
|
|
891
|
-
return isArrayOfRecords(results) ? results.map(
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
1284
|
+
return isArrayOfRecords(results) ? results.map(
|
|
1285
|
+
(trace) => ({
|
|
1286
|
+
...trace,
|
|
1287
|
+
attributes: this.deserializeValue(trace.attributes, "jsonb"),
|
|
1288
|
+
status: this.deserializeValue(trace.status, "jsonb"),
|
|
1289
|
+
events: this.deserializeValue(trace.events, "jsonb"),
|
|
1290
|
+
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1291
|
+
other: this.deserializeValue(trace.other, "jsonb")
|
|
1292
|
+
})
|
|
1293
|
+
) : [];
|
|
1294
|
+
} catch (error$1) {
|
|
1295
|
+
const mastraError = new error.MastraError(
|
|
1296
|
+
{
|
|
1297
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_TRACES_ERROR",
|
|
1298
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1299
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1300
|
+
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1301
|
+
details: {
|
|
1302
|
+
name: name ?? "",
|
|
1303
|
+
scope: scope ?? ""
|
|
1304
|
+
}
|
|
1305
|
+
},
|
|
1306
|
+
error$1
|
|
1307
|
+
);
|
|
1308
|
+
this.logger?.error(mastraError.toString());
|
|
1309
|
+
this.logger?.trackException(mastraError);
|
|
901
1310
|
return [];
|
|
902
1311
|
}
|
|
903
1312
|
}
|
|
1313
|
+
async getTracesPaginated(args) {
|
|
1314
|
+
const { name, scope, page, perPage, attributes, fromDate, toDate } = args;
|
|
1315
|
+
const fullTableName = this.getTableName(storage.TABLE_TRACES);
|
|
1316
|
+
try {
|
|
1317
|
+
const dataQuery = createSqlBuilder().select("*").from(fullTableName).where("1=1");
|
|
1318
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("1=1");
|
|
1319
|
+
if (name) {
|
|
1320
|
+
dataQuery.andWhere("name LIKE ?", `%${name}%`);
|
|
1321
|
+
countQuery.andWhere("name LIKE ?", `%${name}%`);
|
|
1322
|
+
}
|
|
1323
|
+
if (scope) {
|
|
1324
|
+
dataQuery.andWhere("scope = ?", scope);
|
|
1325
|
+
countQuery.andWhere("scope = ?", scope);
|
|
1326
|
+
}
|
|
1327
|
+
if (attributes && Object.keys(attributes).length > 0) {
|
|
1328
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
1329
|
+
dataQuery.jsonLike("attributes", key, value);
|
|
1330
|
+
countQuery.jsonLike("attributes", key, value);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
if (fromDate) {
|
|
1334
|
+
const fromDateStr = fromDate instanceof Date ? fromDate.toISOString() : fromDate;
|
|
1335
|
+
dataQuery.andWhere("createdAt >= ?", fromDateStr);
|
|
1336
|
+
countQuery.andWhere("createdAt >= ?", fromDateStr);
|
|
1337
|
+
}
|
|
1338
|
+
if (toDate) {
|
|
1339
|
+
const toDateStr = toDate instanceof Date ? toDate.toISOString() : toDate;
|
|
1340
|
+
dataQuery.andWhere("createdAt <= ?", toDateStr);
|
|
1341
|
+
countQuery.andWhere("createdAt <= ?", toDateStr);
|
|
1342
|
+
}
|
|
1343
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
1344
|
+
const total = Number(countResult?.[0]?.count ?? 0);
|
|
1345
|
+
dataQuery.orderBy("startTime", "DESC").limit(perPage).offset(page * perPage);
|
|
1346
|
+
const results = await this.executeQuery(dataQuery.build());
|
|
1347
|
+
const traces = isArrayOfRecords(results) ? results.map(
|
|
1348
|
+
(trace) => ({
|
|
1349
|
+
...trace,
|
|
1350
|
+
attributes: this.deserializeValue(trace.attributes, "jsonb"),
|
|
1351
|
+
status: this.deserializeValue(trace.status, "jsonb"),
|
|
1352
|
+
events: this.deserializeValue(trace.events, "jsonb"),
|
|
1353
|
+
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1354
|
+
other: this.deserializeValue(trace.other, "jsonb")
|
|
1355
|
+
})
|
|
1356
|
+
) : [];
|
|
1357
|
+
return {
|
|
1358
|
+
traces,
|
|
1359
|
+
total,
|
|
1360
|
+
page,
|
|
1361
|
+
perPage,
|
|
1362
|
+
hasMore: page * perPage + traces.length < total
|
|
1363
|
+
};
|
|
1364
|
+
} catch (error$1) {
|
|
1365
|
+
const mastraError = new error.MastraError(
|
|
1366
|
+
{
|
|
1367
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_TRACES_ERROR",
|
|
1368
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1369
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1370
|
+
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1371
|
+
details: { name: name ?? "", scope: scope ?? "" }
|
|
1372
|
+
},
|
|
1373
|
+
error$1
|
|
1374
|
+
);
|
|
1375
|
+
this.logger?.error(mastraError.toString());
|
|
1376
|
+
this.logger?.trackException(mastraError);
|
|
1377
|
+
return { traces: [], total: 0, page, perPage, hasMore: false };
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* @deprecated use getEvals instead
|
|
1382
|
+
*/
|
|
904
1383
|
async getEvalsByAgentName(agentName, type) {
|
|
905
1384
|
const fullTableName = this.getTableName(storage.TABLE_EVALS);
|
|
906
1385
|
try {
|
|
@@ -929,13 +1408,116 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
929
1408
|
testInfo
|
|
930
1409
|
};
|
|
931
1410
|
}) : [];
|
|
932
|
-
} catch (error) {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1411
|
+
} catch (error$1) {
|
|
1412
|
+
const mastraError = new error.MastraError(
|
|
1413
|
+
{
|
|
1414
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
1415
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1416
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1417
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1418
|
+
details: { agentName }
|
|
1419
|
+
},
|
|
1420
|
+
error$1
|
|
1421
|
+
);
|
|
1422
|
+
this.logger?.error(mastraError.toString());
|
|
1423
|
+
this.logger?.trackException(mastraError);
|
|
936
1424
|
return [];
|
|
937
1425
|
}
|
|
938
1426
|
}
|
|
1427
|
+
async getEvals(options) {
|
|
1428
|
+
const { agentName, type, page = 0, perPage = 40, fromDate, toDate } = options || {};
|
|
1429
|
+
const fullTableName = this.getTableName(storage.TABLE_EVALS);
|
|
1430
|
+
const conditions = [];
|
|
1431
|
+
const queryParams = [];
|
|
1432
|
+
if (agentName) {
|
|
1433
|
+
conditions.push(`agent_name = ?`);
|
|
1434
|
+
queryParams.push(agentName);
|
|
1435
|
+
}
|
|
1436
|
+
if (type === "test") {
|
|
1437
|
+
conditions.push(`(test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL)`);
|
|
1438
|
+
} else if (type === "live") {
|
|
1439
|
+
conditions.push(`(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)`);
|
|
1440
|
+
}
|
|
1441
|
+
if (fromDate) {
|
|
1442
|
+
conditions.push(`createdAt >= ?`);
|
|
1443
|
+
queryParams.push(this.serializeDate(fromDate));
|
|
1444
|
+
}
|
|
1445
|
+
if (toDate) {
|
|
1446
|
+
conditions.push(`createdAt <= ?`);
|
|
1447
|
+
queryParams.push(this.serializeDate(toDate));
|
|
1448
|
+
}
|
|
1449
|
+
const countQueryBuilder = createSqlBuilder().count().from(fullTableName);
|
|
1450
|
+
if (conditions.length > 0) {
|
|
1451
|
+
countQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
1452
|
+
}
|
|
1453
|
+
const { sql: countSql, params: countParams } = countQueryBuilder.build();
|
|
1454
|
+
try {
|
|
1455
|
+
const countResult = await this.executeQuery({
|
|
1456
|
+
sql: countSql,
|
|
1457
|
+
params: countParams,
|
|
1458
|
+
first: true
|
|
1459
|
+
});
|
|
1460
|
+
const total = Number(countResult?.count || 0);
|
|
1461
|
+
const currentOffset = page * perPage;
|
|
1462
|
+
if (total === 0) {
|
|
1463
|
+
return {
|
|
1464
|
+
evals: [],
|
|
1465
|
+
total: 0,
|
|
1466
|
+
page,
|
|
1467
|
+
perPage,
|
|
1468
|
+
hasMore: false
|
|
1469
|
+
};
|
|
1470
|
+
}
|
|
1471
|
+
const dataQueryBuilder = createSqlBuilder().select("*").from(fullTableName);
|
|
1472
|
+
if (conditions.length > 0) {
|
|
1473
|
+
dataQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
1474
|
+
}
|
|
1475
|
+
dataQueryBuilder.orderBy("createdAt", "DESC").limit(perPage).offset(currentOffset);
|
|
1476
|
+
const { sql: dataSql, params: dataParams } = dataQueryBuilder.build();
|
|
1477
|
+
const rows = await this.executeQuery({
|
|
1478
|
+
sql: dataSql,
|
|
1479
|
+
params: dataParams
|
|
1480
|
+
});
|
|
1481
|
+
const evals = (isArrayOfRecords(rows) ? rows : []).map((row) => {
|
|
1482
|
+
const result = this.deserializeValue(row.result);
|
|
1483
|
+
const testInfo = row.test_info ? this.deserializeValue(row.test_info) : void 0;
|
|
1484
|
+
if (!result || typeof result !== "object" || !("score" in result)) {
|
|
1485
|
+
throw new Error(`Invalid MetricResult format: ${JSON.stringify(result)}`);
|
|
1486
|
+
}
|
|
1487
|
+
return {
|
|
1488
|
+
input: row.input,
|
|
1489
|
+
output: row.output,
|
|
1490
|
+
result,
|
|
1491
|
+
agentName: row.agent_name,
|
|
1492
|
+
metricName: row.metric_name,
|
|
1493
|
+
instructions: row.instructions,
|
|
1494
|
+
testInfo,
|
|
1495
|
+
globalRunId: row.global_run_id,
|
|
1496
|
+
runId: row.run_id,
|
|
1497
|
+
createdAt: row.createdAt
|
|
1498
|
+
};
|
|
1499
|
+
});
|
|
1500
|
+
const hasMore = currentOffset + evals.length < total;
|
|
1501
|
+
return {
|
|
1502
|
+
evals,
|
|
1503
|
+
total,
|
|
1504
|
+
page,
|
|
1505
|
+
perPage,
|
|
1506
|
+
hasMore
|
|
1507
|
+
};
|
|
1508
|
+
} catch (error$1) {
|
|
1509
|
+
throw new error.MastraError(
|
|
1510
|
+
{
|
|
1511
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
1512
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1513
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1514
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1515
|
+
details: { agentName: agentName ?? "", type: type ?? "" }
|
|
1516
|
+
},
|
|
1517
|
+
error$1
|
|
1518
|
+
);
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
939
1521
|
parseWorkflowRun(row) {
|
|
940
1522
|
let parsedSnapshot = row.snapshot;
|
|
941
1523
|
if (typeof parsedSnapshot === "string") {
|
|
@@ -997,17 +1579,30 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
997
1579
|
let total = 0;
|
|
998
1580
|
if (limit !== void 0 && offset !== void 0) {
|
|
999
1581
|
const { sql: countSql, params: countParams } = countBuilder.build();
|
|
1000
|
-
const countResult = await this.executeQuery({
|
|
1582
|
+
const countResult = await this.executeQuery({
|
|
1583
|
+
sql: countSql,
|
|
1584
|
+
params: countParams,
|
|
1585
|
+
first: true
|
|
1586
|
+
});
|
|
1001
1587
|
total = Number(countResult?.count ?? 0);
|
|
1002
1588
|
}
|
|
1003
1589
|
const results = await this.executeQuery({ sql, params });
|
|
1004
1590
|
const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
|
|
1005
1591
|
return { runs, total: total || runs.length };
|
|
1006
|
-
} catch (error) {
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1592
|
+
} catch (error$1) {
|
|
1593
|
+
throw new error.MastraError(
|
|
1594
|
+
{
|
|
1595
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_WORKFLOW_RUNS_ERROR",
|
|
1596
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1597
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1598
|
+
text: `Failed to retrieve workflow runs: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1599
|
+
details: {
|
|
1600
|
+
workflowName: workflowName ?? "",
|
|
1601
|
+
resourceId: resourceId ?? ""
|
|
1602
|
+
}
|
|
1603
|
+
},
|
|
1604
|
+
error$1
|
|
1605
|
+
);
|
|
1011
1606
|
}
|
|
1012
1607
|
}
|
|
1013
1608
|
async getWorkflowRunById({
|
|
@@ -1031,11 +1626,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1031
1626
|
const result = await this.executeQuery({ sql, params, first: true });
|
|
1032
1627
|
if (!result) return null;
|
|
1033
1628
|
return this.parseWorkflowRun(result);
|
|
1034
|
-
} catch (error) {
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1629
|
+
} catch (error$1) {
|
|
1630
|
+
throw new error.MastraError(
|
|
1631
|
+
{
|
|
1632
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_WORKFLOW_RUN_BY_ID_ERROR",
|
|
1633
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1634
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1635
|
+
text: `Failed to retrieve workflow run by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1636
|
+
details: { runId, workflowName: workflowName ?? "" }
|
|
1637
|
+
},
|
|
1638
|
+
error$1
|
|
1639
|
+
);
|
|
1039
1640
|
}
|
|
1040
1641
|
}
|
|
1041
1642
|
/**
|
|
@@ -1045,6 +1646,10 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1045
1646
|
async close() {
|
|
1046
1647
|
this.logger.debug("Closing D1 connection");
|
|
1047
1648
|
}
|
|
1649
|
+
async updateMessages(_args) {
|
|
1650
|
+
this.logger.error("updateMessages is not yet implemented in CloudflareD1Store");
|
|
1651
|
+
throw new Error("Method not implemented");
|
|
1652
|
+
}
|
|
1048
1653
|
};
|
|
1049
1654
|
|
|
1050
1655
|
exports.D1Store = D1Store;
|