@mastra/libsql 1.1.0-alpha.1 → 1.1.0-alpha.2

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,16 @@
1
1
  # @mastra/libsql
2
2
 
3
+ ## 1.1.0-alpha.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Stored agent edits no longer fail silently. PATCH requests now save changes correctly. ([#12504](https://github.com/mastra-ai/mastra/pull/12504))
8
+
9
+ - Fix PATCH request JSON-body handling in `@mastra/client-js` so stored agent edit flows work correctly. Fix stored agent schema migration in `@mastra/libsql` and `@mastra/pg` to drop and recreate the versions table when the old snapshot-based schema is detected, clean up stale draft records from partial create failures, and remove lingering legacy tables. Restores create and edit flows for stored agents. ([#12504](https://github.com/mastra-ai/mastra/pull/12504))
10
+
11
+ - Updated dependencies:
12
+ - @mastra/core@1.1.0-alpha.2
13
+
3
14
  ## 1.1.0-alpha.1
4
15
 
5
16
  ### Minor Changes
@@ -36,4 +36,4 @@ docs/
36
36
  ## Version
37
37
 
38
38
  Package: @mastra/libsql
39
- Version: 1.1.0-alpha.1
39
+ Version: 1.1.0-alpha.2
@@ -5,7 +5,7 @@ description: Documentation for @mastra/libsql. Includes links to type definition
5
5
 
6
6
  # @mastra/libsql Documentation
7
7
 
8
- > **Version**: 1.1.0-alpha.1
8
+ > **Version**: 1.1.0-alpha.2
9
9
  > **Package**: @mastra/libsql
10
10
 
11
11
  ## Quick Navigation
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.0-alpha.1",
2
+ "version": "1.1.0-alpha.2",
3
3
  "package": "@mastra/libsql",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -2043,14 +2043,122 @@ Note: This migration may take some time for large tables.
2043
2043
  // src/storage/domains/agents/index.ts
2044
2044
  var AgentsLibSQL = class extends storage.AgentsStorage {
2045
2045
  #db;
2046
+ #client;
2046
2047
  constructor(config) {
2047
2048
  super();
2048
2049
  const client = resolveClient(config);
2050
+ this.#client = client;
2049
2051
  this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
2050
2052
  }
2051
2053
  async init() {
2054
+ await this.#migrateFromLegacySchema();
2055
+ await this.#migrateVersionsSchema();
2056
+ await this.#db.createTable({ tableName: storage.TABLE_AGENTS, schema: storage.AGENTS_SCHEMA });
2057
+ await this.#db.createTable({ tableName: storage.TABLE_AGENT_VERSIONS, schema: storage.AGENT_VERSIONS_SCHEMA });
2058
+ await this.#db.alterTable({
2059
+ tableName: storage.TABLE_AGENTS,
2060
+ schema: storage.AGENTS_SCHEMA,
2061
+ ifNotExists: ["status", "authorId"]
2062
+ });
2063
+ await this.#cleanupStaleDrafts();
2064
+ }
2065
+ /**
2066
+ * Migrates from the legacy flat agent schema (where config fields like name, instructions, model
2067
+ * were stored directly on mastra_agents) to the new versioned schema (thin agent record + versions table).
2068
+ * SQLite cannot drop columns or alter NOT NULL constraints, so we must recreate the table.
2069
+ */
2070
+ async #migrateFromLegacySchema() {
2071
+ const legacyTable = `${storage.TABLE_AGENTS}_legacy`;
2072
+ const hasLegacyColumns = await this.#db.hasColumn(storage.TABLE_AGENTS, "name");
2073
+ if (hasLegacyColumns) {
2074
+ await this.#client.execute({
2075
+ sql: `ALTER TABLE "${storage.TABLE_AGENTS}" RENAME TO "${legacyTable}"`
2076
+ });
2077
+ await this.#client.execute({
2078
+ sql: `DROP TABLE IF EXISTS "${storage.TABLE_AGENT_VERSIONS}"`
2079
+ });
2080
+ }
2081
+ const legacyExists = await this.#db.hasColumn(legacyTable, "name");
2082
+ if (!legacyExists) return;
2083
+ const result = await this.#client.execute({
2084
+ sql: `SELECT * FROM "${legacyTable}"`
2085
+ });
2086
+ const oldAgents = result.rows || [];
2052
2087
  await this.#db.createTable({ tableName: storage.TABLE_AGENTS, schema: storage.AGENTS_SCHEMA });
