@mastra/pg 1.1.0-alpha.0 → 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/dist/index.js CHANGED
@@ -3119,10 +3119,124 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3119
3119
  }
3120
3120
  }
3121
3121
  async init() {
3122
+ await this.#migrateFromLegacySchema();
3123
+ await this.#migrateVersionsSchema();
3122
3124
  await this.#db.createTable({ tableName: TABLE_AGENTS, schema: TABLE_SCHEMAS[TABLE_AGENTS] });
3123
3125
  await this.#db.createTable({ tableName: TABLE_AGENT_VERSIONS, schema: TABLE_SCHEMAS[TABLE_AGENT_VERSIONS] });
3126
+ await this.#db.alterTable({
3127
+ tableName: TABLE_AGENTS,
3128
+ schema: TABLE_SCHEMAS[TABLE_AGENTS],
3129
+ ifNotExists: ["status", "authorId"]
3130
+ });
3124
3131
  await this.createDefaultIndexes();
3125
3132
  await this.createCustomIndexes();
3133
+ await this.#cleanupStaleDrafts();
3134
+ }
3135
+ /**
3136
+ * Migrates from the legacy flat agent schema (where config fields like name, instructions, model
3137
+ * were stored directly on mastra_agents) to the new versioned schema (thin agent record + versions table).
3138
+ */
3139
+ async #migrateFromLegacySchema() {
3140
+ const fullTableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3141
+ const fullVersionsTableName = getTableName2({
3142
+ indexName: TABLE_AGENT_VERSIONS,
3143
+ schemaName: getSchemaName2(this.#schema)
3144
+ });
3145
+ const legacyTableName = getTableName2({
3146
+ indexName: `${TABLE_AGENTS}_legacy`,
3147
+ schemaName: getSchemaName2(this.#schema)
3148
+ });
3149
+ const hasLegacyColumns = await this.#db.hasColumn(TABLE_AGENTS, "name");
3150
+ if (hasLegacyColumns) {
3151
+ await this.#db.client.none(`ALTER TABLE ${fullTableName} RENAME TO "${TABLE_AGENTS}_legacy"`);
3152
+ await this.#db.client.none(`DROP TABLE IF EXISTS ${fullVersionsTableName}`);
3153
+ }
3154
+ const legacyExists = await this.#db.hasColumn(`${TABLE_AGENTS}_legacy`, "name");
3155
+ if (!legacyExists) return;
3156
+ const oldAgents = await this.#db.client.manyOrNone(`SELECT * FROM ${legacyTableName}`);
3157
+ await this.#db.createTable({ tableName: TABLE_AGENTS, schema: TABLE_SCHEMAS[TABLE_AGENTS] });
3158
+ await this.#db.createTable({ tableName: TABLE_AGENT_VERSIONS, schema: TABLE_SCHEMAS[TABLE_AGENT_VERSIONS] });
3159
+ for (const row of oldAgents) {
3160
+ const agentId = row.id;
3161
+ if (!agentId) continue;
3162
+ const versionId = crypto.randomUUID();
3163
+ const now = /* @__PURE__ */ new Date();
3164
+ await this.#db.client.none(
3165
+ `INSERT INTO ${fullTableName} (id, status, "activeVersionId", "authorId", metadata, "createdAt", "updatedAt")
3166
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
3167
+ ON CONFLICT (id) DO NOTHING`,
3168
+ [
3169
+ agentId,
3170
+ "published",
3171
+ versionId,
3172
+ row.ownerId ?? row.authorId ?? null,
3173
+ row.metadata ? JSON.stringify(row.metadata) : null,
3174
+ row.createdAt ?? now,
3175
+ row.updatedAt ?? now
3176
+ ]
3177
+ );
3178
+ await this.#db.client.none(
3179
+ `INSERT INTO ${fullVersionsTableName}
3180
+ (id, "agentId", "versionNumber", name, description, instructions, model, tools,
3181
+ "defaultOptions", workflows, agents, "integrationTools", "inputProcessors",
3182
+ "outputProcessors", memory, scorers, "changedFields", "changeMessage", "createdAt")
3183
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19)
3184
+ ON CONFLICT (id) DO NOTHING`,
3185
+ [
3186
+ versionId,
3187
+ agentId,
3188
+ 1,
3189
+ row.name ?? agentId,
3190
+ row.description ?? null,
3191
+ row.instructions ?? "",
3192
+ row.model ? JSON.stringify(row.model) : "{}",
3193
+ row.tools ? JSON.stringify(row.tools) : null,
3194
+ row.defaultOptions ? JSON.stringify(row.defaultOptions) : null,
3195
+ row.workflows ? JSON.stringify(row.workflows) : null,
3196
+ row.agents ? JSON.stringify(row.agents) : null,
3197
+ row.integrationTools ? JSON.stringify(row.integrationTools) : null,
3198
+ row.inputProcessors ? JSON.stringify(row.inputProcessors) : null,
3199
+ row.outputProcessors ? JSON.stringify(row.outputProcessors) : null,
3200
+ row.memory ? JSON.stringify(row.memory) : null,
3201
+ row.scorers ? JSON.stringify(row.scorers) : null,
3202
+ null,
3203
+ "Migrated from legacy schema",
3204
+ row.createdAt ?? now
3205
+ ]
3206
+ );
3207
+ }
3208
+ await this.#db.client.none(`DROP TABLE IF EXISTS ${legacyTableName}`);
3209
+ }
3210
+ /**
3211
+ * Migrates the agent_versions table from the old snapshot-based schema (single `snapshot` JSON column)
3212
+ * to the new flat schema (individual config columns). This handles the case where the agents table
3213
+ * was already migrated but the versions table still has the old schema.
3214
+ */
3215
+ async #migrateVersionsSchema() {
3216
+ const hasSnapshotColumn = await this.#db.hasColumn(TABLE_AGENT_VERSIONS, "snapshot");
3217
+ if (!hasSnapshotColumn) return;
3218
+ const fullVersionsTableName = getTableName2({
3219
+ indexName: TABLE_AGENT_VERSIONS,
3220
+ schemaName: getSchemaName2(this.#schema)
3221
+ });
3222
+ const legacyTableName = getTableName2({
3223
+ indexName: `${TABLE_AGENTS}_legacy`,
3224
+ schemaName: getSchemaName2(this.#schema)
3225
+ });
3226
+ await this.#db.client.none(`DROP TABLE IF EXISTS ${fullVersionsTableName}`);
3227
+ await this.#db.client.none(`DROP TABLE IF EXISTS ${legacyTableName}`);
3228
+ }
3229
+ /**
3230
+ * Removes stale draft agent records that have no activeVersionId.
3231
+ * These are left behind when createAgent partially fails (inserts thin record
3232
+ * but fails to create the version due to schema mismatch).
3233
+ */
3234
+ async #cleanupStaleDrafts() {
3235
+ try {
3236
+ const fullTableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3237
+ await this.#db.client.none(`DELETE FROM ${fullTableName} WHERE status = 'draft' AND "activeVersionId" IS NULL`);
3238
+ } catch {
3239
+ }
3126
3240
  }
