@mastra/cloudflare-d1 0.0.0-switch-to-core-20250424015131 → 0.0.0-tool-call-parts-20250630193309
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_tsup-dts-rollup.d.cts +129 -43
- package/dist/_tsup-dts-rollup.d.ts +129 -43
- package/dist/index.cjs +897 -219
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +881 -203
- 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) {
|
|
@@ -74,6 +82,10 @@ var SqlBuilder = class {
|
|
|
74
82
|
this.params.push(count);
|
|
75
83
|
return this;
|
|
76
84
|
}
|
|
85
|
+
count() {
|
|
86
|
+
this.sql += "SELECT COUNT(*) AS count";
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
77
89
|
/**
|
|
78
90
|
* Insert a row, or update specific columns on conflict (upsert).
|
|
79
91
|
* @param table Table name
|
|
@@ -83,27 +95,33 @@ var SqlBuilder = class {
|
|
|
83
95
|
* @param updateMap Object mapping columns to update to their new value (e.g. { name: 'excluded.name' })
|
|
84
96
|
*/
|
|
85
97
|
insert(table, columns, values, conflictColumns, updateMap) {
|
|
86
|
-
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(", ");
|
|
87
101
|
if (conflictColumns && updateMap) {
|
|
102
|
+
const parsedConflictColumns = conflictColumns.map((col) => utils.parseSqlIdentifier(col, "column name"));
|
|
88
103
|
const updateClause = Object.entries(updateMap).map(([col, expr]) => `${col} = ${expr}`).join(", ");
|
|
89
|
-
this.sql = `INSERT INTO ${
|
|
104
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders}) ON CONFLICT(${parsedConflictColumns.join(", ")}) DO UPDATE SET ${updateClause}`;
|
|
90
105
|
this.params.push(...values);
|
|
91
106
|
return this;
|
|
92
107
|
}
|
|
93
|
-
this.sql = `INSERT INTO ${
|
|
108
|
+
this.sql = `INSERT INTO ${parsedTableName} (${parsedColumns.join(", ")}) VALUES (${placeholders})`;
|
|
94
109
|
this.params.push(...values);
|
|
95
110
|
return this;
|
|
96
111
|
}
|
|
97
112
|
// Update operations
|
|
98
113
|
update(table, columns, values) {
|
|
99
|
-
const
|
|
100
|
-
|
|
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}`;
|
|
101
118
|
this.params.push(...values);
|
|
102
119
|
return this;
|
|
103
120
|
}
|
|
104
121
|
// Delete operations
|
|
105
122
|
delete(table) {
|
|
106
|
-
|
|
123
|
+
const parsedTableName = utils.parseSqlIdentifier(table, "table name");
|
|
124
|
+
this.sql = `DELETE FROM ${parsedTableName}`;
|
|
107
125
|
return this;
|
|
108
126
|
}
|
|
109
127
|
/**
|
|
@@ -114,9 +132,16 @@ var SqlBuilder = class {
|
|
|
114
132
|
* @returns The builder instance
|
|
115
133
|
*/
|
|
116
134
|
createTable(table, columnDefinitions, tableConstraints) {
|
|
117
|
-
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(", ");
|
|
118
143
|
const constraints = tableConstraints && tableConstraints.length > 0 ? ", " + tableConstraints.join(", ") : "";
|
|
119
|
-
this.sql = `CREATE TABLE IF NOT EXISTS ${
|
|
144
|
+
this.sql = `CREATE TABLE IF NOT EXISTS ${parsedTableName} (${columns}${constraints})`;
|
|
120
145
|
return this;
|
|
121
146
|
}
|
|
122
147
|
/**
|
|
@@ -139,13 +164,10 @@ var SqlBuilder = class {
|
|
|
139
164
|
* @returns The builder instance
|
|
140
165
|
*/
|
|
141
166
|
createIndex(indexName, tableName, columnName, indexType = "") {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
raw(sql, ...params) {
|
|
147
|
-
this.sql = sql;
|
|
148
|
-
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})`;
|
|
149
171
|
return this;
|
|
150
172
|
}
|
|
151
173
|
/**
|
|
@@ -155,11 +177,12 @@ var SqlBuilder = class {
|
|
|
155
177
|
* @param exact If true, will not add % wildcards
|
|
156
178
|
*/
|
|
157
179
|
like(column, value, exact = false) {
|
|
180
|
+
const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
|
|
158
181
|
const likeValue = exact ? value : `%${value}%`;
|
|
159
182
|
if (this.whereAdded) {
|
|
160
|
-
this.sql += ` AND ${
|
|
183
|
+
this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
161
184
|
} else {
|
|
162
|
-
this.sql += ` WHERE ${
|
|
185
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
163
186
|
this.whereAdded = true;
|
|
164
187
|
}
|
|
165
188
|
this.params.push(likeValue);
|
|
@@ -172,11 +195,13 @@ var SqlBuilder = class {
|
|
|
172
195
|
* @param value The value to match
|
|
173
196
|
*/
|
|
174
197
|
jsonLike(column, key, value) {
|
|
175
|
-
const
|
|
198
|
+
const parsedColumnName = utils.parseSqlIdentifier(column, "column name");
|
|
199
|
+
const parsedKey = utils.parseSqlIdentifier(key, "key name");
|
|
200
|
+
const jsonPattern = `%"${parsedKey}":"${value}"%`;
|
|
176
201
|
if (this.whereAdded) {
|
|
177
|
-
this.sql += ` AND ${
|
|
202
|
+
this.sql += ` AND ${parsedColumnName} LIKE ?`;
|
|
178
203
|
} else {
|
|
179
|
-
this.sql += ` WHERE ${
|
|
204
|
+
this.sql += ` WHERE ${parsedColumnName} LIKE ?`;
|
|
180
205
|
this.whereAdded = true;
|
|
181
206
|
}
|
|
182
207
|
this.params.push(jsonPattern);
|
|
@@ -206,6 +231,15 @@ var SqlBuilder = class {
|
|
|
206
231
|
function createSqlBuilder() {
|
|
207
232
|
return new SqlBuilder();
|
|
208
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
|
+
}
|
|
209
243
|
|
|
210
244
|
// src/storage/index.ts
|
|
211
245
|
function isArrayOfRecords(value) {
|
|
@@ -223,24 +257,39 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
223
257
|
* @param config Configuration for D1 access (either REST API or Workers Binding API)
|
|
224
258
|
*/
|
|
225
259
|
constructor(config) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
throw new Error("D1 binding is required when using Workers Binding API");
|
|
231
|
-
}
|
|
232
|
-
this.binding = config.binding;
|
|
233
|
-
this.logger.info("Using D1 Workers Binding API");
|
|
234
|
-
} else {
|
|
235
|
-
if (!config.accountId || !config.databaseId || !config.apiToken) {
|
|
236
|
-
throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
260
|
+
try {
|
|
261
|
+
super({ name: "D1" });
|
|
262
|
+
if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) {
|
|
263
|
+
throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
|
|
237
264
|
}
|
|
238
|
-
this.
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
265
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
266
|
+
if ("binding" in config) {
|
|
267
|
+
if (!config.binding) {
|
|
268
|
+
throw new Error("D1 binding is required when using Workers Binding API");
|
|
269
|
+
}
|
|
270
|
+
this.binding = config.binding;
|
|
271
|
+
this.logger.info("Using D1 Workers Binding API");
|
|
272
|
+
} else {
|
|
273
|
+
if (!config.accountId || !config.databaseId || !config.apiToken) {
|
|
274
|
+
throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
275
|
+
}
|
|
276
|
+
this.accountId = config.accountId;
|
|
277
|
+
this.databaseId = config.databaseId;
|
|
278
|
+
this.client = new Cloudflare__default.default({
|
|
279
|
+
apiToken: config.apiToken
|
|
280
|
+
});
|
|
281
|
+
this.logger.info("Using D1 REST API");
|
|
282
|
+
}
|
|
283
|
+
} catch (error$1) {
|
|
284
|
+
throw new error.MastraError(
|
|
285
|
+
{
|
|
286
|
+
id: "CLOUDFLARE_D1_STORAGE_INITIALIZATION_ERROR",
|
|
287
|
+
domain: error.ErrorDomain.STORAGE,
|
|
288
|
+
category: error.ErrorCategory.SYSTEM,
|
|
289
|
+
text: "Error initializing D1Store"
|
|
290
|
+
},
|
|
291
|
+
error$1
|
|
292
|
+
);
|
|
244
293
|
}
|
|
245
294
|
}
|
|
246
295
|
// Helper method to get the full table name with prefix
|
|
@@ -250,30 +299,6 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
250
299
|
formatSqlParams(params) {
|
|
251
300
|
return params.map((p) => p === void 0 || p === null ? null : p);
|
|
252
301
|
}
|
|
253
|
-
// Helper method to create SQL indexes for better query performance
|
|
254
|
-
async createIndexIfNotExists(tableName, columnName, indexType = "") {
|
|
255
|
-
const fullTableName = this.getTableName(tableName);
|
|
256
|
-
const indexName = `idx_${tableName}_${columnName}`;
|
|
257
|
-
try {
|
|
258
|
-
const checkQuery = createSqlBuilder().checkIndexExists(indexName, fullTableName);
|
|
259
|
-
const { sql: checkSql, params: checkParams } = checkQuery.build();
|
|
260
|
-
const indexExists = await this.executeQuery({
|
|
261
|
-
sql: checkSql,
|
|
262
|
-
params: checkParams,
|
|
263
|
-
first: true
|
|
264
|
-
});
|
|
265
|
-
if (!indexExists) {
|
|
266
|
-
const createQuery = createSqlBuilder().createIndex(indexName, fullTableName, columnName, indexType);
|
|
267
|
-
const { sql: createSql, params: createParams } = createQuery.build();
|
|
268
|
-
await this.executeQuery({ sql: createSql, params: createParams });
|
|
269
|
-
this.logger.debug(`Created index ${indexName} on ${fullTableName}(${columnName})`);
|
|
270
|
-
}
|
|
271
|
-
} catch (error) {
|
|
272
|
-
this.logger.error(`Error creating index on ${fullTableName}(${columnName}):`, {
|
|
273
|
-
message: error instanceof Error ? error.message : String(error)
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
302
|
async executeWorkersBindingQuery({
|
|
278
303
|
sql,
|
|
279
304
|
params = [],
|
|
@@ -377,34 +402,25 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
377
402
|
throw new Error(`D1 query error: ${error.message}`);
|
|
378
403
|
}
|
|
379
404
|
}
|
|
380
|
-
// Helper to
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
405
|
+
// Helper to get existing table columns
|
|
406
|
+
async getTableColumns(tableName) {
|
|
407
|
+
try {
|
|
408
|
+
const sql = `PRAGMA table_info(${tableName})`;
|
|
409
|
+
const result = await this.executeQuery({ sql, params: [] });
|
|
410
|
+
if (!result || !Array.isArray(result)) {
|
|
411
|
+
return [];
|
|
412
|
+
}
|
|
413
|
+
return result.map((row) => ({
|
|
414
|
+
name: row.name,
|
|
415
|
+
type: row.type
|
|
416
|
+
}));
|
|
417
|
+
} catch (error) {
|
|
418
|
+
this.logger.error(`Error getting table columns for ${tableName}:`, {
|
|
419
|
+
message: error instanceof Error ? error.message : String(error)
|
|
420
|
+
});
|
|
421
|
+
return [];
|
|
397
422
|
}
|
|
398
423
|
}
|
|
399
|
-
ensureDate(date) {
|
|
400
|
-
if (!date) return void 0;
|
|
401
|
-
return date instanceof Date ? date : new Date(date);
|
|
402
|
-
}
|
|
403
|
-
serializeDate(date) {
|
|
404
|
-
if (!date) return void 0;
|
|
405
|
-
const dateObj = this.ensureDate(date);
|
|
406
|
-
return dateObj?.toISOString();
|
|
407
|
-
}
|
|
408
424
|
// Helper to serialize objects to JSON strings
|
|
409
425
|
serializeValue(value) {
|
|
410
426
|
if (value === null || value === void 0) return null;
|
|
@@ -438,6 +454,18 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
438
454
|
}
|
|
439
455
|
return value;
|
|
440
456
|
}
|
|
457
|
+
getSqlType(type) {
|
|
458
|
+
switch (type) {
|
|
459
|
+
case "bigint":
|
|
460
|
+
return "INTEGER";
|
|
461
|
+
// SQLite uses INTEGER for all integer sizes
|
|
462
|
+
case "jsonb":
|
|
463
|
+
return "TEXT";
|
|
464
|
+
// Store JSON as TEXT in SQLite
|
|
465
|
+
default:
|
|
466
|
+
return super.getSqlType(type);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
441
469
|
async createTable({
|
|
442
470
|
tableName,
|
|
443
471
|
schema
|
|
@@ -453,16 +481,64 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
453
481
|
if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
|
|
454
482
|
tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
455
483
|
}
|
|
456
|
-
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
457
|
-
const { sql, params } = query.build();
|
|
458
484
|
try {
|
|
485
|
+
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
486
|
+
const { sql, params } = query.build();
|
|
459
487
|
await this.executeQuery({ sql, params });
|
|
460
488
|
this.logger.debug(`Created table ${fullTableName}`);
|
|
461
|
-
} catch (error) {
|
|
489
|
+
} catch (error$1) {
|
|
462
490
|
this.logger.error(`Error creating table ${fullTableName}:`, {
|
|
463
|
-
message: error instanceof Error ? error.message : String(error)
|
|
491
|
+
message: error$1 instanceof Error ? error$1.message : String(error$1)
|
|
464
492
|
});
|
|
465
|
-
throw new
|
|
493
|
+
throw new error.MastraError(
|
|
494
|
+
{
|
|
495
|
+
id: "CLOUDFLARE_D1_STORAGE_CREATE_TABLE_ERROR",
|
|
496
|
+
domain: error.ErrorDomain.STORAGE,
|
|
497
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
498
|
+
text: `Failed to create table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
499
|
+
details: { tableName }
|
|
500
|
+
},
|
|
501
|
+
error$1
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Alters table schema to add columns if they don't exist
|
|
507
|
+
* @param tableName Name of the table
|
|
508
|
+
* @param schema Schema of the table
|
|
509
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
510
|
+
*/
|
|
511
|
+
async alterTable({
|
|
512
|
+
tableName,
|
|
513
|
+
schema,
|
|
514
|
+
ifNotExists
|
|
515
|
+
}) {
|
|
516
|
+
const fullTableName = this.getTableName(tableName);
|
|
517
|
+
try {
|
|
518
|
+
const existingColumns = await this.getTableColumns(fullTableName);
|
|
519
|
+
const existingColumnNames = new Set(existingColumns.map((col) => col.name.toLowerCase()));
|
|
520
|
+
for (const columnName of ifNotExists) {
|
|
521
|
+
if (!existingColumnNames.has(columnName.toLowerCase()) && schema[columnName]) {
|
|
522
|
+
const columnDef = schema[columnName];
|
|
523
|
+
const sqlType = this.getSqlType(columnDef.type);
|
|
524
|
+
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
525
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
526
|
+
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
527
|
+
await this.executeQuery({ sql: alterSql, params: [] });
|
|
528
|
+
this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} catch (error$1) {
|
|
532
|
+
throw new error.MastraError(
|
|
533
|
+
{
|
|
534
|
+
id: "CLOUDFLARE_D1_STORAGE_ALTER_TABLE_ERROR",
|
|
535
|
+
domain: error.ErrorDomain.STORAGE,
|
|
536
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
537
|
+
text: `Failed to alter table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
538
|
+
details: { tableName }
|
|
539
|
+
},
|
|
540
|
+
error$1
|
|
541
|
+
);
|
|
466
542
|
}
|
|
467
543
|
}
|
|
468
544
|
async clearTable({ tableName }) {
|
|
@@ -472,11 +548,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
472
548
|
const { sql, params } = query.build();
|
|
473
549
|
await this.executeQuery({ sql, params });
|
|
474
550
|
this.logger.debug(`Cleared table ${fullTableName}`);
|
|
475
|
-
} catch (error) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
551
|
+
} catch (error$1) {
|
|
552
|
+
throw new error.MastraError(
|
|
553
|
+
{
|
|
554
|
+
id: "CLOUDFLARE_D1_STORAGE_CLEAR_TABLE_ERROR",
|
|
555
|
+
domain: error.ErrorDomain.STORAGE,
|
|
556
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
557
|
+
text: `Failed to clear table ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
558
|
+
details: { tableName }
|
|
559
|
+
},
|
|
560
|
+
error$1
|
|
561
|
+
);
|
|
480
562
|
}
|
|
481
563
|
}
|
|
482
564
|
async processRecord(record) {
|
|
@@ -495,9 +577,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
495
577
|
const { sql, params } = query.build();
|
|
496
578
|
try {
|
|
497
579
|
await this.executeQuery({ sql, params });
|
|
498
|
-
} catch (error) {
|
|
499
|
-
|
|
500
|
-
|
|
580
|
+
} catch (error$1) {
|
|
581
|
+
throw new error.MastraError(
|
|
582
|
+
{
|
|
583
|
+
id: "CLOUDFLARE_D1_STORAGE_INSERT_ERROR",
|
|
584
|
+
domain: error.ErrorDomain.STORAGE,
|
|
585
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
586
|
+
text: `Failed to insert into ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
587
|
+
details: { tableName }
|
|
588
|
+
},
|
|
589
|
+
error$1
|
|
590
|
+
);
|
|
501
591
|
}
|
|
502
592
|
}
|
|
503
593
|
async load({ tableName, keys }) {
|
|
@@ -522,11 +612,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
522
612
|
processedResult[key] = this.deserializeValue(value);
|
|
523
613
|
}
|
|
524
614
|
return processedResult;
|
|
525
|
-
} catch (error) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
615
|
+
} catch (error$1) {
|
|
616
|
+
throw new error.MastraError(
|
|
617
|
+
{
|
|
618
|
+
id: "CLOUDFLARE_D1_STORAGE_LOAD_ERROR",
|
|
619
|
+
domain: error.ErrorDomain.STORAGE,
|
|
620
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
621
|
+
text: `Failed to load from ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
622
|
+
details: { tableName }
|
|
623
|
+
},
|
|
624
|
+
error$1
|
|
625
|
+
);
|
|
530
626
|
}
|
|
531
627
|
}
|
|
532
628
|
async getThreadById({ threadId }) {
|
|
@@ -542,13 +638,25 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
542
638
|
updatedAt: this.ensureDate(thread.updatedAt),
|
|
543
639
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
544
640
|
};
|
|
545
|
-
} catch (error) {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
641
|
+
} catch (error$1) {
|
|
642
|
+
const mastraError = new error.MastraError(
|
|
643
|
+
{
|
|
644
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREAD_BY_ID_ERROR",
|
|
645
|
+
domain: error.ErrorDomain.STORAGE,
|
|
646
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
647
|
+
text: `Error processing thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
648
|
+
details: { threadId }
|
|
649
|
+
},
|
|
650
|
+
error$1
|
|
651
|
+
);
|
|
652
|
+
this.logger?.error(mastraError.toString());
|
|
653
|
+
this.logger?.trackException(mastraError);
|
|
549
654
|
return null;
|
|
550
655
|
}
|
|
551
656
|
}
|
|
657
|
+
/**
|
|
658
|
+
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
659
|
+
*/
|
|
552
660
|
async getThreadsByResourceId({ resourceId }) {
|
|
553
661
|
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
554
662
|
try {
|
|
@@ -561,13 +669,67 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
561
669
|
updatedAt: this.ensureDate(thread.updatedAt),
|
|
562
670
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
563
671
|
}));
|
|
564
|
-
} catch (error) {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
672
|
+
} catch (error$1) {
|
|
673
|
+
const mastraError = new error.MastraError(
|
|
674
|
+
{
|
|
675
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREADS_BY_RESOURCE_ID_ERROR",
|
|
676
|
+
domain: error.ErrorDomain.STORAGE,
|
|
677
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
678
|
+
text: `Error getting threads by resourceId ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
679
|
+
details: { resourceId }
|
|
680
|
+
},
|
|
681
|
+
error$1
|
|
682
|
+
);
|
|
683
|
+
this.logger?.error(mastraError.toString());
|
|
684
|
+
this.logger?.trackException(mastraError);
|
|
568
685
|
return [];
|
|
569
686
|
}
|
|
570
687
|
}
|
|
688
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
689
|
+
const { resourceId, page, perPage } = args;
|
|
690
|
+
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
691
|
+
const mapRowToStorageThreadType = (row) => ({
|
|
692
|
+
...row,
|
|
693
|
+
createdAt: this.ensureDate(row.createdAt),
|
|
694
|
+
updatedAt: this.ensureDate(row.updatedAt),
|
|
695
|
+
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
|
|
696
|
+
});
|
|
697
|
+
try {
|
|
698
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("resourceId = ?", resourceId);
|
|
699
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
700
|
+
const total = Number(countResult?.[0]?.count ?? 0);
|
|
701
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("resourceId = ?", resourceId).orderBy("createdAt", "DESC").limit(perPage).offset(page * perPage);
|
|
702
|
+
const results = await this.executeQuery(selectQuery.build());
|
|
703
|
+
const threads = results.map(mapRowToStorageThreadType);
|
|
704
|
+
return {
|
|
705
|
+
threads,
|
|
706
|
+
total,
|
|
707
|
+
page,
|
|
708
|
+
perPage,
|
|
709
|
+
hasMore: page * perPage + threads.length < total
|
|
710
|
+
};
|
|
711
|
+
} catch (error$1) {
|
|
712
|
+
const mastraError = new error.MastraError(
|
|
713
|
+
{
|
|
714
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_ERROR",
|
|
715
|
+
domain: error.ErrorDomain.STORAGE,
|
|
716
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
717
|
+
text: `Error getting threads by resourceId ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
718
|
+
details: { resourceId }
|
|
719
|
+
},
|
|
720
|
+
error$1
|
|
721
|
+
);
|
|
722
|
+
this.logger?.error(mastraError.toString());
|
|
723
|
+
this.logger?.trackException(mastraError);
|
|
724
|
+
return {
|
|
725
|
+
threads: [],
|
|
726
|
+
total: 0,
|
|
727
|
+
page,
|
|
728
|
+
perPage,
|
|
729
|
+
hasMore: false
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
}
|
|
571
733
|
async saveThread({ thread }) {
|
|
572
734
|
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
573
735
|
const threadToSave = {
|
|
@@ -593,9 +755,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
593
755
|
try {
|
|
594
756
|
await this.executeQuery({ sql, params });
|
|
595
757
|
return thread;
|
|
596
|
-
} catch (error) {
|
|
597
|
-
|
|
598
|
-
|
|
758
|
+
} catch (error$1) {
|
|
759
|
+
throw new error.MastraError(
|
|
760
|
+
{
|
|
761
|
+
id: "CLOUDFLARE_D1_STORAGE_SAVE_THREAD_ERROR",
|
|
762
|
+
domain: error.ErrorDomain.STORAGE,
|
|
763
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
764
|
+
text: `Failed to save thread to ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
765
|
+
details: { threadId: thread.id }
|
|
766
|
+
},
|
|
767
|
+
error$1
|
|
768
|
+
);
|
|
599
769
|
}
|
|
600
770
|
}
|
|
601
771
|
async updateThread({
|
|
@@ -604,19 +774,19 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
604
774
|
metadata
|
|
605
775
|
}) {
|
|
606
776
|
const thread = await this.getThreadById({ threadId: id });
|
|
607
|
-
if (!thread) {
|
|
608
|
-
throw new Error(`Thread ${id} not found`);
|
|
609
|
-
}
|
|
610
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
611
|
-
const mergedMetadata = {
|
|
612
|
-
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
613
|
-
...metadata
|
|
614
|
-
};
|
|
615
|
-
const columns = ["title", "metadata", "updatedAt"];
|
|
616
|
-
const values = [title, JSON.stringify(mergedMetadata), (/* @__PURE__ */ new Date()).toISOString()];
|
|
617
|
-
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
|
|
618
|
-
const { sql, params } = query.build();
|
|
619
777
|
try {
|
|
778
|
+
if (!thread) {
|
|
779
|
+
throw new Error(`Thread ${id} not found`);
|
|
780
|
+
}
|
|
781
|
+
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
782
|
+
const mergedMetadata = {
|
|
783
|
+
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
784
|
+
...metadata
|
|
785
|
+
};
|
|
786
|
+
const columns = ["title", "metadata", "updatedAt"];
|
|
787
|
+
const values = [title, JSON.stringify(mergedMetadata), (/* @__PURE__ */ new Date()).toISOString()];
|
|
788
|
+
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
|
|
789
|
+
const { sql, params } = query.build();
|
|
620
790
|
await this.executeQuery({ sql, params });
|
|
621
791
|
return {
|
|
622
792
|
...thread,
|
|
@@ -627,9 +797,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
627
797
|
},
|
|
628
798
|
updatedAt: /* @__PURE__ */ new Date()
|
|
629
799
|
};
|
|
630
|
-
} catch (error) {
|
|
631
|
-
|
|
632
|
-
|
|
800
|
+
} catch (error$1) {
|
|
801
|
+
throw new error.MastraError(
|
|
802
|
+
{
|
|
803
|
+
id: "CLOUDFLARE_D1_STORAGE_UPDATE_THREAD_ERROR",
|
|
804
|
+
domain: error.ErrorDomain.STORAGE,
|
|
805
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
806
|
+
text: `Failed to update thread ${id}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
807
|
+
details: { threadId: id }
|
|
808
|
+
},
|
|
809
|
+
error$1
|
|
810
|
+
);
|
|
633
811
|
}
|
|
634
812
|
}
|
|
635
813
|
async deleteThread({ threadId }) {
|
|
@@ -642,18 +820,25 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
642
820
|
const deleteMessagesQuery = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId);
|
|
643
821
|
const { sql: messagesSql, params: messagesParams } = deleteMessagesQuery.build();
|
|
644
822
|
await this.executeQuery({ sql: messagesSql, params: messagesParams });
|
|
645
|
-
} catch (error) {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
823
|
+
} catch (error$1) {
|
|
824
|
+
throw new error.MastraError(
|
|
825
|
+
{
|
|
826
|
+
id: "CLOUDFLARE_D1_STORAGE_DELETE_THREAD_ERROR",
|
|
827
|
+
domain: error.ErrorDomain.STORAGE,
|
|
828
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
829
|
+
text: `Failed to delete thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
830
|
+
details: { threadId }
|
|
831
|
+
},
|
|
832
|
+
error$1
|
|
833
|
+
);
|
|
650
834
|
}
|
|
651
835
|
}
|
|
652
|
-
|
|
653
|
-
|
|
836
|
+
async saveMessages(args) {
|
|
837
|
+
const { messages, format = "v1" } = args;
|
|
654
838
|
if (messages.length === 0) return [];
|
|
655
839
|
try {
|
|
656
840
|
const now = /* @__PURE__ */ new Date();
|
|
841
|
+
const threadId = messages[0]?.threadId;
|
|
657
842
|
for (const [i, message] of messages.entries()) {
|
|
658
843
|
if (!message.id) throw new Error(`Message at index ${i} missing id`);
|
|
659
844
|
if (!message.threadId) throw new Error(`Message at index ${i} missing threadId`);
|
|
@@ -672,36 +857,49 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
672
857
|
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
673
858
|
createdAt: createdAt.toISOString(),
|
|
674
859
|
role: message.role,
|
|
675
|
-
type: message.type
|
|
860
|
+
type: message.type || "v2",
|
|
861
|
+
resourceId: message.resourceId
|
|
676
862
|
};
|
|
677
863
|
});
|
|
678
|
-
await
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
864
|
+
await Promise.all([
|
|
865
|
+
this.batchUpsert({
|
|
866
|
+
tableName: storage.TABLE_MESSAGES,
|
|
867
|
+
records: messagesToInsert
|
|
868
|
+
}),
|
|
869
|
+
// Update thread's updatedAt timestamp
|
|
870
|
+
this.executeQuery({
|
|
871
|
+
sql: `UPDATE ${this.getTableName(storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
|
|
872
|
+
params: [now.toISOString(), threadId]
|
|
873
|
+
})
|
|
874
|
+
]);
|
|
682
875
|
this.logger.debug(`Saved ${messages.length} messages`);
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
876
|
+
const list = new agent.MessageList().add(messages, "memory");
|
|
877
|
+
if (format === `v2`) return list.get.all.v2();
|
|
878
|
+
return list.get.all.v1();
|
|
879
|
+
} catch (error$1) {
|
|
880
|
+
throw new error.MastraError(
|
|
881
|
+
{
|
|
882
|
+
id: "CLOUDFLARE_D1_STORAGE_SAVE_MESSAGES_ERROR",
|
|
883
|
+
domain: error.ErrorDomain.STORAGE,
|
|
884
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
885
|
+
text: `Failed to save messages: ${error$1 instanceof Error ? error$1.message : String(error$1)}`
|
|
886
|
+
},
|
|
887
|
+
error$1
|
|
888
|
+
);
|
|
687
889
|
}
|
|
688
890
|
}
|
|
689
|
-
async
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
const
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
const prevMax = Math.max(...include.map((i) => i.withPreviousMessages || 0));
|
|
697
|
-
const nextMax = Math.max(...include.map((i) => i.withNextMessages || 0));
|
|
698
|
-
const includeIds = include.map((i) => i.id);
|
|
699
|
-
const sql2 = `
|
|
891
|
+
async _getIncludedMessages(threadId, selectBy) {
|
|
892
|
+
const include = selectBy?.include;
|
|
893
|
+
if (!include) return null;
|
|
894
|
+
const prevMax = Math.max(...include.map((i) => i.withPreviousMessages || 0));
|
|
895
|
+
const nextMax = Math.max(...include.map((i) => i.withNextMessages || 0));
|
|
896
|
+
const includeIds = include.map((i) => i.id);
|
|
897
|
+
const sql = `
|
|
700
898
|
WITH ordered_messages AS (
|
|
701
899
|
SELECT
|
|
702
900
|
*,
|
|
703
901
|
ROW_NUMBER() OVER (ORDER BY createdAt DESC) AS row_num
|
|
704
|
-
FROM ${
|
|
902
|
+
FROM ${this.getTableName(storage.TABLE_MESSAGES)}
|
|
705
903
|
WHERE thread_id = ?
|
|
706
904
|
)
|
|
707
905
|
SELECT
|
|
@@ -710,7 +908,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
710
908
|
m.role,
|
|
711
909
|
m.type,
|
|
712
910
|
m.createdAt,
|
|
713
|
-
m.thread_id AS
|
|
911
|
+
m.thread_id AS threadId
|
|
714
912
|
FROM ordered_messages m
|
|
715
913
|
WHERE m.id IN (${includeIds.map(() => "?").join(",")})
|
|
716
914
|
OR EXISTS (
|
|
@@ -724,20 +922,38 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
724
922
|
)
|
|
725
923
|
ORDER BY m.createdAt DESC
|
|
726
924
|
`;
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
925
|
+
const params = [
|
|
926
|
+
threadId,
|
|
927
|
+
...includeIds,
|
|
928
|
+
// for m.id IN (...)
|
|
929
|
+
...includeIds,
|
|
930
|
+
// for target.id IN (...)
|
|
931
|
+
prevMax,
|
|
932
|
+
nextMax
|
|
933
|
+
];
|
|
934
|
+
const messages = await this.executeQuery({ sql, params });
|
|
935
|
+
return messages;
|
|
936
|
+
}
|
|
937
|
+
async getMessages({
|
|
938
|
+
threadId,
|
|
939
|
+
selectBy,
|
|
940
|
+
format
|
|
941
|
+
}) {
|
|
942
|
+
const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
943
|
+
const limit = this.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
944
|
+
const include = selectBy?.include || [];
|
|
945
|
+
const messages = [];
|
|
946
|
+
try {
|
|
947
|
+
if (include.length) {
|
|
948
|
+
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
737
949
|
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
738
950
|
}
|
|
739
951
|
const excludeIds = messages.map((m) => m.id);
|
|
740
|
-
|
|
952
|
+
const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId"]).from(fullTableName).where("thread_id = ?", threadId);
|
|
953
|
+
if (excludeIds.length > 0) {
|
|
954
|
+
query.andWhere(`id NOT IN (${excludeIds.map(() => "?").join(",")})`, ...excludeIds);
|
|
955
|
+
}
|
|
956
|
+
query.orderBy("createdAt", "DESC").limit(limit);
|
|
741
957
|
const { sql, params } = query.build();
|
|
742
958
|
const result = await this.executeQuery({ sql, params });
|
|
743
959
|
if (Array.isArray(result)) messages.push(...result);
|
|
@@ -751,18 +967,92 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
751
967
|
const processedMessages = messages.map((message) => {
|
|
752
968
|
const processedMsg = {};
|
|
753
969
|
for (const [key, value] of Object.entries(message)) {
|
|
970
|
+
if (key === `type` && value === `v2`) continue;
|
|
754
971
|
processedMsg[key] = this.deserializeValue(value);
|
|
755
972
|
}
|
|
756
973
|
return processedMsg;
|
|
757
974
|
});
|
|
758
975
|
this.logger.debug(`Retrieved ${messages.length} messages for thread ${threadId}`);
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
976
|
+
const list = new agent.MessageList().add(processedMessages, "memory");
|
|
977
|
+
if (format === `v2`) return list.get.all.v2();
|
|
978
|
+
return list.get.all.v1();
|
|
979
|
+
} catch (error$1) {
|
|
980
|
+
const mastraError = new error.MastraError(
|
|
981
|
+
{
|
|
982
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_MESSAGES_ERROR",
|
|
983
|
+
domain: error.ErrorDomain.STORAGE,
|
|
984
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
985
|
+
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
986
|
+
details: { threadId }
|
|
987
|
+
},
|
|
988
|
+
error$1
|
|
989
|
+
);
|
|
990
|
+
this.logger?.error(mastraError.toString());
|
|
991
|
+
this.logger?.trackException(mastraError);
|
|
992
|
+
throw mastraError;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
async getMessagesPaginated({
|
|
996
|
+
threadId,
|
|
997
|
+
selectBy,
|
|
998
|
+
format
|
|
999
|
+
}) {
|
|
1000
|
+
const { dateRange, page = 0, perPage = 40 } = selectBy?.pagination || {};
|
|
1001
|
+
const { start: fromDate, end: toDate } = dateRange || {};
|
|
1002
|
+
const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
1003
|
+
const messages = [];
|
|
1004
|
+
try {
|
|
1005
|
+
if (selectBy?.include?.length) {
|
|
1006
|
+
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
1007
|
+
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
1008
|
+
}
|
|
1009
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("thread_id = ?", threadId);
|
|
1010
|
+
if (fromDate) {
|
|
1011
|
+
countQuery.andWhere("createdAt >= ?", this.serializeDate(fromDate));
|
|
1012
|
+
}
|
|
1013
|
+
if (toDate) {
|
|
1014
|
+
countQuery.andWhere("createdAt <= ?", this.serializeDate(toDate));
|
|
1015
|
+
}
|
|
1016
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
1017
|
+
const total = Number(countResult[0]?.count ?? 0);
|
|
1018
|
+
const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId"]).from(fullTableName).where("thread_id = ?", threadId);
|
|
1019
|
+
if (fromDate) {
|
|
1020
|
+
query.andWhere("createdAt >= ?", this.serializeDate(fromDate));
|
|
1021
|
+
}
|
|
1022
|
+
if (toDate) {
|
|
1023
|
+
query.andWhere("createdAt <= ?", this.serializeDate(toDate));
|
|
1024
|
+
}
|
|
1025
|
+
query.orderBy("createdAt", "DESC").limit(perPage).offset(page * perPage);
|
|
1026
|
+
const results = await this.executeQuery(query.build());
|
|
1027
|
+
const list = new agent.MessageList().add(results, "memory");
|
|
1028
|
+
messages.push(...format === `v2` ? list.get.all.v2() : list.get.all.v1());
|
|
1029
|
+
return {
|
|
1030
|
+
messages,
|
|
1031
|
+
total,
|
|
1032
|
+
page,
|
|
1033
|
+
perPage,
|
|
1034
|
+
hasMore: page * perPage + messages.length < total
|
|
1035
|
+
};
|
|
1036
|
+
} catch (error$1) {
|
|
1037
|
+
const mastraError = new error.MastraError(
|
|
1038
|
+
{
|
|
1039
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_MESSAGES_PAGINATED_ERROR",
|
|
1040
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1041
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1042
|
+
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1043
|
+
details: { threadId }
|
|
1044
|
+
},
|
|
1045
|
+
error$1
|
|
1046
|
+
);
|
|
1047
|
+
this.logger?.error(mastraError.toString());
|
|
1048
|
+
this.logger?.trackException(mastraError);
|
|
1049
|
+
return {
|
|
1050
|
+
messages: [],
|
|
1051
|
+
total: 0,
|
|
1052
|
+
page,
|
|
1053
|
+
perPage,
|
|
1054
|
+
hasMore: false
|
|
1055
|
+
};
|
|
766
1056
|
}
|
|
767
1057
|
}
|
|
768
1058
|
async persistWorkflowSnapshot({
|
|
@@ -799,24 +1089,43 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
799
1089
|
const { sql, params } = query.build();
|
|
800
1090
|
try {
|
|
801
1091
|
await this.executeQuery({ sql, params });
|
|
802
|
-
} catch (error) {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
1092
|
+
} catch (error$1) {
|
|
1093
|
+
throw new error.MastraError(
|
|
1094
|
+
{
|
|
1095
|
+
id: "CLOUDFLARE_D1_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_ERROR",
|
|
1096
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1097
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1098
|
+
text: `Failed to persist workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1099
|
+
details: { workflowName, runId }
|
|
1100
|
+
},
|
|
1101
|
+
error$1
|
|
1102
|
+
);
|
|
807
1103
|
}
|
|
808
1104
|
}
|
|
809
1105
|
async loadWorkflowSnapshot(params) {
|
|
810
1106
|
const { workflowName, runId } = params;
|
|
811
1107
|
this.logger.debug("Loading workflow snapshot", { workflowName, runId });
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
1108
|
+
try {
|
|
1109
|
+
const d = await this.load({
|
|
1110
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
1111
|
+
keys: {
|
|
1112
|
+
workflow_name: workflowName,
|
|
1113
|
+
run_id: runId
|
|
1114
|
+
}
|
|
1115
|
+
});
|
|
1116
|
+
return d ? d.snapshot : null;
|
|
1117
|
+
} catch (error$1) {
|
|
1118
|
+
throw new error.MastraError(
|
|
1119
|
+
{
|
|
1120
|
+
id: "CLOUDFLARE_D1_STORAGE_LOAD_WORKFLOW_SNAPSHOT_ERROR",
|
|
1121
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1122
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1123
|
+
text: `Failed to load workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1124
|
+
details: { workflowName, runId }
|
|
1125
|
+
},
|
|
1126
|
+
error$1
|
|
1127
|
+
);
|
|
1128
|
+
}
|
|
820
1129
|
}
|
|
821
1130
|
/**
|
|
822
1131
|
* Insert multiple records in a batch operation
|
|
@@ -850,19 +1159,85 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
850
1159
|
);
|
|
851
1160
|
}
|
|
852
1161
|
this.logger.debug(`Successfully batch inserted ${records.length} records into ${tableName}`);
|
|
853
|
-
} catch (error) {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1162
|
+
} catch (error$1) {
|
|
1163
|
+
throw new error.MastraError(
|
|
1164
|
+
{
|
|
1165
|
+
id: "CLOUDFLARE_D1_STORAGE_BATCH_INSERT_ERROR",
|
|
1166
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1167
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1168
|
+
text: `Failed to batch insert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1169
|
+
details: { tableName }
|
|
1170
|
+
},
|
|
1171
|
+
error$1
|
|
1172
|
+
);
|
|
858
1173
|
}
|
|
859
1174
|
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Upsert multiple records in a batch operation
|
|
1177
|
+
* @param tableName The table to insert into
|
|
1178
|
+
* @param records The records to insert
|
|
1179
|
+
*/
|
|
1180
|
+
async batchUpsert({
|
|
1181
|
+
tableName,
|
|
1182
|
+
records
|
|
1183
|
+
}) {
|
|
1184
|
+
if (records.length === 0) return;
|
|
1185
|
+
const fullTableName = this.getTableName(tableName);
|
|
1186
|
+
try {
|
|
1187
|
+
const batchSize = 50;
|
|
1188
|
+
for (let i = 0; i < records.length; i += batchSize) {
|
|
1189
|
+
const batch = records.slice(i, i + batchSize);
|
|
1190
|
+
const recordsToInsert = batch;
|
|
1191
|
+
if (recordsToInsert.length > 0) {
|
|
1192
|
+
const firstRecord = recordsToInsert[0];
|
|
1193
|
+
const columns = Object.keys(firstRecord || {});
|
|
1194
|
+
for (const record of recordsToInsert) {
|
|
1195
|
+
const values = columns.map((col) => {
|
|
1196
|
+
if (!record) return null;
|
|
1197
|
+
const value = typeof col === "string" ? record[col] : null;
|
|
1198
|
+
return this.serializeValue(value);
|
|
1199
|
+
});
|
|
1200
|
+
const recordToUpsert = columns.reduce(
|
|
1201
|
+
(acc, col) => {
|
|
1202
|
+
if (col !== "createdAt") acc[col] = `excluded.${col}`;
|
|
1203
|
+
return acc;
|
|
1204
|
+
},
|
|
1205
|
+
{}
|
|
1206
|
+
);
|
|
1207
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], recordToUpsert);
|
|
1208
|
+
const { sql, params } = query.build();
|
|
1209
|
+
await this.executeQuery({ sql, params });
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
this.logger.debug(
|
|
1213
|
+
`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`
|
|
1214
|
+
);
|
|
1215
|
+
}
|
|
1216
|
+
this.logger.debug(`Successfully batch upserted ${records.length} records into ${tableName}`);
|
|
1217
|
+
} catch (error$1) {
|
|
1218
|
+
throw new error.MastraError(
|
|
1219
|
+
{
|
|
1220
|
+
id: "CLOUDFLARE_D1_STORAGE_BATCH_UPSERT_ERROR",
|
|
1221
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1222
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1223
|
+
text: `Failed to batch upsert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1224
|
+
details: { tableName }
|
|
1225
|
+
},
|
|
1226
|
+
error$1
|
|
1227
|
+
);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* @deprecated use getTracesPaginated instead
|
|
1232
|
+
*/
|
|
860
1233
|
async getTraces({
|
|
861
1234
|
name,
|
|
862
1235
|
scope,
|
|
863
1236
|
page,
|
|
864
1237
|
perPage,
|
|
865
|
-
attributes
|
|
1238
|
+
attributes,
|
|
1239
|
+
fromDate,
|
|
1240
|
+
toDate
|
|
866
1241
|
}) {
|
|
867
1242
|
const fullTableName = this.getTableName(storage.TABLE_TRACES);
|
|
868
1243
|
try {
|
|
@@ -878,22 +1253,114 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
878
1253
|
query.jsonLike("attributes", key, value);
|
|
879
1254
|
}
|
|
880
1255
|
}
|
|
881
|
-
|
|
1256
|
+
if (fromDate) {
|
|
1257
|
+
query.andWhere("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
1258
|
+
}
|
|
1259
|
+
if (toDate) {
|
|
1260
|
+
query.andWhere("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
1261
|
+
}
|
|
1262
|
+
query.orderBy("startTime", "DESC").limit(perPage).offset(page * perPage);
|
|
882
1263
|
const { sql, params } = query.build();
|
|
883
1264
|
const results = await this.executeQuery({ sql, params });
|
|
884
|
-
return isArrayOfRecords(results) ? results.map(
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
1265
|
+
return isArrayOfRecords(results) ? results.map(
|
|
1266
|
+
(trace) => ({
|
|
1267
|
+
...trace,
|
|
1268
|
+
attributes: this.deserializeValue(trace.attributes, "jsonb"),
|
|
1269
|
+
status: this.deserializeValue(trace.status, "jsonb"),
|
|
1270
|
+
events: this.deserializeValue(trace.events, "jsonb"),
|
|
1271
|
+
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1272
|
+
other: this.deserializeValue(trace.other, "jsonb")
|
|
1273
|
+
})
|
|
1274
|
+
) : [];
|
|
1275
|
+
} catch (error$1) {
|
|
1276
|
+
const mastraError = new error.MastraError(
|
|
1277
|
+
{
|
|
1278
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_TRACES_ERROR",
|
|
1279
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1280
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1281
|
+
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1282
|
+
details: {
|
|
1283
|
+
name: name ?? "",
|
|
1284
|
+
scope: scope ?? ""
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
error$1
|
|
1288
|
+
);
|
|
1289
|
+
this.logger?.error(mastraError.toString());
|
|
1290
|
+
this.logger?.trackException(mastraError);
|
|
894
1291
|
return [];
|
|
895
1292
|
}
|
|
896
1293
|
}
|
|
1294
|
+
async getTracesPaginated(args) {
|
|
1295
|
+
const { name, scope, page, perPage, attributes, fromDate, toDate } = args;
|
|
1296
|
+
const fullTableName = this.getTableName(storage.TABLE_TRACES);
|
|
1297
|
+
try {
|
|
1298
|
+
const dataQuery = createSqlBuilder().select("*").from(fullTableName).where("1=1");
|
|
1299
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("1=1");
|
|
1300
|
+
if (name) {
|
|
1301
|
+
dataQuery.andWhere("name LIKE ?", `%${name}%`);
|
|
1302
|
+
countQuery.andWhere("name LIKE ?", `%${name}%`);
|
|
1303
|
+
}
|
|
1304
|
+
if (scope) {
|
|
1305
|
+
dataQuery.andWhere("scope = ?", scope);
|
|
1306
|
+
countQuery.andWhere("scope = ?", scope);
|
|
1307
|
+
}
|
|
1308
|
+
if (attributes && Object.keys(attributes).length > 0) {
|
|
1309
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
1310
|
+
dataQuery.jsonLike("attributes", key, value);
|
|
1311
|
+
countQuery.jsonLike("attributes", key, value);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
if (fromDate) {
|
|
1315
|
+
const fromDateStr = fromDate instanceof Date ? fromDate.toISOString() : fromDate;
|
|
1316
|
+
dataQuery.andWhere("createdAt >= ?", fromDateStr);
|
|
1317
|
+
countQuery.andWhere("createdAt >= ?", fromDateStr);
|
|
1318
|
+
}
|
|
1319
|
+
if (toDate) {
|
|
1320
|
+
const toDateStr = toDate instanceof Date ? toDate.toISOString() : toDate;
|
|
1321
|
+
dataQuery.andWhere("createdAt <= ?", toDateStr);
|
|
1322
|
+
countQuery.andWhere("createdAt <= ?", toDateStr);
|
|
1323
|
+
}
|
|
1324
|
+
const countResult = await this.executeQuery(countQuery.build());
|
|
1325
|
+
const total = Number(countResult?.[0]?.count ?? 0);
|
|
1326
|
+
dataQuery.orderBy("startTime", "DESC").limit(perPage).offset(page * perPage);
|
|
1327
|
+
const results = await this.executeQuery(dataQuery.build());
|
|
1328
|
+
const traces = isArrayOfRecords(results) ? results.map(
|
|
1329
|
+
(trace) => ({
|
|
1330
|
+
...trace,
|
|
1331
|
+
attributes: this.deserializeValue(trace.attributes, "jsonb"),
|
|
1332
|
+
status: this.deserializeValue(trace.status, "jsonb"),
|
|
1333
|
+
events: this.deserializeValue(trace.events, "jsonb"),
|
|
1334
|
+
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1335
|
+
other: this.deserializeValue(trace.other, "jsonb")
|
|
1336
|
+
})
|
|
1337
|
+
) : [];
|
|
1338
|
+
return {
|
|
1339
|
+
traces,
|
|
1340
|
+
total,
|
|
1341
|
+
page,
|
|
1342
|
+
perPage,
|
|
1343
|
+
hasMore: page * perPage + traces.length < total
|
|
1344
|
+
};
|
|
1345
|
+
} catch (error$1) {
|
|
1346
|
+
const mastraError = new error.MastraError(
|
|
1347
|
+
{
|
|
1348
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_TRACES_ERROR",
|
|
1349
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1350
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1351
|
+
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1352
|
+
details: { name: name ?? "", scope: scope ?? "" }
|
|
1353
|
+
},
|
|
1354
|
+
error$1
|
|
1355
|
+
);
|
|
1356
|
+
this.logger?.error(mastraError.toString());
|
|
1357
|
+
this.logger?.trackException(mastraError);
|
|
1358
|
+
return { traces: [], total: 0, page, perPage, hasMore: false };
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* @deprecated use getEvals instead
|
|
1363
|
+
*/
|
|
897
1364
|
async getEvalsByAgentName(agentName, type) {
|
|
898
1365
|
const fullTableName = this.getTableName(storage.TABLE_EVALS);
|
|
899
1366
|
try {
|
|
@@ -922,15 +1389,222 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
922
1389
|
testInfo
|
|
923
1390
|
};
|
|
924
1391
|
}) : [];
|
|
925
|
-
} catch (error) {
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1392
|
+
} catch (error$1) {
|
|
1393
|
+
const mastraError = new error.MastraError(
|
|
1394
|
+
{
|
|
1395
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
1396
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1397
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1398
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1399
|
+
details: { agentName }
|
|
1400
|
+
},
|
|
1401
|
+
error$1
|
|
1402
|
+
);
|
|
1403
|
+
this.logger?.error(mastraError.toString());
|
|
1404
|
+
this.logger?.trackException(mastraError);
|
|
929
1405
|
return [];
|
|
930
1406
|
}
|
|
931
1407
|
}
|
|
932
|
-
|
|
933
|
-
|
|
1408
|
+
async getEvals(options) {
|
|
1409
|
+
const { agentName, type, page = 0, perPage = 40, fromDate, toDate } = options || {};
|
|
1410
|
+
const fullTableName = this.getTableName(storage.TABLE_EVALS);
|
|
1411
|
+
const conditions = [];
|
|
1412
|
+
const queryParams = [];
|
|
1413
|
+
if (agentName) {
|
|
1414
|
+
conditions.push(`agent_name = ?`);
|
|
1415
|
+
queryParams.push(agentName);
|
|
1416
|
+
}
|
|
1417
|
+
if (type === "test") {
|
|
1418
|
+
conditions.push(`(test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL)`);
|
|
1419
|
+
} else if (type === "live") {
|
|
1420
|
+
conditions.push(`(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)`);
|
|
1421
|
+
}
|
|
1422
|
+
if (fromDate) {
|
|
1423
|
+
conditions.push(`createdAt >= ?`);
|
|
1424
|
+
queryParams.push(this.serializeDate(fromDate));
|
|
1425
|
+
}
|
|
1426
|
+
if (toDate) {
|
|
1427
|
+
conditions.push(`createdAt <= ?`);
|
|
1428
|
+
queryParams.push(this.serializeDate(toDate));
|
|
1429
|
+
}
|
|
1430
|
+
const countQueryBuilder = createSqlBuilder().count().from(fullTableName);
|
|
1431
|
+
if (conditions.length > 0) {
|
|
1432
|
+
countQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
1433
|
+
}
|
|
1434
|
+
const { sql: countSql, params: countParams } = countQueryBuilder.build();
|
|
1435
|
+
try {
|
|
1436
|
+
const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
|
|
1437
|
+
const total = Number(countResult?.count || 0);
|
|
1438
|
+
const currentOffset = page * perPage;
|
|
1439
|
+
if (total === 0) {
|
|
1440
|
+
return {
|
|
1441
|
+
evals: [],
|
|
1442
|
+
total: 0,
|
|
1443
|
+
page,
|
|
1444
|
+
perPage,
|
|
1445
|
+
hasMore: false
|
|
1446
|
+
};
|
|
1447
|
+
}
|
|
1448
|
+
const dataQueryBuilder = createSqlBuilder().select("*").from(fullTableName);
|
|
1449
|
+
if (conditions.length > 0) {
|
|
1450
|
+
dataQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
1451
|
+
}
|
|
1452
|
+
dataQueryBuilder.orderBy("createdAt", "DESC").limit(perPage).offset(currentOffset);
|
|
1453
|
+
const { sql: dataSql, params: dataParams } = dataQueryBuilder.build();
|
|
1454
|
+
const rows = await this.executeQuery({ sql: dataSql, params: dataParams });
|
|
1455
|
+
const evals = (isArrayOfRecords(rows) ? rows : []).map((row) => {
|
|
1456
|
+
const result = this.deserializeValue(row.result);
|
|
1457
|
+
const testInfo = row.test_info ? this.deserializeValue(row.test_info) : void 0;
|
|
1458
|
+
if (!result || typeof result !== "object" || !("score" in result)) {
|
|
1459
|
+
throw new Error(`Invalid MetricResult format: ${JSON.stringify(result)}`);
|
|
1460
|
+
}
|
|
1461
|
+
return {
|
|
1462
|
+
input: row.input,
|
|
1463
|
+
output: row.output,
|
|
1464
|
+
result,
|
|
1465
|
+
agentName: row.agent_name,
|
|
1466
|
+
metricName: row.metric_name,
|
|
1467
|
+
instructions: row.instructions,
|
|
1468
|
+
testInfo,
|
|
1469
|
+
globalRunId: row.global_run_id,
|
|
1470
|
+
runId: row.run_id,
|
|
1471
|
+
createdAt: row.createdAt
|
|
1472
|
+
};
|
|
1473
|
+
});
|
|
1474
|
+
const hasMore = currentOffset + evals.length < total;
|
|
1475
|
+
return {
|
|
1476
|
+
evals,
|
|
1477
|
+
total,
|
|
1478
|
+
page,
|
|
1479
|
+
perPage,
|
|
1480
|
+
hasMore
|
|
1481
|
+
};
|
|
1482
|
+
} catch (error$1) {
|
|
1483
|
+
throw new error.MastraError(
|
|
1484
|
+
{
|
|
1485
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
1486
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1487
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1488
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1489
|
+
details: { agentName: agentName ?? "", type: type ?? "" }
|
|
1490
|
+
},
|
|
1491
|
+
error$1
|
|
1492
|
+
);
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
parseWorkflowRun(row) {
|
|
1496
|
+
let parsedSnapshot = row.snapshot;
|
|
1497
|
+
if (typeof parsedSnapshot === "string") {
|
|
1498
|
+
try {
|
|
1499
|
+
parsedSnapshot = JSON.parse(row.snapshot);
|
|
1500
|
+
} catch (e) {
|
|
1501
|
+
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
return {
|
|
1505
|
+
workflowName: row.workflow_name,
|
|
1506
|
+
runId: row.run_id,
|
|
1507
|
+
snapshot: parsedSnapshot,
|
|
1508
|
+
createdAt: this.ensureDate(row.createdAt),
|
|
1509
|
+
updatedAt: this.ensureDate(row.updatedAt),
|
|
1510
|
+
resourceId: row.resourceId
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
async hasColumn(table, column) {
|
|
1514
|
+
const sql = `PRAGMA table_info(${table});`;
|
|
1515
|
+
const result = await this.executeQuery({ sql, params: [] });
|
|
1516
|
+
if (!result || !Array.isArray(result)) return false;
|
|
1517
|
+
return result.some((col) => col.name === column || col.name === column.toLowerCase());
|
|
1518
|
+
}
|
|
1519
|
+
async getWorkflowRuns({
|
|
1520
|
+
workflowName,
|
|
1521
|
+
fromDate,
|
|
1522
|
+
toDate,
|
|
1523
|
+
limit,
|
|
1524
|
+
offset,
|
|
1525
|
+
resourceId
|
|
1526
|
+
} = {}) {
|
|
1527
|
+
const fullTableName = this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1528
|
+
try {
|
|
1529
|
+
const builder = createSqlBuilder().select().from(fullTableName);
|
|
1530
|
+
const countBuilder = createSqlBuilder().count().from(fullTableName);
|
|
1531
|
+
if (workflowName) builder.whereAnd("workflow_name = ?", workflowName);
|
|
1532
|
+
if (resourceId) {
|
|
1533
|
+
const hasResourceId = await this.hasColumn(fullTableName, "resourceId");
|
|
1534
|
+
if (hasResourceId) {
|
|
1535
|
+
builder.whereAnd("resourceId = ?", resourceId);
|
|
1536
|
+
countBuilder.whereAnd("resourceId = ?", resourceId);
|
|
1537
|
+
} else {
|
|
1538
|
+
console.warn(`[${fullTableName}] resourceId column not found. Skipping resourceId filter.`);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
if (fromDate) {
|
|
1542
|
+
builder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
1543
|
+
countBuilder.whereAnd("createdAt >= ?", fromDate instanceof Date ? fromDate.toISOString() : fromDate);
|
|
1544
|
+
}
|
|
1545
|
+
if (toDate) {
|
|
1546
|
+
builder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
1547
|
+
countBuilder.whereAnd("createdAt <= ?", toDate instanceof Date ? toDate.toISOString() : toDate);
|
|
1548
|
+
}
|
|
1549
|
+
builder.orderBy("createdAt", "DESC");
|
|
1550
|
+
if (typeof limit === "number") builder.limit(limit);
|
|
1551
|
+
if (typeof offset === "number") builder.offset(offset);
|
|
1552
|
+
const { sql, params } = builder.build();
|
|
1553
|
+
let total = 0;
|
|
1554
|
+
if (limit !== void 0 && offset !== void 0) {
|
|
1555
|
+
const { sql: countSql, params: countParams } = countBuilder.build();
|
|
1556
|
+
const countResult = await this.executeQuery({ sql: countSql, params: countParams, first: true });
|
|
1557
|
+
total = Number(countResult?.count ?? 0);
|
|
1558
|
+
}
|
|
1559
|
+
const results = await this.executeQuery({ sql, params });
|
|
1560
|
+
const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
|
|
1561
|
+
return { runs, total: total || runs.length };
|
|
1562
|
+
} catch (error$1) {
|
|
1563
|
+
throw new error.MastraError(
|
|
1564
|
+
{
|
|
1565
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_WORKFLOW_RUNS_ERROR",
|
|
1566
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1567
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1568
|
+
text: `Failed to retrieve workflow runs: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1569
|
+
details: { workflowName: workflowName ?? "", resourceId: resourceId ?? "" }
|
|
1570
|
+
},
|
|
1571
|
+
error$1
|
|
1572
|
+
);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
async getWorkflowRunById({
|
|
1576
|
+
runId,
|
|
1577
|
+
workflowName
|
|
1578
|
+
}) {
|
|
1579
|
+
const fullTableName = this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1580
|
+
try {
|
|
1581
|
+
const conditions = [];
|
|
1582
|
+
const params = [];
|
|
1583
|
+
if (runId) {
|
|
1584
|
+
conditions.push("run_id = ?");
|
|
1585
|
+
params.push(runId);
|
|
1586
|
+
}
|
|
1587
|
+
if (workflowName) {
|
|
1588
|
+
conditions.push("workflow_name = ?");
|
|
1589
|
+
params.push(workflowName);
|
|
1590
|
+
}
|
|
1591
|
+
const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
|
|
1592
|
+
const sql = `SELECT * FROM ${fullTableName} ${whereClause} ORDER BY createdAt DESC LIMIT 1`;
|
|
1593
|
+
const result = await this.executeQuery({ sql, params, first: true });
|
|
1594
|
+
if (!result) return null;
|
|
1595
|
+
return this.parseWorkflowRun(result);
|
|
1596
|
+
} catch (error$1) {
|
|
1597
|
+
throw new error.MastraError(
|
|
1598
|
+
{
|
|
1599
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_WORKFLOW_RUN_BY_ID_ERROR",
|
|
1600
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1601
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1602
|
+
text: `Failed to retrieve workflow run by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1603
|
+
details: { runId, workflowName: workflowName ?? "" }
|
|
1604
|
+
},
|
|
1605
|
+
error$1
|
|
1606
|
+
);
|
|
1607
|
+
}
|
|
934
1608
|
}
|
|
935
1609
|
/**
|
|
936
1610
|
* Close the database connection
|
|
@@ -939,6 +1613,10 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
939
1613
|
async close() {
|
|
940
1614
|
this.logger.debug("Closing D1 connection");
|
|
941
1615
|
}
|
|
1616
|
+
async updateMessages(_args) {
|
|
1617
|
+
this.logger.error("updateMessages is not yet implemented in CloudflareD1Store");
|
|
1618
|
+
throw new Error("Method not implemented");
|
|
1619
|
+
}
|
|
942
1620
|
};
|
|
943
1621
|
|
|
944
1622
|
exports.D1Store = D1Store;
|