@mastra/libsql 1.1.0 → 1.2.0
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 +178 -0
- package/dist/docs/README.md +1 -1
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/SOURCE_MAP.json +1 -1
- package/dist/docs/memory/02-storage.md +10 -0
- package/dist/index.cjs +673 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +673 -15
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/agents/index.d.ts +2 -1
- package/dist/storage/domains/agents/index.d.ts.map +1 -1
- package/dist/storage/domains/memory/index.d.ts +14 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -2039,6 +2039,21 @@ Note: This migration may take some time for large tables.
|
|
|
2039
2039
|
};
|
|
2040
2040
|
|
|
2041
2041
|
// src/storage/domains/agents/index.ts
|
|
2042
|
+
var SNAPSHOT_FIELDS = [
|
|
2043
|
+
"name",
|
|
2044
|
+
"description",
|
|
2045
|
+
"instructions",
|
|
2046
|
+
"model",
|
|
2047
|
+
"tools",
|
|
2048
|
+
"defaultOptions",
|
|
2049
|
+
"workflows",
|
|
2050
|
+
"agents",
|
|
2051
|
+
"integrationTools",
|
|
2052
|
+
"inputProcessors",
|
|
2053
|
+
"outputProcessors",
|
|
2054
|
+
"memory",
|
|
2055
|
+
"scorers"
|
|
2056
|
+
];
|
|
2042
2057
|
var AgentsLibSQL = class extends AgentsStorage {
|
|
2043
2058
|
#db;
|
|
2044
2059
|
#client;
|
|
@@ -2164,6 +2179,16 @@ var AgentsLibSQL = class extends AgentsStorage {
|
|
|
2164
2179
|
}
|
|
2165
2180
|
parseJson(value, fieldName) {
|
|
2166
2181
|
if (!value) return void 0;
|
|
2182
|
+
if (value instanceof ArrayBuffer || value && value.constructor && value.constructor.name === "ArrayBuffer") {
|
|
2183
|
+
try {
|
|
2184
|
+
const decoder = new TextDecoder();
|
|
2185
|
+
const jsonString = decoder.decode(value);
|
|
2186
|
+
return JSON.parse(jsonString);
|
|
2187
|
+
} catch (error) {
|
|
2188
|
+
console.error(`Failed to parse ArrayBuffer for ${fieldName}:`, error);
|
|
2189
|
+
return void 0;
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2167
2192
|
if (typeof value !== "string") return value;
|
|
2168
2193
|
try {
|
|
2169
2194
|
return JSON.parse(value);
|
|
@@ -2241,15 +2266,6 @@ var AgentsLibSQL = class extends AgentsStorage {
|
|
|
2241
2266
|
changedFields: Object.keys(snapshotConfig),
|
|
2242
2267
|
changeMessage: "Initial version"
|
|
2243
2268
|
});
|
|
2244
|
-
await this.#db.update({
|
|
2245
|
-
tableName: TABLE_AGENTS,
|
|
2246
|
-
keys: { id: agent.id },
|
|
2247
|
-
data: {
|
|
2248
|
-
activeVersionId: versionId,
|
|
2249
|
-
status: "published",
|
|
2250
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
2251
|
-
}
|
|
2252
|
-
});
|
|
2253
2269
|
const created = await this.getAgentById({ id: agent.id });
|
|
2254
2270
|
if (!created) {
|
|
2255
2271
|
throw new MastraError({
|
|
@@ -2288,16 +2304,57 @@ var AgentsLibSQL = class extends AgentsStorage {
|
|
|
2288
2304
|
details: { agentId: id }
|
|
2289
2305
|
});
|
|
2290
2306
|
}
|
|
2307
|
+
const metadataFields = {
|
|
2308
|
+
authorId: updates.authorId,
|
|
2309
|
+
activeVersionId: updates.activeVersionId,
|
|
2310
|
+
metadata: updates.metadata
|
|
2311
|
+
};
|
|
2312
|
+
const configFields = {};
|
|
2313
|
+
for (const field of SNAPSHOT_FIELDS) {
|
|
2314
|
+
if (updates[field] !== void 0) {
|
|
2315
|
+
configFields[field] = updates[field];
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
if (Object.keys(configFields).length > 0) {
|
|
2319
|
+
const latestVersion = await this.getLatestVersion(id);
|
|
2320
|
+
const nextVersionNumber = latestVersion ? latestVersion.versionNumber + 1 : 1;
|
|
2321
|
+
if (!latestVersion) {
|
|
2322
|
+
throw new MastraError({
|
|
2323
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_AGENT", "NO_VERSION"),
|
|
2324
|
+
domain: ErrorDomain.STORAGE,
|
|
2325
|
+
category: ErrorCategory.USER,
|
|
2326
|
+
text: `Cannot update config fields for agent ${id} - no versions exist`,
|
|
2327
|
+
details: { id }
|
|
2328
|
+
});
|
|
2329
|
+
}
|
|
2330
|
+
const latestSnapshot = {};
|
|
2331
|
+
for (const field of SNAPSHOT_FIELDS) {
|
|
2332
|
+
if (latestVersion[field] !== void 0) {
|
|
2333
|
+
latestSnapshot[field] = latestVersion[field];
|
|
2334
|
+
}
|
|
2335
|
+
}
|
|
2336
|
+
const versionInput = {
|
|
2337
|
+
id: crypto.randomUUID(),
|
|
2338
|
+
agentId: id,
|
|
2339
|
+
versionNumber: nextVersionNumber,
|
|
2340
|
+
...latestSnapshot,
|
|
2341
|
+
// Start from latest version
|
|
2342
|
+
...configFields,
|
|
2343
|
+
// Apply updates
|
|
2344
|
+
changedFields: Object.keys(configFields),
|
|
2345
|
+
changeMessage: `Updated: ${Object.keys(configFields).join(", ")}`
|
|
2346
|
+
};
|
|
2347
|
+
await this.createVersion(versionInput);
|
|
2348
|
+
}
|
|
2291
2349
|
const data = {
|
|
2292
2350
|
updatedAt: /* @__PURE__ */ new Date()
|
|
2293
2351
|
};
|
|
2294
|
-
if (
|
|
2295
|
-
if (
|
|
2296
|
-
data.activeVersionId =
|
|
2297
|
-
data.status = "published";
|
|
2352
|
+
if (metadataFields.authorId !== void 0) data.authorId = metadataFields.authorId;
|
|
2353
|
+
if (metadataFields.activeVersionId !== void 0) {
|
|
2354
|
+
data.activeVersionId = metadataFields.activeVersionId;
|
|
2298
2355
|
}
|
|
2299
|
-
if (
|
|
2300
|
-
data.metadata =
|
|
2356
|
+
if (metadataFields.metadata !== void 0) {
|
|
2357
|
+
data.metadata = metadataFields.metadata;
|
|
2301
2358
|
}
|
|
2302
2359
|
if (Object.keys(data).length > 1) {
|
|
2303
2360
|
await this.#db.update({
|
|
@@ -2404,6 +2461,88 @@ var AgentsLibSQL = class extends AgentsStorage {
|
|
|
2404
2461
|
);
|
|
2405
2462
|
}
|
|
2406
2463
|
}
|
|
2464
|
+
async listAgentsResolved(args) {
|
|
2465
|
+
const { page = 0, perPage: perPageInput, orderBy } = args || {};
|
|
2466
|
+
const { field, direction } = this.parseOrderBy(orderBy);
|
|
2467
|
+
if (page < 0) {
|
|
2468
|
+
throw new MastraError(
|
|
2469
|
+
{
|
|
2470
|
+
id: createStorageErrorId("LIBSQL", "LIST_AGENTS_RESOLVED", "INVALID_PAGE"),
|
|
2471
|
+
domain: ErrorDomain.STORAGE,
|
|
2472
|
+
category: ErrorCategory.USER,
|
|
2473
|
+
details: { page }
|
|
2474
|
+
},
|
|
2475
|
+
new Error("page must be >= 0")
|
|
2476
|
+
);
|
|
2477
|
+
}
|
|
2478
|
+
const perPage = normalizePerPage(perPageInput, 100);
|
|
2479
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
2480
|
+
try {
|
|
2481
|
+
const total = await this.#db.selectTotalCount({ tableName: TABLE_AGENTS });
|
|
2482
|
+
if (total === 0) {
|
|
2483
|
+
return {
|
|
2484
|
+
agents: [],
|
|
2485
|
+
total: 0,
|
|
2486
|
+
page,
|
|
2487
|
+
perPage: perPageForResponse,
|
|
2488
|
+
hasMore: false
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
2492
|
+
const agents = await this.#db.selectMany({
|
|
2493
|
+
tableName: TABLE_AGENTS,
|
|
2494
|
+
orderBy: `"${field}" ${direction}`,
|
|
2495
|
+
limit: limitValue,
|
|
2496
|
+
offset
|
|
2497
|
+
});
|
|
2498
|
+
const resolvedAgents = await Promise.all(
|
|
2499
|
+
agents.map(async (agent) => {
|
|
2500
|
+
let version = null;
|
|
2501
|
+
if (agent.activeVersionId) {
|
|
2502
|
+
version = await this.getVersion(agent.activeVersionId);
|
|
2503
|
+
}
|
|
2504
|
+
if (!version) {
|
|
2505
|
+
version = await this.getLatestVersion(agent.id);
|
|
2506
|
+
}
|
|
2507
|
+
if (!version) {
|
|
2508
|
+
return agent;
|
|
2509
|
+
}
|
|
2510
|
+
return {
|
|
2511
|
+
...agent,
|
|
2512
|
+
name: version.name,
|
|
2513
|
+
description: version.description,
|
|
2514
|
+
instructions: version.instructions,
|
|
2515
|
+
model: version.model,
|
|
2516
|
+
tools: version.tools,
|
|
2517
|
+
defaultOptions: version.defaultOptions,
|
|
2518
|
+
workflows: version.workflows,
|
|
2519
|
+
agents: version.agents,
|
|
2520
|
+
integrationTools: version.integrationTools,
|
|
2521
|
+
inputProcessors: version.inputProcessors,
|
|
2522
|
+
outputProcessors: version.outputProcessors,
|
|
2523
|
+
memory: version.memory,
|
|
2524
|
+
scorers: version.scorers
|
|
2525
|
+
};
|
|
2526
|
+
})
|
|
2527
|
+
);
|
|
2528
|
+
return {
|
|
2529
|
+
agents: resolvedAgents,
|
|
2530
|
+
total,
|
|
2531
|
+
page,
|
|
2532
|
+
perPage: perPageForResponse,
|
|
2533
|
+
hasMore: perPageInput === false ? false : offset + perPage < total
|
|
2534
|
+
};
|
|
2535
|
+
} catch (error) {
|
|
2536
|
+
throw new MastraError(
|
|
2537
|
+
{
|
|
2538
|
+
id: createStorageErrorId("LIBSQL", "LIST_AGENTS_RESOLVED", "FAILED"),
|
|
2539
|
+
domain: ErrorDomain.STORAGE,
|
|
2540
|
+
category: ErrorCategory.THIRD_PARTY
|
|
2541
|
+
},
|
|
2542
|
+
error
|
|
2543
|
+
);
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2407
2546
|
// ==========================================================================
|
|
2408
2547
|
// Agent Version Methods
|
|
2409
2548
|
// ==========================================================================
|
|
@@ -2683,7 +2822,9 @@ var AgentsLibSQL = class extends AgentsStorage {
|
|
|
2683
2822
|
};
|
|
2684
2823
|
}
|
|
2685
2824
|
};
|
|
2825
|
+
var OM_TABLE = "mastra_observational_memory";
|
|
2686
2826
|
var MemoryLibSQL = class extends MemoryStorage {
|
|
2827
|
+
supportsObservationalMemory = true;
|
|
2687
2828
|
#client;
|
|
2688
2829
|
#db;
|
|
2689
2830
|
constructor(config) {
|
|
@@ -2696,16 +2837,42 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2696
2837
|
await this.#db.createTable({ tableName: TABLE_THREADS, schema: TABLE_SCHEMAS[TABLE_THREADS] });
|
|
2697
2838
|
await this.#db.createTable({ tableName: TABLE_MESSAGES, schema: TABLE_SCHEMAS[TABLE_MESSAGES] });
|
|
2698
2839
|
await this.#db.createTable({ tableName: TABLE_RESOURCES, schema: TABLE_SCHEMAS[TABLE_RESOURCES] });
|
|
2840
|
+
let omSchema;
|
|
2841
|
+
try {
|
|
2842
|
+
const { OBSERVATIONAL_MEMORY_TABLE_SCHEMA } = await import('@mastra/core/storage');
|
|
2843
|
+
omSchema = OBSERVATIONAL_MEMORY_TABLE_SCHEMA?.[OM_TABLE];
|
|
2844
|
+
} catch {
|
|
2845
|
+
}
|
|
2846
|
+
if (omSchema) {
|
|
2847
|
+
await this.#db.createTable({
|
|
2848
|
+
tableName: OM_TABLE,
|
|
2849
|
+
schema: omSchema
|
|
2850
|
+
});
|
|
2851
|
+
await this.#db.alterTable({
|
|
2852
|
+
tableName: OM_TABLE,
|
|
2853
|
+
schema: omSchema,
|
|
2854
|
+
ifNotExists: ["observedMessageIds", "observedTimezone"]
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2699
2857
|
await this.#db.alterTable({
|
|
2700
2858
|
tableName: TABLE_MESSAGES,
|
|
2701
2859
|
schema: TABLE_SCHEMAS[TABLE_MESSAGES],
|
|
2702
2860
|
ifNotExists: ["resourceId"]
|
|
2703
2861
|
});
|
|
2862
|
+
if (omSchema) {
|
|
2863
|
+
await this.#client.execute({
|
|
2864
|
+
sql: `CREATE INDEX IF NOT EXISTS idx_om_lookup_key ON "${OM_TABLE}" ("lookupKey")`,
|
|
2865
|
+
args: []
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2704
2868
|
}
|
|
2705
2869
|
async dangerouslyClearAll() {
|
|
2706
2870
|
await this.#db.deleteData({ tableName: TABLE_MESSAGES });
|
|
2707
2871
|
await this.#db.deleteData({ tableName: TABLE_THREADS });
|
|
2708
2872
|
await this.#db.deleteData({ tableName: TABLE_RESOURCES });
|
|
2873
|
+
{
|
|
2874
|
+
await this.#db.deleteData({ tableName: OM_TABLE });
|
|
2875
|
+
}
|
|
2709
2876
|
}
|
|
2710
2877
|
parseRow(row) {
|
|
2711
2878
|
let content = row.content;
|
|
@@ -2933,6 +3100,126 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
2933
3100
|
};
|
|
2934
3101
|
}
|
|
2935
3102
|
}
|
|
3103
|
+
async listMessagesByResourceId(args) {
|
|
3104
|
+
const { resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
3105
|
+
if (!resourceId || typeof resourceId !== "string" || resourceId.trim().length === 0) {
|
|
3106
|
+
throw new MastraError(
|
|
3107
|
+
{
|
|
3108
|
+
id: createStorageErrorId("LIBSQL", "LIST_MESSAGES", "INVALID_QUERY"),
|
|
3109
|
+
domain: ErrorDomain.STORAGE,
|
|
3110
|
+
category: ErrorCategory.USER,
|
|
3111
|
+
details: { resourceId: resourceId ?? "" }
|
|
3112
|
+
},
|
|
3113
|
+
new Error("resourceId is required")
|
|
3114
|
+
);
|
|
3115
|
+
}
|
|
3116
|
+
if (page < 0) {
|
|
3117
|
+
throw new MastraError(
|
|
3118
|
+
{
|
|
3119
|
+
id: createStorageErrorId("LIBSQL", "LIST_MESSAGES", "INVALID_PAGE"),
|
|
3120
|
+
domain: ErrorDomain.STORAGE,
|
|
3121
|
+
category: ErrorCategory.USER,
|
|
3122
|
+
details: { page }
|
|
3123
|
+
},
|
|
3124
|
+
new Error("page must be >= 0")
|
|
3125
|
+
);
|
|
3126
|
+
}
|
|
3127
|
+
const perPage = normalizePerPage(perPageInput, 40);
|
|
3128
|
+
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
|
|
3129
|
+
try {
|
|
3130
|
+
const { field, direction } = this.parseOrderBy(orderBy, "ASC");
|
|
3131
|
+
const orderByStatement = `ORDER BY "${field}" ${direction}`;
|
|
3132
|
+
const conditions = [];
|
|
3133
|
+
const queryParams = [];
|
|
3134
|
+
conditions.push(`"resourceId" = ?`);
|
|
3135
|
+
queryParams.push(resourceId);
|
|
3136
|
+
if (filter?.dateRange?.start) {
|
|
3137
|
+
const startOp = filter.dateRange.startExclusive ? ">" : ">=";
|
|
3138
|
+
conditions.push(`"createdAt" ${startOp} ?`);
|
|
3139
|
+
queryParams.push(
|
|
3140
|
+
filter.dateRange.start instanceof Date ? filter.dateRange.start.toISOString() : filter.dateRange.start
|
|
3141
|
+
);
|
|
3142
|
+
}
|
|
3143
|
+
if (filter?.dateRange?.end) {
|
|
3144
|
+
const endOp = filter.dateRange.endExclusive ? "<" : "<=";
|
|
3145
|
+
conditions.push(`"createdAt" ${endOp} ?`);
|
|
3146
|
+
queryParams.push(
|
|
3147
|
+
filter.dateRange.end instanceof Date ? filter.dateRange.end.toISOString() : filter.dateRange.end
|
|
3148
|
+
);
|
|
3149
|
+
}
|
|
3150
|
+
const whereClause = `WHERE ${conditions.join(" AND ")}`;
|
|
3151
|
+
const countResult = await this.#client.execute({
|
|
3152
|
+
sql: `SELECT COUNT(*) as count FROM ${TABLE_MESSAGES} ${whereClause}`,
|
|
3153
|
+
args: queryParams
|
|
3154
|
+
});
|
|
3155
|
+
const total = Number(countResult.rows?.[0]?.count ?? 0);
|
|
3156
|
+
const limitValue = perPageInput === false ? total : perPage;
|
|
3157
|
+
const dataResult = await this.#client.execute({
|
|
3158
|
+
sql: `SELECT id, content, role, type, "createdAt", "resourceId", "thread_id" FROM ${TABLE_MESSAGES} ${whereClause} ${orderByStatement} LIMIT ? OFFSET ?`,
|
|
3159
|
+
args: [...queryParams, limitValue, offset]
|
|
3160
|
+
});
|
|
3161
|
+
const messages = (dataResult.rows || []).map((row) => this.parseRow(row));
|
|
3162
|
+
if (total === 0 && messages.length === 0 && (!include || include.length === 0)) {
|
|
3163
|
+
return {
|
|
3164
|
+
messages: [],
|
|
3165
|
+
total: 0,
|
|
3166
|
+
page,
|
|
3167
|
+
perPage: perPageForResponse,
|
|
3168
|
+
hasMore: false
|
|
3169
|
+
};
|
|
3170
|
+
}
|
|
3171
|
+
const messageIds = new Set(messages.map((m) => m.id));
|
|
3172
|
+
if (include && include.length > 0) {
|
|
3173
|
+
const includeMessages = await this._getIncludedMessages({ include });
|
|
3174
|
+
if (includeMessages) {
|
|
3175
|
+
for (const includeMsg of includeMessages) {
|
|
3176
|
+
if (!messageIds.has(includeMsg.id)) {
|
|
3177
|
+
messages.push(includeMsg);
|
|
3178
|
+
messageIds.add(includeMsg.id);
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
}
|
|
3182
|
+
}
|
|
3183
|
+
const list = new MessageList().add(messages, "memory");
|
|
3184
|
+
let finalMessages = list.get.all.db();
|
|
3185
|
+
finalMessages = finalMessages.sort((a, b) => {
|
|
3186
|
+
const isDateField = field === "createdAt" || field === "updatedAt";
|
|
3187
|
+
const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
|
|
3188
|
+
const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
|
|
3189
|
+
if (typeof aValue === "number" && typeof bValue === "number") {
|
|
3190
|
+
return direction === "ASC" ? aValue - bValue : bValue - aValue;
|
|
3191
|
+
}
|
|
3192
|
+
return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
|
|
3193
|
+
});
|
|
3194
|
+
const hasMore = perPageInput !== false && offset + perPage < total;
|
|
3195
|
+
return {
|
|
3196
|
+
messages: finalMessages,
|
|
3197
|
+
total,
|
|
3198
|
+
page,
|
|
3199
|
+
perPage: perPageForResponse,
|
|
3200
|
+
hasMore
|
|
3201
|
+
};
|
|
3202
|
+
} catch (error) {
|
|
3203
|
+
const mastraError = new MastraError(
|
|
3204
|
+
{
|
|
3205
|
+
id: createStorageErrorId("LIBSQL", "LIST_MESSAGES", "FAILED"),
|
|
3206
|
+
domain: ErrorDomain.STORAGE,
|
|
3207
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3208
|
+
details: { resourceId }
|
|
3209
|
+
},
|
|
3210
|
+
error
|
|
3211
|
+
);
|
|
3212
|
+
this.logger?.error?.(mastraError.toString());
|
|
3213
|
+
this.logger?.trackException?.(mastraError);
|
|
3214
|
+
return {
|
|
3215
|
+
messages: [],
|
|
3216
|
+
total: 0,
|
|
3217
|
+
page,
|
|
3218
|
+
perPage: perPageForResponse,
|
|
3219
|
+
hasMore: false
|
|
3220
|
+
};
|
|
3221
|
+
}
|
|
3222
|
+
}
|
|
2936
3223
|
async saveMessages({ messages }) {
|
|
2937
3224
|
if (messages.length === 0) return { messages };
|
|
2938
3225
|
try {
|
|
@@ -3590,6 +3877,377 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
3590
3877
|
);
|
|
3591
3878
|
}
|
|
3592
3879
|
}
|
|
3880
|
+
// ============================================
|
|
3881
|
+
// Observational Memory Methods
|
|
3882
|
+
// ============================================
|
|
3883
|
+
getOMKey(threadId, resourceId) {
|
|
3884
|
+
return threadId ? `thread:${threadId}` : `resource:${resourceId}`;
|
|
3885
|
+
}
|
|
3886
|
+
parseOMRow(row) {
|
|
3887
|
+
return {
|
|
3888
|
+
id: row.id,
|
|
3889
|
+
scope: row.scope,
|
|
3890
|
+
threadId: row.threadId || null,
|
|
3891
|
+
resourceId: row.resourceId,
|
|
3892
|
+
createdAt: new Date(row.createdAt),
|
|
3893
|
+
updatedAt: new Date(row.updatedAt),
|
|
3894
|
+
lastObservedAt: row.lastObservedAt ? new Date(row.lastObservedAt) : void 0,
|
|
3895
|
+
originType: row.originType || "initial",
|
|
3896
|
+
generationCount: Number(row.generationCount || 0),
|
|
3897
|
+
activeObservations: row.activeObservations || "",
|
|
3898
|
+
bufferedObservations: row.activeObservationsPendingUpdate || void 0,
|
|
3899
|
+
totalTokensObserved: Number(row.totalTokensObserved || 0),
|
|
3900
|
+
observationTokenCount: Number(row.observationTokenCount || 0),
|
|
3901
|
+
pendingMessageTokens: Number(row.pendingMessageTokens || 0),
|
|
3902
|
+
isReflecting: Boolean(row.isReflecting),
|
|
3903
|
+
isObserving: Boolean(row.isObserving),
|
|
3904
|
+
config: row.config ? JSON.parse(row.config) : {},
|
|
3905
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : void 0,
|
|
3906
|
+
observedMessageIds: row.observedMessageIds ? JSON.parse(row.observedMessageIds) : void 0,
|
|
3907
|
+
observedTimezone: row.observedTimezone || void 0
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
async getObservationalMemory(threadId, resourceId) {
|
|
3911
|
+
try {
|
|
3912
|
+
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
3913
|
+
const result = await this.#client.execute({
|
|
3914
|
+
// Use generationCount DESC for reliable ordering (incremented for each new record)
|
|
3915
|
+
sql: `SELECT * FROM "${OM_TABLE}" WHERE "lookupKey" = ? ORDER BY "generationCount" DESC LIMIT 1`,
|
|
3916
|
+
args: [lookupKey]
|
|
3917
|
+
});
|
|
3918
|
+
if (!result.rows || result.rows.length === 0) return null;
|
|
3919
|
+
return this.parseOMRow(result.rows[0]);
|
|
3920
|
+
} catch (error) {
|
|
3921
|
+
throw new MastraError(
|
|
3922
|
+
{
|
|
3923
|
+
id: createStorageErrorId("LIBSQL", "GET_OBSERVATIONAL_MEMORY", "FAILED"),
|
|
3924
|
+
domain: ErrorDomain.STORAGE,
|
|
3925
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3926
|
+
details: { threadId, resourceId }
|
|
3927
|
+
},
|
|
3928
|
+
error
|
|
3929
|
+
);
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
async getObservationalMemoryHistory(threadId, resourceId, limit = 10) {
|
|
3933
|
+
try {
|
|
3934
|
+
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
3935
|
+
const result = await this.#client.execute({
|
|
3936
|
+
// Use generationCount DESC for reliable ordering (incremented for each new record)
|
|
3937
|
+
sql: `SELECT * FROM "${OM_TABLE}" WHERE "lookupKey" = ? ORDER BY "generationCount" DESC LIMIT ?`,
|
|
3938
|
+
args: [lookupKey, limit]
|
|
3939
|
+
});
|
|
3940
|
+
if (!result.rows) return [];
|
|
3941
|
+
return result.rows.map((row) => this.parseOMRow(row));
|
|
3942
|
+
} catch (error) {
|
|
3943
|
+
throw new MastraError(
|
|
3944
|
+
{
|
|
3945
|
+
id: createStorageErrorId("LIBSQL", "GET_OBSERVATIONAL_MEMORY_HISTORY", "FAILED"),
|
|
3946
|
+
domain: ErrorDomain.STORAGE,
|
|
3947
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
3948
|
+
details: { threadId, resourceId, limit }
|
|
3949
|
+
},
|
|
3950
|
+
error
|
|
3951
|
+
);
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
async initializeObservationalMemory(input) {
|
|
3955
|
+
try {
|
|
3956
|
+
const id = crypto.randomUUID();
|
|
3957
|
+
const now = /* @__PURE__ */ new Date();
|
|
3958
|
+
const lookupKey = this.getOMKey(input.threadId, input.resourceId);
|
|
3959
|
+
const record = {
|
|
3960
|
+
id,
|
|
3961
|
+
scope: input.scope,
|
|
3962
|
+
threadId: input.threadId,
|
|
3963
|
+
resourceId: input.resourceId,
|
|
3964
|
+
createdAt: now,
|
|
3965
|
+
updatedAt: now,
|
|
3966
|
+
lastObservedAt: void 0,
|
|
3967
|
+
originType: "initial",
|
|
3968
|
+
generationCount: 0,
|
|
3969
|
+
activeObservations: "",
|
|
3970
|
+
totalTokensObserved: 0,
|
|
3971
|
+
observationTokenCount: 0,
|
|
3972
|
+
pendingMessageTokens: 0,
|
|
3973
|
+
isReflecting: false,
|
|
3974
|
+
isObserving: false,
|
|
3975
|
+
config: input.config,
|
|
3976
|
+
observedTimezone: input.observedTimezone
|
|
3977
|
+
};
|
|
3978
|
+
await this.#client.execute({
|
|
3979
|
+
sql: `INSERT INTO "${OM_TABLE}" (
|
|
3980
|
+
id, "lookupKey", scope, "resourceId", "threadId",
|
|
3981
|
+
"activeObservations", "activeObservationsPendingUpdate",
|
|
3982
|
+
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
3983
|
+
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
3984
|
+
"isObserving", "isReflecting", "observedTimezone", "createdAt", "updatedAt"
|
|
3985
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
3986
|
+
args: [
|
|
3987
|
+
id,
|
|
3988
|
+
lookupKey,
|
|
3989
|
+
input.scope,
|
|
3990
|
+
input.resourceId,
|
|
3991
|
+
input.threadId || null,
|
|
3992
|
+
"",
|
|
3993
|
+
null,
|
|
3994
|
+
"initial",
|
|
3995
|
+
JSON.stringify(input.config),
|
|
3996
|
+
0,
|
|
3997
|
+
null,
|
|
3998
|
+
null,
|
|
3999
|
+
0,
|
|
4000
|
+
0,
|
|
4001
|
+
0,
|
|
4002
|
+
false,
|
|
4003
|
+
false,
|
|
4004
|
+
input.observedTimezone || null,
|
|
4005
|
+
now.toISOString(),
|
|
4006
|
+
now.toISOString()
|
|
4007
|
+
]
|
|
4008
|
+
});
|
|
4009
|
+
return record;
|
|
4010
|
+
} catch (error) {
|
|
4011
|
+
throw new MastraError(
|
|
4012
|
+
{
|
|
4013
|
+
id: createStorageErrorId("LIBSQL", "INITIALIZE_OBSERVATIONAL_MEMORY", "FAILED"),
|
|
4014
|
+
domain: ErrorDomain.STORAGE,
|
|
4015
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4016
|
+
details: { threadId: input.threadId, resourceId: input.resourceId }
|
|
4017
|
+
},
|
|
4018
|
+
error
|
|
4019
|
+
);
|
|
4020
|
+
}
|
|
4021
|
+
}
|
|
4022
|
+
async updateActiveObservations(input) {
|
|
4023
|
+
try {
|
|
4024
|
+
const now = /* @__PURE__ */ new Date();
|
|
4025
|
+
const observedMessageIdsJson = input.observedMessageIds ? JSON.stringify(input.observedMessageIds) : null;
|
|
4026
|
+
const result = await this.#client.execute({
|
|
4027
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
4028
|
+
"activeObservations" = ?,
|
|
4029
|
+
"lastObservedAt" = ?,
|
|
4030
|
+
"pendingMessageTokens" = 0,
|
|
4031
|
+
"observationTokenCount" = ?,
|
|
4032
|
+
"totalTokensObserved" = "totalTokensObserved" + ?,
|
|
4033
|
+
"observedMessageIds" = ?,
|
|
4034
|
+
"updatedAt" = ?
|
|
4035
|
+
WHERE id = ?`,
|
|
4036
|
+
args: [
|
|
4037
|
+
input.observations,
|
|
4038
|
+
input.lastObservedAt.toISOString(),
|
|
4039
|
+
input.tokenCount,
|
|
4040
|
+
input.tokenCount,
|
|
4041
|
+
observedMessageIdsJson,
|
|
4042
|
+
now.toISOString(),
|
|
4043
|
+
input.id
|
|
4044
|
+
]
|
|
4045
|
+
});
|
|
4046
|
+
if (result.rowsAffected === 0) {
|
|
4047
|
+
throw new MastraError({
|
|
4048
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_ACTIVE_OBSERVATIONS", "NOT_FOUND"),
|
|
4049
|
+
text: `Observational memory record not found: ${input.id}`,
|
|
4050
|
+
domain: ErrorDomain.STORAGE,
|
|
4051
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4052
|
+
details: { id: input.id }
|
|
4053
|
+
});
|
|
4054
|
+
}
|
|
4055
|
+
} catch (error) {
|
|
4056
|
+
if (error instanceof MastraError) {
|
|
4057
|
+
throw error;
|
|
4058
|
+
}
|
|
4059
|
+
throw new MastraError(
|
|
4060
|
+
{
|
|
4061
|
+
id: createStorageErrorId("LIBSQL", "UPDATE_ACTIVE_OBSERVATIONS", "FAILED"),
|
|
4062
|
+
domain: ErrorDomain.STORAGE,
|
|
4063
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4064
|
+
details: { id: input.id }
|
|
4065
|
+
},
|
|
4066
|
+
error
|
|
4067
|
+
);
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
async createReflectionGeneration(input) {
|
|
4071
|
+
try {
|
|
4072
|
+
const id = crypto.randomUUID();
|
|
4073
|
+
const now = /* @__PURE__ */ new Date();
|
|
4074
|
+
const lookupKey = this.getOMKey(input.currentRecord.threadId, input.currentRecord.resourceId);
|
|
4075
|
+
const record = {
|
|
4076
|
+
id,
|
|
4077
|
+
scope: input.currentRecord.scope,
|
|
4078
|
+
threadId: input.currentRecord.threadId,
|
|
4079
|
+
resourceId: input.currentRecord.resourceId,
|
|
4080
|
+
createdAt: now,
|
|
4081
|
+
updatedAt: now,
|
|
4082
|
+
lastObservedAt: input.currentRecord.lastObservedAt,
|
|
4083
|
+
originType: "reflection",
|
|
4084
|
+
generationCount: input.currentRecord.generationCount + 1,
|
|
4085
|
+
activeObservations: input.reflection,
|
|
4086
|
+
totalTokensObserved: input.currentRecord.totalTokensObserved,
|
|
4087
|
+
observationTokenCount: input.tokenCount,
|
|
4088
|
+
pendingMessageTokens: 0,
|
|
4089
|
+
isReflecting: false,
|
|
4090
|
+
isObserving: false,
|
|
4091
|
+
config: input.currentRecord.config,
|
|
4092
|
+
metadata: input.currentRecord.metadata,
|
|
4093
|
+
observedTimezone: input.currentRecord.observedTimezone
|
|
4094
|
+
};
|
|
4095
|
+
await this.#client.execute({
|
|
4096
|
+
sql: `INSERT INTO "${OM_TABLE}" (
|
|
4097
|
+
id, "lookupKey", scope, "resourceId", "threadId",
|
|
4098
|
+
"activeObservations", "activeObservationsPendingUpdate",
|
|
4099
|
+
"originType", config, "generationCount", "lastObservedAt", "lastReflectionAt",
|
|
4100
|
+
"pendingMessageTokens", "totalTokensObserved", "observationTokenCount",
|
|
4101
|
+
"isObserving", "isReflecting", "observedTimezone", "createdAt", "updatedAt"
|
|
4102
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
4103
|
+
args: [
|
|
4104
|
+
id,
|
|
4105
|
+
lookupKey,
|
|
4106
|
+
record.scope,
|
|
4107
|
+
record.resourceId,
|
|
4108
|
+
record.threadId || null,
|
|
4109
|
+
input.reflection,
|
|
4110
|
+
null,
|
|
4111
|
+
"reflection",
|
|
4112
|
+
JSON.stringify(record.config),
|
|
4113
|
+
input.currentRecord.generationCount + 1,
|
|
4114
|
+
record.lastObservedAt?.toISOString() || null,
|
|
4115
|
+
now.toISOString(),
|
|
4116
|
+
record.pendingMessageTokens,
|
|
4117
|
+
record.totalTokensObserved,
|
|
4118
|
+
record.observationTokenCount,
|
|
4119
|
+
false,
|
|
4120
|
+
false,
|
|
4121
|
+
record.observedTimezone || null,
|
|
4122
|
+
now.toISOString(),
|
|
4123
|
+
now.toISOString()
|
|
4124
|
+
]
|
|
4125
|
+
});
|
|
4126
|
+
return record;
|
|
4127
|
+
} catch (error) {
|
|
4128
|
+
throw new MastraError(
|
|
4129
|
+
{
|
|
4130
|
+
id: createStorageErrorId("LIBSQL", "CREATE_REFLECTION_GENERATION", "FAILED"),
|
|
4131
|
+
domain: ErrorDomain.STORAGE,
|
|
4132
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4133
|
+
details: { currentRecordId: input.currentRecord.id }
|
|
4134
|
+
},
|
|
4135
|
+
error
|
|
4136
|
+
);
|
|
4137
|
+
}
|
|
4138
|
+
}
|
|
4139
|
+
async setReflectingFlag(id, isReflecting) {
|
|
4140
|
+
try {
|
|
4141
|
+
const result = await this.#client.execute({
|
|
4142
|
+
sql: `UPDATE "${OM_TABLE}" SET "isReflecting" = ?, "updatedAt" = ? WHERE id = ?`,
|
|
4143
|
+
args: [isReflecting, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
4144
|
+
});
|
|
4145
|
+
if (result.rowsAffected === 0) {
|
|
4146
|
+
throw new MastraError({
|
|
4147
|
+
id: createStorageErrorId("LIBSQL", "SET_REFLECTING_FLAG", "NOT_FOUND"),
|
|
4148
|
+
text: `Observational memory record not found: ${id}`,
|
|
4149
|
+
domain: ErrorDomain.STORAGE,
|
|
4150
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4151
|
+
details: { id, isReflecting }
|
|
4152
|
+
});
|
|
4153
|
+
}
|
|
4154
|
+
} catch (error) {
|
|
4155
|
+
if (error instanceof MastraError) {
|
|
4156
|
+
throw error;
|
|
4157
|
+
}
|
|
4158
|
+
throw new MastraError(
|
|
4159
|
+
{
|
|
4160
|
+
id: createStorageErrorId("LIBSQL", "SET_REFLECTING_FLAG", "FAILED"),
|
|
4161
|
+
domain: ErrorDomain.STORAGE,
|
|
4162
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4163
|
+
details: { id, isReflecting }
|
|
4164
|
+
},
|
|
4165
|
+
error
|
|
4166
|
+
);
|
|
4167
|
+
}
|
|
4168
|
+
}
|
|
4169
|
+
async setObservingFlag(id, isObserving) {
|
|
4170
|
+
try {
|
|
4171
|
+
const result = await this.#client.execute({
|
|
4172
|
+
sql: `UPDATE "${OM_TABLE}" SET "isObserving" = ?, "updatedAt" = ? WHERE id = ?`,
|
|
4173
|
+
args: [isObserving, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
4174
|
+
});
|
|
4175
|
+
if (result.rowsAffected === 0) {
|
|
4176
|
+
throw new MastraError({
|
|
4177
|
+
id: createStorageErrorId("LIBSQL", "SET_OBSERVING_FLAG", "NOT_FOUND"),
|
|
4178
|
+
text: `Observational memory record not found: ${id}`,
|
|
4179
|
+
domain: ErrorDomain.STORAGE,
|
|
4180
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4181
|
+
details: { id, isObserving }
|
|
4182
|
+
});
|
|
4183
|
+
}
|
|
4184
|
+
} catch (error) {
|
|
4185
|
+
if (error instanceof MastraError) {
|
|
4186
|
+
throw error;
|
|
4187
|
+
}
|
|
4188
|
+
throw new MastraError(
|
|
4189
|
+
{
|
|
4190
|
+
id: createStorageErrorId("LIBSQL", "SET_OBSERVING_FLAG", "FAILED"),
|
|
4191
|
+
domain: ErrorDomain.STORAGE,
|
|
4192
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4193
|
+
details: { id, isObserving }
|
|
4194
|
+
},
|
|
4195
|
+
error
|
|
4196
|
+
);
|
|
4197
|
+
}
|
|
4198
|
+
}
|
|
4199
|
+
async clearObservationalMemory(threadId, resourceId) {
|
|
4200
|
+
try {
|
|
4201
|
+
const lookupKey = this.getOMKey(threadId, resourceId);
|
|
4202
|
+
await this.#client.execute({
|
|
4203
|
+
sql: `DELETE FROM "${OM_TABLE}" WHERE "lookupKey" = ?`,
|
|
4204
|
+
args: [lookupKey]
|
|
4205
|
+
});
|
|
4206
|
+
} catch (error) {
|
|
4207
|
+
throw new MastraError(
|
|
4208
|
+
{
|
|
4209
|
+
id: createStorageErrorId("LIBSQL", "CLEAR_OBSERVATIONAL_MEMORY", "FAILED"),
|
|
4210
|
+
domain: ErrorDomain.STORAGE,
|
|
4211
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4212
|
+
details: { threadId, resourceId }
|
|
4213
|
+
},
|
|
4214
|
+
error
|
|
4215
|
+
);
|
|
4216
|
+
}
|
|
4217
|
+
}
|
|
4218
|
+
async addPendingMessageTokens(id, tokenCount) {
|
|
4219
|
+
try {
|
|
4220
|
+
const result = await this.#client.execute({
|
|
4221
|
+
sql: `UPDATE "${OM_TABLE}" SET
|
|
4222
|
+
"pendingMessageTokens" = "pendingMessageTokens" + ?,
|
|
4223
|
+
"updatedAt" = ?
|
|
4224
|
+
WHERE id = ?`,
|
|
4225
|
+
args: [tokenCount, (/* @__PURE__ */ new Date()).toISOString(), id]
|
|
4226
|
+
});
|
|
4227
|
+
if (result.rowsAffected === 0) {
|
|
4228
|
+
throw new MastraError({
|
|
4229
|
+
id: createStorageErrorId("LIBSQL", "ADD_PENDING_MESSAGE_TOKENS", "NOT_FOUND"),
|
|
4230
|
+
text: `Observational memory record not found: ${id}`,
|
|
4231
|
+
domain: ErrorDomain.STORAGE,
|
|
4232
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4233
|
+
details: { id, tokenCount }
|
|
4234
|
+
});
|
|
4235
|
+
}
|
|
4236
|
+
} catch (error) {
|
|
4237
|
+
if (error instanceof MastraError) {
|
|
4238
|
+
throw error;
|
|
4239
|
+
}
|
|
4240
|
+
throw new MastraError(
|
|
4241
|
+
{
|
|
4242
|
+
id: createStorageErrorId("LIBSQL", "ADD_PENDING_MESSAGE_TOKENS", "FAILED"),
|
|
4243
|
+
domain: ErrorDomain.STORAGE,
|
|
4244
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
4245
|
+
details: { id, tokenCount }
|
|
4246
|
+
},
|
|
4247
|
+
error
|
|
4248
|
+
);
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
3593
4251
|
};
|
|
3594
4252
|
var ObservabilityLibSQL = class extends ObservabilityStorage {
|
|
3595
4253
|
#db;
|