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