3127
3241
  /**
3128
3242
  * Creates custom user-defined indexes for this domain's tables.
@@ -3170,22 +3284,10 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3170
3284
  parseRow(row) {
3171
3285
  return {
3172
3286
  id: row.id,
3173
- name: row.name,
3174
- description: row.description,
3175
- instructions: row.instructions,
3176
- model: this.parseJson(row.model, "model"),
3177
- tools: this.parseJson(row.tools, "tools"),
3178
- defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
3179
- workflows: this.parseJson(row.workflows, "workflows"),
3180
- agents: this.parseJson(row.agents, "agents"),
3181
- integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
3182
- inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
3183
- outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
3184
- memory: this.parseJson(row.memory, "memory"),
3185
- scorers: this.parseJson(row.scorers, "scorers"),
3186
- metadata: this.parseJson(row.metadata, "metadata"),
3187
- ownerId: row.ownerId,
3287
+ status: row.status,
3188
3288
  activeVersionId: row.activeVersionId,
3289
+ authorId: row.authorId,
3290
+ metadata: this.parseJson(row.metadata, "metadata"),
3189
3291
  createdAt: row.createdAtZ || row.createdAt,
3190
3292
  updatedAt: row.updatedAtZ || row.updatedAt
3191
3293
  };
@@ -3212,43 +3314,48 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3212
3314
  }
3213
3315
  async createAgent({ agent }) {
3214
3316
  try {
3215
- const tableName = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3317
+ const agentsTable = getTableName2({ indexName: TABLE_AGENTS, schemaName: getSchemaName2(this.#schema) });
3216
3318
  const now = /* @__PURE__ */ new Date();
3217
3319
  const nowIso = now.toISOString();
3218
3320
  await this.#db.client.none(
