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