@mastra/libsql 0.0.0-studio-deploy-20260404184540 → 0.0.0-studio-cli-20260504022012
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 +132 -3
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-memory-processors.md +3 -3
- package/dist/docs/references/docs-memory-message-history.md +8 -2
- package/dist/docs/references/docs-memory-storage.md +1 -2
- package/dist/docs/references/docs-memory-working-memory.md +2 -2
- package/dist/docs/references/guides-agent-frameworks-ai-sdk.md +4 -4
- package/dist/docs/references/reference-core-mastra-class.md +11 -1
- package/dist/docs/references/reference-storage-composite.md +5 -3
- package/dist/index.cjs +813 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +812 -10
- package/dist/index.js.map +1 -1
- package/dist/storage/db/utils.d.ts.map +1 -1
- package/dist/storage/domains/background-tasks/index.d.ts +18 -0
- package/dist/storage/domains/background-tasks/index.d.ts.map +1 -0
- package/dist/storage/domains/channels/index.d.ts +20 -0
- package/dist/storage/domains/channels/index.d.ts.map +1 -0
- package/dist/storage/domains/experiments/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +3 -2
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/index.d.ts +2 -1
- package/dist/storage/domains/observability/index.d.ts.map +1 -1
- package/dist/storage/domains/schedules/index.d.ts +19 -0
- package/dist/storage/domains/schedules/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +4 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/vector/index.d.ts +14 -1
- package/dist/vector/index.d.ts.map +1 -1
- package/package.json +11 -11
package/dist/index.cjs
CHANGED
|
@@ -511,6 +511,9 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
511
511
|
turso;
|
|
512
512
|
maxRetries;
|
|
513
513
|
initialBackoffMs;
|
|
514
|
+
overFetchMultiplier;
|
|
515
|
+
isMemoryDb;
|
|
516
|
+
vectorIndexes;
|
|
514
517
|
constructor({
|
|
515
518
|
url,
|
|
516
519
|
authToken,
|
|
@@ -518,6 +521,7 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
518
521
|
syncInterval,
|
|
519
522
|
maxRetries = 5,
|
|
520
523
|
initialBackoffMs = 100,
|
|
524
|
+
vectorTopKOverFetchMultiplier = 10,
|
|
521
525
|
id
|
|
522
526
|
}) {
|
|
523
527
|
super({ id });
|
|
@@ -529,10 +533,27 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
529
533
|
});
|
|
530
534
|
this.maxRetries = maxRetries;
|
|
531
535
|
this.initialBackoffMs = initialBackoffMs;
|
|
532
|
-
if (
|
|
536
|
+
if (!Number.isInteger(vectorTopKOverFetchMultiplier) || vectorTopKOverFetchMultiplier < 1) {
|
|
537
|
+
throw new Error("vectorTopKOverFetchMultiplier must be a positive integer");
|
|
538
|
+
}
|
|
539
|
+
this.overFetchMultiplier = vectorTopKOverFetchMultiplier;
|
|
540
|
+
this.isMemoryDb = url.includes(":memory:");
|
|
541
|
+
if (url.includes(`file:`) || this.isMemoryDb) {
|
|
533
542
|
this.turso.execute("PRAGMA journal_mode=WAL;").then(() => this.logger.debug("LibSQLStore: PRAGMA journal_mode=WAL set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA journal_mode=WAL.", err));
|
|
534
543
|
this.turso.execute("PRAGMA busy_timeout = 5000;").then(() => this.logger.debug("LibSQLStore: PRAGMA busy_timeout=5000 set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA busy_timeout=5000.", err));
|
|
535
544
|
}
|
|
545
|
+
this.vectorIndexes = this.isMemoryDb ? Promise.resolve(/* @__PURE__ */ new Set()) : this.discoverVectorIndexes();
|
|
546
|
+
}
|
|
547
|
+
async discoverVectorIndexes() {
|
|
548
|
+
try {
|
|
549
|
+
const result = await this.turso.execute({
|
|
550
|
+
sql: `SELECT name FROM sqlite_master WHERE type='index' AND name LIKE '%_vector_idx'`,
|
|
551
|
+
args: []
|
|
552
|
+
});
|
|
553
|
+
return new Set(result.rows.map((row) => row.name));
|
|
554
|
+
} catch {
|
|
555
|
+
return /* @__PURE__ */ new Set();
|
|
556
|
+
}
|
|
536
557
|
}
|
|
537
558
|
async executeWriteOperationWithRetry(operation, isTransaction = false) {
|
|
538
559
|
let attempts = 0;
|
|
@@ -566,6 +587,40 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
566
587
|
const translator = new LibSQLFilterTranslator();
|
|
567
588
|
return translator.translate(filter);
|
|
568
589
|
}
|
|
590
|
+
async hasVectorIndex(parsedIndexName) {
|
|
591
|
+
const indexes = await this.vectorIndexes;
|
|
592
|
+
return indexes.has(`${parsedIndexName}_vector_idx`);
|
|
593
|
+
}
|
|
594
|
+
async queryWithIndex(parsedIndexName, vectorStr, topK, filter, includeVector, minScore) {
|
|
595
|
+
const translatedFilter = this.transformFilter(filter);
|
|
596
|
+
const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
597
|
+
const hasFilter = filterQuery.length > 0;
|
|
598
|
+
const fetchCount = hasFilter ? topK * this.overFetchMultiplier : topK * 2;
|
|
599
|
+
const embeddingSelect = includeVector ? ", vector_extract(t.embedding) as embedding" : "";
|
|
600
|
+
const filterCondition = hasFilter ? filterQuery.replace(/^\s*WHERE\s+/i, "") : "";
|
|
601
|
+
const whereClause = hasFilter ? `WHERE ${filterCondition} AND score > ?` : "WHERE score > ?";
|
|
602
|
+
const query = `
|
|
603
|
+
WITH candidates AS (
|
|
604
|
+
SELECT t.vector_id AS id,
|
|
605
|
+
(1 - vector_distance_cos(t.embedding, vector32(?))) AS score,
|
|
606
|
+
t.metadata
|
|
607
|
+
${embeddingSelect}
|
|
608
|
+
FROM vector_top_k('${parsedIndexName}_vector_idx', vector32(?), ?) AS v
|
|
609
|
+
JOIN "${parsedIndexName}" AS t ON t.rowid = v.id
|
|
610
|
+
)
|
|
611
|
+
SELECT * FROM candidates
|
|
612
|
+
${whereClause}
|
|
613
|
+
ORDER BY score DESC
|
|
614
|
+
LIMIT ?`;
|
|
615
|
+
const args = [vectorStr, vectorStr, fetchCount, ...filterValues, minScore, topK];
|
|
616
|
+
const result = await this.turso.execute({ sql: query, args });
|
|
617
|
+
return result.rows.map(({ id, score, metadata, embedding }) => ({
|
|
618
|
+
id,
|
|
619
|
+
score,
|
|
620
|
+
metadata: JSON.parse(metadata ?? "{}"),
|
|
621
|
+
...includeVector && embedding && { vector: JSON.parse(embedding) }
|
|
622
|
+
}));
|
|
623
|
+
}
|
|
569
624
|
async query({
|
|
570
625
|
indexName,
|
|
571
626
|
queryVector,
|
|
@@ -596,6 +651,23 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
596
651
|
try {
|
|
597
652
|
const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
|
|
598
653
|
const vectorStr = `[${queryVector.join(",")}]`;
|
|
654
|
+
if (!this.isMemoryDb && await this.hasVectorIndex(parsedIndexName)) {
|
|
655
|
+
try {
|
|
656
|
+
const indexedResults = await this.queryWithIndex(
|
|
657
|
+
parsedIndexName,
|
|
658
|
+
vectorStr,
|
|
659
|
+
topK,
|
|
660
|
+
filter,
|
|
661
|
+
includeVector,
|
|
662
|
+
minScore
|
|
663
|
+
);
|
|
664
|
+
if (!filter || indexedResults.length >= topK) {
|
|
665
|
+
return indexedResults;
|
|
666
|
+
}
|
|
667
|
+
} catch (err) {
|
|
668
|
+
this.logger.warn("LibSQLVector: indexed query failed, falling back to brute-force", err);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
599
671
|
const translatedFilter = this.transformFilter(filter);
|
|
600
672
|
const { sql: filterQuery, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
601
673
|
filterValues.push(minScore);
|
|
@@ -729,6 +801,7 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
729
801
|
`,
|
|
730
802
|
args: []
|
|
731
803
|
});
|
|
804
|
+
void this.vectorIndexes.then((indexes) => indexes.add(`${parsedIndexName}_vector_idx`));
|
|
732
805
|
}
|
|
733
806
|
deleteIndex(args) {
|
|
734
807
|
try {
|
|
@@ -751,6 +824,7 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
751
824
|
sql: `DROP TABLE IF EXISTS ${parsedIndexName}`,
|
|
752
825
|
args: []
|
|
753
826
|
});
|
|
827
|
+
void this.vectorIndexes.then((indexes) => indexes.delete(`${parsedIndexName}_vector_idx`));
|
|
754
828
|
}
|
|
755
829
|
async listIndexes() {
|
|
756
830
|
try {
|
|
@@ -1287,6 +1361,9 @@ function transformFromSqlRow({
|
|
|
1287
1361
|
const dateColumns = new Set(
|
|
1288
1362
|
Object.keys(storage.TABLE_SCHEMAS[tableName]).filter((key) => storage.TABLE_SCHEMAS[tableName][key].type === "timestamp").map((key) => key)
|
|
1289
1363
|
);
|
|
1364
|
+
const booleanColumns = new Set(
|
|
1365
|
+
Object.keys(storage.TABLE_SCHEMAS[tableName]).filter((key) => storage.TABLE_SCHEMAS[tableName][key].type === "boolean").map((key) => key)
|
|
1366
|
+
);
|
|
1290
1367
|
for (const [key, value] of Object.entries(sqlRow)) {
|
|
1291
1368
|
if (value === null || value === void 0) {
|
|
1292
1369
|
result[key] = value;
|
|
@@ -1300,6 +1377,10 @@ function transformFromSqlRow({
|
|
|
1300
1377
|
result[key] = storage.safelyParseJSON(value);
|
|
1301
1378
|
continue;
|
|
1302
1379
|
}
|
|
1380
|
+
if (booleanColumns.has(key)) {
|
|
1381
|
+
result[key] = Boolean(value);
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1303
1384
|
result[key] = value;
|
|
1304
1385
|
}
|
|
1305
1386
|
return result;
|
|
@@ -2884,6 +2965,235 @@ var AgentsLibSQL = class extends storage.AgentsStorage {
|
|
|
2884
2965
|
};
|
|
2885
2966
|
}
|
|
2886
2967
|
};
|
|
2968
|
+
function serializeJson(v) {
|
|
2969
|
+
if (typeof v === "object" && v != null) return JSON.stringify(v);
|
|
2970
|
+
return v ?? null;
|
|
2971
|
+
}
|
|
2972
|
+
function parseJson(val) {
|
|
2973
|
+
if (val == null) return void 0;
|
|
2974
|
+
if (typeof val === "string") {
|
|
2975
|
+
try {
|
|
2976
|
+
return JSON.parse(val);
|
|
2977
|
+
} catch {
|
|
2978
|
+
return val;
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
return val;
|
|
2982
|
+
}
|
|
2983
|
+
function rowToTask(row) {
|
|
2984
|
+
return {
|
|
2985
|
+
id: String(row.id),
|
|
2986
|
+
status: String(row.status),
|
|
2987
|
+
toolName: String(row.tool_name),
|
|
2988
|
+
toolCallId: String(row.tool_call_id),
|
|
2989
|
+
args: parseJson(row.args) ?? {},
|
|
2990
|
+
agentId: String(row.agent_id),
|
|
2991
|
+
threadId: row.thread_id != null ? String(row.thread_id) : void 0,
|
|
2992
|
+
resourceId: row.resource_id != null ? String(row.resource_id) : void 0,
|
|
2993
|
+
runId: String(row.run_id),
|
|
2994
|
+
result: parseJson(row.result),
|
|
2995
|
+
error: parseJson(row.error),
|
|
2996
|
+
retryCount: Number(row.retry_count),
|
|
2997
|
+
maxRetries: Number(row.max_retries),
|
|
2998
|
+
timeoutMs: Number(row.timeout_ms),
|
|
2999
|
+
createdAt: new Date(String(row.createdAt)),
|
|
3000
|
+
startedAt: row.startedAt ? new Date(String(row.startedAt)) : void 0,
|
|
3001
|
+
completedAt: row.completedAt ? new Date(String(row.completedAt)) : void 0
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
var BackgroundTasksLibSQL = class extends storage.BackgroundTasksStorage {
|
|
3005
|
+
#db;
|
|
3006
|
+
#client;
|
|
3007
|
+
constructor(config) {
|
|
3008
|
+
super();
|
|
3009
|
+
const client = resolveClient(config);
|
|
3010
|
+
this.#client = client;
|
|
3011
|
+
this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
|
|
3012
|
+
}
|
|
3013
|
+
async init() {
|
|
3014
|
+
await this.#db.createTable({
|
|
3015
|
+
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
3016
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_BACKGROUND_TASKS]
|
|
3017
|
+
});
|
|
3018
|
+
}
|
|
3019
|
+
async dangerouslyClearAll() {
|
|
3020
|
+
await this.#db.deleteData({ tableName: storage.TABLE_BACKGROUND_TASKS });
|
|
3021
|
+
}
|
|
3022
|
+
async createTask(task) {
|
|
3023
|
+
await this.#db.insert({
|
|
3024
|
+
tableName: storage.TABLE_BACKGROUND_TASKS,
|
|
3025
|
+
record: {
|
|
3026
|
+
id: task.id,
|
|
3027
|
+
tool_call_id: task.toolCallId,
|
|
3028
|
+
tool_name: task.toolName,
|
|
3029
|
+
agent_id: task.agentId,
|
|
3030
|
+
thread_id: task.threadId ?? null,
|
|
3031
|
+
resource_id: task.resourceId ?? null,
|
|
3032
|
+
run_id: task.runId,
|
|
3033
|
+
status: task.status,
|
|
3034
|
+
args: task.args,
|
|
3035
|
+
result: task.result ?? null,
|
|
3036
|
+
error: task.error ?? null,
|
|
3037
|
+
retry_count: task.retryCount,
|
|
3038
|
+
max_retries: task.maxRetries,
|
|
3039
|
+
timeout_ms: task.timeoutMs,
|
|
3040
|
+
createdAt: task.createdAt.toISOString(),
|
|
3041
|
+
startedAt: task.startedAt?.toISOString() ?? null,
|
|
3042
|
+
completedAt: task.completedAt?.toISOString() ?? null
|
|
3043
|
+
}
|
|
3044
|
+
});
|
|
3045
|
+
}
|
|
3046
|
+
async updateTask(taskId, update) {
|
|
3047
|
+
const setClauses = [];
|
|
3048
|
+
const params = [];
|
|
3049
|
+
if ("status" in update) {
|
|
3050
|
+
setClauses.push("status = ?");
|
|
3051
|
+
params.push(update.status);
|
|
3052
|
+
}
|
|
3053
|
+
if ("result" in update) {
|
|
3054
|
+
setClauses.push("result = jsonb(?)");
|
|
3055
|
+
params.push(serializeJson(update.result));
|
|
3056
|
+
}
|
|
3057
|
+
if ("error" in update) {
|
|
3058
|
+
setClauses.push("error = jsonb(?)");
|
|
3059
|
+
params.push(serializeJson(update.error));
|
|
3060
|
+
}
|
|
3061
|
+
if ("retryCount" in update) {
|
|
3062
|
+
setClauses.push("retry_count = ?");
|
|
3063
|
+
params.push(update.retryCount);
|
|
3064
|
+
}
|
|
3065
|
+
if ("startedAt" in update) {
|
|
3066
|
+
setClauses.push("startedAt = ?");
|
|
3067
|
+
params.push(update.startedAt?.toISOString() ?? null);
|
|
3068
|
+
}
|
|
3069
|
+
if ("completedAt" in update) {
|
|
3070
|
+
setClauses.push("completedAt = ?");
|
|
3071
|
+
params.push(update.completedAt?.toISOString() ?? null);
|
|
3072
|
+
}
|
|
3073
|
+
if (setClauses.length === 0) return;
|
|
3074
|
+
params.push(taskId);
|
|
3075
|
+
await this.#client.execute({
|
|
3076
|
+
sql: `UPDATE ${storage.TABLE_BACKGROUND_TASKS} SET ${setClauses.join(", ")} WHERE id = ?`,
|
|
3077
|
+
args: params
|
|
3078
|
+
});
|
|
3079
|
+
}
|
|
3080
|
+
async getTask(taskId) {
|
|
3081
|
+
const result = await this.#client.execute({
|
|
3082
|
+
sql: `SELECT ${buildSelectColumns(storage.TABLE_BACKGROUND_TASKS)} FROM ${storage.TABLE_BACKGROUND_TASKS} WHERE id = ?`,
|
|
3083
|
+
args: [taskId]
|
|
3084
|
+
});
|
|
3085
|
+
const row = result.rows[0];
|
|
3086
|
+
return row ? rowToTask(row) : null;
|
|
3087
|
+
}
|
|
3088
|
+
async listTasks(filter) {
|
|
3089
|
+
const conditions = [];
|
|
3090
|
+
const params = [];
|
|
3091
|
+
if (filter.status) {
|
|
3092
|
+
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
3093
|
+
conditions.push(`status IN (${statuses.map(() => "?").join(", ")})`);
|
|
3094
|
+
params.push(...statuses);
|
|
3095
|
+
}
|
|
3096
|
+
if (filter.agentId) {
|
|
3097
|
+
conditions.push("agent_id = ?");
|
|
3098
|
+
params.push(filter.agentId);
|
|
3099
|
+
}
|
|
3100
|
+
if (filter.threadId) {
|
|
3101
|
+
conditions.push("thread_id = ?");
|
|
3102
|
+
params.push(filter.threadId);
|
|
3103
|
+
}
|
|
3104
|
+
if (filter.runId) {
|
|
3105
|
+
conditions.push("run_id = ?");
|
|
3106
|
+
params.push(filter.runId);
|
|
3107
|
+
}
|
|
3108
|
+
if (filter.resourceId) {
|
|
3109
|
+
conditions.push("resource_id = ?");
|
|
3110
|
+
params.push(filter.resourceId);
|
|
3111
|
+
}
|
|
3112
|
+
if (filter.toolName) {
|
|
3113
|
+
conditions.push("tool_name = ?");
|
|
3114
|
+
params.push(filter.toolName);
|
|
3115
|
+
}
|
|
3116
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3117
|
+
if (filter.fromDate) {
|
|
3118
|
+
conditions.push(`${dateCol} >= ?`);
|
|
3119
|
+
params.push(filter.fromDate.toISOString());
|
|
3120
|
+
}
|
|
3121
|
+
if (filter.toDate) {
|
|
3122
|
+
conditions.push(`${dateCol} < ?`);
|
|
3123
|
+
params.push(filter.toDate.toISOString());
|
|
3124
|
+
}
|
|
3125
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
3126
|
+
const countResult = await this.#client.execute({
|
|
3127
|
+
sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_BACKGROUND_TASKS} ${where}`,
|
|
3128
|
+
args: [...params]
|
|
3129
|
+
});
|
|
3130
|
+
const total = Number(countResult.rows[0]?.count ?? 0);
|
|
3131
|
+
const orderCol = filter.orderBy === "startedAt" ? "startedAt" : filter.orderBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3132
|
+
const direction = filter.orderDirection === "desc" ? "DESC" : "ASC";
|
|
3133
|
+
let sql = `SELECT ${buildSelectColumns(storage.TABLE_BACKGROUND_TASKS)} FROM ${storage.TABLE_BACKGROUND_TASKS} ${where} ORDER BY ${orderCol} ${direction}`;
|
|
3134
|
+
if (filter.perPage != null) {
|
|
3135
|
+
sql += " LIMIT ?";
|
|
3136
|
+
params.push(filter.perPage);
|
|
3137
|
+
if (filter.page != null) {
|
|
3138
|
+
sql += " OFFSET ?";
|
|
3139
|
+
params.push(filter.page * filter.perPage);
|
|
3140
|
+
}
|
|
3141
|
+
}
|
|
3142
|
+
const result = await this.#client.execute({ sql, args: params });
|
|
3143
|
+
return { tasks: result.rows.map((row) => rowToTask(row)), total };
|
|
3144
|
+
}
|
|
3145
|
+
async deleteTask(taskId) {
|
|
3146
|
+
await this.#client.execute({
|
|
3147
|
+
sql: `DELETE FROM ${storage.TABLE_BACKGROUND_TASKS} WHERE id = ?`,
|
|
3148
|
+
args: [taskId]
|
|
3149
|
+
});
|
|
3150
|
+
}
|
|
3151
|
+
async deleteTasks(filter) {
|
|
3152
|
+
const conditions = [];
|
|
3153
|
+
const params = [];
|
|
3154
|
+
if (filter.status) {
|
|
3155
|
+
const statuses = Array.isArray(filter.status) ? filter.status : [filter.status];
|
|
3156
|
+
conditions.push(`status IN (${statuses.map(() => "?").join(", ")})`);
|
|
3157
|
+
params.push(...statuses);
|
|
3158
|
+
}
|
|
3159
|
+
const dateCol = filter.dateFilterBy === "startedAt" ? "startedAt" : filter.dateFilterBy === "completedAt" ? "completedAt" : "createdAt";
|
|
3160
|
+
if (filter.fromDate) {
|
|
3161
|
+
conditions.push(`${dateCol} >= ?`);
|
|
3162
|
+
params.push(filter.fromDate.toISOString());
|
|
3163
|
+
}
|
|
3164
|
+
if (filter.toDate) {
|
|
3165
|
+
conditions.push(`${dateCol} < ?`);
|
|
3166
|
+
params.push(filter.toDate.toISOString());
|
|
3167
|
+
}
|
|
3168
|
+
if (filter.agentId) {
|
|
3169
|
+
conditions.push("agent_id = ?");
|
|
3170
|
+
params.push(filter.agentId);
|
|
3171
|
+
}
|
|
3172
|
+
if (filter.runId) {
|
|
3173
|
+
conditions.push("run_id = ?");
|
|
3174
|
+
params.push(filter.runId);
|
|
3175
|
+
}
|
|
3176
|
+
if (conditions.length === 0) return;
|
|
3177
|
+
await this.#client.execute({
|
|
3178
|
+
sql: `DELETE FROM ${storage.TABLE_BACKGROUND_TASKS} WHERE ${conditions.join(" AND ")}`,
|
|
3179
|
+
args: params
|
|
3180
|
+
});
|
|
3181
|
+
}
|
|
3182
|
+
async getRunningCount() {
|
|
3183
|
+
const result = await this.#client.execute({
|
|
3184
|
+
sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_BACKGROUND_TASKS} WHERE status = 'running'`,
|
|
3185
|
+
args: []
|
|
3186
|
+
});
|
|
3187
|
+
return Number(result.rows[0]?.count ?? 0);
|
|
3188
|
+
}
|
|
3189
|
+
async getRunningCountByAgent(agentId) {
|
|
3190
|
+
const result = await this.#client.execute({
|
|
3191
|
+
sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_BACKGROUND_TASKS} WHERE status = 'running' AND agent_id = ?`,
|
|
3192
|
+
args: [agentId]
|
|
3193
|
+
});
|
|
3194
|
+
return Number(result.rows[0]?.count ?? 0);
|
|
3195
|
+
}
|
|
3196
|
+
};
|
|
2887
3197
|
var BlobsLibSQL = class extends storage.BlobStore {
|
|
2888
3198
|
#db;
|
|
2889
3199
|
#client;
|
|
@@ -2970,6 +3280,149 @@ var BlobsLibSQL = class extends storage.BlobStore {
|
|
|
2970
3280
|
};
|
|
2971
3281
|
}
|
|
2972
3282
|
};
|
|
3283
|
+
var ChannelsLibSQL = class extends storage.ChannelsStorage {
|
|
3284
|
+
#db;
|
|
3285
|
+
#client;
|
|
3286
|
+
static MANAGED_TABLES = [storage.TABLE_CHANNEL_INSTALLATIONS, storage.TABLE_CHANNEL_CONFIG];
|
|
3287
|
+
constructor(config) {
|
|
3288
|
+
super();
|
|
3289
|
+
const client = resolveClient(config);
|
|
3290
|
+
this.#client = client;
|
|
3291
|
+
this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
|
|
3292
|
+
}
|
|
3293
|
+
async init() {
|
|
3294
|
+
await this.#db.createTable({
|
|
3295
|
+
tableName: storage.TABLE_CHANNEL_INSTALLATIONS,
|
|
3296
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_CHANNEL_INSTALLATIONS]
|
|
3297
|
+
});
|
|
3298
|
+
await this.#db.createTable({
|
|
3299
|
+
tableName: storage.TABLE_CHANNEL_CONFIG,
|
|
3300
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_CHANNEL_CONFIG]
|
|
3301
|
+
});
|
|
3302
|
+
await this.#client.execute(
|
|
3303
|
+
`CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_installations_webhook ON "${storage.TABLE_CHANNEL_INSTALLATIONS}" ("webhookId")`
|
|
3304
|
+
);
|
|
3305
|
+
await this.#client.execute(
|
|
3306
|
+
`CREATE INDEX IF NOT EXISTS idx_channel_installations_platform_agent ON "${storage.TABLE_CHANNEL_INSTALLATIONS}" ("platform", "agentId")`
|
|
3307
|
+
);
|
|
3308
|
+
}
|
|
3309
|
+
async dangerouslyClearAll() {
|
|
3310
|
+
await this.#db.deleteData({ tableName: storage.TABLE_CHANNEL_INSTALLATIONS });
|
|
3311
|
+
await this.#db.deleteData({ tableName: storage.TABLE_CHANNEL_CONFIG });
|
|
3312
|
+
}
|
|
3313
|
+
async saveInstallation(installation) {
|
|
3314
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
3315
|
+
await this.#client.execute({
|
|
3316
|
+
sql: `
|
|
3317
|
+
INSERT INTO "${storage.TABLE_CHANNEL_INSTALLATIONS}" (id, platform, agentId, status, webhookId, data, configHash, error, createdAt, updatedAt)
|
|
3318
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
3319
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
3320
|
+
platform = excluded.platform,
|
|
3321
|
+
agentId = excluded.agentId,
|
|
3322
|
+
status = excluded.status,
|
|
3323
|
+
webhookId = excluded.webhookId,
|
|
3324
|
+
data = excluded.data,
|
|
3325
|
+
configHash = excluded.configHash,
|
|
3326
|
+
error = excluded.error,
|
|
3327
|
+
updatedAt = excluded.updatedAt
|
|
3328
|
+
`,
|
|
3329
|
+
args: [
|
|
3330
|
+
installation.id,
|
|
3331
|
+
installation.platform,
|
|
3332
|
+
installation.agentId,
|
|
3333
|
+
installation.status,
|
|
3334
|
+
installation.webhookId ?? null,
|
|
3335
|
+
JSON.stringify(installation.data),
|
|
3336
|
+
installation.configHash ?? null,
|
|
3337
|
+
installation.error ?? null,
|
|
3338
|
+
installation.createdAt?.toISOString() ?? now,
|
|
3339
|
+
now
|
|
3340
|
+
]
|
|
3341
|
+
});
|
|
3342
|
+
}
|
|
3343
|
+
async getInstallation(id) {
|
|
3344
|
+
const result = await this.#client.execute({
|
|
3345
|
+
sql: `SELECT * FROM "${storage.TABLE_CHANNEL_INSTALLATIONS}" WHERE id = ?`,
|
|
3346
|
+
args: [id]
|
|
3347
|
+
});
|
|
3348
|
+
const row = result.rows?.[0];
|
|
3349
|
+
return row ? this.#parseInstallationRow(row) : null;
|
|
3350
|
+
}
|
|
3351
|
+
async getInstallationByAgent(platform, agentId) {
|
|
3352
|
+
const result = await this.#client.execute({
|
|
3353
|
+
sql: `SELECT * FROM "${storage.TABLE_CHANNEL_INSTALLATIONS}" WHERE platform = ? AND agentId = ? ORDER BY CASE status WHEN 'active' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END, updatedAt DESC LIMIT 1`,
|
|
3354
|
+
args: [platform, agentId]
|
|
3355
|
+
});
|
|
3356
|
+
const row = result.rows?.[0];
|
|
3357
|
+
return row ? this.#parseInstallationRow(row) : null;
|
|
3358
|
+
}
|
|
3359
|
+
async getInstallationByWebhookId(webhookId) {
|
|
3360
|
+
const result = await this.#client.execute({
|
|
3361
|
+
sql: `SELECT * FROM "${storage.TABLE_CHANNEL_INSTALLATIONS}" WHERE webhookId = ?`,
|
|
3362
|
+
args: [webhookId]
|
|
3363
|
+
});
|
|
3364
|
+
const row = result.rows?.[0];
|
|
3365
|
+
return row ? this.#parseInstallationRow(row) : null;
|
|
3366
|
+
}
|
|
3367
|
+
async listInstallations(platform) {
|
|
3368
|
+
const result = await this.#client.execute({
|
|
3369
|
+
sql: `SELECT * FROM "${storage.TABLE_CHANNEL_INSTALLATIONS}" WHERE platform = ? ORDER BY createdAt DESC`,
|
|
3370
|
+
args: [platform]
|
|
3371
|
+
});
|
|
3372
|
+
return result.rows.map((row) => this.#parseInstallationRow(row));
|
|
3373
|
+
}
|
|
3374
|
+
async deleteInstallation(id) {
|
|
3375
|
+
await this.#client.execute({
|
|
3376
|
+
sql: `DELETE FROM "${storage.TABLE_CHANNEL_INSTALLATIONS}" WHERE id = ?`,
|
|
3377
|
+
args: [id]
|
|
3378
|
+
});
|
|
3379
|
+
}
|
|
3380
|
+
async saveConfig(config) {
|
|
3381
|
+
await this.#client.execute({
|
|
3382
|
+
sql: `
|
|
3383
|
+
INSERT INTO "${storage.TABLE_CHANNEL_CONFIG}" (platform, data, updatedAt)
|
|
3384
|
+
VALUES (?, ?, ?)
|
|
3385
|
+
ON CONFLICT(platform) DO UPDATE SET
|
|
3386
|
+
data = excluded.data,
|
|
3387
|
+
updatedAt = excluded.updatedAt
|
|
3388
|
+
`,
|
|
3389
|
+
args: [config.platform, JSON.stringify(config.data), config.updatedAt.toISOString()]
|
|
3390
|
+
});
|
|
3391
|
+
}
|
|
3392
|
+
async getConfig(platform) {
|
|
3393
|
+
const result = await this.#client.execute({
|
|
3394
|
+
sql: `SELECT * FROM "${storage.TABLE_CHANNEL_CONFIG}" WHERE platform = ?`,
|
|
3395
|
+
args: [platform]
|
|
3396
|
+
});
|
|
3397
|
+
const row = result.rows?.[0];
|
|
3398
|
+
if (!row) return null;
|
|
3399
|
+
return {
|
|
3400
|
+
platform: row.platform,
|
|
3401
|
+
data: JSON.parse(row.data || "{}"),
|
|
3402
|
+
updatedAt: new Date(row.updatedAt)
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
3405
|
+
async deleteConfig(platform) {
|
|
3406
|
+
await this.#client.execute({
|
|
3407
|
+
sql: `DELETE FROM "${storage.TABLE_CHANNEL_CONFIG}" WHERE platform = ?`,
|
|
3408
|
+
args: [platform]
|
|
3409
|
+
});
|
|
3410
|
+
}
|
|
3411
|
+
#parseInstallationRow(row) {
|
|
3412
|
+
return {
|
|
3413
|
+
id: row.id,
|
|
3414
|
+
platform: row.platform,
|
|
3415
|
+
agentId: row.agentId,
|
|
3416
|
+
status: row.status,
|
|
3417
|
+
webhookId: row.webhookId || void 0,
|
|
3418
|
+
data: JSON.parse(row.data || "{}"),
|
|
3419
|
+
configHash: row.configHash || void 0,
|
|
3420
|
+
error: row.error || void 0,
|
|
3421
|
+
createdAt: new Date(row.createdAt),
|
|
3422
|
+
updatedAt: new Date(row.updatedAt)
|
|
3423
|
+
};
|
|
3424
|
+
}
|
|
3425
|
+
};
|
|
2973
3426
|
function jsonbArg(value) {
|
|
2974
3427
|
return value === void 0 || value === null ? null : JSON.stringify(value);
|
|
2975
3428
|
}
|
|
@@ -3904,6 +4357,16 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
|
|
|
3904
4357
|
tableName: storage.TABLE_EXPERIMENT_RESULTS,
|
|
3905
4358
|
schema: storage.EXPERIMENT_RESULTS_SCHEMA
|
|
3906
4359
|
});
|
|
4360
|
+
await this.#db.alterTable({
|
|
4361
|
+
tableName: storage.TABLE_EXPERIMENTS,
|
|
4362
|
+
schema: storage.EXPERIMENTS_SCHEMA,
|
|
4363
|
+
ifNotExists: ["agentVersion"]
|
|
4364
|
+
});
|
|
4365
|
+
await this.#db.alterTable({
|
|
4366
|
+
tableName: storage.TABLE_EXPERIMENT_RESULTS,
|
|
4367
|
+
schema: storage.EXPERIMENT_RESULTS_SCHEMA,
|
|
4368
|
+
ifNotExists: ["status", "tags"]
|
|
4369
|
+
});
|
|
3907
4370
|
await this.#client.execute({
|
|
3908
4371
|
sql: `CREATE INDEX IF NOT EXISTS idx_experiments_datasetid ON "${storage.TABLE_EXPERIMENTS}" ("datasetId")`,
|
|
3909
4372
|
args: []
|
|
@@ -4124,6 +4587,22 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
|
|
|
4124
4587
|
conditions.push("datasetId = ?");
|
|
4125
4588
|
queryParams.push(args.datasetId);
|
|
4126
4589
|
}
|
|
4590
|
+
if (args.targetType) {
|
|
4591
|
+
conditions.push("targetType = ?");
|
|
4592
|
+
queryParams.push(args.targetType);
|
|
4593
|
+
}
|
|
4594
|
+
if (args.targetId) {
|
|
4595
|
+
conditions.push("targetId = ?");
|
|
4596
|
+
queryParams.push(args.targetId);
|
|
4597
|
+
}
|
|
4598
|
+
if (args.agentVersion) {
|
|
4599
|
+
conditions.push("agentVersion = ?");
|
|
4600
|
+
queryParams.push(args.agentVersion);
|
|
4601
|
+
}
|
|
4602
|
+
if (args.status) {
|
|
4603
|
+
conditions.push("status = ?");
|
|
4604
|
+
queryParams.push(args.status);
|
|
4605
|
+
}
|
|
4127
4606
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
4128
4607
|
const countResult = await this.#client.execute({
|
|
4129
4608
|
sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENTS} ${whereClause}`,
|
|
@@ -4326,6 +4805,14 @@ var ExperimentsLibSQL = class extends storage.ExperimentsStorage {
|
|
|
4326
4805
|
const { page, perPage: perPageInput } = args.pagination;
|
|
4327
4806
|
const conditions = ["experimentId = ?"];
|
|
4328
4807
|
const queryParams = [args.experimentId];
|
|
4808
|
+
if (args.traceId) {
|
|
4809
|
+
conditions.push("traceId = ?");
|
|
4810
|
+
queryParams.push(args.traceId);
|
|
4811
|
+
}
|
|
4812
|
+
if (args.status) {
|
|
4813
|
+
conditions.push("status = ?");
|
|
4814
|
+
queryParams.push(args.status);
|
|
4815
|
+
}
|
|
4329
4816
|
const whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
4330
4817
|
const countResult = await this.#client.execute({
|
|
4331
4818
|
sql: `SELECT COUNT(*) as count FROM ${storage.TABLE_EXPERIMENT_RESULTS} ${whereClause}`,
|
|
@@ -6557,14 +7044,26 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
|
|
|
6557
7044
|
);
|
|
6558
7045
|
}
|
|
6559
7046
|
}
|
|
6560
|
-
async getObservationalMemoryHistory(threadId, resourceId, limit = 10) {
|
|
7047
|
+
async getObservationalMemoryHistory(threadId, resourceId, limit = 10, options) {
|
|
6561
7048
|
try {
|
|
6562
7049
|
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
6563
|
-
const
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
7050
|
+
const conditions = [`"lookupKey" = ?`];
|
|
7051
|
+
const args = [lookupKey];
|
|
7052
|
+
if (options?.from) {
|
|
7053
|
+
conditions.push(`"createdAt" >= ?`);
|
|
7054
|
+
args.push(options.from.toISOString());
|
|
7055
|
+
}
|
|
7056
|
+
if (options?.to) {
|
|
7057
|
+
conditions.push(`"createdAt" <= ?`);
|
|
7058
|
+
args.push(options.to.toISOString());
|
|
7059
|
+
}
|
|
7060
|
+
args.push(limit);
|
|
7061
|
+
let sql = `SELECT * FROM "${OM_TABLE}" WHERE ${conditions.join(" AND ")} ORDER BY "generationCount" DESC LIMIT ?`;
|
|
7062
|
+
if (options?.offset != null) {
|
|
7063
|
+
args.push(options.offset);
|
|
7064
|
+
sql += ` OFFSET ?`;
|
|
7065
|
+
}
|
|
7066
|
+
const result = await this.#client.execute({ sql, args });
|
|
6568
7067
|
if (!result.rows) return [];
|
|
6569
7068
|
return result.rows.map((row) => this.parseOMRow(row));
|
|
6570
7069
|
} catch (error$1) {
|
|
@@ -7034,6 +7533,43 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
|
|
|
7034
7533
|
);
|
|
7035
7534
|
}
|
|
7036
7535
|
}
|
|
7536
|
+
async updateObservationalMemoryConfig(input) {
|
|
7537
|
+
try {
|
|
7538
|
+
const selectResult = await this.#client.execute({
|
|
7539
|
+
sql: `SELECT config FROM "${OM_TABLE}" WHERE id = ?`,
|
|
7540
|
+
args: [input.id]
|
|
7541
|
+
});
|
|
7542
|
+
if (selectResult.rows.length === 0) {
|
|
7543
|
+
throw new error.MastraError({
|
|
7544
|
+
id: storage.createStorageErrorId("LIBSQL", "UPDATE_OM_CONFIG", "NOT_FOUND"),
|
|
7545
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
7546
|
+
domain: error.ErrorDomain.STORAGE,
|
|
7547
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
7548
|
+
details: { id: input.id }
|
|
7549
|
+
});
|
|
7550
|
+
}
|
|
7551
|
+
const row = selectResult.rows[0];
|
|
7552
|
+
const existing = row.config ? JSON.parse(row.config) : {};
|
|
7553
|
+
const merged = this.deepMergeConfig(existing, input.config);
|
|
7554
|
+
await this.#client.execute({
|
|
7555
|
+
sql: `UPDATE "${OM_TABLE}" SET config = ?, "updatedAt" = ? WHERE id = ?`,
|
|
7556
|
+
args: [JSON.stringify(merged), (/* @__PURE__ */ new Date()).toISOString(), input.id]
|
|
7557
|
+
});
|
|
7558
|
+
} catch (error$1) {
|
|
7559
|
+
if (error$1 instanceof error.MastraError) {
|
|
7560
|
+
throw error$1;
|
|
7561
|
+
}
|
|
7562
|
+
throw new error.MastraError(
|
|
7563
|
+
{
|
|
7564
|
+
id: storage.createStorageErrorId("LIBSQL", "UPDATE_OM_CONFIG", "FAILED"),
|
|
7565
|
+
domain: error.ErrorDomain.STORAGE,
|
|
7566
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
7567
|
+
details: { id: input.id }
|
|
7568
|
+
},
|
|
7569
|
+
error$1
|
|
7570
|
+
);
|
|
7571
|
+
}
|
|
7572
|
+
}
|
|
7037
7573
|
// ============================================
|
|
7038
7574
|
// Async Buffering Methods
|
|
7039
7575
|
// ============================================
|
|
@@ -7540,6 +8076,39 @@ var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
|
|
|
7540
8076
|
);
|
|
7541
8077
|
}
|
|
7542
8078
|
}
|
|
8079
|
+
async getTraceLight(args) {
|
|
8080
|
+
const { traceId } = args;
|
|
8081
|
+
try {
|
|
8082
|
+
const spans = await this.#db.selectMany({
|
|
8083
|
+
tableName: storage.TABLE_SPANS,
|
|
8084
|
+
whereClause: { sql: " WHERE traceId = ?", args: [traceId] },
|
|
8085
|
+
orderBy: "startedAt ASC"
|
|
8086
|
+
});
|
|
8087
|
+
if (!spans || spans.length === 0) {
|
|
8088
|
+
return null;
|
|
8089
|
+
}
|
|
8090
|
+
return {
|
|
8091
|
+
traceId,
|
|
8092
|
+
spans: spans.map((span) => {
|
|
8093
|
+
const transformed = transformFromSqlRow({ tableName: storage.TABLE_SPANS, sqlRow: span });
|
|
8094
|
+
const { input, output, attributes, metadata, tags, links, ...light } = transformed;
|
|
8095
|
+
return light;
|
|
8096
|
+
})
|
|
8097
|
+
};
|
|
8098
|
+
} catch (error$1) {
|
|
8099
|
+
throw new error.MastraError(
|
|
8100
|
+
{
|
|
8101
|
+
id: storage.createStorageErrorId("LIBSQL", "GET_TRACE_LIGHT", "FAILED"),
|
|
8102
|
+
domain: error.ErrorDomain.STORAGE,
|
|
8103
|
+
category: error.ErrorCategory.USER,
|
|
8104
|
+
details: {
|
|
8105
|
+
traceId
|
|
8106
|
+
}
|
|
8107
|
+
},
|
|
8108
|
+
error$1
|
|
8109
|
+
);
|
|
8110
|
+
}
|
|
8111
|
+
}
|
|
7543
8112
|
async updateSpan(args) {
|
|
7544
8113
|
const { traceId, spanId, updates } = args;
|
|
7545
8114
|
try {
|
|
@@ -8327,6 +8896,233 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
|
|
|
8327
8896
|
};
|
|
8328
8897
|
}
|
|
8329
8898
|
};
|
|
8899
|
+
function parseJson2(val) {
|
|
8900
|
+
if (val == null) return void 0;
|
|
8901
|
+
if (typeof val === "string") {
|
|
8902
|
+
try {
|
|
8903
|
+
return JSON.parse(val);
|
|
8904
|
+
} catch {
|
|
8905
|
+
return val;
|
|
8906
|
+
}
|
|
8907
|
+
}
|
|
8908
|
+
return val;
|
|
8909
|
+
}
|
|
8910
|
+
function toNumber(val) {
|
|
8911
|
+
if (typeof val === "bigint") return Number(val);
|
|
8912
|
+
return Number(val);
|
|
8913
|
+
}
|
|
8914
|
+
function rowToSchedule(row) {
|
|
8915
|
+
const target = parseJson2(row.target);
|
|
8916
|
+
if (!target) {
|
|
8917
|
+
throw new Error(`Schedule row ${row.id} has invalid target`);
|
|
8918
|
+
}
|
|
8919
|
+
const schedule = {
|
|
8920
|
+
id: String(row.id),
|
|
8921
|
+
target,
|
|
8922
|
+
cron: String(row.cron),
|
|
8923
|
+
status: String(row.status),
|
|
8924
|
+
nextFireAt: toNumber(row.next_fire_at),
|
|
8925
|
+
createdAt: toNumber(row.created_at),
|
|
8926
|
+
updatedAt: toNumber(row.updated_at)
|
|
8927
|
+
};
|
|
8928
|
+
if (row.timezone != null) schedule.timezone = String(row.timezone);
|
|
8929
|
+
if (row.last_fire_at != null) schedule.lastFireAt = toNumber(row.last_fire_at);
|
|
8930
|
+
if (row.last_run_id != null) schedule.lastRunId = String(row.last_run_id);
|
|
8931
|
+
const metadata = parseJson2(row.metadata);
|
|
8932
|
+
if (metadata !== void 0) schedule.metadata = metadata;
|
|
8933
|
+
return schedule;
|
|
8934
|
+
}
|
|
8935
|
+
function rowToTrigger(row) {
|
|
8936
|
+
const trigger = {
|
|
8937
|
+
scheduleId: String(row.schedule_id),
|
|
8938
|
+
runId: String(row.run_id),
|
|
8939
|
+
scheduledFireAt: toNumber(row.scheduled_fire_at),
|
|
8940
|
+
actualFireAt: toNumber(row.actual_fire_at),
|
|
8941
|
+
status: String(row.status)
|
|
8942
|
+
};
|
|
8943
|
+
if (row.error != null) trigger.error = String(row.error);
|
|
8944
|
+
return trigger;
|
|
8945
|
+
}
|
|
8946
|
+
var SchedulesLibSQL = class extends storage.SchedulesStorage {
|
|
8947
|
+
#db;
|
|
8948
|
+
#client;
|
|
8949
|
+
constructor(config) {
|
|
8950
|
+
super();
|
|
8951
|
+
const client = resolveClient(config);
|
|
8952
|
+
this.#client = client;
|
|
8953
|
+
this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
|
|
8954
|
+
}
|
|
8955
|
+
async init() {
|
|
8956
|
+
await this.#db.createTable({
|
|
8957
|
+
tableName: storage.TABLE_SCHEDULES,
|
|
8958
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_SCHEDULES]
|
|
8959
|
+
});
|
|
8960
|
+
await this.#db.createTable({
|
|
8961
|
+
tableName: storage.TABLE_SCHEDULE_TRIGGERS,
|
|
8962
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_SCHEDULE_TRIGGERS]
|
|
8963
|
+
});
|
|
8964
|
+
}
|
|
8965
|
+
async dangerouslyClearAll() {
|
|
8966
|
+
await this.#db.deleteData({ tableName: storage.TABLE_SCHEDULE_TRIGGERS });
|
|
8967
|
+
await this.#db.deleteData({ tableName: storage.TABLE_SCHEDULES });
|
|
8968
|
+
}
|
|
8969
|
+
async createSchedule(schedule) {
|
|
8970
|
+
const existing = await this.getSchedule(schedule.id);
|
|
8971
|
+
if (existing) {
|
|
8972
|
+
throw new Error(`Schedule with id "${schedule.id}" already exists`);
|
|
8973
|
+
}
|
|
8974
|
+
await this.#db.insert({
|
|
8975
|
+
tableName: storage.TABLE_SCHEDULES,
|
|
8976
|
+
record: {
|
|
8977
|
+
id: schedule.id,
|
|
8978
|
+
target: schedule.target,
|
|
8979
|
+
cron: schedule.cron,
|
|
8980
|
+
timezone: schedule.timezone ?? null,
|
|
8981
|
+
status: schedule.status,
|
|
8982
|
+
next_fire_at: schedule.nextFireAt,
|
|
8983
|
+
last_fire_at: schedule.lastFireAt ?? null,
|
|
8984
|
+
last_run_id: schedule.lastRunId ?? null,
|
|
8985
|
+
created_at: schedule.createdAt,
|
|
8986
|
+
updated_at: schedule.updatedAt,
|
|
8987
|
+
metadata: schedule.metadata ?? null
|
|
8988
|
+
}
|
|
8989
|
+
});
|
|
8990
|
+
return schedule;
|
|
8991
|
+
}
|
|
8992
|
+
async getSchedule(id) {
|
|
8993
|
+
const result = await this.#client.execute({
|
|
8994
|
+
sql: `SELECT ${buildSelectColumns(storage.TABLE_SCHEDULES)} FROM ${storage.TABLE_SCHEDULES} WHERE id = ?`,
|
|
8995
|
+
args: [id]
|
|
8996
|
+
});
|
|
8997
|
+
const row = result.rows[0];
|
|
8998
|
+
return row ? rowToSchedule(row) : null;
|
|
8999
|
+
}
|
|
9000
|
+
async listSchedules(filter) {
|
|
9001
|
+
const conditions = [];
|
|
9002
|
+
const params = [];
|
|
9003
|
+
if (filter?.status) {
|
|
9004
|
+
conditions.push("status = ?");
|
|
9005
|
+
params.push(filter.status);
|
|
9006
|
+
}
|
|
9007
|
+
if (filter?.workflowId) {
|
|
9008
|
+
conditions.push("json_extract(target, '$.workflowId') = ?");
|
|
9009
|
+
params.push(filter.workflowId);
|
|
9010
|
+
}
|
|
9011
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
9012
|
+
const result = await this.#client.execute({
|
|
9013
|
+
sql: `SELECT ${buildSelectColumns(storage.TABLE_SCHEDULES)} FROM ${storage.TABLE_SCHEDULES} ${where} ORDER BY created_at ASC`,
|
|
9014
|
+
args: params
|
|
9015
|
+
});
|
|
9016
|
+
return result.rows.map((r) => rowToSchedule(r));
|
|
9017
|
+
}
|
|
9018
|
+
async listDueSchedules(now, limit) {
|
|
9019
|
+
const cap = limit ?? 100;
|
|
9020
|
+
const result = await this.#client.execute({
|
|
9021
|
+
sql: `SELECT ${buildSelectColumns(storage.TABLE_SCHEDULES)} FROM ${storage.TABLE_SCHEDULES}
|
|
9022
|
+
WHERE status = ? AND next_fire_at <= ?
|
|
9023
|
+
ORDER BY next_fire_at ASC
|
|
9024
|
+
LIMIT ?`,
|
|
9025
|
+
args: ["active", now, cap]
|
|
9026
|
+
});
|
|
9027
|
+
return result.rows.map((r) => rowToSchedule(r));
|
|
9028
|
+
}
|
|
9029
|
+
async updateSchedule(id, patch) {
|
|
9030
|
+
const setClauses = [];
|
|
9031
|
+
const params = [];
|
|
9032
|
+
if ("cron" in patch && patch.cron !== void 0) {
|
|
9033
|
+
setClauses.push("cron = ?");
|
|
9034
|
+
params.push(patch.cron);
|
|
9035
|
+
}
|
|
9036
|
+
if ("timezone" in patch) {
|
|
9037
|
+
setClauses.push("timezone = ?");
|
|
9038
|
+
params.push(patch.timezone ?? null);
|
|
9039
|
+
}
|
|
9040
|
+
if ("status" in patch && patch.status !== void 0) {
|
|
9041
|
+
setClauses.push("status = ?");
|
|
9042
|
+
params.push(patch.status);
|
|
9043
|
+
}
|
|
9044
|
+
if ("nextFireAt" in patch && patch.nextFireAt !== void 0) {
|
|
9045
|
+
setClauses.push("next_fire_at = ?");
|
|
9046
|
+
params.push(patch.nextFireAt);
|
|
9047
|
+
}
|
|
9048
|
+
if ("target" in patch && patch.target !== void 0) {
|
|
9049
|
+
setClauses.push("target = jsonb(?)");
|
|
9050
|
+
params.push(JSON.stringify(patch.target));
|
|
9051
|
+
}
|
|
9052
|
+
if ("metadata" in patch) {
|
|
9053
|
+
setClauses.push("metadata = jsonb(?)");
|
|
9054
|
+
params.push(patch.metadata != null ? JSON.stringify(patch.metadata) : null);
|
|
9055
|
+
}
|
|
9056
|
+
setClauses.push("updated_at = ?");
|
|
9057
|
+
params.push(Date.now());
|
|
9058
|
+
params.push(id);
|
|
9059
|
+
if (setClauses.length === 1) {
|
|
9060
|
+
const existing = await this.getSchedule(id);
|
|
9061
|
+
if (!existing) throw new Error(`Schedule ${id} not found`);
|
|
9062
|
+
return existing;
|
|
9063
|
+
}
|
|
9064
|
+
await this.#client.execute({
|
|
9065
|
+
sql: `UPDATE ${storage.TABLE_SCHEDULES} SET ${setClauses.join(", ")} WHERE id = ?`,
|
|
9066
|
+
args: params
|
|
9067
|
+
});
|
|
9068
|
+
const updated = await this.getSchedule(id);
|
|
9069
|
+
if (!updated) throw new Error(`Schedule ${id} not found`);
|
|
9070
|
+
return updated;
|
|
9071
|
+
}
|
|
9072
|
+
async updateScheduleNextFire(id, expectedNextFireAt, newNextFireAt, lastFireAt, lastRunId) {
|
|
9073
|
+
const result = await this.#client.execute({
|
|
9074
|
+
sql: `UPDATE ${storage.TABLE_SCHEDULES}
|
|
9075
|
+
SET next_fire_at = ?, last_fire_at = ?, last_run_id = ?, updated_at = ?
|
|
9076
|
+
WHERE id = ? AND next_fire_at = ? AND status = ?`,
|
|
9077
|
+
args: [newNextFireAt, lastFireAt, lastRunId, Date.now(), id, expectedNextFireAt, "active"]
|
|
9078
|
+
});
|
|
9079
|
+
return (result.rowsAffected ?? 0) > 0;
|
|
9080
|
+
}
|
|
9081
|
+
async deleteSchedule(id) {
|
|
9082
|
+
await this.#client.execute({
|
|
9083
|
+
sql: `DELETE FROM ${storage.TABLE_SCHEDULE_TRIGGERS} WHERE schedule_id = ?`,
|
|
9084
|
+
args: [id]
|
|
9085
|
+
});
|
|
9086
|
+
await this.#client.execute({
|
|
9087
|
+
sql: `DELETE FROM ${storage.TABLE_SCHEDULES} WHERE id = ?`,
|
|
9088
|
+
args: [id]
|
|
9089
|
+
});
|
|
9090
|
+
}
|
|
9091
|
+
async recordTrigger(trigger) {
|
|
9092
|
+
await this.#db.insert({
|
|
9093
|
+
tableName: storage.TABLE_SCHEDULE_TRIGGERS,
|
|
9094
|
+
record: {
|
|
9095
|
+
schedule_id: trigger.scheduleId,
|
|
9096
|
+
run_id: trigger.runId,
|
|
9097
|
+
scheduled_fire_at: trigger.scheduledFireAt,
|
|
9098
|
+
actual_fire_at: trigger.actualFireAt,
|
|
9099
|
+
status: trigger.status,
|
|
9100
|
+
error: trigger.error ?? null
|
|
9101
|
+
}
|
|
9102
|
+
});
|
|
9103
|
+
}
|
|
9104
|
+
async listTriggers(scheduleId, opts) {
|
|
9105
|
+
const conditions = ["schedule_id = ?"];
|
|
9106
|
+
const params = [scheduleId];
|
|
9107
|
+
if (opts?.fromActualFireAt != null) {
|
|
9108
|
+
conditions.push("actual_fire_at >= ?");
|
|
9109
|
+
params.push(opts.fromActualFireAt);
|
|
9110
|
+
}
|
|
9111
|
+
if (opts?.toActualFireAt != null) {
|
|
9112
|
+
conditions.push("actual_fire_at < ?");
|
|
9113
|
+
params.push(opts.toActualFireAt);
|
|
9114
|
+
}
|
|
9115
|
+
const limitClause = opts?.limit != null ? `LIMIT ${Math.floor(opts.limit)}` : "";
|
|
9116
|
+
const result = await this.#client.execute({
|
|
9117
|
+
sql: `SELECT ${buildSelectColumns(storage.TABLE_SCHEDULE_TRIGGERS)} FROM ${storage.TABLE_SCHEDULE_TRIGGERS}
|
|
9118
|
+
WHERE ${conditions.join(" AND ")}
|
|
9119
|
+
ORDER BY actual_fire_at DESC
|
|
9120
|
+
${limitClause}`,
|
|
9121
|
+
args: params
|
|
9122
|
+
});
|
|
9123
|
+
return result.rows.map((r) => rowToTrigger(r));
|
|
9124
|
+
}
|
|
9125
|
+
};
|
|
8330
9126
|
var ScorerDefinitionsLibSQL = class extends storage.ScorerDefinitionsStorage {
|
|
8331
9127
|
#db;
|
|
8332
9128
|
#client;
|
|
@@ -10547,6 +11343,7 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
|
|
|
10547
11343
|
const memory = new MemoryLibSQL(domainConfig);
|
|
10548
11344
|
const observability = new ObservabilityLibSQL(domainConfig);
|
|
10549
11345
|
const agents = new AgentsLibSQL(domainConfig);
|
|
11346
|
+
const channels = new ChannelsLibSQL(domainConfig);
|
|
10550
11347
|
const datasets = new DatasetsLibSQL(domainConfig);
|
|
10551
11348
|
const experiments = new ExperimentsLibSQL(domainConfig);
|
|
10552
11349
|
const promptBlocks = new PromptBlocksLibSQL(domainConfig);
|
|
@@ -10556,12 +11353,15 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
|
|
|
10556
11353
|
const workspaces = new WorkspacesLibSQL(domainConfig);
|
|
10557
11354
|
const skills = new SkillsLibSQL(domainConfig);
|
|
10558
11355
|
const blobs = new BlobsLibSQL(domainConfig);
|
|
11356
|
+
const backgroundTasks = new BackgroundTasksLibSQL(domainConfig);
|
|
11357
|
+
const schedules = new SchedulesLibSQL(domainConfig);
|
|
10559
11358
|
this.stores = {
|
|
10560
11359
|
scores,
|
|
10561
11360
|
workflows,
|
|
10562
11361
|
memory,
|
|
10563
11362
|
observability,
|
|
10564
11363
|
agents,
|
|
11364
|
+
channels,
|
|
10565
11365
|
datasets,
|
|
10566
11366
|
experiments,
|
|
10567
11367
|
promptBlocks,
|
|
@@ -10570,7 +11370,9 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
|
|
|
10570
11370
|
mcpServers,
|
|
10571
11371
|
workspaces,
|
|
10572
11372
|
skills,
|
|
10573
|
-
blobs
|
|
11373
|
+
blobs,
|
|
11374
|
+
backgroundTasks,
|
|
11375
|
+
schedules
|
|
10574
11376
|
};
|
|
10575
11377
|
}
|
|
10576
11378
|
};
|
|
@@ -10675,7 +11477,9 @@ Example Complex Query:
|
|
|
10675
11477
|
}`;
|
|
10676
11478
|
|
|
10677
11479
|
exports.AgentsLibSQL = AgentsLibSQL;
|
|
11480
|
+
exports.BackgroundTasksLibSQL = BackgroundTasksLibSQL;
|
|
10678
11481
|
exports.BlobsLibSQL = BlobsLibSQL;
|
|
11482
|
+
exports.ChannelsLibSQL = ChannelsLibSQL;
|
|
10679
11483
|
exports.DatasetsLibSQL = DatasetsLibSQL;
|
|
10680
11484
|
exports.DefaultStorage = LibSQLStore;
|
|
10681
11485
|
exports.ExperimentsLibSQL = ExperimentsLibSQL;
|
|
@@ -10687,6 +11491,7 @@ exports.MCPServersLibSQL = MCPServersLibSQL;
|
|
|
10687
11491
|
exports.MemoryLibSQL = MemoryLibSQL;
|
|
10688
11492
|
exports.ObservabilityLibSQL = ObservabilityLibSQL;
|
|
10689
11493
|
exports.PromptBlocksLibSQL = PromptBlocksLibSQL;
|
|
11494
|
+
exports.SchedulesLibSQL = SchedulesLibSQL;
|
|
10690
11495
|
exports.ScorerDefinitionsLibSQL = ScorerDefinitionsLibSQL;
|
|
10691
11496
|
exports.ScoresLibSQL = ScoresLibSQL;
|
|
10692
11497
|
exports.SkillsLibSQL = SkillsLibSQL;
|