@mastra/cloudflare-d1 0.0.0-share-agent-metadata-with-cloud-20250718110128 → 0.0.0-sidebar-window-undefined-fix-20251029233656
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1232 -0
- package/dist/index.cjs +1450 -727
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1451 -728
- package/dist/index.js.map +1 -0
- package/dist/storage/domains/legacy-evals/index.d.ts +20 -0
- package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +90 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -0
- package/dist/storage/domains/operations/index.d.ts +72 -0
- package/dist/storage/domains/operations/index.d.ts.map +1 -0
- package/dist/storage/domains/scores/index.d.ts +60 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -0
- package/dist/storage/domains/utils.d.ts +3 -0
- package/dist/storage/domains/utils.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +52 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +279 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/sql-builder.d.ts +128 -0
- package/dist/storage/sql-builder.d.ts.map +1 -0
- package/dist/storage/test-utils.d.ts +19 -0
- package/dist/storage/test-utils.d.ts.map +1 -0
- package/package.json +24 -13
- package/dist/_tsup-dts-rollup.d.cts +0 -422
- package/dist/_tsup-dts-rollup.d.ts +0 -422
- package/dist/index.d.cts +0 -7
package/dist/index.cjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var agent = require('@mastra/core/agent');
|
|
4
3
|
var error = require('@mastra/core/error');
|
|
5
4
|
var storage = require('@mastra/core/storage');
|
|
6
5
|
var Cloudflare = require('cloudflare');
|
|
7
6
|
var utils = require('@mastra/core/utils');
|
|
7
|
+
var agent = require('@mastra/core/agent');
|
|
8
|
+
var scores = require('@mastra/core/scores');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
|
|
@@ -241,402 +242,291 @@ function parseSelectIdentifier(column) {
|
|
|
241
242
|
return column;
|
|
242
243
|
}
|
|
243
244
|
|
|
244
|
-
// src/storage/
|
|
245
|
+
// src/storage/domains/utils.ts
|
|
245
246
|
function isArrayOfRecords(value) {
|
|
246
247
|
return value && Array.isArray(value) && value.length > 0;
|
|
247
248
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
// D1Database binding
|
|
252
|
-
tablePrefix;
|
|
253
|
-
/**
|
|
254
|
-
* Creates a new D1Store instance
|
|
255
|
-
* @param config Configuration for D1 access (either REST API or Workers Binding API)
|
|
256
|
-
*/
|
|
257
|
-
constructor(config) {
|
|
249
|
+
function deserializeValue(value, type) {
|
|
250
|
+
if (value === null || value === void 0) return null;
|
|
251
|
+
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
|
|
258
252
|
try {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
263
|
-
this.tablePrefix = config.tablePrefix || "";
|
|
264
|
-
if ("binding" in config) {
|
|
265
|
-
if (!config.binding) {
|
|
266
|
-
throw new Error("D1 binding is required when using Workers Binding API");
|
|
267
|
-
}
|
|
268
|
-
this.binding = config.binding;
|
|
269
|
-
this.logger.info("Using D1 Workers Binding API");
|
|
270
|
-
} else if ("client" in config) {
|
|
271
|
-
if (!config.client) {
|
|
272
|
-
throw new Error("D1 client is required when using D1ClientConfig");
|
|
273
|
-
}
|
|
274
|
-
this.client = config.client;
|
|
275
|
-
this.logger.info("Using D1 Client");
|
|
276
|
-
} else {
|
|
277
|
-
if (!config.accountId || !config.databaseId || !config.apiToken) {
|
|
278
|
-
throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
279
|
-
}
|
|
280
|
-
const cfClient = new Cloudflare__default.default({
|
|
281
|
-
apiToken: config.apiToken
|
|
282
|
-
});
|
|
283
|
-
this.client = {
|
|
284
|
-
query: ({ sql, params }) => {
|
|
285
|
-
return cfClient.d1.database.query(config.databaseId, {
|
|
286
|
-
account_id: config.accountId,
|
|
287
|
-
sql,
|
|
288
|
-
params
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
this.logger.info("Using D1 REST API");
|
|
293
|
-
}
|
|
294
|
-
} catch (error$1) {
|
|
295
|
-
throw new error.MastraError(
|
|
296
|
-
{
|
|
297
|
-
id: "CLOUDFLARE_D1_STORAGE_INITIALIZATION_ERROR",
|
|
298
|
-
domain: error.ErrorDomain.STORAGE,
|
|
299
|
-
category: error.ErrorCategory.SYSTEM,
|
|
300
|
-
text: "Error initializing D1Store"
|
|
301
|
-
},
|
|
302
|
-
error$1
|
|
303
|
-
);
|
|
253
|
+
return JSON.parse(value);
|
|
254
|
+
} catch {
|
|
255
|
+
return value;
|
|
304
256
|
}
|
|
305
257
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
258
|
+
return value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/storage/domains/legacy-evals/index.ts
|
|
262
|
+
var LegacyEvalsStorageD1 = class extends storage.LegacyEvalsStorage {
|
|
263
|
+
operations;
|
|
264
|
+
constructor({ operations }) {
|
|
265
|
+
super();
|
|
266
|
+
this.operations = operations;
|
|
312
267
|
}
|
|
313
|
-
async
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
if (
|
|
319
|
-
|
|
268
|
+
async getEvals(options) {
|
|
269
|
+
const { agentName, type, page = 0, perPage = 40, dateRange } = options || {};
|
|
270
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_EVALS);
|
|
271
|
+
const conditions = [];
|
|
272
|
+
const queryParams = [];
|
|
273
|
+
if (agentName) {
|
|
274
|
+
conditions.push(`agent_name = ?`);
|
|
275
|
+
queryParams.push(agentName);
|
|
320
276
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (formattedParams.length > 0) {
|
|
326
|
-
if (first) {
|
|
327
|
-
result = await statement.bind(...formattedParams).first();
|
|
328
|
-
if (!result) return null;
|
|
329
|
-
return result;
|
|
330
|
-
} else {
|
|
331
|
-
result = await statement.bind(...formattedParams).all();
|
|
332
|
-
const results = result.results || [];
|
|
333
|
-
if (result.meta) {
|
|
334
|
-
this.logger.debug("Query metadata", { meta: result.meta });
|
|
335
|
-
}
|
|
336
|
-
return results;
|
|
337
|
-
}
|
|
338
|
-
} else {
|
|
339
|
-
if (first) {
|
|
340
|
-
result = await statement.first();
|
|
341
|
-
if (!result) return null;
|
|
342
|
-
return result;
|
|
343
|
-
} else {
|
|
344
|
-
result = await statement.all();
|
|
345
|
-
const results = result.results || [];
|
|
346
|
-
if (result.meta) {
|
|
347
|
-
this.logger.debug("Query metadata", { meta: result.meta });
|
|
348
|
-
}
|
|
349
|
-
return results;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
} catch (workerError) {
|
|
353
|
-
this.logger.error("Workers Binding API error", {
|
|
354
|
-
message: workerError instanceof Error ? workerError.message : String(workerError),
|
|
355
|
-
sql
|
|
356
|
-
});
|
|
357
|
-
throw new Error(`D1 Workers API error: ${workerError.message}`);
|
|
277
|
+
if (type === "test") {
|
|
278
|
+
conditions.push(`(test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL)`);
|
|
279
|
+
} else if (type === "live") {
|
|
280
|
+
conditions.push(`(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)`);
|
|
358
281
|
}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
params = [],
|
|
363
|
-
first = false
|
|
364
|
-
}) {
|
|
365
|
-
if (!this.client) {
|
|
366
|
-
throw new Error("Missing required REST API configuration");
|
|
282
|
+
if (dateRange?.start) {
|
|
283
|
+
conditions.push(`created_at >= ?`);
|
|
284
|
+
queryParams.push(storage.serializeDate(dateRange.start));
|
|
367
285
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
params: this.formatSqlParams(params)
|
|
372
|
-
});
|
|
373
|
-
const result = response.result || [];
|
|
374
|
-
const results = result.flatMap((r) => r.results || []);
|
|
375
|
-
if (first) {
|
|
376
|
-
const firstResult = isArrayOfRecords(results) && results.length > 0 ? results[0] : null;
|
|
377
|
-
if (!firstResult) return null;
|
|
378
|
-
return firstResult;
|
|
379
|
-
}
|
|
380
|
-
return results;
|
|
381
|
-
} catch (restError) {
|
|
382
|
-
this.logger.error("REST API error", {
|
|
383
|
-
message: restError instanceof Error ? restError.message : String(restError),
|
|
384
|
-
sql
|
|
385
|
-
});
|
|
386
|
-
throw new Error(`D1 REST API error: ${restError.message}`);
|
|
286
|
+
if (dateRange?.end) {
|
|
287
|
+
conditions.push(`created_at <= ?`);
|
|
288
|
+
queryParams.push(storage.serializeDate(dateRange.end));
|
|
387
289
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
* @param options Query options including SQL, parameters, and whether to return only the first result
|
|
392
|
-
* @returns Query results as an array or a single object if first=true
|
|
393
|
-
*/
|
|
394
|
-
async executeQuery(options) {
|
|
395
|
-
const { sql, params = [], first = false } = options;
|
|
396
|
-
try {
|
|
397
|
-
this.logger.debug("Executing SQL query", { sql, params, first });
|
|
398
|
-
if (this.binding) {
|
|
399
|
-
return this.executeWorkersBindingQuery({ sql, params, first });
|
|
400
|
-
} else if (this.client) {
|
|
401
|
-
return this.executeRestQuery({ sql, params, first });
|
|
402
|
-
} else {
|
|
403
|
-
throw new Error("No valid D1 configuration provided");
|
|
404
|
-
}
|
|
405
|
-
} catch (error) {
|
|
406
|
-
this.logger.error("Error executing SQL query", {
|
|
407
|
-
message: error instanceof Error ? error.message : String(error),
|
|
408
|
-
sql,
|
|
409
|
-
params,
|
|
410
|
-
first
|
|
411
|
-
});
|
|
412
|
-
throw new Error(`D1 query error: ${error.message}`);
|
|
290
|
+
const countQueryBuilder = createSqlBuilder().count().from(fullTableName);
|
|
291
|
+
if (conditions.length > 0) {
|
|
292
|
+
countQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
413
293
|
}
|
|
414
|
-
|
|
415
|
-
// Helper to get existing table columns
|
|
416
|
-
async getTableColumns(tableName) {
|
|
294
|
+
const { sql: countSql, params: countParams } = countQueryBuilder.build();
|
|
417
295
|
try {
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
}
|
|
423
|
-
return result.map((row) => ({
|
|
424
|
-
name: row.name,
|
|
425
|
-
type: row.type
|
|
426
|
-
}));
|
|
427
|
-
} catch (error) {
|
|
428
|
-
this.logger.error(`Error getting table columns for ${tableName}:`, {
|
|
429
|
-
message: error instanceof Error ? error.message : String(error)
|
|
296
|
+
const countResult = await this.operations.executeQuery({
|
|
297
|
+
sql: countSql,
|
|
298
|
+
params: countParams,
|
|
299
|
+
first: true
|
|
430
300
|
});
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
return JSON.stringify(value);
|
|
442
|
-
}
|
|
443
|
-
return value;
|
|
444
|
-
}
|
|
445
|
-
// Helper to deserialize JSON strings to objects
|
|
446
|
-
deserializeValue(value, type) {
|
|
447
|
-
if (value === null || value === void 0) return null;
|
|
448
|
-
if (type === "date" && typeof value === "string") {
|
|
449
|
-
return new Date(value);
|
|
450
|
-
}
|
|
451
|
-
if (type === "jsonb" && typeof value === "string") {
|
|
452
|
-
try {
|
|
453
|
-
return JSON.parse(value);
|
|
454
|
-
} catch {
|
|
455
|
-
return value;
|
|
301
|
+
const total = Number(countResult?.count || 0);
|
|
302
|
+
const currentOffset = page * perPage;
|
|
303
|
+
if (total === 0) {
|
|
304
|
+
return {
|
|
305
|
+
evals: [],
|
|
306
|
+
total: 0,
|
|
307
|
+
page,
|
|
308
|
+
perPage,
|
|
309
|
+
hasMore: false
|
|
310
|
+
};
|
|
456
311
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return JSON.parse(value);
|
|
461
|
-
} catch {
|
|
462
|
-
return value;
|
|
312
|
+
const dataQueryBuilder = createSqlBuilder().select("*").from(fullTableName);
|
|
313
|
+
if (conditions.length > 0) {
|
|
314
|
+
dataQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
463
315
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
return
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return `${colName} ${type} ${nullable} ${primaryKey}`.trim();
|
|
489
|
-
});
|
|
490
|
-
const tableConstraints = [];
|
|
491
|
-
if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
|
|
492
|
-
tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
493
|
-
}
|
|
494
|
-
try {
|
|
495
|
-
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
496
|
-
const { sql, params } = query.build();
|
|
497
|
-
await this.executeQuery({ sql, params });
|
|
498
|
-
this.logger.debug(`Created table ${fullTableName}`);
|
|
499
|
-
} catch (error$1) {
|
|
500
|
-
this.logger.error(`Error creating table ${fullTableName}:`, {
|
|
501
|
-
message: error$1 instanceof Error ? error$1.message : String(error$1)
|
|
316
|
+
dataQueryBuilder.orderBy("created_at", "DESC").limit(perPage).offset(currentOffset);
|
|
317
|
+
const { sql: dataSql, params: dataParams } = dataQueryBuilder.build();
|
|
318
|
+
const rows = await this.operations.executeQuery({
|
|
319
|
+
sql: dataSql,
|
|
320
|
+
params: dataParams
|
|
321
|
+
});
|
|
322
|
+
const evals = (isArrayOfRecords(rows) ? rows : []).map((row) => {
|
|
323
|
+
const result = deserializeValue(row.result);
|
|
324
|
+
const testInfo = row.test_info ? deserializeValue(row.test_info) : void 0;
|
|
325
|
+
if (!result || typeof result !== "object" || !("score" in result)) {
|
|
326
|
+
throw new Error(`Invalid MetricResult format: ${JSON.stringify(result)}`);
|
|
327
|
+
}
|
|
328
|
+
return {
|
|
329
|
+
input: row.input,
|
|
330
|
+
output: row.output,
|
|
331
|
+
result,
|
|
332
|
+
agentName: row.agent_name,
|
|
333
|
+
metricName: row.metric_name,
|
|
334
|
+
instructions: row.instructions,
|
|
335
|
+
testInfo,
|
|
336
|
+
globalRunId: row.global_run_id,
|
|
337
|
+
runId: row.run_id,
|
|
338
|
+
createdAt: row.created_at
|
|
339
|
+
};
|
|
502
340
|
});
|
|
341
|
+
const hasMore = currentOffset + evals.length < total;
|
|
342
|
+
return {
|
|
343
|
+
evals,
|
|
344
|
+
total,
|
|
345
|
+
page,
|
|
346
|
+
perPage,
|
|
347
|
+
hasMore
|
|
348
|
+
};
|
|
349
|
+
} catch (error$1) {
|
|
503
350
|
throw new error.MastraError(
|
|
504
351
|
{
|
|
505
|
-
id: "
|
|
352
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
506
353
|
domain: error.ErrorDomain.STORAGE,
|
|
507
354
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
508
|
-
text: `Failed to
|
|
509
|
-
details: {
|
|
355
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
356
|
+
details: { agentName: agentName ?? "", type: type ?? "" }
|
|
510
357
|
},
|
|
511
358
|
error$1
|
|
512
359
|
);
|
|
513
360
|
}
|
|
514
361
|
}
|
|
515
362
|
/**
|
|
516
|
-
*
|
|
517
|
-
* @param tableName Name of the table
|
|
518
|
-
* @param schema Schema of the table
|
|
519
|
-
* @param ifNotExists Array of column names to add if they don't exist
|
|
363
|
+
* @deprecated use getEvals instead
|
|
520
364
|
*/
|
|
521
|
-
async
|
|
522
|
-
|
|
523
|
-
schema,
|
|
524
|
-
ifNotExists
|
|
525
|
-
}) {
|
|
526
|
-
const fullTableName = this.getTableName(tableName);
|
|
365
|
+
async getEvalsByAgentName(agentName, type) {
|
|
366
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_EVALS);
|
|
527
367
|
try {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
const sqlType = this.getSqlType(columnDef.type);
|
|
534
|
-
const nullable = columnDef.nullable === false ? "NOT NULL" : "";
|
|
535
|
-
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
536
|
-
const alterSql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${sqlType} ${nullable} ${defaultValue}`.trim();
|
|
537
|
-
await this.executeQuery({ sql: alterSql, params: [] });
|
|
538
|
-
this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
|
|
539
|
-
}
|
|
368
|
+
let query = createSqlBuilder().select("*").from(fullTableName).where("agent_name = ?", agentName);
|
|
369
|
+
if (type === "test") {
|
|
370
|
+
query = query.andWhere("test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL");
|
|
371
|
+
} else if (type === "live") {
|
|
372
|
+
query = query.andWhere("(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)");
|
|
540
373
|
}
|
|
374
|
+
query.orderBy("created_at", "DESC");
|
|
375
|
+
const { sql, params } = query.build();
|
|
376
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
377
|
+
return isArrayOfRecords(results) ? results.map((row) => {
|
|
378
|
+
const result = deserializeValue(row.result);
|
|
379
|
+
const testInfo = row.test_info ? deserializeValue(row.test_info) : void 0;
|
|
380
|
+
return {
|
|
381
|
+
input: row.input || "",
|
|
382
|
+
output: row.output || "",
|
|
383
|
+
result,
|
|
384
|
+
agentName: row.agent_name || "",
|
|
385
|
+
metricName: row.metric_name || "",
|
|
386
|
+
instructions: row.instructions || "",
|
|
387
|
+
runId: row.run_id || "",
|
|
388
|
+
globalRunId: row.global_run_id || "",
|
|
389
|
+
createdAt: row.created_at || "",
|
|
390
|
+
testInfo
|
|
391
|
+
};
|
|
392
|
+
}) : [];
|
|
541
393
|
} catch (error$1) {
|
|
542
|
-
|
|
394
|
+
const mastraError = new error.MastraError(
|
|
543
395
|
{
|
|
544
|
-
id: "
|
|
396
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_EVALS_ERROR",
|
|
545
397
|
domain: error.ErrorDomain.STORAGE,
|
|
546
398
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
547
|
-
text: `Failed to
|
|
548
|
-
details: {
|
|
399
|
+
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
400
|
+
details: { agentName }
|
|
549
401
|
},
|
|
550
402
|
error$1
|
|
551
403
|
);
|
|
404
|
+
this.logger?.error(mastraError.toString());
|
|
405
|
+
this.logger?.trackException(mastraError);
|
|
406
|
+
return [];
|
|
552
407
|
}
|
|
553
408
|
}
|
|
554
|
-
|
|
555
|
-
|
|
409
|
+
};
|
|
410
|
+
var MemoryStorageD1 = class extends storage.MemoryStorage {
|
|
411
|
+
operations;
|
|
412
|
+
constructor({ operations }) {
|
|
413
|
+
super();
|
|
414
|
+
this.operations = operations;
|
|
415
|
+
}
|
|
416
|
+
async getResourceById({ resourceId }) {
|
|
417
|
+
const resource = await this.operations.load({
|
|
418
|
+
tableName: storage.TABLE_RESOURCES,
|
|
419
|
+
keys: { id: resourceId }
|
|
420
|
+
});
|
|
421
|
+
if (!resource) return null;
|
|
556
422
|
try {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
423
|
+
return {
|
|
424
|
+
...resource,
|
|
425
|
+
createdAt: storage.ensureDate(resource.createdAt),
|
|
426
|
+
updatedAt: storage.ensureDate(resource.updatedAt),
|
|
427
|
+
metadata: typeof resource.metadata === "string" ? JSON.parse(resource.metadata || "{}") : resource.metadata
|
|
428
|
+
};
|
|
561
429
|
} catch (error$1) {
|
|
562
|
-
|
|
430
|
+
const mastraError = new error.MastraError(
|
|
563
431
|
{
|
|
564
|
-
id: "
|
|
432
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_RESOURCE_BY_ID_ERROR",
|
|
565
433
|
domain: error.ErrorDomain.STORAGE,
|
|
566
434
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
567
|
-
text: `
|
|
568
|
-
details: {
|
|
435
|
+
text: `Error processing resource ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
436
|
+
details: { resourceId }
|
|
569
437
|
},
|
|
570
438
|
error$1
|
|
571
439
|
);
|
|
440
|
+
this.logger?.error(mastraError.toString());
|
|
441
|
+
this.logger?.trackException(mastraError);
|
|
442
|
+
return null;
|
|
572
443
|
}
|
|
573
444
|
}
|
|
574
|
-
async
|
|
575
|
-
const
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
const processedRecord = await this.processRecord(
|
|
445
|
+
async saveResource({ resource }) {
|
|
446
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_RESOURCES);
|
|
447
|
+
const resourceToSave = {
|
|
448
|
+
id: resource.id,
|
|
449
|
+
workingMemory: resource.workingMemory,
|
|
450
|
+
metadata: resource.metadata ? JSON.stringify(resource.metadata) : null,
|
|
451
|
+
createdAt: resource.createdAt,
|
|
452
|
+
updatedAt: resource.updatedAt
|
|
453
|
+
};
|
|
454
|
+
const processedRecord = await this.operations.processRecord(resourceToSave);
|
|
584
455
|
const columns = Object.keys(processedRecord);
|
|
585
456
|
const values = Object.values(processedRecord);
|
|
586
|
-
const
|
|
457
|
+
const updateMap = {
|
|
458
|
+
workingMemory: "excluded.workingMemory",
|
|
459
|
+
metadata: "excluded.metadata",
|
|
460
|
+
createdAt: "excluded.createdAt",
|
|
461
|
+
updatedAt: "excluded.updatedAt"
|
|
462
|
+
};
|
|
463
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], updateMap);
|
|
587
464
|
const { sql, params } = query.build();
|
|
588
465
|
try {
|
|
589
|
-
await this.executeQuery({ sql, params });
|
|
466
|
+
await this.operations.executeQuery({ sql, params });
|
|
467
|
+
return resource;
|
|
590
468
|
} catch (error$1) {
|
|
591
469
|
throw new error.MastraError(
|
|
592
470
|
{
|
|
593
|
-
id: "
|
|
471
|
+
id: "CLOUDFLARE_D1_STORAGE_SAVE_RESOURCE_ERROR",
|
|
594
472
|
domain: error.ErrorDomain.STORAGE,
|
|
595
473
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
596
|
-
text: `Failed to
|
|
597
|
-
details: {
|
|
474
|
+
text: `Failed to save resource to ${fullTableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
475
|
+
details: { resourceId: resource.id }
|
|
598
476
|
},
|
|
599
477
|
error$1
|
|
600
478
|
);
|
|
601
479
|
}
|
|
602
480
|
}
|
|
603
|
-
async
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
481
|
+
async updateResource({
|
|
482
|
+
resourceId,
|
|
483
|
+
workingMemory,
|
|
484
|
+
metadata
|
|
485
|
+
}) {
|
|
486
|
+
const existingResource = await this.getResourceById({ resourceId });
|
|
487
|
+
if (!existingResource) {
|
|
488
|
+
const newResource = {
|
|
489
|
+
id: resourceId,
|
|
490
|
+
workingMemory,
|
|
491
|
+
metadata: metadata || {},
|
|
492
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
493
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
494
|
+
};
|
|
495
|
+
return this.saveResource({ resource: newResource });
|
|
614
496
|
}
|
|
615
|
-
|
|
497
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
498
|
+
const updatedResource = {
|
|
499
|
+
...existingResource,
|
|
500
|
+
workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
|
|
501
|
+
metadata: {
|
|
502
|
+
...existingResource.metadata,
|
|
503
|
+
...metadata
|
|
504
|
+
},
|
|
505
|
+
updatedAt
|
|
506
|
+
};
|
|
507
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_RESOURCES);
|
|
508
|
+
const columns = ["workingMemory", "metadata", "updatedAt"];
|
|
509
|
+
const values = [updatedResource.workingMemory, JSON.stringify(updatedResource.metadata), updatedAt.toISOString()];
|
|
510
|
+
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", resourceId);
|
|
616
511
|
const { sql, params } = query.build();
|
|
617
512
|
try {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
const processedResult = {};
|
|
621
|
-
for (const [key, value] of Object.entries(result)) {
|
|
622
|
-
processedResult[key] = this.deserializeValue(value);
|
|
623
|
-
}
|
|
624
|
-
return processedResult;
|
|
513
|
+
await this.operations.executeQuery({ sql, params });
|
|
514
|
+
return updatedResource;
|
|
625
515
|
} catch (error$1) {
|
|
626
516
|
throw new error.MastraError(
|
|
627
517
|
{
|
|
628
|
-
id: "
|
|
518
|
+
id: "CLOUDFLARE_D1_STORAGE_UPDATE_RESOURCE_ERROR",
|
|
629
519
|
domain: error.ErrorDomain.STORAGE,
|
|
630
520
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
631
|
-
text: `Failed to
|
|
632
|
-
details: {
|
|
521
|
+
text: `Failed to update resource ${resourceId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
522
|
+
details: { resourceId }
|
|
633
523
|
},
|
|
634
524
|
error$1
|
|
635
525
|
);
|
|
636
526
|
}
|
|
637
527
|
}
|
|
638
528
|
async getThreadById({ threadId }) {
|
|
639
|
-
const thread = await this.load({
|
|
529
|
+
const thread = await this.operations.load({
|
|
640
530
|
tableName: storage.TABLE_THREADS,
|
|
641
531
|
keys: { id: threadId }
|
|
642
532
|
});
|
|
@@ -644,8 +534,8 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
644
534
|
try {
|
|
645
535
|
return {
|
|
646
536
|
...thread,
|
|
647
|
-
createdAt:
|
|
648
|
-
updatedAt:
|
|
537
|
+
createdAt: storage.ensureDate(thread.createdAt),
|
|
538
|
+
updatedAt: storage.ensureDate(thread.updatedAt),
|
|
649
539
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
650
540
|
};
|
|
651
541
|
} catch (error$1) {
|
|
@@ -668,15 +558,15 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
668
558
|
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
669
559
|
*/
|
|
670
560
|
async getThreadsByResourceId({ resourceId }) {
|
|
671
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
561
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
672
562
|
try {
|
|
673
563
|
const query = createSqlBuilder().select("*").from(fullTableName).where("resourceId = ?", resourceId);
|
|
674
564
|
const { sql, params } = query.build();
|
|
675
|
-
const results = await this.executeQuery({ sql, params });
|
|
565
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
676
566
|
return (isArrayOfRecords(results) ? results : []).map((thread) => ({
|
|
677
567
|
...thread,
|
|
678
|
-
createdAt:
|
|
679
|
-
updatedAt:
|
|
568
|
+
createdAt: storage.ensureDate(thread.createdAt),
|
|
569
|
+
updatedAt: storage.ensureDate(thread.updatedAt),
|
|
680
570
|
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata || "{}") : thread.metadata || {}
|
|
681
571
|
}));
|
|
682
572
|
} catch (error$1) {
|
|
@@ -697,19 +587,19 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
697
587
|
}
|
|
698
588
|
async getThreadsByResourceIdPaginated(args) {
|
|
699
589
|
const { resourceId, page, perPage } = args;
|
|
700
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
590
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
701
591
|
const mapRowToStorageThreadType = (row) => ({
|
|
702
592
|
...row,
|
|
703
|
-
createdAt:
|
|
704
|
-
updatedAt:
|
|
593
|
+
createdAt: storage.ensureDate(row.createdAt),
|
|
594
|
+
updatedAt: storage.ensureDate(row.updatedAt),
|
|
705
595
|
metadata: typeof row.metadata === "string" ? JSON.parse(row.metadata || "{}") : row.metadata || {}
|
|
706
596
|
});
|
|
707
597
|
try {
|
|
708
598
|
const countQuery = createSqlBuilder().count().from(fullTableName).where("resourceId = ?", resourceId);
|
|
709
|
-
const countResult = await this.executeQuery(countQuery.build());
|
|
599
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
710
600
|
const total = Number(countResult?.[0]?.count ?? 0);
|
|
711
601
|
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("resourceId = ?", resourceId).orderBy("createdAt", "DESC").limit(perPage).offset(page * perPage);
|
|
712
|
-
const results = await this.executeQuery(selectQuery.build());
|
|
602
|
+
const results = await this.operations.executeQuery(selectQuery.build());
|
|
713
603
|
const threads = results.map(mapRowToStorageThreadType);
|
|
714
604
|
return {
|
|
715
605
|
threads,
|
|
@@ -741,16 +631,16 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
741
631
|
}
|
|
742
632
|
}
|
|
743
633
|
async saveThread({ thread }) {
|
|
744
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
634
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
745
635
|
const threadToSave = {
|
|
746
636
|
id: thread.id,
|
|
747
637
|
resourceId: thread.resourceId,
|
|
748
638
|
title: thread.title,
|
|
749
639
|
metadata: thread.metadata ? JSON.stringify(thread.metadata) : null,
|
|
750
|
-
createdAt: thread.createdAt,
|
|
751
|
-
updatedAt: thread.updatedAt
|
|
640
|
+
createdAt: thread.createdAt.toISOString(),
|
|
641
|
+
updatedAt: thread.updatedAt.toISOString()
|
|
752
642
|
};
|
|
753
|
-
const processedRecord = await this.processRecord(threadToSave);
|
|
643
|
+
const processedRecord = await this.operations.processRecord(threadToSave);
|
|
754
644
|
const columns = Object.keys(processedRecord);
|
|
755
645
|
const values = Object.values(processedRecord);
|
|
756
646
|
const updateMap = {
|
|
@@ -763,7 +653,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
763
653
|
const query = createSqlBuilder().insert(fullTableName, columns, values, ["id"], updateMap);
|
|
764
654
|
const { sql, params } = query.build();
|
|
765
655
|
try {
|
|
766
|
-
await this.executeQuery({ sql, params });
|
|
656
|
+
await this.operations.executeQuery({ sql, params });
|
|
767
657
|
return thread;
|
|
768
658
|
} catch (error$1) {
|
|
769
659
|
throw new error.MastraError(
|
|
@@ -788,16 +678,17 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
788
678
|
if (!thread) {
|
|
789
679
|
throw new Error(`Thread ${id} not found`);
|
|
790
680
|
}
|
|
791
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
681
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
792
682
|
const mergedMetadata = {
|
|
793
683
|
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
794
684
|
...metadata
|
|
795
685
|
};
|
|
686
|
+
const updatedAt = /* @__PURE__ */ new Date();
|
|
796
687
|
const columns = ["title", "metadata", "updatedAt"];
|
|
797
|
-
const values = [title, JSON.stringify(mergedMetadata),
|
|
688
|
+
const values = [title, JSON.stringify(mergedMetadata), updatedAt.toISOString()];
|
|
798
689
|
const query = createSqlBuilder().update(fullTableName, columns, values).where("id = ?", id);
|
|
799
690
|
const { sql, params } = query.build();
|
|
800
|
-
await this.executeQuery({ sql, params });
|
|
691
|
+
await this.operations.executeQuery({ sql, params });
|
|
801
692
|
return {
|
|
802
693
|
...thread,
|
|
803
694
|
title,
|
|
@@ -805,7 +696,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
805
696
|
...typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
806
697
|
...metadata
|
|
807
698
|
},
|
|
808
|
-
updatedAt
|
|
699
|
+
updatedAt
|
|
809
700
|
};
|
|
810
701
|
} catch (error$1) {
|
|
811
702
|
throw new error.MastraError(
|
|
@@ -821,15 +712,15 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
821
712
|
}
|
|
822
713
|
}
|
|
823
714
|
async deleteThread({ threadId }) {
|
|
824
|
-
const fullTableName = this.getTableName(storage.TABLE_THREADS);
|
|
715
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
825
716
|
try {
|
|
826
717
|
const deleteThreadQuery = createSqlBuilder().delete(fullTableName).where("id = ?", threadId);
|
|
827
718
|
const { sql: threadSql, params: threadParams } = deleteThreadQuery.build();
|
|
828
|
-
await this.executeQuery({ sql: threadSql, params: threadParams });
|
|
829
|
-
const messagesTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
719
|
+
await this.operations.executeQuery({ sql: threadSql, params: threadParams });
|
|
720
|
+
const messagesTableName = this.operations.getTableName(storage.TABLE_MESSAGES);
|
|
830
721
|
const deleteMessagesQuery = createSqlBuilder().delete(messagesTableName).where("thread_id = ?", threadId);
|
|
831
722
|
const { sql: messagesSql, params: messagesParams } = deleteMessagesQuery.build();
|
|
832
|
-
await this.executeQuery({ sql: messagesSql, params: messagesParams });
|
|
723
|
+
await this.operations.executeQuery({ sql: messagesSql, params: messagesParams });
|
|
833
724
|
} catch (error$1) {
|
|
834
725
|
throw new error.MastraError(
|
|
835
726
|
{
|
|
@@ -860,6 +751,9 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
860
751
|
if (!message.role) {
|
|
861
752
|
throw new Error(`Message at index ${i} missing role`);
|
|
862
753
|
}
|
|
754
|
+
if (!message.resourceId) {
|
|
755
|
+
throw new Error(`Message at index ${i} missing resourceId`);
|
|
756
|
+
}
|
|
863
757
|
const thread = await this.getThreadById({ threadId: message.threadId });
|
|
864
758
|
if (!thread) {
|
|
865
759
|
throw new Error(`Thread ${message.threadId} not found`);
|
|
@@ -878,13 +772,13 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
878
772
|
};
|
|
879
773
|
});
|
|
880
774
|
await Promise.all([
|
|
881
|
-
this.batchUpsert({
|
|
775
|
+
this.operations.batchUpsert({
|
|
882
776
|
tableName: storage.TABLE_MESSAGES,
|
|
883
777
|
records: messagesToInsert
|
|
884
778
|
}),
|
|
885
779
|
// Update thread's updatedAt timestamp
|
|
886
|
-
this.executeQuery({
|
|
887
|
-
sql: `UPDATE ${this.getTableName(storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
|
|
780
|
+
this.operations.executeQuery({
|
|
781
|
+
sql: `UPDATE ${this.operations.getTableName(storage.TABLE_THREADS)} SET updatedAt = ? WHERE id = ?`,
|
|
888
782
|
params: [now.toISOString(), threadId]
|
|
889
783
|
})
|
|
890
784
|
]);
|
|
@@ -905,64 +799,78 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
905
799
|
}
|
|
906
800
|
}
|
|
907
801
|
async _getIncludedMessages(threadId, selectBy) {
|
|
802
|
+
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
908
803
|
const include = selectBy?.include;
|
|
909
804
|
if (!include) return null;
|
|
910
|
-
const
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
const
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
const messages = await this.executeQuery({ sql, params });
|
|
951
|
-
|
|
805
|
+
const unionQueries = [];
|
|
806
|
+
const params = [];
|
|
807
|
+
let paramIdx = 1;
|
|
808
|
+
for (const inc of include) {
|
|
809
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
810
|
+
const searchId = inc.threadId || threadId;
|
|
811
|
+
unionQueries.push(`
|
|
812
|
+
SELECT * FROM (
|
|
813
|
+
WITH ordered_messages AS (
|
|
814
|
+
SELECT
|
|
815
|
+
*,
|
|
816
|
+
ROW_NUMBER() OVER (ORDER BY createdAt ASC) AS row_num
|
|
817
|
+
FROM ${this.operations.getTableName(storage.TABLE_MESSAGES)}
|
|
818
|
+
WHERE thread_id = ?
|
|
819
|
+
)
|
|
820
|
+
SELECT
|
|
821
|
+
m.id,
|
|
822
|
+
m.content,
|
|
823
|
+
m.role,
|
|
824
|
+
m.type,
|
|
825
|
+
m.createdAt,
|
|
826
|
+
m.thread_id AS threadId,
|
|
827
|
+
m.resourceId
|
|
828
|
+
FROM ordered_messages m
|
|
829
|
+
WHERE m.id = ?
|
|
830
|
+
OR EXISTS (
|
|
831
|
+
SELECT 1 FROM ordered_messages target
|
|
832
|
+
WHERE target.id = ?
|
|
833
|
+
AND (
|
|
834
|
+
(m.row_num <= target.row_num + ? AND m.row_num > target.row_num)
|
|
835
|
+
OR
|
|
836
|
+
(m.row_num >= target.row_num - ? AND m.row_num < target.row_num)
|
|
837
|
+
)
|
|
838
|
+
)
|
|
839
|
+
) AS query_${paramIdx}
|
|
840
|
+
`);
|
|
841
|
+
params.push(searchId, id, id, withNextMessages, withPreviousMessages);
|
|
842
|
+
paramIdx++;
|
|
843
|
+
}
|
|
844
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + " ORDER BY createdAt ASC";
|
|
845
|
+
const messages = await this.operations.executeQuery({ sql: finalQuery, params });
|
|
846
|
+
if (!Array.isArray(messages)) {
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
const processedMessages = messages.map((message) => {
|
|
850
|
+
const processedMsg = {};
|
|
851
|
+
for (const [key, value] of Object.entries(message)) {
|
|
852
|
+
if (key === `type` && value === `v2`) continue;
|
|
853
|
+
processedMsg[key] = deserializeValue(value);
|
|
854
|
+
}
|
|
855
|
+
return processedMsg;
|
|
856
|
+
});
|
|
857
|
+
return processedMessages;
|
|
952
858
|
}
|
|
953
859
|
async getMessages({
|
|
954
860
|
threadId,
|
|
861
|
+
resourceId,
|
|
955
862
|
selectBy,
|
|
956
863
|
format
|
|
957
864
|
}) {
|
|
958
|
-
const fullTableName = this.getTableName(storage.TABLE_MESSAGES);
|
|
959
|
-
const limit = this.resolveMessageLimit({
|
|
960
|
-
last: selectBy?.last,
|
|
961
|
-
defaultLimit: 40
|
|
962
|
-
});
|
|
963
|
-
const include = selectBy?.include || [];
|
|
964
|
-
const messages = [];
|
|
965
865
|
try {
|
|
866
|
+
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
867
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_MESSAGES);
|
|
868
|
+
const limit = storage.resolveMessageLimit({
|
|
869
|
+
last: selectBy?.last,
|
|
870
|
+
defaultLimit: 40
|
|
871
|
+
});
|
|
872
|
+
const include = selectBy?.include || [];
|
|
873
|
+
const messages = [];
|
|
966
874
|
if (include.length) {
|
|
967
875
|
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
968
876
|
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
@@ -974,7 +882,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
974
882
|
}
|
|
975
883
|
query.orderBy("createdAt", "DESC").limit(limit);
|
|
976
884
|
const { sql, params } = query.build();
|
|
977
|
-
const result = await this.executeQuery({ sql, params });
|
|
885
|
+
const result = await this.operations.executeQuery({ sql, params });
|
|
978
886
|
if (Array.isArray(result)) messages.push(...result);
|
|
979
887
|
messages.sort((a, b) => {
|
|
980
888
|
const aRecord = a;
|
|
@@ -987,7 +895,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
987
895
|
const processedMsg = {};
|
|
988
896
|
for (const [key, value] of Object.entries(message)) {
|
|
989
897
|
if (key === `type` && value === `v2`) continue;
|
|
990
|
-
processedMsg[key] =
|
|
898
|
+
processedMsg[key] = deserializeValue(value);
|
|
991
899
|
}
|
|
992
900
|
return processedMsg;
|
|
993
901
|
});
|
|
@@ -1002,7 +910,48 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1002
910
|
domain: error.ErrorDomain.STORAGE,
|
|
1003
911
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1004
912
|
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1005
|
-
details: { threadId }
|
|
913
|
+
details: { threadId, resourceId: resourceId ?? "" }
|
|
914
|
+
},
|
|
915
|
+
error$1
|
|
916
|
+
);
|
|
917
|
+
this.logger?.error(mastraError.toString());
|
|
918
|
+
this.logger?.trackException(mastraError);
|
|
919
|
+
throw mastraError;
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
async getMessagesById({
|
|
923
|
+
messageIds,
|
|
924
|
+
format
|
|
925
|
+
}) {
|
|
926
|
+
if (messageIds.length === 0) return [];
|
|
927
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_MESSAGES);
|
|
928
|
+
const messages = [];
|
|
929
|
+
try {
|
|
930
|
+
const query = createSqlBuilder().select(["id", "content", "role", "type", "createdAt", "thread_id AS threadId", "resourceId"]).from(fullTableName).where(`id in (${messageIds.map(() => "?").join(",")})`, ...messageIds);
|
|
931
|
+
query.orderBy("createdAt", "DESC");
|
|
932
|
+
const { sql, params } = query.build();
|
|
933
|
+
const result = await this.operations.executeQuery({ sql, params });
|
|
934
|
+
if (Array.isArray(result)) messages.push(...result);
|
|
935
|
+
const processedMessages = messages.map((message) => {
|
|
936
|
+
const processedMsg = {};
|
|
937
|
+
for (const [key, value] of Object.entries(message)) {
|
|
938
|
+
if (key === `type` && value === `v2`) continue;
|
|
939
|
+
processedMsg[key] = deserializeValue(value);
|
|
940
|
+
}
|
|
941
|
+
return processedMsg;
|
|
942
|
+
});
|
|
943
|
+
this.logger.debug(`Retrieved ${messages.length} messages`);
|
|
944
|
+
const list = new agent.MessageList().add(processedMessages, "memory");
|
|
945
|
+
if (format === `v1`) return list.get.all.v1();
|
|
946
|
+
return list.get.all.v2();
|
|
947
|
+
} catch (error$1) {
|
|
948
|
+
const mastraError = new error.MastraError(
|
|
949
|
+
{
|
|
950
|
+
id: "CLOUDFLARE_D1_STORAGE_GET_MESSAGES_BY_ID_ERROR",
|
|
951
|
+
domain: error.ErrorDomain.STORAGE,
|
|
952
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
953
|
+
text: `Failed to retrieve messages by ID: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
954
|
+
details: { messageIds: JSON.stringify(messageIds) }
|
|
1006
955
|
},
|
|
1007
956
|
error$1
|
|
1008
957
|
);
|
|
@@ -1013,44 +962,97 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1013
962
|
}
|
|
1014
963
|
async getMessagesPaginated({
|
|
1015
964
|
threadId,
|
|
965
|
+
resourceId,
|
|
1016
966
|
selectBy,
|
|
1017
967
|
format
|
|
1018
968
|
}) {
|
|
1019
|
-
const { dateRange, page = 0, perPage
|
|
969
|
+
const { dateRange, page = 0, perPage: perPageInput } = selectBy?.pagination || {};
|
|
1020
970
|
const { start: fromDate, end: toDate } = dateRange || {};
|
|
1021
|
-
const
|
|
971
|
+
const perPage = perPageInput !== void 0 ? perPageInput : storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
972
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_MESSAGES);
|
|
1022
973
|
const messages = [];
|
|
1023
974
|
try {
|
|
975
|
+
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
1024
976
|
if (selectBy?.include?.length) {
|
|
1025
977
|
const includeResult = await this._getIncludedMessages(threadId, selectBy);
|
|
1026
978
|
if (Array.isArray(includeResult)) messages.push(...includeResult);
|
|
1027
979
|
}
|
|
1028
980
|
const countQuery = createSqlBuilder().count().from(fullTableName).where("thread_id = ?", threadId);
|
|
1029
981
|
if (fromDate) {
|
|
1030
|
-
countQuery.andWhere("createdAt >= ?",
|
|
982
|
+
countQuery.andWhere("createdAt >= ?", storage.serializeDate(fromDate));
|
|
1031
983
|
}
|
|
1032
984
|
if (toDate) {
|
|
1033
|
-
countQuery.andWhere("createdAt <= ?",
|
|
985
|
+
countQuery.andWhere("createdAt <= ?", storage.serializeDate(toDate));
|
|
1034
986
|
}
|
|
1035
|
-
const countResult = await this.executeQuery(countQuery.build());
|
|
987
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
1036
988
|
const total = Number(countResult[0]?.count ?? 0);
|
|
1037
|
-
|
|
989
|
+
if (total === 0 && messages.length === 0) {
|
|
990
|
+
return {
|
|
991
|
+
messages: [],
|
|
992
|
+
total: 0,
|
|
993
|
+
page,
|
|
994
|
+
perPage,
|
|
995
|
+
hasMore: false
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
const excludeIds = messages.map((m) => m.id);
|
|
999
|
+
const excludeCondition = excludeIds.length > 0 ? `AND id NOT IN (${excludeIds.map(() => "?").join(",")})` : "";
|
|
1000
|
+
let query;
|
|
1001
|
+
let queryParams = [threadId];
|
|
1038
1002
|
if (fromDate) {
|
|
1039
|
-
|
|
1003
|
+
queryParams.push(storage.serializeDate(fromDate));
|
|
1040
1004
|
}
|
|
1041
1005
|
if (toDate) {
|
|
1042
|
-
|
|
1006
|
+
queryParams.push(storage.serializeDate(toDate));
|
|
1007
|
+
}
|
|
1008
|
+
if (excludeIds.length > 0) {
|
|
1009
|
+
queryParams.push(...excludeIds);
|
|
1010
|
+
}
|
|
1011
|
+
if (selectBy?.last && selectBy.last > 0) {
|
|
1012
|
+
query = `
|
|
1013
|
+
SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
|
|
1014
|
+
FROM ${fullTableName}
|
|
1015
|
+
WHERE thread_id = ?
|
|
1016
|
+
${fromDate ? "AND createdAt >= ?" : ""}
|
|
1017
|
+
${toDate ? "AND createdAt <= ?" : ""}
|
|
1018
|
+
${excludeCondition}
|
|
1019
|
+
ORDER BY createdAt DESC
|
|
1020
|
+
LIMIT ?
|
|
1021
|
+
`;
|
|
1022
|
+
queryParams.push(selectBy.last);
|
|
1023
|
+
} else {
|
|
1024
|
+
query = `
|
|
1025
|
+
SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId
|
|
1026
|
+
FROM ${fullTableName}
|
|
1027
|
+
WHERE thread_id = ?
|
|
1028
|
+
${fromDate ? "AND createdAt >= ?" : ""}
|
|
1029
|
+
${toDate ? "AND createdAt <= ?" : ""}
|
|
1030
|
+
${excludeCondition}
|
|
1031
|
+
ORDER BY createdAt DESC
|
|
1032
|
+
LIMIT ? OFFSET ?
|
|
1033
|
+
`;
|
|
1034
|
+
queryParams.push(perPage, page * perPage);
|
|
1035
|
+
}
|
|
1036
|
+
const results = await this.operations.executeQuery({ sql: query, params: queryParams });
|
|
1037
|
+
const processedMessages = results.map((message) => {
|
|
1038
|
+
const processedMsg = {};
|
|
1039
|
+
for (const [key, value] of Object.entries(message)) {
|
|
1040
|
+
if (key === `type` && value === `v2`) continue;
|
|
1041
|
+
processedMsg[key] = deserializeValue(value);
|
|
1042
|
+
}
|
|
1043
|
+
return processedMsg;
|
|
1044
|
+
});
|
|
1045
|
+
if (selectBy?.last) {
|
|
1046
|
+
processedMessages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1043
1047
|
}
|
|
1044
|
-
|
|
1045
|
-
const results = await this.executeQuery(query.build());
|
|
1046
|
-
const list = new agent.MessageList().add(results, "memory");
|
|
1048
|
+
const list = new agent.MessageList().add(processedMessages, "memory");
|
|
1047
1049
|
messages.push(...format === `v2` ? list.get.all.v2() : list.get.all.v1());
|
|
1048
1050
|
return {
|
|
1049
1051
|
messages,
|
|
1050
1052
|
total,
|
|
1051
1053
|
page,
|
|
1052
1054
|
perPage,
|
|
1053
|
-
hasMore: page * perPage + messages.length < total
|
|
1055
|
+
hasMore: selectBy?.last ? false : page * perPage + messages.length < total
|
|
1054
1056
|
};
|
|
1055
1057
|
} catch (error$1) {
|
|
1056
1058
|
const mastraError = new error.MastraError(
|
|
@@ -1059,7 +1061,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1059
1061
|
domain: error.ErrorDomain.STORAGE,
|
|
1060
1062
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1061
1063
|
text: `Failed to retrieve messages for thread ${threadId}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1062
|
-
details: { threadId }
|
|
1064
|
+
details: { threadId, resourceId: resourceId ?? "" }
|
|
1063
1065
|
},
|
|
1064
1066
|
error$1
|
|
1065
1067
|
);
|
|
@@ -1074,132 +1076,446 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1074
1076
|
};
|
|
1075
1077
|
}
|
|
1076
1078
|
}
|
|
1077
|
-
async
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
const
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
keys: { workflow_name: workflowName, run_id: runId }
|
|
1087
|
-
});
|
|
1088
|
-
const persisting = currentSnapshot ? {
|
|
1089
|
-
...currentSnapshot,
|
|
1090
|
-
snapshot: JSON.stringify(snapshot),
|
|
1091
|
-
updatedAt: now
|
|
1092
|
-
} : {
|
|
1093
|
-
workflow_name: workflowName,
|
|
1094
|
-
run_id: runId,
|
|
1095
|
-
snapshot,
|
|
1096
|
-
createdAt: now,
|
|
1097
|
-
updatedAt: now
|
|
1098
|
-
};
|
|
1099
|
-
const processedRecord = await this.processRecord(persisting);
|
|
1100
|
-
const columns = Object.keys(processedRecord);
|
|
1101
|
-
const values = Object.values(processedRecord);
|
|
1102
|
-
const updateMap = {
|
|
1103
|
-
snapshot: "excluded.snapshot",
|
|
1104
|
-
updatedAt: "excluded.updatedAt"
|
|
1105
|
-
};
|
|
1106
|
-
this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
|
|
1107
|
-
const query = createSqlBuilder().insert(fullTableName, columns, values, ["workflow_name", "run_id"], updateMap);
|
|
1108
|
-
const { sql, params } = query.build();
|
|
1079
|
+
async updateMessages(args) {
|
|
1080
|
+
const { messages } = args;
|
|
1081
|
+
this.logger.debug("Updating messages", { count: messages.length });
|
|
1082
|
+
if (!messages.length) {
|
|
1083
|
+
return [];
|
|
1084
|
+
}
|
|
1085
|
+
const messageIds = messages.map((m) => m.id);
|
|
1086
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_MESSAGES);
|
|
1087
|
+
const threadsTableName = this.operations.getTableName(storage.TABLE_THREADS);
|
|
1109
1088
|
try {
|
|
1110
|
-
|
|
1089
|
+
const placeholders = messageIds.map(() => "?").join(",");
|
|
1090
|
+
const selectQuery = `SELECT id, content, role, type, createdAt, thread_id AS threadId, resourceId FROM ${fullTableName} WHERE id IN (${placeholders})`;
|
|
1091
|
+
const existingMessages = await this.operations.executeQuery({ sql: selectQuery, params: messageIds });
|
|
1092
|
+
if (existingMessages.length === 0) {
|
|
1093
|
+
return [];
|
|
1094
|
+
}
|
|
1095
|
+
const parsedExistingMessages = existingMessages.map((msg) => {
|
|
1096
|
+
if (typeof msg.content === "string") {
|
|
1097
|
+
try {
|
|
1098
|
+
msg.content = JSON.parse(msg.content);
|
|
1099
|
+
} catch {
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
return msg;
|
|
1103
|
+
});
|
|
1104
|
+
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
1105
|
+
const updateQueries = [];
|
|
1106
|
+
for (const existingMessage of parsedExistingMessages) {
|
|
1107
|
+
const updatePayload = messages.find((m) => m.id === existingMessage.id);
|
|
1108
|
+
if (!updatePayload) continue;
|
|
1109
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1110
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
1111
|
+
threadIdsToUpdate.add(existingMessage.threadId);
|
|
1112
|
+
if ("threadId" in updatePayload && updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
1113
|
+
threadIdsToUpdate.add(updatePayload.threadId);
|
|
1114
|
+
}
|
|
1115
|
+
const setClauses = [];
|
|
1116
|
+
const values = [];
|
|
1117
|
+
const updatableFields = { ...fieldsToUpdate };
|
|
1118
|
+
if (updatableFields.content) {
|
|
1119
|
+
const existingContent = existingMessage.content || {};
|
|
1120
|
+
const newContent = {
|
|
1121
|
+
...existingContent,
|
|
1122
|
+
...updatableFields.content,
|
|
1123
|
+
// Deep merge metadata if it exists on both
|
|
1124
|
+
...existingContent?.metadata && updatableFields.content.metadata ? {
|
|
1125
|
+
metadata: {
|
|
1126
|
+
...existingContent.metadata,
|
|
1127
|
+
...updatableFields.content.metadata
|
|
1128
|
+
}
|
|
1129
|
+
} : {}
|
|
1130
|
+
};
|
|
1131
|
+
setClauses.push(`content = ?`);
|
|
1132
|
+
values.push(JSON.stringify(newContent));
|
|
1133
|
+
delete updatableFields.content;
|
|
1134
|
+
}
|
|
1135
|
+
for (const key in updatableFields) {
|
|
1136
|
+
if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
|
|
1137
|
+
const dbColumn = key === "threadId" ? "thread_id" : key;
|
|
1138
|
+
setClauses.push(`${dbColumn} = ?`);
|
|
1139
|
+
values.push(updatableFields[key]);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
if (setClauses.length > 0) {
|
|
1143
|
+
values.push(id);
|
|
1144
|
+
const updateQuery = `UPDATE ${fullTableName} SET ${setClauses.join(", ")} WHERE id = ?`;
|
|
1145
|
+
updateQueries.push({ sql: updateQuery, params: values });
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
for (const query of updateQueries) {
|
|
1149
|
+
await this.operations.executeQuery(query);
|
|
1150
|
+
}
|
|
1151
|
+
if (threadIdsToUpdate.size > 0) {
|
|
1152
|
+
const threadPlaceholders = Array.from(threadIdsToUpdate).map(() => "?").join(",");
|
|
1153
|
+
const threadUpdateQuery = `UPDATE ${threadsTableName} SET updatedAt = ? WHERE id IN (${threadPlaceholders})`;
|
|
1154
|
+
const threadUpdateParams = [(/* @__PURE__ */ new Date()).toISOString(), ...Array.from(threadIdsToUpdate)];
|
|
1155
|
+
await this.operations.executeQuery({ sql: threadUpdateQuery, params: threadUpdateParams });
|
|
1156
|
+
}
|
|
1157
|
+
const updatedMessages = await this.operations.executeQuery({ sql: selectQuery, params: messageIds });
|
|
1158
|
+
return updatedMessages.map((message) => {
|
|
1159
|
+
if (typeof message.content === "string") {
|
|
1160
|
+
try {
|
|
1161
|
+
message.content = JSON.parse(message.content);
|
|
1162
|
+
} catch {
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return message;
|
|
1166
|
+
});
|
|
1111
1167
|
} catch (error$1) {
|
|
1112
1168
|
throw new error.MastraError(
|
|
1113
1169
|
{
|
|
1114
|
-
id: "
|
|
1170
|
+
id: "CLOUDFLARE_D1_STORAGE_UPDATE_MESSAGES_FAILED",
|
|
1115
1171
|
domain: error.ErrorDomain.STORAGE,
|
|
1116
1172
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1117
|
-
|
|
1118
|
-
details: { workflowName, runId }
|
|
1173
|
+
details: { count: messages.length }
|
|
1119
1174
|
},
|
|
1120
1175
|
error$1
|
|
1121
1176
|
);
|
|
1122
1177
|
}
|
|
1123
1178
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1179
|
+
};
|
|
1180
|
+
var StoreOperationsD1 = class extends storage.StoreOperations {
|
|
1181
|
+
client;
|
|
1182
|
+
binding;
|
|
1183
|
+
tablePrefix;
|
|
1184
|
+
constructor(config) {
|
|
1185
|
+
super();
|
|
1186
|
+
this.client = config.client;
|
|
1187
|
+
this.binding = config.binding;
|
|
1188
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
1189
|
+
}
|
|
1190
|
+
async hasColumn(table, column) {
|
|
1191
|
+
const fullTableName = table.startsWith(this.tablePrefix) ? table : `${this.tablePrefix}${table}`;
|
|
1192
|
+
const sql = `PRAGMA table_info(${fullTableName});`;
|
|
1193
|
+
const result = await this.executeQuery({ sql, params: [] });
|
|
1194
|
+
if (!result || !Array.isArray(result)) return false;
|
|
1195
|
+
return result.some((col) => col.name === column || col.name === column.toLowerCase());
|
|
1196
|
+
}
|
|
1197
|
+
getTableName(tableName) {
|
|
1198
|
+
return `${this.tablePrefix}${tableName}`;
|
|
1199
|
+
}
|
|
1200
|
+
formatSqlParams(params) {
|
|
1201
|
+
return params.map((p) => p === void 0 || p === null ? null : p);
|
|
1202
|
+
}
|
|
1203
|
+
async executeWorkersBindingQuery({
|
|
1204
|
+
sql,
|
|
1205
|
+
params = [],
|
|
1206
|
+
first = false
|
|
1207
|
+
}) {
|
|
1208
|
+
if (!this.binding) {
|
|
1209
|
+
throw new Error("Workers binding is not configured");
|
|
1210
|
+
}
|
|
1127
1211
|
try {
|
|
1128
|
-
const
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1212
|
+
const statement = this.binding.prepare(sql);
|
|
1213
|
+
const formattedParams = this.formatSqlParams(params);
|
|
1214
|
+
let result;
|
|
1215
|
+
if (formattedParams.length > 0) {
|
|
1216
|
+
if (first) {
|
|
1217
|
+
result = await statement.bind(...formattedParams).first();
|
|
1218
|
+
if (!result) return null;
|
|
1219
|
+
return result;
|
|
1220
|
+
} else {
|
|
1221
|
+
result = await statement.bind(...formattedParams).all();
|
|
1222
|
+
const results = result.results || [];
|
|
1223
|
+
return results;
|
|
1133
1224
|
}
|
|
1134
|
-
}
|
|
1135
|
-
|
|
1225
|
+
} else {
|
|
1226
|
+
if (first) {
|
|
1227
|
+
result = await statement.first();
|
|
1228
|
+
if (!result) return null;
|
|
1229
|
+
return result;
|
|
1230
|
+
} else {
|
|
1231
|
+
result = await statement.all();
|
|
1232
|
+
const results = result.results || [];
|
|
1233
|
+
return results;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1136
1236
|
} catch (error$1) {
|
|
1137
1237
|
throw new error.MastraError(
|
|
1138
1238
|
{
|
|
1139
|
-
id: "
|
|
1239
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_WORKERS_BINDING_QUERY_FAILED",
|
|
1140
1240
|
domain: error.ErrorDomain.STORAGE,
|
|
1141
1241
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1142
|
-
|
|
1143
|
-
|
|
1242
|
+
details: { sql }
|
|
1243
|
+
},
|
|
1244
|
+
error$1
|
|
1245
|
+
);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
async executeRestQuery({
|
|
1249
|
+
sql,
|
|
1250
|
+
params = [],
|
|
1251
|
+
first = false
|
|
1252
|
+
}) {
|
|
1253
|
+
if (!this.client) {
|
|
1254
|
+
throw new Error("D1 client is not configured");
|
|
1255
|
+
}
|
|
1256
|
+
try {
|
|
1257
|
+
const formattedParams = this.formatSqlParams(params);
|
|
1258
|
+
const response = await this.client.query({
|
|
1259
|
+
sql,
|
|
1260
|
+
params: formattedParams
|
|
1261
|
+
});
|
|
1262
|
+
const result = response.result || [];
|
|
1263
|
+
const results = result.flatMap((r) => r.results || []);
|
|
1264
|
+
if (first) {
|
|
1265
|
+
return results[0] || null;
|
|
1266
|
+
}
|
|
1267
|
+
return results;
|
|
1268
|
+
} catch (error$1) {
|
|
1269
|
+
throw new error.MastraError(
|
|
1270
|
+
{
|
|
1271
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_REST_QUERY_FAILED",
|
|
1272
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1273
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1274
|
+
details: { sql }
|
|
1275
|
+
},
|
|
1276
|
+
error$1
|
|
1277
|
+
);
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
async executeQuery(options) {
|
|
1281
|
+
if (this.binding) {
|
|
1282
|
+
return this.executeWorkersBindingQuery(options);
|
|
1283
|
+
} else if (this.client) {
|
|
1284
|
+
return this.executeRestQuery(options);
|
|
1285
|
+
} else {
|
|
1286
|
+
throw new Error("Neither binding nor client is configured");
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
async getTableColumns(tableName) {
|
|
1290
|
+
try {
|
|
1291
|
+
const sql = `PRAGMA table_info(${tableName})`;
|
|
1292
|
+
const result = await this.executeQuery({ sql });
|
|
1293
|
+
if (!result || !Array.isArray(result)) {
|
|
1294
|
+
return [];
|
|
1295
|
+
}
|
|
1296
|
+
return result.map((row) => ({
|
|
1297
|
+
name: row.name,
|
|
1298
|
+
type: row.type
|
|
1299
|
+
}));
|
|
1300
|
+
} catch (error) {
|
|
1301
|
+
this.logger.warn(`Failed to get table columns for ${tableName}:`, error);
|
|
1302
|
+
return [];
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
serializeValue(value) {
|
|
1306
|
+
if (value === null || value === void 0) {
|
|
1307
|
+
return null;
|
|
1308
|
+
}
|
|
1309
|
+
if (value instanceof Date) {
|
|
1310
|
+
return value.toISOString();
|
|
1311
|
+
}
|
|
1312
|
+
if (typeof value === "object") {
|
|
1313
|
+
return JSON.stringify(value);
|
|
1314
|
+
}
|
|
1315
|
+
return value;
|
|
1316
|
+
}
|
|
1317
|
+
getSqlType(type) {
|
|
1318
|
+
switch (type) {
|
|
1319
|
+
case "bigint":
|
|
1320
|
+
return "INTEGER";
|
|
1321
|
+
// SQLite uses INTEGER for all integer sizes
|
|
1322
|
+
case "jsonb":
|
|
1323
|
+
return "TEXT";
|
|
1324
|
+
// Store JSON as TEXT in SQLite
|
|
1325
|
+
default:
|
|
1326
|
+
return super.getSqlType(type);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
async createTable({
|
|
1330
|
+
tableName,
|
|
1331
|
+
schema
|
|
1332
|
+
}) {
|
|
1333
|
+
try {
|
|
1334
|
+
const fullTableName = this.getTableName(tableName);
|
|
1335
|
+
const columnDefinitions = Object.entries(schema).map(([colName, colDef]) => {
|
|
1336
|
+
const type = this.getSqlType(colDef.type);
|
|
1337
|
+
const nullable = colDef.nullable === false ? "NOT NULL" : "";
|
|
1338
|
+
const primaryKey = colDef.primaryKey ? "PRIMARY KEY" : "";
|
|
1339
|
+
return `${colName} ${type} ${nullable} ${primaryKey}`.trim();
|
|
1340
|
+
});
|
|
1341
|
+
const tableConstraints = [];
|
|
1342
|
+
if (tableName === storage.TABLE_WORKFLOW_SNAPSHOT) {
|
|
1343
|
+
tableConstraints.push("UNIQUE (workflow_name, run_id)");
|
|
1344
|
+
}
|
|
1345
|
+
const query = createSqlBuilder().createTable(fullTableName, columnDefinitions, tableConstraints);
|
|
1346
|
+
const { sql, params } = query.build();
|
|
1347
|
+
await this.executeQuery({ sql, params });
|
|
1348
|
+
this.logger.debug(`Created table ${fullTableName}`);
|
|
1349
|
+
} catch (error$1) {
|
|
1350
|
+
throw new error.MastraError(
|
|
1351
|
+
{
|
|
1352
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_CREATE_TABLE_FAILED",
|
|
1353
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1354
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1355
|
+
details: { tableName }
|
|
1356
|
+
},
|
|
1357
|
+
error$1
|
|
1358
|
+
);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
async clearTable({ tableName }) {
|
|
1362
|
+
try {
|
|
1363
|
+
const fullTableName = this.getTableName(tableName);
|
|
1364
|
+
const query = createSqlBuilder().delete(fullTableName);
|
|
1365
|
+
const { sql, params } = query.build();
|
|
1366
|
+
await this.executeQuery({ sql, params });
|
|
1367
|
+
this.logger.debug(`Cleared table ${fullTableName}`);
|
|
1368
|
+
} catch (error$1) {
|
|
1369
|
+
throw new error.MastraError(
|
|
1370
|
+
{
|
|
1371
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_CLEAR_TABLE_FAILED",
|
|
1372
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1373
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1374
|
+
details: { tableName }
|
|
1375
|
+
},
|
|
1376
|
+
error$1
|
|
1377
|
+
);
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
async dropTable({ tableName }) {
|
|
1381
|
+
try {
|
|
1382
|
+
const fullTableName = this.getTableName(tableName);
|
|
1383
|
+
const sql = `DROP TABLE IF EXISTS ${fullTableName}`;
|
|
1384
|
+
await this.executeQuery({ sql });
|
|
1385
|
+
this.logger.debug(`Dropped table ${fullTableName}`);
|
|
1386
|
+
} catch (error$1) {
|
|
1387
|
+
throw new error.MastraError(
|
|
1388
|
+
{
|
|
1389
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_DROP_TABLE_FAILED",
|
|
1390
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1391
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1392
|
+
details: { tableName }
|
|
1393
|
+
},
|
|
1394
|
+
error$1
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
async alterTable(args) {
|
|
1399
|
+
try {
|
|
1400
|
+
const fullTableName = this.getTableName(args.tableName);
|
|
1401
|
+
const existingColumns = await this.getTableColumns(fullTableName);
|
|
1402
|
+
const existingColumnNames = new Set(existingColumns.map((col) => col.name));
|
|
1403
|
+
for (const [columnName, column] of Object.entries(args.schema)) {
|
|
1404
|
+
if (!existingColumnNames.has(columnName) && args.ifNotExists.includes(columnName)) {
|
|
1405
|
+
const sqlType = this.getSqlType(column.type);
|
|
1406
|
+
const defaultValue = this.getDefaultValue(column.type);
|
|
1407
|
+
const sql = `ALTER TABLE ${fullTableName} ADD COLUMN ${columnName} ${sqlType} ${defaultValue}`;
|
|
1408
|
+
await this.executeQuery({ sql });
|
|
1409
|
+
this.logger.debug(`Added column ${columnName} to table ${fullTableName}`);
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
} catch (error$1) {
|
|
1413
|
+
throw new error.MastraError(
|
|
1414
|
+
{
|
|
1415
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_ALTER_TABLE_FAILED",
|
|
1416
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1417
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1418
|
+
details: { tableName: args.tableName }
|
|
1419
|
+
},
|
|
1420
|
+
error$1
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
async insert({ tableName, record }) {
|
|
1425
|
+
try {
|
|
1426
|
+
const fullTableName = this.getTableName(tableName);
|
|
1427
|
+
const processedRecord = await this.processRecord(record);
|
|
1428
|
+
const columns = Object.keys(processedRecord);
|
|
1429
|
+
const values = Object.values(processedRecord);
|
|
1430
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values);
|
|
1431
|
+
const { sql, params } = query.build();
|
|
1432
|
+
await this.executeQuery({ sql, params });
|
|
1433
|
+
} catch (error$1) {
|
|
1434
|
+
throw new error.MastraError(
|
|
1435
|
+
{
|
|
1436
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_INSERT_FAILED",
|
|
1437
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1438
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1439
|
+
details: { tableName }
|
|
1144
1440
|
},
|
|
1145
1441
|
error$1
|
|
1146
1442
|
);
|
|
1147
1443
|
}
|
|
1148
1444
|
}
|
|
1149
|
-
/**
|
|
1150
|
-
* Insert multiple records in a batch operation
|
|
1151
|
-
* @param tableName The table to insert into
|
|
1152
|
-
* @param records The records to insert
|
|
1153
|
-
*/
|
|
1154
1445
|
async batchInsert({ tableName, records }) {
|
|
1155
|
-
if (records.length === 0) return;
|
|
1156
|
-
const fullTableName = this.getTableName(tableName);
|
|
1157
1446
|
try {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
}
|
|
1447
|
+
if (records.length === 0) return;
|
|
1448
|
+
const fullTableName = this.getTableName(tableName);
|
|
1449
|
+
const processedRecords = await Promise.all(records.map((record) => this.processRecord(record)));
|
|
1450
|
+
const columns = Object.keys(processedRecords[0] || {});
|
|
1451
|
+
for (const record of processedRecords) {
|
|
1452
|
+
const values = Object.values(record);
|
|
1453
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values);
|
|
1454
|
+
const { sql, params } = query.build();
|
|
1455
|
+
await this.executeQuery({ sql, params });
|
|
1456
|
+
}
|
|
1457
|
+
} catch (error$1) {
|
|
1458
|
+
throw new error.MastraError(
|
|
1459
|
+
{
|
|
1460
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_BATCH_INSERT_FAILED",
|
|
1461
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1462
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1463
|
+
details: { tableName }
|
|
1464
|
+
},
|
|
1465
|
+
error$1
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
async load({ tableName, keys }) {
|
|
1470
|
+
try {
|
|
1471
|
+
const fullTableName = this.getTableName(tableName);
|
|
1472
|
+
const query = createSqlBuilder().select("*").from(fullTableName);
|
|
1473
|
+
let firstKey = true;
|
|
1474
|
+
for (const [key, value] of Object.entries(keys)) {
|
|
1475
|
+
if (firstKey) {
|
|
1476
|
+
query.where(`${key} = ?`, value);
|
|
1477
|
+
firstKey = false;
|
|
1478
|
+
} else {
|
|
1479
|
+
query.andWhere(`${key} = ?`, value);
|
|
1175
1480
|
}
|
|
1176
|
-
this.logger.debug(
|
|
1177
|
-
`Processed batch ${Math.floor(i / batchSize) + 1} of ${Math.ceil(records.length / batchSize)}`
|
|
1178
|
-
);
|
|
1179
1481
|
}
|
|
1180
|
-
|
|
1482
|
+
query.orderBy("createdAt", "DESC");
|
|
1483
|
+
query.limit(1);
|
|
1484
|
+
const { sql, params } = query.build();
|
|
1485
|
+
const result = await this.executeQuery({ sql, params, first: true });
|
|
1486
|
+
if (!result) {
|
|
1487
|
+
return null;
|
|
1488
|
+
}
|
|
1489
|
+
const deserializedResult = {};
|
|
1490
|
+
for (const [key, value] of Object.entries(result)) {
|
|
1491
|
+
deserializedResult[key] = deserializeValue(value);
|
|
1492
|
+
}
|
|
1493
|
+
return deserializedResult;
|
|
1181
1494
|
} catch (error$1) {
|
|
1182
1495
|
throw new error.MastraError(
|
|
1183
1496
|
{
|
|
1184
|
-
id: "
|
|
1497
|
+
id: "CLOUDFLARE_D1_STORE_OPERATIONS_LOAD_FAILED",
|
|
1185
1498
|
domain: error.ErrorDomain.STORAGE,
|
|
1186
1499
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1187
|
-
text: `Failed to batch insert into ${tableName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1188
1500
|
details: { tableName }
|
|
1189
1501
|
},
|
|
1190
1502
|
error$1
|
|
1191
1503
|
);
|
|
1192
1504
|
}
|
|
1193
1505
|
}
|
|
1506
|
+
async processRecord(record) {
|
|
1507
|
+
const processed = {};
|
|
1508
|
+
for (const [key, value] of Object.entries(record)) {
|
|
1509
|
+
processed[key] = this.serializeValue(value);
|
|
1510
|
+
}
|
|
1511
|
+
return processed;
|
|
1512
|
+
}
|
|
1194
1513
|
/**
|
|
1195
1514
|
* Upsert multiple records in a batch operation
|
|
1196
1515
|
* @param tableName The table to insert into
|
|
1197
1516
|
* @param records The records to insert
|
|
1198
1517
|
*/
|
|
1199
|
-
async batchUpsert({
|
|
1200
|
-
tableName,
|
|
1201
|
-
records
|
|
1202
|
-
}) {
|
|
1518
|
+
async batchUpsert({ tableName, records }) {
|
|
1203
1519
|
if (records.length === 0) return;
|
|
1204
1520
|
const fullTableName = this.getTableName(tableName);
|
|
1205
1521
|
try {
|
|
@@ -1246,273 +1562,395 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1246
1562
|
);
|
|
1247
1563
|
}
|
|
1248
1564
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1565
|
+
};
|
|
1566
|
+
function transformScoreRow(row) {
|
|
1567
|
+
const deserialized = { ...row };
|
|
1568
|
+
deserialized.input = storage.safelyParseJSON(row.input);
|
|
1569
|
+
deserialized.output = storage.safelyParseJSON(row.output);
|
|
1570
|
+
deserialized.scorer = storage.safelyParseJSON(row.scorer);
|
|
1571
|
+
deserialized.preprocessStepResult = storage.safelyParseJSON(row.preprocessStepResult);
|
|
1572
|
+
deserialized.analyzeStepResult = storage.safelyParseJSON(row.analyzeStepResult);
|
|
1573
|
+
deserialized.metadata = storage.safelyParseJSON(row.metadata);
|
|
1574
|
+
deserialized.additionalContext = storage.safelyParseJSON(row.additionalContext);
|
|
1575
|
+
deserialized.runtimeContext = storage.safelyParseJSON(row.runtimeContext);
|
|
1576
|
+
deserialized.entity = storage.safelyParseJSON(row.entity);
|
|
1577
|
+
deserialized.createdAt = row.createdAtZ || row.createdAt;
|
|
1578
|
+
deserialized.updatedAt = row.updatedAtZ || row.updatedAt;
|
|
1579
|
+
return deserialized;
|
|
1580
|
+
}
|
|
1581
|
+
var ScoresStorageD1 = class extends storage.ScoresStorage {
|
|
1582
|
+
operations;
|
|
1583
|
+
constructor({ operations }) {
|
|
1584
|
+
super();
|
|
1585
|
+
this.operations = operations;
|
|
1586
|
+
}
|
|
1587
|
+
async getScoreById({ id }) {
|
|
1262
1588
|
try {
|
|
1263
|
-
const
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
}
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1589
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1590
|
+
const query = createSqlBuilder().select("*").from(fullTableName).where("id = ?", id);
|
|
1591
|
+
const { sql, params } = query.build();
|
|
1592
|
+
const result = await this.operations.executeQuery({ sql, params, first: true });
|
|
1593
|
+
if (!result) {
|
|
1594
|
+
return null;
|
|
1269
1595
|
}
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1596
|
+
return transformScoreRow(result);
|
|
1597
|
+
} catch (error$1) {
|
|
1598
|
+
throw new error.MastraError(
|
|
1599
|
+
{
|
|
1600
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_GET_SCORE_BY_ID_FAILED",
|
|
1601
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1602
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1603
|
+
},
|
|
1604
|
+
error$1
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1608
|
+
async saveScore(score) {
|
|
1609
|
+
let parsedScore;
|
|
1610
|
+
try {
|
|
1611
|
+
parsedScore = scores.saveScorePayloadSchema.parse(score);
|
|
1612
|
+
} catch (error$1) {
|
|
1613
|
+
throw new error.MastraError(
|
|
1614
|
+
{
|
|
1615
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_SAVE_SCORE_FAILED_INVALID_SCORE_PAYLOAD",
|
|
1616
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1617
|
+
category: error.ErrorCategory.USER,
|
|
1618
|
+
details: { scoreId: score.id }
|
|
1619
|
+
},
|
|
1620
|
+
error$1
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
try {
|
|
1624
|
+
const id = crypto.randomUUID();
|
|
1625
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1626
|
+
const serializedRecord = {};
|
|
1627
|
+
for (const [key, value] of Object.entries(parsedScore)) {
|
|
1628
|
+
if (value !== null && value !== void 0) {
|
|
1629
|
+
if (typeof value === "object") {
|
|
1630
|
+
serializedRecord[key] = JSON.stringify(value);
|
|
1631
|
+
} else {
|
|
1632
|
+
serializedRecord[key] = value;
|
|
1633
|
+
}
|
|
1634
|
+
} else {
|
|
1635
|
+
serializedRecord[key] = null;
|
|
1273
1636
|
}
|
|
1274
1637
|
}
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
query.orderBy("startTime", "DESC").limit(perPage).offset(page * perPage);
|
|
1638
|
+
serializedRecord.id = id;
|
|
1639
|
+
serializedRecord.createdAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1640
|
+
serializedRecord.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1641
|
+
const columns = Object.keys(serializedRecord);
|
|
1642
|
+
const values = Object.values(serializedRecord);
|
|
1643
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values);
|
|
1282
1644
|
const { sql, params } = query.build();
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
...trace,
|
|
1287
|
-
attributes: this.deserializeValue(trace.attributes, "jsonb"),
|
|
1288
|
-
status: this.deserializeValue(trace.status, "jsonb"),
|
|
1289
|
-
events: this.deserializeValue(trace.events, "jsonb"),
|
|
1290
|
-
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1291
|
-
other: this.deserializeValue(trace.other, "jsonb")
|
|
1292
|
-
})
|
|
1293
|
-
) : [];
|
|
1645
|
+
await this.operations.executeQuery({ sql, params });
|
|
1646
|
+
const scoreFromDb = await this.getScoreById({ id });
|
|
1647
|
+
return { score: scoreFromDb };
|
|
1294
1648
|
} catch (error$1) {
|
|
1295
|
-
|
|
1649
|
+
throw new error.MastraError(
|
|
1296
1650
|
{
|
|
1297
|
-
id: "
|
|
1651
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_SAVE_SCORE_FAILED",
|
|
1298
1652
|
domain: error.ErrorDomain.STORAGE,
|
|
1299
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
1300
|
-
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1301
|
-
details: {
|
|
1302
|
-
name: name ?? "",
|
|
1303
|
-
scope: scope ?? ""
|
|
1304
|
-
}
|
|
1653
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1305
1654
|
},
|
|
1306
1655
|
error$1
|
|
1307
1656
|
);
|
|
1308
|
-
this.logger?.error(mastraError.toString());
|
|
1309
|
-
this.logger?.trackException(mastraError);
|
|
1310
|
-
return [];
|
|
1311
1657
|
}
|
|
1312
1658
|
}
|
|
1313
|
-
async
|
|
1314
|
-
|
|
1315
|
-
|
|
1659
|
+
async getScoresByScorerId({
|
|
1660
|
+
scorerId,
|
|
1661
|
+
entityId,
|
|
1662
|
+
entityType,
|
|
1663
|
+
source,
|
|
1664
|
+
pagination
|
|
1665
|
+
}) {
|
|
1316
1666
|
try {
|
|
1317
|
-
const
|
|
1318
|
-
const countQuery = createSqlBuilder().count().from(fullTableName).where("
|
|
1319
|
-
if (
|
|
1320
|
-
|
|
1321
|
-
countQuery.andWhere("name LIKE ?", `%${name}%`);
|
|
1667
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1668
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("scorerId = ?", scorerId);
|
|
1669
|
+
if (entityId) {
|
|
1670
|
+
countQuery.andWhere("entityId = ?", entityId);
|
|
1322
1671
|
}
|
|
1323
|
-
if (
|
|
1324
|
-
|
|
1325
|
-
countQuery.andWhere("scope = ?", scope);
|
|
1672
|
+
if (entityType) {
|
|
1673
|
+
countQuery.andWhere("entityType = ?", entityType);
|
|
1326
1674
|
}
|
|
1327
|
-
if (
|
|
1328
|
-
|
|
1329
|
-
dataQuery.jsonLike("attributes", key, value);
|
|
1330
|
-
countQuery.jsonLike("attributes", key, value);
|
|
1331
|
-
}
|
|
1675
|
+
if (source) {
|
|
1676
|
+
countQuery.andWhere("source = ?", source);
|
|
1332
1677
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1678
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
1679
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1680
|
+
if (total === 0) {
|
|
1681
|
+
return {
|
|
1682
|
+
pagination: {
|
|
1683
|
+
total: 0,
|
|
1684
|
+
page: pagination.page,
|
|
1685
|
+
perPage: pagination.perPage,
|
|
1686
|
+
hasMore: false
|
|
1687
|
+
},
|
|
1688
|
+
scores: []
|
|
1689
|
+
};
|
|
1337
1690
|
}
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
countQuery.andWhere("createdAt <= ?", toDateStr);
|
|
1691
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("scorerId = ?", scorerId);
|
|
1692
|
+
if (entityId) {
|
|
1693
|
+
selectQuery.andWhere("entityId = ?", entityId);
|
|
1342
1694
|
}
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
links: this.deserializeValue(trace.links, "jsonb"),
|
|
1354
|
-
other: this.deserializeValue(trace.other, "jsonb")
|
|
1355
|
-
})
|
|
1356
|
-
) : [];
|
|
1695
|
+
if (entityType) {
|
|
1696
|
+
selectQuery.andWhere("entityType = ?", entityType);
|
|
1697
|
+
}
|
|
1698
|
+
if (source) {
|
|
1699
|
+
selectQuery.andWhere("source = ?", source);
|
|
1700
|
+
}
|
|
1701
|
+
selectQuery.limit(pagination.perPage).offset(pagination.page * pagination.perPage);
|
|
1702
|
+
const { sql, params } = selectQuery.build();
|
|
1703
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
1704
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
1357
1705
|
return {
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1706
|
+
pagination: {
|
|
1707
|
+
total,
|
|
1708
|
+
page: pagination.page,
|
|
1709
|
+
perPage: pagination.perPage,
|
|
1710
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
1711
|
+
},
|
|
1712
|
+
scores
|
|
1363
1713
|
};
|
|
1364
1714
|
} catch (error$1) {
|
|
1365
|
-
|
|
1715
|
+
throw new error.MastraError(
|
|
1366
1716
|
{
|
|
1367
|
-
id: "
|
|
1717
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_GET_SCORES_BY_SCORER_ID_FAILED",
|
|
1368
1718
|
domain: error.ErrorDomain.STORAGE,
|
|
1369
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
1370
|
-
text: `Failed to retrieve traces: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1371
|
-
details: { name: name ?? "", scope: scope ?? "" }
|
|
1719
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1372
1720
|
},
|
|
1373
1721
|
error$1
|
|
1374
1722
|
);
|
|
1375
|
-
this.logger?.error(mastraError.toString());
|
|
1376
|
-
this.logger?.trackException(mastraError);
|
|
1377
|
-
return { traces: [], total: 0, page, perPage, hasMore: false };
|
|
1378
1723
|
}
|
|
1379
1724
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
const fullTableName = this.getTableName(storage.TABLE_EVALS);
|
|
1725
|
+
async getScoresByRunId({
|
|
1726
|
+
runId,
|
|
1727
|
+
pagination
|
|
1728
|
+
}) {
|
|
1385
1729
|
try {
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
}
|
|
1392
|
-
query.orderBy("created_at", "DESC");
|
|
1393
|
-
const { sql, params } = query.build();
|
|
1394
|
-
const results = await this.executeQuery({ sql, params });
|
|
1395
|
-
return isArrayOfRecords(results) ? results.map((row) => {
|
|
1396
|
-
const result = this.deserializeValue(row.result);
|
|
1397
|
-
const testInfo = row.test_info ? this.deserializeValue(row.test_info) : void 0;
|
|
1730
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1731
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("runId = ?", runId);
|
|
1732
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
1733
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1734
|
+
if (total === 0) {
|
|
1398
1735
|
return {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
globalRunId: row.global_run_id || "",
|
|
1407
|
-
createdAt: row.created_at || "",
|
|
1408
|
-
testInfo
|
|
1736
|
+
pagination: {
|
|
1737
|
+
total: 0,
|
|
1738
|
+
page: pagination.page,
|
|
1739
|
+
perPage: pagination.perPage,
|
|
1740
|
+
hasMore: false
|
|
1741
|
+
},
|
|
1742
|
+
scores: []
|
|
1409
1743
|
};
|
|
1410
|
-
}
|
|
1744
|
+
}
|
|
1745
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("runId = ?", runId).limit(pagination.perPage).offset(pagination.page * pagination.perPage);
|
|
1746
|
+
const { sql, params } = selectQuery.build();
|
|
1747
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
1748
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
1749
|
+
return {
|
|
1750
|
+
pagination: {
|
|
1751
|
+
total,
|
|
1752
|
+
page: pagination.page,
|
|
1753
|
+
perPage: pagination.perPage,
|
|
1754
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
1755
|
+
},
|
|
1756
|
+
scores
|
|
1757
|
+
};
|
|
1411
1758
|
} catch (error$1) {
|
|
1412
|
-
|
|
1759
|
+
throw new error.MastraError(
|
|
1413
1760
|
{
|
|
1414
|
-
id: "
|
|
1761
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_GET_SCORES_BY_RUN_ID_FAILED",
|
|
1415
1762
|
domain: error.ErrorDomain.STORAGE,
|
|
1416
|
-
category: error.ErrorCategory.THIRD_PARTY
|
|
1417
|
-
text: `Failed to retrieve evals for agent ${agentName}: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1418
|
-
details: { agentName }
|
|
1763
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1419
1764
|
},
|
|
1420
1765
|
error$1
|
|
1421
1766
|
);
|
|
1422
|
-
this.logger?.error(mastraError.toString());
|
|
1423
|
-
this.logger?.trackException(mastraError);
|
|
1424
|
-
return [];
|
|
1425
1767
|
}
|
|
1426
1768
|
}
|
|
1427
|
-
async
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
if (agentName) {
|
|
1433
|
-
conditions.push(`agent_name = ?`);
|
|
1434
|
-
queryParams.push(agentName);
|
|
1435
|
-
}
|
|
1436
|
-
if (type === "test") {
|
|
1437
|
-
conditions.push(`(test_info IS NOT NULL AND json_extract(test_info, '$.testPath') IS NOT NULL)`);
|
|
1438
|
-
} else if (type === "live") {
|
|
1439
|
-
conditions.push(`(test_info IS NULL OR json_extract(test_info, '$.testPath') IS NULL)`);
|
|
1440
|
-
}
|
|
1441
|
-
if (fromDate) {
|
|
1442
|
-
conditions.push(`createdAt >= ?`);
|
|
1443
|
-
queryParams.push(this.serializeDate(fromDate));
|
|
1444
|
-
}
|
|
1445
|
-
if (toDate) {
|
|
1446
|
-
conditions.push(`createdAt <= ?`);
|
|
1447
|
-
queryParams.push(this.serializeDate(toDate));
|
|
1448
|
-
}
|
|
1449
|
-
const countQueryBuilder = createSqlBuilder().count().from(fullTableName);
|
|
1450
|
-
if (conditions.length > 0) {
|
|
1451
|
-
countQueryBuilder.where(conditions.join(" AND "), ...queryParams);
|
|
1452
|
-
}
|
|
1453
|
-
const { sql: countSql, params: countParams } = countQueryBuilder.build();
|
|
1769
|
+
async getScoresByEntityId({
|
|
1770
|
+
entityId,
|
|
1771
|
+
entityType,
|
|
1772
|
+
pagination
|
|
1773
|
+
}) {
|
|
1454
1774
|
try {
|
|
1455
|
-
const
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
});
|
|
1460
|
-
const total = Number(countResult?.count || 0);
|
|
1461
|
-
const currentOffset = page * perPage;
|
|
1775
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1776
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType);
|
|
1777
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
1778
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1462
1779
|
if (total === 0) {
|
|
1463
1780
|
return {
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1781
|
+
pagination: {
|
|
1782
|
+
total: 0,
|
|
1783
|
+
page: pagination.page,
|
|
1784
|
+
perPage: pagination.perPage,
|
|
1785
|
+
hasMore: false
|
|
1786
|
+
},
|
|
1787
|
+
scores: []
|
|
1469
1788
|
};
|
|
1470
1789
|
}
|
|
1471
|
-
const
|
|
1472
|
-
|
|
1473
|
-
|
|
1790
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("entityId = ?", entityId).andWhere("entityType = ?", entityType).limit(pagination.perPage).offset(pagination.page * pagination.perPage);
|
|
1791
|
+
const { sql, params } = selectQuery.build();
|
|
1792
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
1793
|
+
const scores = Array.isArray(results) ? results.map(transformScoreRow) : [];
|
|
1794
|
+
return {
|
|
1795
|
+
pagination: {
|
|
1796
|
+
total,
|
|
1797
|
+
page: pagination.page,
|
|
1798
|
+
perPage: pagination.perPage,
|
|
1799
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
1800
|
+
},
|
|
1801
|
+
scores
|
|
1802
|
+
};
|
|
1803
|
+
} catch (error$1) {
|
|
1804
|
+
throw new error.MastraError(
|
|
1805
|
+
{
|
|
1806
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_GET_SCORES_BY_ENTITY_ID_FAILED",
|
|
1807
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1808
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1809
|
+
},
|
|
1810
|
+
error$1
|
|
1811
|
+
);
|
|
1812
|
+
}
|
|
1813
|
+
}
|
|
1814
|
+
async getScoresBySpan({
|
|
1815
|
+
traceId,
|
|
1816
|
+
spanId,
|
|
1817
|
+
pagination
|
|
1818
|
+
}) {
|
|
1819
|
+
try {
|
|
1820
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_SCORERS);
|
|
1821
|
+
const countQuery = createSqlBuilder().count().from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId);
|
|
1822
|
+
const countResult = await this.operations.executeQuery(countQuery.build());
|
|
1823
|
+
const total = Array.isArray(countResult) ? Number(countResult?.[0]?.count ?? 0) : Number(countResult?.count ?? 0);
|
|
1824
|
+
if (total === 0) {
|
|
1825
|
+
return {
|
|
1826
|
+
pagination: {
|
|
1827
|
+
total: 0,
|
|
1828
|
+
page: pagination.page,
|
|
1829
|
+
perPage: pagination.perPage,
|
|
1830
|
+
hasMore: false
|
|
1831
|
+
},
|
|
1832
|
+
scores: []
|
|
1833
|
+
};
|
|
1474
1834
|
}
|
|
1475
|
-
|
|
1476
|
-
const
|
|
1477
|
-
const
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1835
|
+
const limit = pagination.perPage + 1;
|
|
1836
|
+
const selectQuery = createSqlBuilder().select("*").from(fullTableName).where("traceId = ?", traceId).andWhere("spanId = ?", spanId).orderBy("createdAt", "DESC").limit(limit).offset(pagination.page * pagination.perPage);
|
|
1837
|
+
const { sql, params } = selectQuery.build();
|
|
1838
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
1839
|
+
const rows = Array.isArray(results) ? results : [];
|
|
1840
|
+
const scores = rows.slice(0, pagination.perPage).map(transformScoreRow);
|
|
1841
|
+
return {
|
|
1842
|
+
pagination: {
|
|
1843
|
+
total,
|
|
1844
|
+
page: pagination.page,
|
|
1845
|
+
perPage: pagination.perPage,
|
|
1846
|
+
hasMore: rows.length > pagination.perPage
|
|
1847
|
+
},
|
|
1848
|
+
scores
|
|
1849
|
+
};
|
|
1850
|
+
} catch (error$1) {
|
|
1851
|
+
throw new error.MastraError(
|
|
1852
|
+
{
|
|
1853
|
+
id: "CLOUDFLARE_D1_STORE_SCORES_GET_SCORES_BY_SPAN_FAILED",
|
|
1854
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1855
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
1856
|
+
},
|
|
1857
|
+
error$1
|
|
1858
|
+
);
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
};
|
|
1862
|
+
var WorkflowsStorageD1 = class extends storage.WorkflowsStorage {
|
|
1863
|
+
operations;
|
|
1864
|
+
constructor({ operations }) {
|
|
1865
|
+
super();
|
|
1866
|
+
this.operations = operations;
|
|
1867
|
+
}
|
|
1868
|
+
updateWorkflowResults({
|
|
1869
|
+
// workflowName,
|
|
1870
|
+
// runId,
|
|
1871
|
+
// stepId,
|
|
1872
|
+
// result,
|
|
1873
|
+
// runtimeContext,
|
|
1874
|
+
}) {
|
|
1875
|
+
throw new Error("Method not implemented.");
|
|
1876
|
+
}
|
|
1877
|
+
updateWorkflowState({
|
|
1878
|
+
// workflowName,
|
|
1879
|
+
// runId,
|
|
1880
|
+
// opts,
|
|
1881
|
+
}) {
|
|
1882
|
+
throw new Error("Method not implemented.");
|
|
1883
|
+
}
|
|
1884
|
+
async persistWorkflowSnapshot({
|
|
1885
|
+
workflowName,
|
|
1886
|
+
runId,
|
|
1887
|
+
resourceId,
|
|
1888
|
+
snapshot
|
|
1889
|
+
}) {
|
|
1890
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1891
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
1892
|
+
const currentSnapshot = await this.operations.load({
|
|
1893
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
1894
|
+
keys: { workflow_name: workflowName, run_id: runId }
|
|
1895
|
+
});
|
|
1896
|
+
const persisting = currentSnapshot ? {
|
|
1897
|
+
...currentSnapshot,
|
|
1898
|
+
resourceId,
|
|
1899
|
+
snapshot: JSON.stringify(snapshot),
|
|
1900
|
+
updatedAt: now
|
|
1901
|
+
} : {
|
|
1902
|
+
workflow_name: workflowName,
|
|
1903
|
+
run_id: runId,
|
|
1904
|
+
resourceId,
|
|
1905
|
+
snapshot,
|
|
1906
|
+
createdAt: now,
|
|
1907
|
+
updatedAt: now
|
|
1908
|
+
};
|
|
1909
|
+
const processedRecord = await this.operations.processRecord(persisting);
|
|
1910
|
+
const columns = Object.keys(processedRecord);
|
|
1911
|
+
const values = Object.values(processedRecord);
|
|
1912
|
+
const updateMap = {
|
|
1913
|
+
snapshot: "excluded.snapshot",
|
|
1914
|
+
updatedAt: "excluded.updatedAt"
|
|
1915
|
+
};
|
|
1916
|
+
this.logger.debug("Persisting workflow snapshot", { workflowName, runId });
|
|
1917
|
+
const query = createSqlBuilder().insert(fullTableName, columns, values, ["workflow_name", "run_id"], updateMap);
|
|
1918
|
+
const { sql, params } = query.build();
|
|
1919
|
+
try {
|
|
1920
|
+
await this.operations.executeQuery({ sql, params });
|
|
1921
|
+
} catch (error$1) {
|
|
1922
|
+
throw new error.MastraError(
|
|
1923
|
+
{
|
|
1924
|
+
id: "CLOUDFLARE_D1_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_ERROR",
|
|
1925
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1926
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1927
|
+
text: `Failed to persist workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1928
|
+
details: { workflowName, runId }
|
|
1929
|
+
},
|
|
1930
|
+
error$1
|
|
1931
|
+
);
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
async loadWorkflowSnapshot(params) {
|
|
1935
|
+
const { workflowName, runId } = params;
|
|
1936
|
+
this.logger.debug("Loading workflow snapshot", { workflowName, runId });
|
|
1937
|
+
try {
|
|
1938
|
+
const d = await this.operations.load({
|
|
1939
|
+
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
1940
|
+
keys: {
|
|
1941
|
+
workflow_name: workflowName,
|
|
1942
|
+
run_id: runId
|
|
1486
1943
|
}
|
|
1487
|
-
return {
|
|
1488
|
-
input: row.input,
|
|
1489
|
-
output: row.output,
|
|
1490
|
-
result,
|
|
1491
|
-
agentName: row.agent_name,
|
|
1492
|
-
metricName: row.metric_name,
|
|
1493
|
-
instructions: row.instructions,
|
|
1494
|
-
testInfo,
|
|
1495
|
-
globalRunId: row.global_run_id,
|
|
1496
|
-
runId: row.run_id,
|
|
1497
|
-
createdAt: row.createdAt
|
|
1498
|
-
};
|
|
1499
1944
|
});
|
|
1500
|
-
|
|
1501
|
-
return {
|
|
1502
|
-
evals,
|
|
1503
|
-
total,
|
|
1504
|
-
page,
|
|
1505
|
-
perPage,
|
|
1506
|
-
hasMore
|
|
1507
|
-
};
|
|
1945
|
+
return d ? d.snapshot : null;
|
|
1508
1946
|
} catch (error$1) {
|
|
1509
1947
|
throw new error.MastraError(
|
|
1510
1948
|
{
|
|
1511
|
-
id: "
|
|
1949
|
+
id: "CLOUDFLARE_D1_STORAGE_LOAD_WORKFLOW_SNAPSHOT_ERROR",
|
|
1512
1950
|
domain: error.ErrorDomain.STORAGE,
|
|
1513
1951
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
1514
|
-
text: `Failed to
|
|
1515
|
-
details: {
|
|
1952
|
+
text: `Failed to load workflow snapshot: ${error$1 instanceof Error ? error$1.message : String(error$1)}`,
|
|
1953
|
+
details: { workflowName, runId }
|
|
1516
1954
|
},
|
|
1517
1955
|
error$1
|
|
1518
1956
|
);
|
|
@@ -1531,17 +1969,11 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1531
1969
|
workflowName: row.workflow_name,
|
|
1532
1970
|
runId: row.run_id,
|
|
1533
1971
|
snapshot: parsedSnapshot,
|
|
1534
|
-
createdAt:
|
|
1535
|
-
updatedAt:
|
|
1972
|
+
createdAt: storage.ensureDate(row.createdAt),
|
|
1973
|
+
updatedAt: storage.ensureDate(row.updatedAt),
|
|
1536
1974
|
resourceId: row.resourceId
|
|
1537
1975
|
};
|
|
1538
1976
|
}
|
|
1539
|
-
async hasColumn(table, column) {
|
|
1540
|
-
const sql = `PRAGMA table_info(${table});`;
|
|
1541
|
-
const result = await this.executeQuery({ sql, params: [] });
|
|
1542
|
-
if (!result || !Array.isArray(result)) return false;
|
|
1543
|
-
return result.some((col) => col.name === column || col.name === column.toLowerCase());
|
|
1544
|
-
}
|
|
1545
1977
|
async getWorkflowRuns({
|
|
1546
1978
|
workflowName,
|
|
1547
1979
|
fromDate,
|
|
@@ -1550,13 +1982,13 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1550
1982
|
offset,
|
|
1551
1983
|
resourceId
|
|
1552
1984
|
} = {}) {
|
|
1553
|
-
const fullTableName = this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1985
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1554
1986
|
try {
|
|
1555
1987
|
const builder = createSqlBuilder().select().from(fullTableName);
|
|
1556
1988
|
const countBuilder = createSqlBuilder().count().from(fullTableName);
|
|
1557
1989
|
if (workflowName) builder.whereAnd("workflow_name = ?", workflowName);
|
|
1558
1990
|
if (resourceId) {
|
|
1559
|
-
const hasResourceId = await this.hasColumn(fullTableName, "resourceId");
|
|
1991
|
+
const hasResourceId = await this.operations.hasColumn(fullTableName, "resourceId");
|
|
1560
1992
|
if (hasResourceId) {
|
|
1561
1993
|
builder.whereAnd("resourceId = ?", resourceId);
|
|
1562
1994
|
countBuilder.whereAnd("resourceId = ?", resourceId);
|
|
@@ -1579,14 +2011,14 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1579
2011
|
let total = 0;
|
|
1580
2012
|
if (limit !== void 0 && offset !== void 0) {
|
|
1581
2013
|
const { sql: countSql, params: countParams } = countBuilder.build();
|
|
1582
|
-
const countResult = await this.executeQuery({
|
|
2014
|
+
const countResult = await this.operations.executeQuery({
|
|
1583
2015
|
sql: countSql,
|
|
1584
2016
|
params: countParams,
|
|
1585
2017
|
first: true
|
|
1586
2018
|
});
|
|
1587
2019
|
total = Number(countResult?.count ?? 0);
|
|
1588
2020
|
}
|
|
1589
|
-
const results = await this.executeQuery({ sql, params });
|
|
2021
|
+
const results = await this.operations.executeQuery({ sql, params });
|
|
1590
2022
|
const runs = (isArrayOfRecords(results) ? results : []).map((row) => this.parseWorkflowRun(row));
|
|
1591
2023
|
return { runs, total: total || runs.length };
|
|
1592
2024
|
} catch (error$1) {
|
|
@@ -1609,7 +2041,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1609
2041
|
runId,
|
|
1610
2042
|
workflowName
|
|
1611
2043
|
}) {
|
|
1612
|
-
const fullTableName = this.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
2044
|
+
const fullTableName = this.operations.getTableName(storage.TABLE_WORKFLOW_SNAPSHOT);
|
|
1613
2045
|
try {
|
|
1614
2046
|
const conditions = [];
|
|
1615
2047
|
const params = [];
|
|
@@ -1623,7 +2055,7 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1623
2055
|
}
|
|
1624
2056
|
const whereClause = conditions.length > 0 ? "WHERE " + conditions.join(" AND ") : "";
|
|
1625
2057
|
const sql = `SELECT * FROM ${fullTableName} ${whereClause} ORDER BY createdAt DESC LIMIT 1`;
|
|
1626
|
-
const result = await this.executeQuery({ sql, params, first: true });
|
|
2058
|
+
const result = await this.operations.executeQuery({ sql, params, first: true });
|
|
1627
2059
|
if (!result) return null;
|
|
1628
2060
|
return this.parseWorkflowRun(result);
|
|
1629
2061
|
} catch (error$1) {
|
|
@@ -1639,6 +2071,299 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1639
2071
|
);
|
|
1640
2072
|
}
|
|
1641
2073
|
}
|
|
2074
|
+
};
|
|
2075
|
+
|
|
2076
|
+
// src/storage/index.ts
|
|
2077
|
+
var D1Store = class extends storage.MastraStorage {
|
|
2078
|
+
client;
|
|
2079
|
+
binding;
|
|
2080
|
+
// D1Database binding
|
|
2081
|
+
tablePrefix;
|
|
2082
|
+
stores;
|
|
2083
|
+
/**
|
|
2084
|
+
* Creates a new D1Store instance
|
|
2085
|
+
* @param config Configuration for D1 access (either REST API or Workers Binding API)
|
|
2086
|
+
*/
|
|
2087
|
+
constructor(config) {
|
|
2088
|
+
try {
|
|
2089
|
+
super({ name: "D1" });
|
|
2090
|
+
if (config.tablePrefix && !/^[a-zA-Z0-9_]*$/.test(config.tablePrefix)) {
|
|
2091
|
+
throw new Error("Invalid tablePrefix: only letters, numbers, and underscores are allowed.");
|
|
2092
|
+
}
|
|
2093
|
+
this.tablePrefix = config.tablePrefix || "";
|
|
2094
|
+
if ("binding" in config) {
|
|
2095
|
+
if (!config.binding) {
|
|
2096
|
+
throw new Error("D1 binding is required when using Workers Binding API");
|
|
2097
|
+
}
|
|
2098
|
+
this.binding = config.binding;
|
|
2099
|
+
this.logger.info("Using D1 Workers Binding API");
|
|
2100
|
+
} else if ("client" in config) {
|
|
2101
|
+
if (!config.client) {
|
|
2102
|
+
throw new Error("D1 client is required when using D1ClientConfig");
|
|
2103
|
+
}
|
|
2104
|
+
this.client = config.client;
|
|
2105
|
+
this.logger.info("Using D1 Client");
|
|
2106
|
+
} else {
|
|
2107
|
+
if (!config.accountId || !config.databaseId || !config.apiToken) {
|
|
2108
|
+
throw new Error("accountId, databaseId, and apiToken are required when using REST API");
|
|
2109
|
+
}
|
|
2110
|
+
const cfClient = new Cloudflare__default.default({
|
|
2111
|
+
apiToken: config.apiToken
|
|
2112
|
+
});
|
|
2113
|
+
this.client = {
|
|
2114
|
+
query: ({ sql, params }) => {
|
|
2115
|
+
return cfClient.d1.database.query(config.databaseId, {
|
|
2116
|
+
account_id: config.accountId,
|
|
2117
|
+
sql,
|
|
2118
|
+
params
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
};
|
|
2122
|
+
this.logger.info("Using D1 REST API");
|
|
2123
|
+
}
|
|
2124
|
+
} catch (error$1) {
|
|
2125
|
+
throw new error.MastraError(
|
|
2126
|
+
{
|
|
2127
|
+
id: "CLOUDFLARE_D1_STORAGE_INITIALIZATION_ERROR",
|
|
2128
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2129
|
+
category: error.ErrorCategory.SYSTEM,
|
|
2130
|
+
text: "Error initializing D1Store"
|
|
2131
|
+
},
|
|
2132
|
+
error$1
|
|
2133
|
+
);
|
|
2134
|
+
}
|
|
2135
|
+
const operations = new StoreOperationsD1({
|
|
2136
|
+
client: this.client,
|
|
2137
|
+
binding: this.binding,
|
|
2138
|
+
tablePrefix: this.tablePrefix
|
|
2139
|
+
});
|
|
2140
|
+
const scores = new ScoresStorageD1({
|
|
2141
|
+
operations
|
|
2142
|
+
});
|
|
2143
|
+
const legacyEvals = new LegacyEvalsStorageD1({
|
|
2144
|
+
operations
|
|
2145
|
+
});
|
|
2146
|
+
const workflows = new WorkflowsStorageD1({
|
|
2147
|
+
operations
|
|
2148
|
+
});
|
|
2149
|
+
const memory = new MemoryStorageD1({
|
|
2150
|
+
operations
|
|
2151
|
+
});
|
|
2152
|
+
this.stores = {
|
|
2153
|
+
operations,
|
|
2154
|
+
scores,
|
|
2155
|
+
legacyEvals,
|
|
2156
|
+
workflows,
|
|
2157
|
+
memory
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2160
|
+
get supports() {
|
|
2161
|
+
return {
|
|
2162
|
+
selectByIncludeResourceScope: true,
|
|
2163
|
+
resourceWorkingMemory: true,
|
|
2164
|
+
hasColumn: true,
|
|
2165
|
+
createTable: true,
|
|
2166
|
+
deleteMessages: false,
|
|
2167
|
+
getScoresBySpan: true
|
|
2168
|
+
};
|
|
2169
|
+
}
|
|
2170
|
+
async createTable({
|
|
2171
|
+
tableName,
|
|
2172
|
+
schema
|
|
2173
|
+
}) {
|
|
2174
|
+
return this.stores.operations.createTable({ tableName, schema });
|
|
2175
|
+
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Alters table schema to add columns if they don't exist
|
|
2178
|
+
* @param tableName Name of the table
|
|
2179
|
+
* @param schema Schema of the table
|
|
2180
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
2181
|
+
*/
|
|
2182
|
+
async alterTable({
|
|
2183
|
+
tableName,
|
|
2184
|
+
schema,
|
|
2185
|
+
ifNotExists
|
|
2186
|
+
}) {
|
|
2187
|
+
return this.stores.operations.alterTable({ tableName, schema, ifNotExists });
|
|
2188
|
+
}
|
|
2189
|
+
async clearTable({ tableName }) {
|
|
2190
|
+
return this.stores.operations.clearTable({ tableName });
|
|
2191
|
+
}
|
|
2192
|
+
async dropTable({ tableName }) {
|
|
2193
|
+
return this.stores.operations.dropTable({ tableName });
|
|
2194
|
+
}
|
|
2195
|
+
async hasColumn(table, column) {
|
|
2196
|
+
return this.stores.operations.hasColumn(table, column);
|
|
2197
|
+
}
|
|
2198
|
+
async insert({ tableName, record }) {
|
|
2199
|
+
return this.stores.operations.insert({ tableName, record });
|
|
2200
|
+
}
|
|
2201
|
+
async load({ tableName, keys }) {
|
|
2202
|
+
return this.stores.operations.load({ tableName, keys });
|
|
2203
|
+
}
|
|
2204
|
+
async getThreadById({ threadId }) {
|
|
2205
|
+
return this.stores.memory.getThreadById({ threadId });
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* @deprecated use getThreadsByResourceIdPaginated instead
|
|
2209
|
+
*/
|
|
2210
|
+
async getThreadsByResourceId({ resourceId }) {
|
|
2211
|
+
return this.stores.memory.getThreadsByResourceId({ resourceId });
|
|
2212
|
+
}
|
|
2213
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
2214
|
+
return this.stores.memory.getThreadsByResourceIdPaginated(args);
|
|
2215
|
+
}
|
|
2216
|
+
async saveThread({ thread }) {
|
|
2217
|
+
return this.stores.memory.saveThread({ thread });
|
|
2218
|
+
}
|
|
2219
|
+
async updateThread({
|
|
2220
|
+
id,
|
|
2221
|
+
title,
|
|
2222
|
+
metadata
|
|
2223
|
+
}) {
|
|
2224
|
+
return this.stores.memory.updateThread({ id, title, metadata });
|
|
2225
|
+
}
|
|
2226
|
+
async deleteThread({ threadId }) {
|
|
2227
|
+
return this.stores.memory.deleteThread({ threadId });
|
|
2228
|
+
}
|
|
2229
|
+
async saveMessages(args) {
|
|
2230
|
+
return this.stores.memory.saveMessages(args);
|
|
2231
|
+
}
|
|
2232
|
+
async getMessages({
|
|
2233
|
+
threadId,
|
|
2234
|
+
selectBy,
|
|
2235
|
+
format
|
|
2236
|
+
}) {
|
|
2237
|
+
return this.stores.memory.getMessages({ threadId, selectBy, format });
|
|
2238
|
+
}
|
|
2239
|
+
async getMessagesById({
|
|
2240
|
+
messageIds,
|
|
2241
|
+
format
|
|
2242
|
+
}) {
|
|
2243
|
+
return this.stores.memory.getMessagesById({ messageIds, format });
|
|
2244
|
+
}
|
|
2245
|
+
async getMessagesPaginated({
|
|
2246
|
+
threadId,
|
|
2247
|
+
selectBy,
|
|
2248
|
+
format
|
|
2249
|
+
}) {
|
|
2250
|
+
return this.stores.memory.getMessagesPaginated({ threadId, selectBy, format });
|
|
2251
|
+
}
|
|
2252
|
+
async updateWorkflowResults({
|
|
2253
|
+
workflowName,
|
|
2254
|
+
runId,
|
|
2255
|
+
stepId,
|
|
2256
|
+
result,
|
|
2257
|
+
runtimeContext
|
|
2258
|
+
}) {
|
|
2259
|
+
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
|
|
2260
|
+
}
|
|
2261
|
+
async updateWorkflowState({
|
|
2262
|
+
workflowName,
|
|
2263
|
+
runId,
|
|
2264
|
+
opts
|
|
2265
|
+
}) {
|
|
2266
|
+
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
2267
|
+
}
|
|
2268
|
+
async persistWorkflowSnapshot({
|
|
2269
|
+
workflowName,
|
|
2270
|
+
runId,
|
|
2271
|
+
resourceId,
|
|
2272
|
+
snapshot
|
|
2273
|
+
}) {
|
|
2274
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
2275
|
+
}
|
|
2276
|
+
async loadWorkflowSnapshot(params) {
|
|
2277
|
+
return this.stores.workflows.loadWorkflowSnapshot(params);
|
|
2278
|
+
}
|
|
2279
|
+
async getWorkflowRuns({
|
|
2280
|
+
workflowName,
|
|
2281
|
+
fromDate,
|
|
2282
|
+
toDate,
|
|
2283
|
+
limit,
|
|
2284
|
+
offset,
|
|
2285
|
+
resourceId
|
|
2286
|
+
} = {}) {
|
|
2287
|
+
return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
|
|
2288
|
+
}
|
|
2289
|
+
async getWorkflowRunById({
|
|
2290
|
+
runId,
|
|
2291
|
+
workflowName
|
|
2292
|
+
}) {
|
|
2293
|
+
return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
|
|
2294
|
+
}
|
|
2295
|
+
/**
|
|
2296
|
+
* Insert multiple records in a batch operation
|
|
2297
|
+
* @param tableName The table to insert into
|
|
2298
|
+
* @param records The records to insert
|
|
2299
|
+
*/
|
|
2300
|
+
async batchInsert({ tableName, records }) {
|
|
2301
|
+
return this.stores.operations.batchInsert({ tableName, records });
|
|
2302
|
+
}
|
|
2303
|
+
/**
|
|
2304
|
+
* @deprecated use getEvals instead
|
|
2305
|
+
*/
|
|
2306
|
+
async getEvalsByAgentName(agentName, type) {
|
|
2307
|
+
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
2308
|
+
}
|
|
2309
|
+
async getEvals(options) {
|
|
2310
|
+
return this.stores.legacyEvals.getEvals(options);
|
|
2311
|
+
}
|
|
2312
|
+
async updateMessages(_args) {
|
|
2313
|
+
return this.stores.memory.updateMessages(_args);
|
|
2314
|
+
}
|
|
2315
|
+
async getResourceById({ resourceId }) {
|
|
2316
|
+
return this.stores.memory.getResourceById({ resourceId });
|
|
2317
|
+
}
|
|
2318
|
+
async saveResource({ resource }) {
|
|
2319
|
+
return this.stores.memory.saveResource({ resource });
|
|
2320
|
+
}
|
|
2321
|
+
async updateResource({
|
|
2322
|
+
resourceId,
|
|
2323
|
+
workingMemory,
|
|
2324
|
+
metadata
|
|
2325
|
+
}) {
|
|
2326
|
+
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
2327
|
+
}
|
|
2328
|
+
async getScoreById({ id: _id }) {
|
|
2329
|
+
return this.stores.scores.getScoreById({ id: _id });
|
|
2330
|
+
}
|
|
2331
|
+
async saveScore(_score) {
|
|
2332
|
+
return this.stores.scores.saveScore(_score);
|
|
2333
|
+
}
|
|
2334
|
+
async getScoresByRunId({
|
|
2335
|
+
runId: _runId,
|
|
2336
|
+
pagination: _pagination
|
|
2337
|
+
}) {
|
|
2338
|
+
return this.stores.scores.getScoresByRunId({ runId: _runId, pagination: _pagination });
|
|
2339
|
+
}
|
|
2340
|
+
async getScoresByEntityId({
|
|
2341
|
+
entityId: _entityId,
|
|
2342
|
+
entityType: _entityType,
|
|
2343
|
+
pagination: _pagination
|
|
2344
|
+
}) {
|
|
2345
|
+
return this.stores.scores.getScoresByEntityId({
|
|
2346
|
+
entityId: _entityId,
|
|
2347
|
+
entityType: _entityType,
|
|
2348
|
+
pagination: _pagination
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
async getScoresByScorerId({
|
|
2352
|
+
scorerId,
|
|
2353
|
+
pagination,
|
|
2354
|
+
entityId,
|
|
2355
|
+
entityType,
|
|
2356
|
+
source
|
|
2357
|
+
}) {
|
|
2358
|
+
return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
|
|
2359
|
+
}
|
|
2360
|
+
async getScoresBySpan({
|
|
2361
|
+
traceId,
|
|
2362
|
+
spanId,
|
|
2363
|
+
pagination
|
|
2364
|
+
}) {
|
|
2365
|
+
return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
|
|
2366
|
+
}
|
|
1642
2367
|
/**
|
|
1643
2368
|
* Close the database connection
|
|
1644
2369
|
* No explicit cleanup needed for D1 in either REST or Workers Binding mode
|
|
@@ -1646,10 +2371,8 @@ var D1Store = class extends storage.MastraStorage {
|
|
|
1646
2371
|
async close() {
|
|
1647
2372
|
this.logger.debug("Closing D1 connection");
|
|
1648
2373
|
}
|
|
1649
|
-
async updateMessages(_args) {
|
|
1650
|
-
this.logger.error("updateMessages is not yet implemented in CloudflareD1Store");
|
|
1651
|
-
throw new Error("Method not implemented");
|
|
1652
|
-
}
|
|
1653
2374
|
};
|
|
1654
2375
|
|
|
1655
2376
|
exports.D1Store = D1Store;
|
|
2377
|
+
//# sourceMappingURL=index.cjs.map
|
|
2378
|
+
//# sourceMappingURL=index.cjs.map
|