@mastra/libsql 1.0.0-beta.4 → 1.0.0-beta.6

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 CHANGED
@@ -1,5 +1,69 @@
1
1
  # @mastra/libsql
2
2
 
3
+ ## 1.0.0-beta.6
4
+
5
+ ### Minor Changes
6
+
7
+ - Add stored agents support ([#10953](https://github.com/mastra-ai/mastra/pull/10953))
8
+
9
+ Agents can now be stored in the database and loaded at runtime. This lets you persist agent configurations and dynamically create executable Agent instances from storage.
10
+
11
+ ```typescript
12
+ import { Mastra } from '@mastra/core';
13
+ import { LibSQLStore } from '@mastra/libsql';
14
+
15
+ const mastra = new Mastra({
16
+ storage: new LibSQLStore({ url: ':memory:' }),
17
+ tools: { myTool },
18
+ scorers: { myScorer },
19
+ });
20
+
21
+ // Create agent in storage via API or directly
22
+ await mastra.getStorage().createAgent({
23
+ agent: {
24
+ id: 'my-agent',
25
+ name: 'My Agent',
26
+ instructions: 'You are helpful',
27
+ model: { provider: 'openai', name: 'gpt-4' },
28
+ tools: { myTool: {} },
29
+ scorers: { myScorer: { sampling: { type: 'ratio', rate: 0.5 } } },
30
+ },
31
+ });
32
+
33
+ // Load and use the agent
34
+ const agent = await mastra.getStoredAgentById('my-agent');
35
+ const response = await agent.generate({ messages: 'Hello!' });
36
+
37
+ // List all stored agents with pagination
38
+ const { agents, total, hasMore } = await mastra.listStoredAgents({
39
+ page: 0,
40
+ perPage: 10,
41
+ });
42
+ ```
43
+
44
+ Also adds a memory registry to Mastra so stored agents can reference memory instances by key.
45
+
46
+ ### Patch Changes
47
+
48
+ - Updated dependencies [[`72df8ae`](https://github.com/mastra-ai/mastra/commit/72df8ae595584cdd7747d5c39ffaca45e4507227), [`9198899`](https://github.com/mastra-ai/mastra/commit/91988995c427b185c33714b7f3be955367911324), [`653e65a`](https://github.com/mastra-ai/mastra/commit/653e65ae1f9502c2958a32f47a5a2df11e612a92), [`c6fd6fe`](https://github.com/mastra-ai/mastra/commit/c6fd6fedd09e9cf8004b03a80925f5e94826ad7e), [`0bed332`](https://github.com/mastra-ai/mastra/commit/0bed332843f627202c6520eaf671771313cd20f3)]:
49
+ - @mastra/core@1.0.0-beta.9
50
+
51
+ ## 1.0.0-beta.5
52
+
53
+ ### Patch Changes
54
+
55
+ - Fix saveScore not persisting ID correctly, breaking getScoreById retrieval ([#10915](https://github.com/mastra-ai/mastra/pull/10915))
56
+
57
+ **What Changed**
58
+ - saveScore now correctly returns scores that can be retrieved with getScoreById
59
+ - Validation errors now include contextual information (scorer, entity, trace details) for easier debugging
60
+
61
+ **Impact**
62
+ Previously, calling getScoreById after saveScore would return null because the generated ID wasn't persisted to the database. This is now fixed across all store implementations, ensuring consistent behavior and data integrity.
63
+
64
+ - Updated dependencies [[`0d41fe2`](https://github.com/mastra-ai/mastra/commit/0d41fe245355dfc66d61a0d9c85d9400aac351ff), [`6b3ba91`](https://github.com/mastra-ai/mastra/commit/6b3ba91494cc10394df96782f349a4f7b1e152cc), [`7907fd1`](https://github.com/mastra-ai/mastra/commit/7907fd1c5059813b7b870b81ca71041dc807331b)]:
65
+ - @mastra/core@1.0.0-beta.8
66
+
3
67
  ## 1.0.0-beta.4
4
68
 
5
69
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -1094,6 +1094,298 @@ var LibSQLVector = class extends vector.MastraVector {
1094
1094
  });
1095
1095
  }
1096
1096
  };
1097
+ var AgentsLibSQL = class extends storage.AgentsStorage {
1098
+ client;
1099
+ constructor({ client, operations: _ }) {
1100
+ super();
1101
+ this.client = client;
1102
+ }
1103
+ parseJson(value, fieldName) {
1104
+ if (!value) return void 0;
1105
+ if (typeof value !== "string") return value;
1106
+ try {
1107
+ return JSON.parse(value);
1108
+ } catch (error$1) {
1109
+ const details = {
1110
+ value: value.length > 100 ? value.substring(0, 100) + "..." : value
1111
+ };
1112
+ if (fieldName) {
1113
+ details.field = fieldName;
1114
+ }
1115
+ throw new error.MastraError(
1116
+ {
1117
+ id: storage.createStorageErrorId("LIBSQL", "PARSE_JSON", "INVALID_JSON"),
1118
+ domain: error.ErrorDomain.STORAGE,
1119
+ category: error.ErrorCategory.SYSTEM,
1120
+ text: `Failed to parse JSON${fieldName ? ` for field "${fieldName}"` : ""}: ${error$1 instanceof Error ? error$1.message : "Unknown error"}`,
1121
+ details
1122
+ },
1123
+ error$1
1124
+ );
1125
+ }
1126
+ }
1127
+ parseRow(row) {
1128
+ return {
1129
+ id: row.id,
1130
+ name: row.name,
1131
+ description: row.description,
1132
+ instructions: row.instructions,
1133
+ model: this.parseJson(row.model, "model"),
1134
+ tools: this.parseJson(row.tools, "tools"),
1135
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
1136
+ workflows: this.parseJson(row.workflows, "workflows"),
1137
+ agents: this.parseJson(row.agents, "agents"),
1138
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
1139
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
1140
+ memory: this.parseJson(row.memory, "memory"),
1141
+ scorers: this.parseJson(row.scorers, "scorers"),
1142
+ metadata: this.parseJson(row.metadata, "metadata"),
1143
+ createdAt: new Date(row.createdAt),
1144
+ updatedAt: new Date(row.updatedAt)
1145
+ };
1146
+ }
1147
+ async getAgentById({ id }) {
1148
+ try {
1149
+ const result = await this.client.execute({
1150
+ sql: `SELECT * FROM "${storage.TABLE_AGENTS}" WHERE id = ?`,
1151
+ args: [id]
1152
+ });
1153
+ if (!result.rows || result.rows.length === 0) {
1154
+ return null;
1155
+ }
1156
+ return this.parseRow(result.rows[0]);
1157
+ } catch (error$1) {
1158
+ throw new error.MastraError(
1159
+ {
1160
+ id: storage.createStorageErrorId("LIBSQL", "GET_AGENT_BY_ID", "FAILED"),
1161
+ domain: error.ErrorDomain.STORAGE,
1162
+ category: error.ErrorCategory.THIRD_PARTY,
1163
+ details: { agentId: id }
1164
+ },
1165
+ error$1
1166
+ );
1167
+ }
1168
+ }
1169
+ async createAgent({ agent }) {
1170
+ try {
1171
+ const now = /* @__PURE__ */ new Date();
1172
+ const nowIso = now.toISOString();
1173
+ await this.client.execute({
1174
+ sql: `INSERT INTO "${storage.TABLE_AGENTS}" (id, name, description, instructions, model, tools, "defaultOptions", workflows, agents, "inputProcessors", "outputProcessors", memory, scorers, metadata, "createdAt", "updatedAt")
1175
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
1176
+ args: [
1177
+ agent.id,
1178
+ agent.name,
1179
+ agent.description ?? null,
1180
+ agent.instructions,
1181
+ JSON.stringify(agent.model),
1182
+ agent.tools ? JSON.stringify(agent.tools) : null,
1183
+ agent.defaultOptions ? JSON.stringify(agent.defaultOptions) : null,
1184
+ agent.workflows ? JSON.stringify(agent.workflows) : null,
1185
+ agent.agents ? JSON.stringify(agent.agents) : null,
1186
+ agent.inputProcessors ? JSON.stringify(agent.inputProcessors) : null,
1187
+ agent.outputProcessors ? JSON.stringify(agent.outputProcessors) : null,
1188
+ agent.memory ? JSON.stringify(agent.memory) : null,
1189
+ agent.scorers ? JSON.stringify(agent.scorers) : null,
1190
+ agent.metadata ? JSON.stringify(agent.metadata) : null,
1191
+ nowIso,
1192
+ nowIso
1193
+ ]
1194
+ });
1195
+ return {
1196
+ ...agent,
1197
+ createdAt: now,
1198
+ updatedAt: now
1199
+ };
1200
+ } catch (error$1) {
1201
+ throw new error.MastraError(
1202
+ {
1203
+ id: storage.createStorageErrorId("LIBSQL", "CREATE_AGENT", "FAILED"),
1204
+ domain: error.ErrorDomain.STORAGE,
1205
+ category: error.ErrorCategory.THIRD_PARTY,
1206
+ details: { agentId: agent.id }
1207
+ },
1208
+ error$1
1209
+ );
1210
+ }
1211
+ }
1212
+ async updateAgent({ id, ...updates }) {
1213
+ try {
1214
+ const existingAgent = await this.getAgentById({ id });
1215
+ if (!existingAgent) {
1216
+ throw new error.MastraError({
1217
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_AGENT", "NOT_FOUND"),
1218
+ domain: error.ErrorDomain.STORAGE,
1219
+ category: error.ErrorCategory.USER,
1220
+ text: `Agent ${id} not found`,
1221
+ details: { agentId: id }
1222
+ });
1223
+ }
1224
+ const setClauses = [];
1225
+ const args = [];
1226
+ if (updates.name !== void 0) {
1227
+ setClauses.push("name = ?");
1228
+ args.push(updates.name);
1229
+ }
1230
+ if (updates.description !== void 0) {
1231
+ setClauses.push("description = ?");
1232
+ args.push(updates.description);
1233
+ }
1234
+ if (updates.instructions !== void 0) {
1235
+ setClauses.push("instructions = ?");
1236
+ args.push(updates.instructions);
1237
+ }
1238
+ if (updates.model !== void 0) {
1239
+ setClauses.push("model = ?");
1240
+ args.push(JSON.stringify(updates.model));
1241
+ }
1242
+ if (updates.tools !== void 0) {
1243
+ setClauses.push("tools = ?");
1244
+ args.push(JSON.stringify(updates.tools));
1245
+ }
1246
+ if (updates.defaultOptions !== void 0) {
1247
+ setClauses.push('"defaultOptions" = ?');
1248
+ args.push(JSON.stringify(updates.defaultOptions));
1249
+ }
1250
+ if (updates.workflows !== void 0) {
1251
+ setClauses.push("workflows = ?");
1252
+ args.push(JSON.stringify(updates.workflows));
1253
+ }
1254
+ if (updates.agents !== void 0) {
1255
+ setClauses.push("agents = ?");
1256
+ args.push(JSON.stringify(updates.agents));
1257
+ }
1258
+ if (updates.inputProcessors !== void 0) {
1259
+ setClauses.push('"inputProcessors" = ?');
1260
+ args.push(JSON.stringify(updates.inputProcessors));
1261
+ }
1262
+ if (updates.outputProcessors !== void 0) {
1263
+ setClauses.push('"outputProcessors" = ?');
1264
+ args.push(JSON.stringify(updates.outputProcessors));
1265
+ }
1266
+ if (updates.memory !== void 0) {
1267
+ setClauses.push("memory = ?");
1268
+ args.push(JSON.stringify(updates.memory));
1269
+ }
1270
+ if (updates.scorers !== void 0) {
1271
+ setClauses.push("scorers = ?");
1272
+ args.push(JSON.stringify(updates.scorers));
1273
+ }
1274
+ if (updates.metadata !== void 0) {
1275
+ const mergedMetadata = { ...existingAgent.metadata, ...updates.metadata };
1276
+ setClauses.push("metadata = ?");
1277
+ args.push(JSON.stringify(mergedMetadata));
1278
+ }
1279
+ const now = /* @__PURE__ */ new Date();
1280
+ setClauses.push('"updatedAt" = ?');
1281
+ args.push(now.toISOString());
1282
+ args.push(id);
1283
+ if (setClauses.length > 1) {
1284
+ await this.client.execute({
1285
+ sql: `UPDATE "${storage.TABLE_AGENTS}" SET ${setClauses.join(", ")} WHERE id = ?`,
1286
+ args
1287
+ });
1288
+ }
1289
+ const updatedAgent = await this.getAgentById({ id });
1290
+ if (!updatedAgent) {
1291
+ throw new error.MastraError({
1292
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_AGENT", "NOT_FOUND_AFTER_UPDATE"),
1293
+ domain: error.ErrorDomain.STORAGE,
1294
+ category: error.ErrorCategory.SYSTEM,
1295
+ text: `Agent ${id} not found after update`,
1296
+ details: { agentId: id }
1297
+ });
1298
+ }
1299
+ return updatedAgent;
1300
+ } catch (error$1) {
1301
+ if (error$1 instanceof error.MastraError) {
1302
+ throw error$1;
1303
+ }
1304
+ throw new error.MastraError(
1305
+ {
1306
+ id: storage.createStorageErrorId("LIBSQL", "UPDATE_AGENT", "FAILED"),
1307
+ domain: error.ErrorDomain.STORAGE,
1308
+ category: error.ErrorCategory.THIRD_PARTY,
1309
+ details: { agentId: id }
1310
+ },
1311
+ error$1
1312
+ );
1313
+ }
1314
+ }
1315
+ async deleteAgent({ id }) {
1316
+ try {
1317
+ await this.client.execute({
1318
+ sql: `DELETE FROM "${storage.TABLE_AGENTS}" WHERE id = ?`,
1319
+ args: [id]
1320
+ });
1321
+ } catch (error$1) {
1322
+ throw new error.MastraError(
1323
+ {
1324
+ id: storage.createStorageErrorId("LIBSQL", "DELETE_AGENT", "FAILED"),
1325
+ domain: error.ErrorDomain.STORAGE,
1326
+ category: error.ErrorCategory.THIRD_PARTY,
1327
+ details: { agentId: id }
1328
+ },
1329
+ error$1
1330
+ );
1331
+ }
1332
+ }
1333
+ async listAgents(args) {
1334
+ const { page = 0, perPage: perPageInput, orderBy } = args || {};
1335
+ const { field, direction } = this.parseOrderBy(orderBy);
1336
+ if (page < 0) {
1337
+ throw new error.MastraError(
1338
+ {
1339
+ id: storage.createStorageErrorId("LIBSQL", "LIST_AGENTS", "INVALID_PAGE"),
1340
+ domain: error.ErrorDomain.STORAGE,
1341
+ category: error.ErrorCategory.USER,
1342
+ details: { page }
1343
+ },
1344
+ new Error("page must be >= 0")
1345
+ );
1346
+ }
1347
+ const perPage = storage.normalizePerPage(perPageInput, 100);
1348
+ const { offset, perPage: perPageForResponse } = storage.calculatePagination(page, perPageInput, perPage);
1349
+ try {
1350
+ const countResult = await this.client.execute({
1351
+ sql: `SELECT COUNT(*) as count FROM "${storage.TABLE_AGENTS}"`,
1352
+ args: []
1353
+ });
1354
+ const total = Number(countResult.rows?.[0]?.count ?? 0);
1355
+ if (total === 0) {
1356
+ return {
1357
+ agents: [],
1358
+ total: 0,
1359
+ page,
1360
+ perPage: perPageForResponse,
1361
+ hasMore: false
1362
+ };
1363
+ }
1364
+ const limitValue = perPageInput === false ? total : perPage;
1365
+ const dataResult = await this.client.execute({
1366
+ sql: `SELECT * FROM "${storage.TABLE_AGENTS}" ORDER BY "${field}" ${direction} LIMIT ? OFFSET ?`,
1367
+ args: [limitValue, offset]
1368
+ });
1369
+ const agents = (dataResult.rows || []).map((row) => this.parseRow(row));
1370
+ return {
1371
+ agents,
1372
+ total,
1373
+ page,
1374
+ perPage: perPageForResponse,
1375
+ hasMore: perPageInput === false ? false : offset + perPage < total
1376
+ };
1377
+ } catch (error$1) {
1378
+ throw new error.MastraError(
1379
+ {
1380
+ id: storage.createStorageErrorId("LIBSQL", "LIST_AGENTS", "FAILED"),
1381
+ domain: error.ErrorDomain.STORAGE,
1382
+ category: error.ErrorCategory.THIRD_PARTY
1383
+ },
1384
+ error$1
1385
+ );
1386
+ }
1387
+ }
1388
+ };
1097
1389
  var MemoryLibSQL = class extends storage.MemoryStorage {
1098
1390
  client;
1099
1391
  operations;
@@ -2755,11 +3047,11 @@ var ScoresLibSQL = class extends storage.ScoresStorage {
2755
3047
  domain: error.ErrorDomain.STORAGE,
2756
3048
  category: error.ErrorCategory.USER,
2757
3049
  details: {
2758
- scorer: score.scorer.id,
2759
- entityId: score.entityId,
2760
- entityType: score.entityType,
2761
- traceId: score.traceId || "",
2762
- spanId: score.spanId || ""
3050
+ scorer: score.scorer?.id ?? "unknown",
3051
+ entityId: score.entityId ?? "unknown",
3052
+ entityType: score.entityType ?? "unknown",
3053
+ traceId: score.traceId ?? "",
3054
+ spanId: score.spanId ?? ""
2763
3055
  }
2764
3056
  },
2765
3057
  error$1
@@ -2767,17 +3059,17 @@ var ScoresLibSQL = class extends storage.ScoresStorage {
2767
3059
  }
2768
3060
  try {
2769
3061
  const id = crypto.randomUUID();
3062
+ const now = /* @__PURE__ */ new Date();
2770
3063
  await this.operations.insert({
2771
3064
  tableName: storage.TABLE_SCORERS,
2772
3065
  record: {
3066
+ ...parsedScore,
2773
3067
  id,
2774
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
2775
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
2776
- ...parsedScore
3068
+ createdAt: now.toISOString(),
3069
+ updatedAt: now.toISOString()
2777
3070
  }
2778
3071
  });
2779
- const scoreFromDb = await this.getScoreById({ id });
2780
- return { score: scoreFromDb };
3072
+ return { score: { ...parsedScore, id, createdAt: now, updatedAt: now } };
2781
3073
  } catch (error$1) {
2782
3074
  throw new error.MastraError(
2783
3075
  {
@@ -3237,12 +3529,14 @@ var LibSQLStore = class extends storage.MastraStorage {
3237
3529
  const workflows = new WorkflowsLibSQL({ client: this.client, operations });
3238
3530
  const memory = new MemoryLibSQL({ client: this.client, operations });
3239
3531
  const observability = new ObservabilityLibSQL({ operations });
3532
+ const agents = new AgentsLibSQL({ client: this.client, operations });
3240
3533
  this.stores = {
3241
3534
  operations,
3242
3535
  scores,
3243
3536
  workflows,
3244
3537
  memory,
3245
- observability
3538
+ observability,
3539
+ agents
3246
3540
  };
3247
3541
  }
3248
3542
  get supports() {
@@ -3253,7 +3547,8 @@ var LibSQLStore = class extends storage.MastraStorage {
3253
3547
  createTable: true,
3254
3548
  deleteMessages: true,
3255
3549
  observabilityInstance: true,
3256
- listScoresBySpan: true
3550
+ listScoresBySpan: true,
3551
+ agents: true
3257
3552
  };
3258
3553
  }
3259
3554
  async createTable({