@mastra/libsql 1.0.0-beta.5 → 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,53 @@
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
+
3
51
  ## 1.0.0-beta.5
4
52
 
5
53
  ### Patch 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;
@@ -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({