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