3219
- `INSERT INTO ${tableName} (
3220
- id, name, description, instructions, model, tools,
3221
- "defaultOptions", workflows, agents, "integrationTools",
3222
- "inputProcessors", "outputProcessors", memory, scorers, metadata,
3223
- "ownerId", "activeVersionId",
3321
+ `INSERT INTO ${agentsTable} (
3322
+ id, status, "authorId", metadata,
3323
+ "activeVersionId",
3224
3324
  "createdAt", "createdAtZ", "updatedAt", "updatedAtZ"
3225
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21)`,
3325
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
3226
3326
  [
3227
3327
  agent.id,
3228
- agent.name,
3229
- agent.description ?? null,
3230
- agent.instructions,
3231
- JSON.stringify(agent.model),
3232
- agent.tools ? JSON.stringify(agent.tools) : null,
3233
- agent.defaultOptions ? JSON.stringify(agent.defaultOptions) : null,
3234
- agent.workflows ? JSON.stringify(agent.workflows) : null,
3235
- agent.agents ? JSON.stringify(agent.agents) : null,
3236
- agent.integrationTools ? JSON.stringify(agent.integrationTools) : null,
3237
- agent.inputProcessors ? JSON.stringify(agent.inputProcessors) : null,
3238
- agent.outputProcessors ? JSON.stringify(agent.outputProcessors) : null,
3239
- agent.memory ? JSON.stringify(agent.memory) : null,
3240
- agent.scorers ? JSON.stringify(agent.scorers) : null,
3328
+ "draft",
3329
+ agent.authorId ?? null,
3241
3330
  agent.metadata ? JSON.stringify(agent.metadata) : null,
3242
- agent.ownerId ?? null,
3243
- agent.activeVersionId ?? null,
3331
+ null,
3332
+ // activeVersionId starts as null
3244
3333
  nowIso,
3245
3334
  nowIso,
3246
3335
  nowIso,
3247
3336
  nowIso
3248
3337
  ]
3249
3338
  );
3339
+ const { id: _id, authorId: _authorId, metadata: _metadata, ...snapshotConfig } = agent;
3340
+ const versionId = crypto.randomUUID();
3341
+ await this.createVersion({
3342
+ id: versionId,
3343
+ agentId: agent.id,
3344
+ versionNumber: 1,
3345
+ ...snapshotConfig,
3346
+ changedFields: Object.keys(snapshotConfig),
3347
+ changeMessage: "Initial version"
3348
+ });
3349
+ await this.#db.client.none(
3350
+ `UPDATE ${agentsTable} SET "activeVersionId" = $1, status = $2, "updatedAt" = $3, "updatedAtZ" = $4 WHERE id = $5`,
3351
+ [versionId, "published", nowIso, nowIso, agent.id]
3352
+ );
3250
3353
  return {
3251
- ...agent,
3354
+ id: agent.id,
3355
+ status: "published",
3356
+ activeVersionId: versionId,
3357
+ authorId: agent.authorId,
3358
+ metadata: agent.metadata,
3252
3359
  createdAt: now,
3253
3360
  updatedAt: now
3254
3361
  };
@@ -3280,65 +3387,15 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3280
3387
  const setClauses = [];
3281
3388
  const values = [];
3282
3389
  let paramIndex = 1;
3283
- if (updates.name !== void 0) {
3284
- setClauses.push(`name = $${paramIndex++}`);
3285
- values.push(updates.name);
3286
- }
3287
- if (updates.description !== void 0) {
3288
- setClauses.push(`description = $${paramIndex++}`);
3289
- values.push(updates.description);
3290
- }
3291
- if (updates.instructions !== void 0) {
3292
- setClauses.push(`instructions = $${paramIndex++}`);
3293
- values.push(updates.instructions);
3294
- }
3295
- if (updates.model !== void 0) {
3296
- setClauses.push(`model = $${paramIndex++}`);
3297
- values.push(JSON.stringify(updates.model));
3298
- }
3299
- if (updates.tools !== void 0) {
3300
- setClauses.push(`tools = $${paramIndex++}`);
3301
- values.push(JSON.stringify(updates.tools));
3302
- }
3303
- if (updates.defaultOptions !== void 0) {
3304
- setClauses.push(`"defaultOptions" = $${paramIndex++}`);
3305
- values.push(JSON.stringify(updates.defaultOptions));
3306
- }
3307
- if (updates.workflows !== void 0) {
3308
- setClauses.push(`workflows = $${paramIndex++}`);
3309
- values.push(JSON.stringify(updates.workflows));
3310
- }
3311
- if (updates.agents !== void 0) {
3312
- setClauses.push(`agents = $${paramIndex++}`);
3313
- values.push(JSON.stringify(updates.agents));
3314
- }
3315
- if (updates.inputProcessors !== void 0) {
3316
- setClauses.push(`"inputProcessors" = $${paramIndex++}`);
3317
- values.push(JSON.stringify(updates.inputProcessors));
3318
- }
3319
- if (updates.outputProcessors !== void 0) {
3320
- setClauses.push(`"outputProcessors" = $${paramIndex++}`);
3321
- values.push(JSON.stringify(updates.outputProcessors));
3322
- }
3323
- if (updates.memory !== void 0) {
3324
- setClauses.push(`memory = $${paramIndex++}`);
3325
- values.push(JSON.stringify(updates.memory));
3326
- }
3327
- if (updates.scorers !== void 0) {
3328
- setClauses.push(`scorers = $${paramIndex++}`);
3329
- values.push(JSON.stringify(updates.scorers));
3330
- }
3331
- if (updates.integrationTools !== void 0) {
3332
- setClauses.push(`"integrationTools" = $${paramIndex++}`);
3333
- values.push(JSON.stringify(updates.integrationTools));
3334
- }
3335
- if (updates.ownerId !== void 0) {
3336
- setClauses.push(`"ownerId" = $${paramIndex++}`);
3337
- values.push(updates.ownerId);
3390
+ if (updates.authorId !== void 0) {
3391
+ setClauses.push(`"authorId" = $${paramIndex++}`);
3392
+ values.push(updates.authorId);
3338
3393
  }
3339
3394
  if (updates.activeVersionId !== void 0) {
3340
3395
  setClauses.push(`"activeVersionId" = $${paramIndex++}`);
3341
3396
  values.push(updates.activeVersionId);
3397
+ setClauses.push(`status = $${paramIndex++}`);
3398
+ values.push("published");
3342
3399
  }
3343
3400
  if (updates.metadata !== void 0) {
3344
3401
  const mergedMetadata = { ...existingAgent.metadata, ...updates.metadata };
@@ -3463,14 +3520,30 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3463
3520
  const nowIso = now.toISOString();
3464
3521
  await this.#db.client.none(
3465
3522
  `INSERT INTO ${tableName} (
3466
- id, "agentId", "versionNumber", name, snapshot, "changedFields", "changeMessage", "createdAt", "createdAtZ"
3467
- ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
3523
+ id, "agentId", "versionNumber",
3524
+ name, description, instructions, model, tools,
3525
+ "defaultOptions", workflows, agents, "integrationTools",
3526
+ "inputProcessors", "outputProcessors", memory, scorers,
3527
+ "changedFields", "changeMessage",
3528
+ "createdAt", "createdAtZ"
3529
+ ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20)`,
3468
3530
  [
3469
3531
  input.id,
3470
3532
  input.agentId,
3471
3533
  input.versionNumber,
3472
- input.name ?? null,
3473
- JSON.stringify(input.snapshot),
3534
+ input.name,
3535
+ input.description ?? null,
3536
+ input.instructions,
3537
+ JSON.stringify(input.model),
3538
+ input.tools ? JSON.stringify(input.tools) : null,
3539
+ input.defaultOptions ? JSON.stringify(input.defaultOptions) : null,
3540
+ input.workflows ? JSON.stringify(input.workflows) : null,
3541
+ input.agents ? JSON.stringify(input.agents) : null,
3542
+ input.integrationTools ? JSON.stringify(input.integrationTools) : null,
3543
+ input.inputProcessors ? JSON.stringify(input.inputProcessors) : null,
3544
+ input.outputProcessors ? JSON.stringify(input.outputProcessors) : null,
3545
+ input.memory ? JSON.stringify(input.memory) : null,
3546
+ input.scorers ? JSON.stringify(input.scorers) : null,
3474
3547
  input.changedFields ? JSON.stringify(input.changedFields) : null,
3475
3548
  input.changeMessage ?? null,
3476
3549
  nowIso,
@@ -3675,7 +3748,18 @@ var AgentsPG = class _AgentsPG extends AgentsStorage {
3675
3748
  agentId: row.agentId,
3676
3749
  versionNumber: row.versionNumber,
3677
3750
  name: row.name,
3678
- snapshot: this.parseJson(row.snapshot, "snapshot"),
3751
+ description: row.description,
3752
+ instructions: row.instructions,
3753
+ model: this.parseJson(row.model, "model"),
3754
+ tools: this.parseJson(row.tools, "tools"),
3755
+ defaultOptions: this.parseJson(row.defaultOptions, "defaultOptions"),
3756
+ workflows: this.parseJson(row.workflows, "workflows"),
3757
+ agents: this.parseJson(row.agents, "agents"),
3758
+ integrationTools: this.parseJson(row.integrationTools, "integrationTools"),
3759
+ inputProcessors: this.parseJson(row.inputProcessors, "inputProcessors"),
3760
+ outputProcessors: this.parseJson(row.outputProcessors, "outputProcessors"),
3761
+ memory: this.parseJson(row.memory, "memory"),
3762
+ scorers: this.parseJson(row.scorers, "scorers"),
3679
3763
  changedFields: this.parseJson(row.changedFields, "changedFields"),
3680
3764
  changeMessage: row.changeMessage,
3681
3765
  createdAt: row.createdAtZ || row.createdAt