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