2053
2088
  await this.#db.createTable({ tableName: storage.TABLE_AGENT_VERSIONS, schema: storage.AGENT_VERSIONS_SCHEMA });
2089
+ for (const row of oldAgents) {
2090
+ const agentId = row.id;
2091
+ if (!agentId) continue;
2092
+ const versionId = crypto.randomUUID();
2093
+ const now = /* @__PURE__ */ new Date();
2094
+ await this.#db.insert({
2095
+ tableName: storage.TABLE_AGENTS,
2096
+ record: {
2097
+ id: agentId,
2098
+ status: "published",
2099
+ activeVersionId: versionId,
2100
+ authorId: row.ownerId ?? row.authorId ?? null,
2101
+ metadata: row.metadata ?? null,
2102
+ createdAt: row.createdAt ?? now,
2103
+ updatedAt: row.updatedAt ?? now
2104
+ }
2105
+ });
2106
+ await this.#db.insert({
2107
+ tableName: storage.TABLE_AGENT_VERSIONS,
2108
+ record: {
2109
+ id: versionId,
2110
+ agentId,
2111
+ versionNumber: 1,
2112
+ name: row.name ?? agentId,
2113
+ description: row.description ?? null,
2114
+ instructions: row.instructions ?? "",
2115
+ model: row.model ?? "{}",
2116
+ tools: row.tools ?? null,
2117
+ defaultOptions: row.defaultOptions ?? null,
2118
+ workflows: row.workflows ?? null,
2119
+ agents: row.agents ?? null,
2120
+ integrationTools: row.integrationTools ?? null,
2121
+ inputProcessors: row.inputProcessors ?? null,
2122
+ outputProcessors: row.outputProcessors ?? null,
2123
+ memory: row.memory ?? null,
2124
+ scorers: row.scorers ?? null,
2125
+ changedFields: null,
2126
+ changeMessage: "Migrated from legacy schema",
2127
+ createdAt: row.createdAt ?? now
2128
+ }
2129
+ });
2130
+ }
2131
+ await this.#client.execute({
2132
+ sql: `DROP TABLE IF EXISTS "${legacyTable}"`
2133
+ });
2134
+ }
2135
+ /**
2136
+ * Migrates the agent_versions table from the old snapshot-based schema (single `snapshot` JSON column)
2137
+ * to the new flat schema (individual config columns). This handles the case where the agents table
2138
+ * was already migrated but the versions table still has the old schema.
2139
+ */
2140
+ async #migrateVersionsSchema() {
2141
+ const hasSnapshotColumn = await this.#db.hasColumn(storage.TABLE_AGENT_VERSIONS, "snapshot");
2142
+ if (!hasSnapshotColumn) return;
2143
+ await this.#client.execute({
2144
+ sql: `DROP TABLE IF EXISTS "${storage.TABLE_AGENT_VERSIONS}"`
2145
+ });
2146
+ await this.#client.execute({
2147
+ sql: `DROP TABLE IF EXISTS "${storage.TABLE_AGENTS}_legacy"`
2148
+ });
2149
+ }
2150
+ /**
2151
+ * Removes stale draft agent records that have no activeVersionId.
2152
+ * These are left behind when createAgent partially fails (inserts thin record
2153
+ * but fails to create the version due to schema mismatch).
2154
+ */
2155
+ async #cleanupStaleDrafts() {
2156
+ try {
2157
+ await this.#client.execute({
2158
+ sql: `DELETE FROM "${storage.TABLE_AGENTS}" WHERE status = 'draft' AND activeVersionId IS NULL`
2159
+ });
2160
+ } catch {
2161
+ }
2054
2162
  }
2055
2163
  async dangerouslyClearAll() {
2056
2164
  await this.#db.deleteData({ tableName: storage.TABLE_AGENT_VERSIONS });