@mastra/pg 1.23.0-alpha.0 → 1.23.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.
Files changed (33) hide show
  1. package/dist/docs/SKILL.md +1 -1
  2. package/dist/docs/assets/SOURCE_MAP.json +1 -1
  3. package/dist/index.cjs +492 -273
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +492 -273
  6. package/dist/index.js.map +1 -1
  7. package/dist/shared/config.d.ts +12 -2
  8. package/dist/shared/config.d.ts.map +1 -1
  9. package/dist/storage/db/index.d.ts +9 -2
  10. package/dist/storage/db/index.d.ts.map +1 -1
  11. package/dist/storage/domains/agents/index.d.ts.map +1 -1
  12. package/dist/storage/domains/datasets/index.d.ts +6 -1
  13. package/dist/storage/domains/datasets/index.d.ts.map +1 -1
  14. package/dist/storage/domains/experiments/index.d.ts +2 -2
  15. package/dist/storage/domains/experiments/index.d.ts.map +1 -1
  16. package/dist/storage/domains/knowledge/index.d.ts.map +1 -1
  17. package/dist/storage/domains/mcp-clients/index.d.ts.map +1 -1
  18. package/dist/storage/domains/mcp-servers/index.d.ts.map +1 -1
  19. package/dist/storage/domains/memory/index.d.ts.map +1 -1
  20. package/dist/storage/domains/notifications/index.d.ts.map +1 -1
  21. package/dist/storage/domains/observability/index.d.ts.map +1 -1
  22. package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
  23. package/dist/storage/domains/observability/v-next/tracing.d.ts +7 -0
  24. package/dist/storage/domains/observability/v-next/tracing.d.ts.map +1 -1
  25. package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
  26. package/dist/storage/domains/schedules/index.d.ts.map +1 -1
  27. package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
  28. package/dist/storage/domains/skills/index.d.ts.map +1 -1
  29. package/dist/storage/domains/workflow-definitions/index.d.ts.map +1 -1
  30. package/dist/storage/domains/workspaces/index.d.ts.map +1 -1
  31. package/dist/storage/index.d.ts +7 -5
  32. package/dist/storage/index.d.ts.map +1 -1
  33. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -20,7 +20,11 @@ import { skillSnapshotFieldValuesEqual } from "@mastra/core/storage/domains/skil
20
20
  * Type guard for pre-configured pg.Pool config
21
21
  */
22
22
  const isPoolConfig = (cfg) => {
23
- return "pool" in cfg;
23
+ return "pool" in cfg && cfg.pool !== void 0;
24
+ };
25
+ /** Type guard for an explicitly named pre-configured writer pool. */
26
+ const isWritePoolConfig = (cfg) => {
27
+ return "writePool" in cfg && cfg.writePool !== void 0;
24
28
  };
25
29
  /**
26
30
  * Type guard for connection string config
@@ -45,10 +49,8 @@ const isCloudSqlConfig = (cfg) => {
45
49
  */
46
50
  const validateConfig = (name, config) => {
47
51
  if (!config.id || typeof config.id !== "string" || config.id.trim() === "") throw new Error(`${name}: id must be provided and cannot be empty.`);
48
- if (isPoolConfig(config)) {
49
- if (!config.pool) throw new Error(`${name}: pool must be provided when using pool config.`);
50
- return;
51
- }
52
+ if ("pool" in config && "writePool" in config) throw new Error(`${name}: provide either pool or writePool, not both.`);
53
+ if (isPoolConfig(config) || isWritePoolConfig(config)) return;
52
54
  if (isConnectionStringConfig(config)) {
53
55
  if (!config.connectionString || typeof config.connectionString !== "string" || config.connectionString.trim() === "") throw new Error(`${name}: connectionString must be provided and cannot be empty. Passing an empty string may cause fallback to local Postgres defaults.`);
54
56
  } else if (isCloudSqlConfig(config)) {} else if (isHostConfig(config)) {
@@ -2359,16 +2361,21 @@ async function loadSchemaSnapshot(client, schemaName) {
2359
2361
  function resolvePgConfig(config) {
2360
2362
  if ("client" in config) return {
2361
2363
  client: config.client,
2364
+ readClient: config.readClient ?? config.client,
2362
2365
  schemaName: config.schemaName,
2363
2366
  skipDefaultIndexes: config.skipDefaultIndexes,
2364
2367
  indexes: config.indexes
2365
2368
  };
2366
- if ("pool" in config) return {
2367
- client: new PoolAdapter(config.pool),
2368
- schemaName: config.schemaName,
2369
- skipDefaultIndexes: config.skipDefaultIndexes,
2370
- indexes: config.indexes
2371
- };
2369
+ if ("pool" in config) {
2370
+ const client = new PoolAdapter(config.pool);
2371
+ return {
2372
+ client,
2373
+ readClient: config.readPool && config.readPool !== config.pool ? new PoolAdapter(config.readPool) : client,
2374
+ schemaName: config.schemaName,
2375
+ skipDefaultIndexes: config.skipDefaultIndexes,
2376
+ indexes: config.indexes
2377
+ };
2378
+ }
2372
2379
  let pool;
2373
2380
  if ("connectionString" in config) pool = new Pool({
2374
2381
  connectionString: config.connectionString,
@@ -2385,8 +2392,10 @@ function resolvePgConfig(config) {
2385
2392
  pool.on("error", (err) => {
2386
2393
  console.warn(`resolvePgConfig: idle pool client error (pool discards the client and reconnects on next checkout): ${err instanceof Error ? err.message : String(err)}`);
2387
2394
  });
2395
+ const client = new PoolAdapter(pool);
2388
2396
  return {
2389
- client: new PoolAdapter(pool),
2397
+ client,
2398
+ readClient: client,
2390
2399
  schemaName: config.schemaName,
2391
2400
  skipDefaultIndexes: config.skipDefaultIndexes,
2392
2401
  indexes: config.indexes
@@ -2594,6 +2603,7 @@ function assertPositiveLimit(limit) {
2594
2603
  }
2595
2604
  var PgDB = class extends MastraBase {
2596
2605
  client;
2606
+ readClient;
2597
2607
  schemaName;
2598
2608
  skipDefaultIndexes;
2599
2609
  /** Cache of actual table columns: tableName -> Set<columnName> */
@@ -2606,6 +2616,7 @@ var PgDB = class extends MastraBase {
2606
2616
  name: "PG_DB_LAYER"
2607
2617
  });
2608
2618
  this.client = config.client;
2619
+ this.readClient = config.readClient ?? config.client;
2609
2620
  this.schemaName = config.schemaName;
2610
2621
  this.skipDefaultIndexes = config.skipDefaultIndexes;
2611
2622
  }
@@ -3861,9 +3872,10 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
3861
3872
  static MANAGED_TABLES = [TABLE_AGENTS, TABLE_AGENT_VERSIONS];
3862
3873
  constructor(config) {
3863
3874
  super();
3864
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
3875
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
3865
3876
  this.#db = new PgDB({
3866
3877
  client,
3878
+ readClient,
3867
3879
  schemaName,
3868
3880
  skipDefaultIndexes
3869
3881
  });
@@ -4122,12 +4134,19 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4122
4134
  };
4123
4135
  }
4124
4136
  async getById(id) {
4137
+ return this.#getById(this.#db.readClient, id);
4138
+ }
4139
+ /**
4140
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
4141
+ * lagging read replica cannot yield stale or missing rows mid-update.
4142
+ */
4143
+ async #getById(client, id) {
4125
4144
  try {
4126
4145
  const tableName = getTableName$5({
4127
4146
  indexName: TABLE_AGENTS,
4128
4147
  schemaName: getSchemaName$5(this.#schema)
4129
4148
  });
4130
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4149
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4131
4150
  if (!result) return null;
4132
4151
  return this.parseRow(result);
4133
4152
  } catch (error) {
@@ -4212,7 +4231,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4212
4231
  indexName: TABLE_AGENTS,
4213
4232
  schemaName: getSchemaName$5(this.#schema)
4214
4233
  });
4215
- if (!await this.getById(id)) throw new MastraError({
4234
+ if (!await this.#getById(this.#db.client, id)) throw new MastraError({
4216
4235
  id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND"),
4217
4236
  domain: ErrorDomain.STORAGE,
4218
4237
  category: ErrorCategory.USER,
@@ -4250,7 +4269,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4250
4269
  values.push(now);
4251
4270
  values.push(id);
4252
4271
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
4253
- const updatedAgent = await this.getById(id);
4272
+ const updatedAgent = await this.#getById(this.#db.client, id);
4254
4273
  if (!updatedAgent) throw new MastraError({
4255
4274
  id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND_AFTER_UPDATE"),
4256
4275
  domain: ErrorDomain.STORAGE,
@@ -4347,7 +4366,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4347
4366
  const joinClause = useJoin && joinSqlIdx !== null ? `LEFT JOIN ${favoritesTable} s ON s."entityType" = 'agent' AND s."entityId" = a.id AND s."userId" = $${joinSqlIdx}` : "";
4348
4367
  const joinParams = useJoin && joinUserId ? [joinUserId] : [];
4349
4368
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
4350
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} a ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
4369
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} a ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
4351
4370
  const total = parseInt(countResult.count, 10);
4352
4371
  if (total === 0) return {
4353
4372
  agents: [],
@@ -4365,7 +4384,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4365
4384
  const limitIdx = paramIdx++;
4366
4385
  const offsetIdx = paramIdx++;
4367
4386
  return {
4368
- agents: (await this.#db.client.manyOrNone(`SELECT a.* FROM ${tableName} a ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
4387
+ agents: (await this.#db.readClient.manyOrNone(`SELECT a.* FROM ${tableName} a ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
4369
4388
  ...joinParams,
4370
4389
  ...queryParams,
4371
4390
  limitValue,
@@ -4465,7 +4484,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4465
4484
  indexName: TABLE_AGENT_VERSIONS,
4466
4485
  schemaName: getSchemaName$5(this.#schema)
4467
4486
  });
4468
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4487
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4469
4488
  if (!result) return null;
4470
4489
  return this.parseVersionRow(result);
4471
4490
  } catch (error) {
@@ -4486,7 +4505,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4486
4505
  schemaName: getSchemaName$5(this.#schema)
4487
4506
  });
4488
4507
  const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
4489
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
4508
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
4490
4509
  } catch (error) {
4491
4510
  if (error instanceof MastraError) throw error;
4492
4511
  throw new MastraError({
@@ -4503,7 +4522,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4503
4522
  indexName: TABLE_AGENT_VERSIONS,
4504
4523
  schemaName: getSchemaName$5(this.#schema)
4505
4524
  });
4506
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`, [agentId, versionNumber]);
4525
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`, [agentId, versionNumber]);
4507
4526
  if (!result) return null;
4508
4527
  return this.parseVersionRow(result);
4509
4528
  } catch (error) {
@@ -4525,7 +4544,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4525
4544
  indexName: TABLE_AGENT_VERSIONS,
4526
4545
  schemaName: getSchemaName$5(this.#schema)
4527
4546
  });
4528
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [agentId]);
4547
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [agentId]);
4529
4548
  if (!result) return null;
4530
4549
  return this.parseVersionRow(result);
4531
4550
  } catch (error) {
@@ -4554,7 +4573,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4554
4573
  indexName: TABLE_AGENT_VERSIONS,
4555
4574
  schemaName: getSchemaName$5(this.#schema)
4556
4575
  });
4557
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4576
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4558
4577
  const total = parseInt(countResult.count, 10);
4559
4578
  if (total === 0) return {
4560
4579
  versions: [],
@@ -4565,7 +4584,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4565
4584
  };
4566
4585
  const limitValue = perPageInput === false ? total : perPage;
4567
4586
  return {
4568
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
4587
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
4569
4588
  agentId,
4570
4589
  limitValue,
4571
4590
  offset
@@ -4635,7 +4654,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4635
4654
  indexName: TABLE_AGENT_VERSIONS,
4636
4655
  schemaName: getSchemaName$5(this.#schema)
4637
4656
  });
4638
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4657
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4639
4658
  return parseInt(result.count, 10);
4640
4659
  } catch (error) {
4641
4660
  if (error instanceof MastraError) throw error;
@@ -4892,9 +4911,10 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
4892
4911
  } };
4893
4912
  constructor(config) {
4894
4913
  super();
4895
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4914
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4896
4915
  this.#db = new PgDB({
4897
4916
  client,
4917
+ readClient,
4898
4918
  schemaName,
4899
4919
  skipDefaultIndexes
4900
4920
  });
@@ -5146,7 +5166,7 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5146
5166
  params.push(filter.toDate.toISOString());
5147
5167
  }
5148
5168
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5149
- const countResult = await this.#db.client.oneOrNone(`SELECT COUNT(*) as count FROM ${table} ${where}`, params.slice(0, paramIdx - 1));
5169
+ const countResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) as count FROM ${table} ${where}`, params.slice(0, paramIdx - 1));
5150
5170
  const total = Number(countResult?.count ?? 0);
5151
5171
  let sql = `SELECT * FROM ${table} ${where} ORDER BY ${filter.orderBy === "startedAt" ? "\"startedAt\"" : filter.orderBy === "suspendedAt" ? "\"suspendedAt\"" : filter.orderBy === "completedAt" ? "\"completedAt\"" : "\"createdAt\""} ${filter.orderDirection === "desc" ? "DESC" : "ASC"}`;
5152
5172
  if (filter.perPage != null) {
@@ -5158,7 +5178,7 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5158
5178
  }
5159
5179
  }
5160
5180
  return {
5161
- tasks: (await this.#db.client.manyOrNone(sql, params)).map(rowToTask),
5181
+ tasks: (await this.#db.readClient.manyOrNone(sql, params)).map(rowToTask),
5162
5182
  total
5163
5183
  };
5164
5184
  }
@@ -5195,12 +5215,12 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5195
5215
  }
5196
5216
  async getRunningCount() {
5197
5217
  const table = getTableName$4(getSchemaName$4(this.#schema));
5198
- const result = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running'`);
5218
+ const result = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running'`);
5199
5219
  return Number(result?.count ?? 0);
5200
5220
  }
5201
5221
  async getRunningCountByAgent(agentId) {
5202
5222
  const table = getTableName$4(getSchemaName$4(this.#schema));
5203
- const result = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running' AND "agent_id" = $1`, [agentId]);
5223
+ const result = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running' AND "agent_id" = $1`, [agentId]);
5204
5224
  return Number(result?.count ?? 0);
5205
5225
  }
5206
5226
  };
@@ -5212,9 +5232,10 @@ var BlobsPG = class extends BlobStore {
5212
5232
  static MANAGED_TABLES = [TABLE_SKILL_BLOBS];
5213
5233
  constructor(config) {
5214
5234
  super();
5215
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
5235
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
5216
5236
  this.#db = new PgDB({
5217
5237
  client,
5238
+ readClient,
5218
5239
  schemaName,
5219
5240
  skipDefaultIndexes
5220
5241
  });
@@ -5256,7 +5277,7 @@ var BlobsPG = class extends BlobStore {
5256
5277
  indexName: TABLE_SKILL_BLOBS,
5257
5278
  schemaName: getSchemaName$5(this.#schema)
5258
5279
  });
5259
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "hash" = $1`, [hash]);
5280
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "hash" = $1`, [hash]);
5260
5281
  if (!row) return null;
5261
5282
  return this.#parseRow(row);
5262
5283
  }
@@ -5265,7 +5286,7 @@ var BlobsPG = class extends BlobStore {
5265
5286
  indexName: TABLE_SKILL_BLOBS,
5266
5287
  schemaName: getSchemaName$5(this.#schema)
5267
5288
  });
5268
- return await this.#db.client.oneOrNone(`SELECT 1 FROM ${tableName} WHERE "hash" = $1 LIMIT 1`, [hash]) !== null;
5289
+ return await this.#db.readClient.oneOrNone(`SELECT 1 FROM ${tableName} WHERE "hash" = $1 LIMIT 1`, [hash]) !== null;
5269
5290
  }
5270
5291
  async delete(hash) {
5271
5292
  const tableName = getTableName$5({
@@ -5286,7 +5307,7 @@ var BlobsPG = class extends BlobStore {
5286
5307
  schemaName: getSchemaName$5(this.#schema)
5287
5308
  });
5288
5309
  const placeholders = hashes.map((_, i) => `$${i + 1}`).join(", ");
5289
- const rows = await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "hash" IN (${placeholders})`, hashes);
5310
+ const rows = await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "hash" IN (${placeholders})`, hashes);
5290
5311
  for (const row of rows) {
5291
5312
  const entry = this.#parseRow(row);
5292
5313
  result.set(entry.hash, entry);
@@ -5316,9 +5337,10 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5316
5337
  static MANAGED_TABLES = [TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG];
5317
5338
  constructor(config) {
5318
5339
  super();
5319
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5340
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5320
5341
  this.#db = new PgDB({
5321
5342
  client,
5343
+ readClient,
5322
5344
  schemaName,
5323
5345
  skipDefaultIndexes
5324
5346
  });
@@ -5425,7 +5447,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5425
5447
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5426
5448
  schemaName: getSchemaName$5(this.#schema)
5427
5449
  });
5428
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5450
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5429
5451
  return row ? this.#parseInstallationRow(row) : null;
5430
5452
  }
5431
5453
  async getInstallationByAgent(platform, agentId) {
@@ -5433,7 +5455,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5433
5455
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5434
5456
  schemaName: getSchemaName$5(this.#schema)
5435
5457
  });
5436
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 AND "agentId" = $2 ORDER BY CASE "status" WHEN 'active' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END, "updatedAt" DESC LIMIT 1`, [platform, agentId]);
5458
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 AND "agentId" = $2 ORDER BY CASE "status" WHEN 'active' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END, "updatedAt" DESC LIMIT 1`, [platform, agentId]);
5437
5459
  return row ? this.#parseInstallationRow(row) : null;
5438
5460
  }
5439
5461
  async getInstallationByWebhookId(webhookId) {
@@ -5441,7 +5463,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5441
5463
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5442
5464
  schemaName: getSchemaName$5(this.#schema)
5443
5465
  });
5444
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "webhookId" = $1`, [webhookId]);
5466
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "webhookId" = $1`, [webhookId]);
5445
5467
  return row ? this.#parseInstallationRow(row) : null;
5446
5468
  }
5447
5469
  async listInstallations(platform) {
@@ -5449,7 +5471,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5449
5471
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5450
5472
  schemaName: getSchemaName$5(this.#schema)
5451
5473
  });
5452
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 ORDER BY "createdAt" DESC`, [platform])).map((row) => this.#parseInstallationRow(row));
5474
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 ORDER BY "createdAt" DESC`, [platform])).map((row) => this.#parseInstallationRow(row));
5453
5475
  }
5454
5476
  async deleteInstallation(id) {
5455
5477
  const tableName = getTableName$5({
@@ -5481,7 +5503,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5481
5503
  indexName: TABLE_CHANNEL_CONFIG,
5482
5504
  schemaName: getSchemaName$5(this.#schema)
5483
5505
  });
5484
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1`, [platform]);
5506
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1`, [platform]);
5485
5507
  if (!row) return null;
5486
5508
  return {
5487
5509
  platform: row.platform,
@@ -5529,9 +5551,10 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5529
5551
  ];
5530
5552
  constructor(config) {
5531
5553
  super();
5532
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5554
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5533
5555
  this.#db = new PgDB({
5534
5556
  client,
5557
+ readClient,
5535
5558
  schemaName,
5536
5559
  skipDefaultIndexes
5537
5560
  });
@@ -5792,7 +5815,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5792
5815
  };
5793
5816
  } catch (error) {
5794
5817
  if (input.id !== void 0 && hasErrorCode(error, /* @__PURE__ */ new Set(["23505"]))) {
5795
- const existing = await this.getDatasetById({ id: input.id });
5818
+ const existing = await this.#getDatasetById(this.#db.client, { id: input.id });
5796
5819
  if (existing) return this.resolveExistingDataset(existing, {
5797
5820
  ...input,
5798
5821
  id: input.id
@@ -5806,7 +5829,20 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5806
5829
  }, error);
5807
5830
  }
5808
5831
  }
5809
- async getDatasetById({ id, filters }) {
5832
+ async getDatasetById(args) {
5833
+ return this.#getDatasetById(this.#db.readClient, args);
5834
+ }
5835
+ getDatasetForMutation(args) {
5836
+ return this.#getDatasetById(this.#db.client, args);
5837
+ }
5838
+ listItemsForMutation(args) {
5839
+ return this.#listItems(this.#db.client, args);
5840
+ }
5841
+ /**
5842
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
5843
+ * lagging read replica cannot yield stale or missing rows mid-update.
5844
+ */
5845
+ async #getDatasetById(client, { id, filters }) {
5810
5846
  try {
5811
5847
  const tableName = getTableName$5({
5812
5848
  indexName: TABLE_DATASETS,
@@ -5814,7 +5850,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5814
5850
  });
5815
5851
  const { conditions, params } = tenancyWhere(filters, 2);
5816
5852
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
5817
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
5853
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
5818
5854
  return result ? this.transformDatasetRow(result) : null;
5819
5855
  } catch (error) {
5820
5856
  throw new MastraError({
@@ -5826,7 +5862,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5826
5862
  }
5827
5863
  async _doUpdateDataset(args) {
5828
5864
  try {
5829
- const existing = await this.getDatasetById({
5865
+ const existing = await this.#getDatasetById(this.#db.client, {
5830
5866
  id: args.id,
5831
5867
  filters: args.filters
5832
5868
  });
@@ -5998,7 +6034,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5998
6034
  }
5999
6035
  }
6000
6036
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
6001
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6037
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6002
6038
  const total = parseInt(countResult.count, 10);
6003
6039
  if (total === 0) return {
6004
6040
  datasets: [],
@@ -6013,7 +6049,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6013
6049
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6014
6050
  const limitValue = perPageInput === false ? total : perPage;
6015
6051
  return {
6016
- datasets: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6052
+ datasets: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6017
6053
  ...queryParams,
6018
6054
  limitValue,
6019
6055
  offset
@@ -6117,7 +6153,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6117
6153
  }
6118
6154
  async _doUpdateItem(args) {
6119
6155
  try {
6120
- const existing = await this.getItemById({ id: args.id });
6156
+ const existing = await this.#getItemById(this.#db.client, { id: args.id });
6121
6157
  if (!existing) throw new MastraError({
6122
6158
  id: createStorageErrorId("PG", "UPDATE_ITEM", "NOT_FOUND"),
6123
6159
  domain: ErrorDomain.STORAGE,
@@ -6223,7 +6259,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6223
6259
  }
6224
6260
  async _doDeleteItem({ id, datasetId }) {
6225
6261
  try {
6226
- const existing = await this.getItemById({ id });
6262
+ const existing = await this.#getItemById(this.#db.client, { id });
6227
6263
  if (!existing) return;
6228
6264
  if (existing.datasetId !== datasetId) throw new MastraError({
6229
6265
  id: createStorageErrorId("PG", "DELETE_ITEM", "DATASET_MISMATCH"),
@@ -6390,7 +6426,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6390
6426
  }
6391
6427
  async _doBatchDeleteItems(input) {
6392
6428
  try {
6393
- const dataset = await this.getDatasetById({ id: input.datasetId });
6429
+ const dataset = await this.#getDatasetById(this.#db.client, { id: input.datasetId });
6394
6430
  if (!dataset) throw new MastraError({
6395
6431
  id: createStorageErrorId("PG", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
6396
6432
  domain: ErrorDomain.STORAGE,
@@ -6399,7 +6435,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6399
6435
  });
6400
6436
  const currentItems = [];
6401
6437
  for (const itemId of input.itemIds) {
6402
- const item = await this.getItemById({ id: itemId });
6438
+ const item = await this.#getItemById(this.#db.client, { id: itemId });
6403
6439
  if (item && item.datasetId === input.datasetId) currentItems.push(item);
6404
6440
  }
6405
6441
  if (currentItems.length === 0) return;
@@ -6463,14 +6499,17 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6463
6499
  }
6464
6500
  }
6465
6501
  async getItemById(args) {
6502
+ return this.#getItemById(this.#db.readClient, args);
6503
+ }
6504
+ async #getItemById(client, args) {
6466
6505
  try {
6467
6506
  const tableName = getTableName$5({
6468
6507
  indexName: TABLE_DATASET_ITEMS,
6469
6508
  schemaName: getSchemaName$5(this.#schema)
6470
6509
  });
6471
6510
  let result;
6472
- if (args.datasetVersion !== void 0) result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6473
- else result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6511
+ if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6512
+ else result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6474
6513
  return result ? this.transformItemRow(result) : null;
6475
6514
  } catch (error) {
6476
6515
  throw new MastraError({
@@ -6486,7 +6525,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6486
6525
  indexName: TABLE_DATASET_ITEMS,
6487
6526
  schemaName: getSchemaName$5(this.#schema)
6488
6527
  });
6489
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6528
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6490
6529
  datasetId,
6491
6530
  version,
6492
6531
  version
@@ -6505,7 +6544,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6505
6544
  indexName: TABLE_DATASET_ITEMS,
6506
6545
  schemaName: getSchemaName$5(this.#schema)
6507
6546
  });
6508
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6547
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6509
6548
  } catch (error) {
6510
6549
  throw new MastraError({
6511
6550
  id: createStorageErrorId("PG", "GET_ITEM_HISTORY", "FAILED"),
@@ -6515,6 +6554,13 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6515
6554
  }
6516
6555
  }
6517
6556
  async listItems(args) {
6557
+ return this.#listItems(this.#db.readClient, args);
6558
+ }
6559
+ /**
6560
+ * Same listing against an explicit client. `updateDataset` validates existing
6561
+ * items on the writer so a lagging replica cannot hide freshly inserted rows.
6562
+ */
6563
+ async #listItems(client, args) {
6518
6564
  try {
6519
6565
  const { page, perPage: perPageInput } = args.pagination;
6520
6566
  const tableName = getTableName$5({
@@ -6551,7 +6597,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6551
6597
  }
6552
6598
  }
6553
6599
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
6554
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6600
+ const countResult = await client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6555
6601
  const total = parseInt(countResult.count, 10);
6556
6602
  if (total === 0) return {
6557
6603
  items: [],
@@ -6566,7 +6612,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6566
6612
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6567
6613
  const limitValue = perPageInput === false ? total : perPage;
6568
6614
  return {
6569
- items: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6615
+ items: (await client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6570
6616
  ...queryParams,
6571
6617
  limitValue,
6572
6618
  offset
@@ -6621,7 +6667,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6621
6667
  indexName: TABLE_DATASET_VERSIONS,
6622
6668
  schemaName: getSchemaName$5(this.#schema)
6623
6669
  });
6624
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`, [input.datasetId]);
6670
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`, [input.datasetId]);
6625
6671
  const total = parseInt(countResult.count, 10);
6626
6672
  if (total === 0) return {
6627
6673
  versions: [],
@@ -6636,7 +6682,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6636
6682
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6637
6683
  const limitValue = perPageInput === false ? total : perPage;
6638
6684
  return {
6639
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`, [
6685
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`, [
6640
6686
  input.datasetId,
6641
6687
  limitValue,
6642
6688
  offset
@@ -6686,9 +6732,10 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
6686
6732
  } };
6687
6733
  constructor(config) {
6688
6734
  super();
6689
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
6735
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
6690
6736
  this.#db = new PgDB({
6691
6737
  client,
6738
+ readClient,
6692
6739
  schemaName,
6693
6740
  skipDefaultIndexes
6694
6741
  });
@@ -7026,7 +7073,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7026
7073
  }
7027
7074
  async updateExperiment(input) {
7028
7075
  try {
7029
- if (!await this.getExperimentById({ id: input.id })) throw new MastraError({
7076
+ if (!await this.#getExperimentById(this.#db.client, { id: input.id })) throw new MastraError({
7030
7077
  id: createStorageErrorId("PG", "UPDATE_EXPERIMENT", "NOT_FOUND"),
7031
7078
  domain: ErrorDomain.STORAGE,
7032
7079
  category: ErrorCategory.USER,
@@ -7082,7 +7129,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7082
7129
  }
7083
7130
  values.push(input.id);
7084
7131
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`, values);
7085
- return await this.getExperimentById({ id: input.id });
7132
+ return await this.#getExperimentById(this.#db.client, { id: input.id });
7086
7133
  } catch (error) {
7087
7134
  if (error instanceof MastraError) throw error;
7088
7135
  throw new MastraError({
@@ -7092,7 +7139,14 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7092
7139
  }, error);
7093
7140
  }
7094
7141
  }
7095
- async getExperimentById({ id, filters }) {
7142
+ async getExperimentById(args) {
7143
+ return this.#getExperimentById(this.#db.readClient, args);
7144
+ }
7145
+ /**
7146
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
7147
+ * lagging read replica cannot yield stale or missing rows mid-update.
7148
+ */
7149
+ async #getExperimentById(client, { id, filters }) {
7096
7150
  try {
7097
7151
  const tableName = getTableName$5({
7098
7152
  indexName: TABLE_EXPERIMENTS,
@@ -7100,7 +7154,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7100
7154
  });
7101
7155
  const { conditions, params } = tenancyWhere(filters, 2);
7102
7156
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
7103
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7157
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7104
7158
  return result ? this.transformExperimentRow(result) : null;
7105
7159
  } catch (error) {
7106
7160
  throw new MastraError({
@@ -7168,7 +7222,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7168
7222
  }
7169
7223
  }
7170
7224
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
7171
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7225
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7172
7226
  const total = parseInt(countResult.count, 10);
7173
7227
  if (total === 0) return {
7174
7228
  experiments: [],
@@ -7183,7 +7237,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7183
7237
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
7184
7238
  const limitValue = perPageInput === false ? total : perPage;
7185
7239
  return {
7186
- experiments: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7240
+ experiments: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7187
7241
  ...queryParams,
7188
7242
  limitValue,
7189
7243
  offset
@@ -7387,7 +7441,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7387
7441
  values.push(input.comment);
7388
7442
  }
7389
7443
  if (setClauses.length === 0) {
7390
- const existing = await this.getExperimentResultById({ id: input.id });
7444
+ const existing = await this.#getExperimentResultById(this.#db.client, { id: input.id });
7391
7445
  if (!existing) throw new MastraError({
7392
7446
  id: createStorageErrorId("PG", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
7393
7447
  domain: ErrorDomain.STORAGE,
@@ -7420,7 +7474,14 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7420
7474
  }, error);
7421
7475
  }
7422
7476
  }
7423
- async getExperimentResultById({ id, filters }) {
7477
+ async getExperimentResultById(args) {
7478
+ return this.#getExperimentResultById(this.#db.readClient, args);
7479
+ }
7480
+ /**
7481
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
7482
+ * lagging read replica cannot yield stale or missing rows mid-update.
7483
+ */
7484
+ async #getExperimentResultById(client, { id, filters }) {
7424
7485
  try {
7425
7486
  const tableName = getTableName$5({
7426
7487
  indexName: TABLE_EXPERIMENT_RESULTS,
@@ -7428,7 +7489,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7428
7489
  });
7429
7490
  const { conditions, params } = tenancyWhere(filters, 2);
7430
7491
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
7431
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7492
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7432
7493
  return result ? this.transformExperimentResultRow(result) : null;
7433
7494
  } catch (error) {
7434
7495
  throw new MastraError({
@@ -7468,7 +7529,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7468
7529
  }
7469
7530
  }
7470
7531
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
7471
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7532
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7472
7533
  const total = parseInt(countResult.count, 10);
7473
7534
  if (total === 0) return {
7474
7535
  results: [],
@@ -7483,7 +7544,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7483
7544
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
7484
7545
  const limitValue = perPageInput === false ? total : perPage;
7485
7546
  return {
7486
- results: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "startedAt" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7547
+ results: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "startedAt" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7487
7548
  ...queryParams,
7488
7549
  limitValue,
7489
7550
  offset
@@ -7537,7 +7598,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7537
7598
  indexName: TABLE_EXPERIMENT_RESULTS,
7538
7599
  schemaName: getSchemaName$5(this.#schema)
7539
7600
  });
7540
- return (await this.#db.client.manyOrNone(`SELECT
7601
+ return (await this.#db.readClient.manyOrNone(`SELECT
7541
7602
  "experimentId",
7542
7603
  COUNT(*)::int as total,
7543
7604
  SUM(CASE WHEN status = 'needs-review' THEN 1 ELSE 0 END)::int as "needsReview",
@@ -7579,9 +7640,10 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7579
7640
  static MANAGED_TABLES = [TABLE_FAVORITES];
7580
7641
  constructor(config) {
7581
7642
  super();
7582
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
7643
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
7583
7644
  this.#db = new PgDB({
7584
7645
  client,
7646
+ readClient,
7585
7647
  schemaName,
7586
7648
  skipDefaultIndexes
7587
7649
  });
@@ -7747,7 +7809,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7747
7809
  schemaName: getSchemaName$5(this.#schema)
7748
7810
  });
7749
7811
  try {
7750
- return await this.#db.client.oneOrNone(`SELECT 1 FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" = $3 LIMIT 1`, [
7812
+ return await this.#db.readClient.oneOrNone(`SELECT 1 FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" = $3 LIMIT 1`, [
7751
7813
  input.userId,
7752
7814
  input.entityType,
7753
7815
  input.entityId
@@ -7770,7 +7832,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7770
7832
  });
7771
7833
  try {
7772
7834
  const placeholders = entityIds.map((_, i) => `$${i + 3}`).join(", ");
7773
- const rows = await this.#db.client.manyOrNone(`SELECT "entityId" FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" IN (${placeholders})`, [
7835
+ const rows = await this.#db.readClient.manyOrNone(`SELECT "entityId" FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" IN (${placeholders})`, [
7774
7836
  userId,
7775
7837
  entityType,
7776
7838
  ...entityIds
@@ -7793,7 +7855,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7793
7855
  schemaName: getSchemaName$5(this.#schema)
7794
7856
  });
7795
7857
  try {
7796
- return (await this.#db.client.manyOrNone(`SELECT "entityId" FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 ORDER BY "createdAt" DESC, "entityId" ASC`, [input.userId, input.entityType]) ?? []).map((row) => row.entityId);
7858
+ return (await this.#db.readClient.manyOrNone(`SELECT "entityId" FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 ORDER BY "createdAt" DESC, "entityId" ASC`, [input.userId, input.entityType]) ?? []).map((row) => row.entityId);
7797
7859
  } catch (error) {
7798
7860
  if (error instanceof MastraError) throw error;
7799
7861
  throw new MastraError({
@@ -8096,16 +8158,20 @@ var KnowledgePG = class extends KnowledgeStorage {
8096
8158
  }
8097
8159
  #client;
8098
8160
  #executor;
8161
+ /** Reader-backed executor for standalone reads; mutations and read-modify-write stay on #executor. */
8162
+ #readExecutor;
8099
8163
  #db;
8100
8164
  #schemaName;
8101
8165
  constructor(config) {
8102
8166
  super();
8103
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
8167
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
8104
8168
  this.#client = client;
8105
8169
  this.#schemaName = schemaName;
8106
8170
  this.#executor = createExecutor(client, schemaName);
8171
+ this.#readExecutor = createExecutor(readClient, schemaName);
8107
8172
  this.#db = new PgDB({
8108
8173
  client,
8174
+ readClient,
8109
8175
  schemaName,
8110
8176
  skipDefaultIndexes
8111
8177
  });
@@ -8207,13 +8273,13 @@ var KnowledgePG = class extends KnowledgeStorage {
8207
8273
  });
8208
8274
  }
8209
8275
  async getNode(id) {
8210
- return this.#getNode(this.#executor, id);
8276
+ return this.#getNode(this.#readExecutor, id);
8211
8277
  }
8212
8278
  async getNodeByName(input) {
8213
- return this.#getNodeByName(this.#executor, input.name, canonicalizeKnowledgeScope(input.scope));
8279
+ return this.#getNodeByName(this.#readExecutor, input.name, canonicalizeKnowledgeScope(input.scope));
8214
8280
  }
8215
8281
  async resolveNode(input) {
8216
- return this.#resolveNode(this.#executor, input.name, canonicalizeKnowledgeScope(input.scope));
8282
+ return this.#resolveNode(this.#readExecutor, input.name, canonicalizeKnowledgeScope(input.scope));
8217
8283
  }
8218
8284
  async listNodes(input) {
8219
8285
  const key = knowledgeScopeKey(canonicalizeKnowledgeScope(input.scope));
@@ -8243,7 +8309,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8243
8309
  args.push(updatedAt, updatedAt, cursor.name, cursor.name, cursor.id);
8244
8310
  }
8245
8311
  args.push(input.limit ?? 100);
8246
- return (await this.#executor.execute({
8312
+ return (await this.#readExecutor.execute({
8247
8313
  sql: `SELECT *, scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_NODES}" WHERE ${clauses.join(" AND ")} ORDER BY updatedAt DESC, name ASC, id ASC LIMIT ?`,
8248
8314
  args
8249
8315
  })).rows.map(parseNode);
@@ -8409,7 +8475,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8409
8475
  });
8410
8476
  }
8411
8477
  async getKnowledge(input) {
8412
- const result = await this.#executor.execute({
8478
+ const result = await this.#readExecutor.execute({
8413
8479
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_RECORDS}" WHERE id=?${input.includeDeleted ? "" : " AND deletedAt IS NULL"}`,
8414
8480
  args: [input.id]
8415
8481
  });
@@ -8434,7 +8500,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8434
8500
  if (input.after) args.push(input.after);
8435
8501
  const limit = input.limit ?? 100;
8436
8502
  args.push(limit + 1);
8437
- const records = (await this.#executor.execute({
8503
+ const records = (await this.#readExecutor.execute({
8438
8504
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_RECORDS}" WHERE sourceThreadId=? AND ${visibleSql}${input.includeDeleted ? "" : " AND deletedAt IS NULL"}${input.after ? " AND id > ?" : ""} ORDER BY id ASC LIMIT ?`,
8439
8505
  args
8440
8506
  })).rows.map(parseKnowledge);
@@ -8529,7 +8595,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8529
8595
  const normalizedQuery = input.query.trim().toLocaleLowerCase();
8530
8596
  if (!normalizedQuery) return [];
8531
8597
  const query = `%${escapeLikePattern(normalizedQuery)}%`;
8532
- const results = (await this.#executor.execute({
8598
+ const results = (await this.#readExecutor.execute({
8533
8599
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_NODES}" WHERE mergedInto IS NULL AND ${visibleSql} AND (canonicalName LIKE ? ESCAPE '=' OR lower(COALESCE(kind,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(content,'')) LIKE ? ESCAPE '=' OR lower(COALESCE(description,'')) LIKE ? ESCAPE '=') ORDER BY updatedAt DESC LIMIT ?`,
8534
8600
  args: [
8535
8601
  key,
@@ -8553,7 +8619,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8553
8619
  scope: parseJson$1(row.scopeJson)
8554
8620
  }));
8555
8621
  if (results.length < (input.limit ?? 20)) {
8556
- const records = await this.#executor.execute({
8622
+ const records = await this.#readExecutor.execute({
8557
8623
  sql: `SELECT f.*,f.scope AS "scopeJson",r.name,r.scope AS "parentScopeJson" FROM "${TABLE_KNOWLEDGE_RECORDS}" f JOIN "${TABLE_KNOWLEDGE_NODES}" r ON r.id=f.node AND r.type='node' AND r.mergedInto IS NULL WHERE f.deletedAt IS NULL AND ${visibleSql.replaceAll("scopeKey", "f.scopeKey")} AND lower(f.text) LIKE ? ESCAPE '=' ORDER BY f.id DESC LIMIT ?`,
8558
8624
  args: [
8559
8625
  key,
@@ -8606,7 +8672,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8606
8672
  }
8607
8673
  async listActivity(input) {
8608
8674
  const key = knowledgeScopeKey(canonicalizeKnowledgeScope(input.scope));
8609
- return (await this.#executor.execute({
8675
+ return (await this.#readExecutor.execute({
8610
8676
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
8611
8677
  args: [
8612
8678
  key,
@@ -8750,7 +8816,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8750
8816
  }
8751
8817
  async #queryKnowledge(input, relationship) {
8752
8818
  const scope = canonicalizeKnowledgeScope(input.scope);
8753
- const node = await this.#resolveTerminalNode(this.#executor, nodeReferenceId(input.node));
8819
+ const node = await this.#resolveTerminalNode(this.#readExecutor, nodeReferenceId(input.node));
8754
8820
  if (!node) return { records: [] };
8755
8821
  const key = knowledgeScopeKey(scope);
8756
8822
  const args = [
@@ -8761,7 +8827,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8761
8827
  ];
8762
8828
  if (input.after) args.push(input.after);
8763
8829
  args.push((input.limit ?? 100) + 1);
8764
- const records = (await this.#executor.execute({
8830
+ const records = (await this.#readExecutor.execute({
8765
8831
  sql: `SELECT DISTINCT f.*,f.scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_RECORDS}" f${relationship === "about" ? "" : ` LEFT JOIN "${TABLE_KNOWLEDGE_MENTIONS}" m ON m.sourceType='record' AND m.sourceId=f.id`} WHERE ${relationship === "about" ? "f.node=?" : relationship === "mentioning" ? "m.recordId=?" : "(f.node=? OR m.recordId=?)"} AND ${visibleSql.replaceAll("scopeKey", "f.scopeKey")}${input.includeDeleted ? "" : " AND f.deletedAt IS NULL"}${input.after ? " AND f.id < ?" : ""} ORDER BY f.id DESC LIMIT ?`,
8766
8832
  args
8767
8833
  })).rows.map(parseKnowledge);
@@ -8873,9 +8939,10 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
8873
8939
  static MANAGED_TABLES = [TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS];
8874
8940
  constructor(config) {
8875
8941
  super();
8876
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
8942
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
8877
8943
  this.#db = new PgDB({
8878
8944
  client,
8945
+ readClient,
8879
8946
  schemaName,
8880
8947
  skipDefaultIndexes
8881
8948
  });
@@ -8939,12 +9006,19 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
8939
9006
  await this.#db.clearTable({ tableName: TABLE_MCP_CLIENTS });
8940
9007
  }
8941
9008
  async getById(id) {
9009
+ return this.#getById(this.#db.readClient, id);
9010
+ }
9011
+ /**
9012
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
9013
+ * lagging read replica cannot yield stale or missing rows mid-update.
9014
+ */
9015
+ async #getById(client, id) {
8942
9016
  try {
8943
9017
  const tableName = getTableName$5({
8944
9018
  indexName: TABLE_MCP_CLIENTS,
8945
9019
  schemaName: getSchemaName$5(this.#schema)
8946
9020
  });
8947
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9021
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
8948
9022
  if (!result) return null;
8949
9023
  return this.parseMCPClientRow(result);
8950
9024
  } catch (error) {
@@ -9023,7 +9097,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9023
9097
  indexName: TABLE_MCP_CLIENTS,
9024
9098
  schemaName: getSchemaName$5(this.#schema)
9025
9099
  });
9026
- const existingClient = await this.getById(id);
9100
+ const existingClient = await this.#getById(this.#db.client, id);
9027
9101
  if (!existingClient) throw new MastraError({
9028
9102
  id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND"),
9029
9103
  domain: ErrorDomain.STORAGE,
@@ -9062,7 +9136,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9062
9136
  values.push(now);
9063
9137
  values.push(id);
9064
9138
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9065
- const updatedClient = await this.getById(id);
9139
+ const updatedClient = await this.#getById(this.#db.client, id);
9066
9140
  if (!updatedClient) throw new MastraError({
9067
9141
  id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND_AFTER_UPDATE"),
9068
9142
  domain: ErrorDomain.STORAGE,
@@ -9129,7 +9203,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9129
9203
  queryParams.push(JSON.stringify(metadata));
9130
9204
  }
9131
9205
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9132
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9206
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9133
9207
  const total = parseInt(countResult.count, 10);
9134
9208
  if (total === 0) return {
9135
9209
  mcpClients: [],
@@ -9140,7 +9214,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9140
9214
  };
9141
9215
  const limitValue = perPageInput === false ? total : perPage;
9142
9216
  return {
9143
- mcpClients: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9217
+ mcpClients: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9144
9218
  ...queryParams,
9145
9219
  limitValue,
9146
9220
  offset
@@ -9217,7 +9291,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9217
9291
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9218
9292
  schemaName: getSchemaName$5(this.#schema)
9219
9293
  });
9220
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9294
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9221
9295
  if (!result) return null;
9222
9296
  return this.parseVersionRow(result);
9223
9297
  } catch (error) {
@@ -9236,7 +9310,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9236
9310
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9237
9311
  schemaName: getSchemaName$5(this.#schema)
9238
9312
  });
9239
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`, [mcpClientId, versionNumber]);
9313
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`, [mcpClientId, versionNumber]);
9240
9314
  if (!result) return null;
9241
9315
  return this.parseVersionRow(result);
9242
9316
  } catch (error) {
@@ -9258,7 +9332,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9258
9332
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9259
9333
  schemaName: getSchemaName$5(this.#schema)
9260
9334
  });
9261
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpClientId]);
9335
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpClientId]);
9262
9336
  if (!result) return null;
9263
9337
  return this.parseVersionRow(result);
9264
9338
  } catch (error) {
@@ -9287,7 +9361,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9287
9361
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9288
9362
  schemaName: getSchemaName$5(this.#schema)
9289
9363
  });
9290
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9364
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9291
9365
  const total = parseInt(countResult.count, 10);
9292
9366
  if (total === 0) return {
9293
9367
  versions: [],
@@ -9298,7 +9372,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9298
9372
  };
9299
9373
  const limitValue = perPageInput === false ? total : perPage;
9300
9374
  return {
9301
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9375
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9302
9376
  mcpClientId,
9303
9377
  limitValue,
9304
9378
  offset
@@ -9368,7 +9442,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9368
9442
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9369
9443
  schemaName: getSchemaName$5(this.#schema)
9370
9444
  });
9371
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9445
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9372
9446
  return parseInt(result.count, 10);
9373
9447
  } catch (error) {
9374
9448
  if (error instanceof MastraError) throw error;
@@ -9428,9 +9502,10 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9428
9502
  static MANAGED_TABLES = [TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS];
9429
9503
  constructor(config) {
9430
9504
  super();
9431
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
9505
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
9432
9506
  this.#db = new PgDB({
9433
9507
  client,
9508
+ readClient,
9434
9509
  schemaName,
9435
9510
  skipDefaultIndexes
9436
9511
  });
@@ -9494,12 +9569,19 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9494
9569
  await this.#db.clearTable({ tableName: TABLE_MCP_SERVERS });
9495
9570
  }
9496
9571
  async getById(id) {
9572
+ return this.#getById(this.#db.readClient, id);
9573
+ }
9574
+ /**
9575
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
9576
+ * lagging read replica cannot yield stale or missing rows mid-update.
9577
+ */
9578
+ async #getById(client, id) {
9497
9579
  try {
9498
9580
  const tableName = getTableName$5({
9499
9581
  indexName: TABLE_MCP_SERVERS,
9500
9582
  schemaName: getSchemaName$5(this.#schema)
9501
9583
  });
9502
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9584
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9503
9585
  if (!result) return null;
9504
9586
  return this.parseMCPServerRow(result);
9505
9587
  } catch (error) {
@@ -9578,7 +9660,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9578
9660
  indexName: TABLE_MCP_SERVERS,
9579
9661
  schemaName: getSchemaName$5(this.#schema)
9580
9662
  });
9581
- const existingServer = await this.getById(id);
9663
+ const existingServer = await this.#getById(this.#db.client, id);
9582
9664
  if (!existingServer) throw new MastraError({
9583
9665
  id: createStorageErrorId("PG", "UPDATE_MCP_SERVER", "NOT_FOUND"),
9584
9666
  domain: ErrorDomain.STORAGE,
@@ -9617,7 +9699,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9617
9699
  values.push(now);
9618
9700
  values.push(id);
9619
9701
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9620
- const updatedServer = await this.getById(id);
9702
+ const updatedServer = await this.#getById(this.#db.client, id);
9621
9703
  if (!updatedServer) throw new MastraError({
9622
9704
  id: createStorageErrorId("PG", "UPDATE_MCP_SERVER", "NOT_FOUND_AFTER_UPDATE"),
9623
9705
  domain: ErrorDomain.STORAGE,
@@ -9684,7 +9766,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9684
9766
  queryParams.push(JSON.stringify(metadata));
9685
9767
  }
9686
9768
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9687
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9769
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9688
9770
  const total = parseInt(countResult.count, 10);
9689
9771
  if (total === 0) return {
9690
9772
  mcpServers: [],
@@ -9695,7 +9777,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9695
9777
  };
9696
9778
  const limitValue = perPageInput === false ? total : perPage;
9697
9779
  return {
9698
- mcpServers: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9780
+ mcpServers: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9699
9781
  ...queryParams,
9700
9782
  limitValue,
9701
9783
  offset
@@ -9782,7 +9864,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9782
9864
  indexName: TABLE_MCP_SERVER_VERSIONS,
9783
9865
  schemaName: getSchemaName$5(this.#schema)
9784
9866
  });
9785
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9867
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9786
9868
  if (!result) return null;
9787
9869
  return this.parseVersionRow(result);
9788
9870
  } catch (error) {
@@ -9801,7 +9883,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9801
9883
  indexName: TABLE_MCP_SERVER_VERSIONS,
9802
9884
  schemaName: getSchemaName$5(this.#schema)
9803
9885
  });
9804
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 AND "versionNumber" = $2`, [mcpServerId, versionNumber]);
9886
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 AND "versionNumber" = $2`, [mcpServerId, versionNumber]);
9805
9887
  if (!result) return null;
9806
9888
  return this.parseVersionRow(result);
9807
9889
  } catch (error) {
@@ -9823,7 +9905,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9823
9905
  indexName: TABLE_MCP_SERVER_VERSIONS,
9824
9906
  schemaName: getSchemaName$5(this.#schema)
9825
9907
  });
9826
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpServerId]);
9908
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpServerId]);
9827
9909
  if (!result) return null;
9828
9910
  return this.parseVersionRow(result);
9829
9911
  } catch (error) {
@@ -9852,7 +9934,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9852
9934
  indexName: TABLE_MCP_SERVER_VERSIONS,
9853
9935
  schemaName: getSchemaName$5(this.#schema)
9854
9936
  });
9855
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9937
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9856
9938
  const total = parseInt(countResult.count, 10);
9857
9939
  if (total === 0) return {
9858
9940
  versions: [],
@@ -9863,7 +9945,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9863
9945
  };
9864
9946
  const limitValue = perPageInput === false ? total : perPage;
9865
9947
  return {
9866
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9948
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9867
9949
  mcpServerId,
9868
9950
  limitValue,
9869
9951
  offset
@@ -9933,7 +10015,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9933
10015
  indexName: TABLE_MCP_SERVER_VERSIONS,
9934
10016
  schemaName: getSchemaName$5(this.#schema)
9935
10017
  });
9936
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
10018
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9937
10019
  return parseInt(result.count, 10);
9938
10020
  } catch (error) {
9939
10021
  if (error instanceof MastraError) throw error;
@@ -10102,9 +10184,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10102
10184
  ];
10103
10185
  constructor(config) {
10104
10186
  super();
10105
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10187
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10106
10188
  this.#db = new PgDB({
10107
10189
  client,
10190
+ readClient,
10108
10191
  schemaName,
10109
10192
  skipDefaultIndexes
10110
10193
  });
@@ -10353,6 +10436,16 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10353
10436
  };
10354
10437
  }
10355
10438
  async getThreadById({ threadId, resourceId }) {
10439
+ return this.#getThreadById(this.#db.readClient, {
10440
+ threadId,
10441
+ resourceId
10442
+ });
10443
+ }
10444
+ /**
10445
+ * Thread lookup against an explicit client. Mutation paths pass the writer so
10446
+ * a lagging read replica cannot produce false not-found or stale metadata.
10447
+ */
10448
+ async #getThreadById(client, { threadId, resourceId }) {
10356
10449
  try {
10357
10450
  let query = `SELECT * FROM ${getTableName$3({
10358
10451
  indexName: TABLE_THREADS,
@@ -10363,7 +10456,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10363
10456
  query += ` AND "resourceId" = $2`;
10364
10457
  params.push(resourceId);
10365
10458
  }
10366
- const thread = await this.#db.client.oneOrNone(query, params);
10459
+ const thread = await client.oneOrNone(query, params);
10367
10460
  if (!thread) return null;
10368
10461
  return {
10369
10462
  id: thread.id,
@@ -10432,7 +10525,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10432
10525
  }
10433
10526
  const baseQuery = `FROM ${tableName} ${whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : ""}`;
10434
10527
  const countQuery = `SELECT COUNT(*) ${baseQuery}`;
10435
- const countResult = await this.#db.client.one(countQuery, queryParams);
10528
+ const countResult = await this.#db.readClient.one(countQuery, queryParams);
10436
10529
  const total = parseInt(countResult.count, 10);
10437
10530
  if (total === 0) return {
10438
10531
  threads: [],
@@ -10444,7 +10537,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10444
10537
  const limitValue = perPageInput === false ? total : perPage;
10445
10538
  const dataQuery = `SELECT id, "resourceId", title, metadata, "createdAt", "createdAtZ", "updatedAt", "updatedAtZ" ${baseQuery} ORDER BY COALESCE("${field}Z", "${field}") ${direction} LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`;
10446
10539
  return {
10447
- threads: (await this.#db.client.manyOrNone(dataQuery, [
10540
+ threads: (await this.#db.readClient.manyOrNone(dataQuery, [
10448
10541
  ...queryParams,
10449
10542
  limitValue,
10450
10543
  offset
@@ -10528,7 +10621,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10528
10621
  indexName: TABLE_THREADS,
10529
10622
  schemaName: getSchemaName$3(this.#schema)
10530
10623
  });
10531
- const existingThread = await this.getThreadById({ threadId: id });
10624
+ const existingThread = await this.#getThreadById(this.#db.client, { threadId: id });
10532
10625
  if (!existingThread) throw new MastraError({
10533
10626
  id: createStorageErrorId("PG", "UPDATE_THREAD", "FAILED"),
10534
10627
  domain: ErrorDomain.STORAGE,
@@ -10660,7 +10753,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10660
10753
  if (targetIds.length === 0) return null;
10661
10754
  const idPlaceholders = targetIds.map((_, i) => "$" + (i + 1)).join(", ");
10662
10755
  const targetResourceCondition = resourceId ? ` AND "resourceId" = $${targetIds.length + 1}` : "";
10663
- const targetRows = await this.#db.client.manyOrNone(`SELECT id, thread_id, "createdAt" FROM ${tableName} WHERE id IN (${idPlaceholders})${targetResourceCondition}`, resourceId ? [...targetIds, resourceId] : targetIds);
10756
+ const targetRows = await this.#db.readClient.manyOrNone(`SELECT id, thread_id, "createdAt" FROM ${tableName} WHERE id IN (${idPlaceholders})${targetResourceCondition}`, resourceId ? [...targetIds, resourceId] : targetIds);
10664
10757
  if (targetRows.length === 0) return null;
10665
10758
  const targetMap = new Map(targetRows.map((r) => [r.id, {
10666
10759
  threadId: r.thread_id,
@@ -10711,7 +10804,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10711
10804
  let finalQuery;
10712
10805
  if (unionQueries.length === 1) finalQuery = unionQueries[0].slice(1, -1);
10713
10806
  else finalQuery = `SELECT * FROM (${unionQueries.join(" UNION ALL ")}) AS combined ORDER BY "createdAt" ASC, id ASC`;
10714
- const includedRows = await this.#db.client.manyOrNone(finalQuery, params);
10807
+ const includedRows = await this.#db.readClient.manyOrNone(finalQuery, params);
10715
10808
  const seen = /* @__PURE__ */ new Set();
10716
10809
  return includedRows.filter((row) => {
10717
10810
  if (seen.has(row.id)) return false;
@@ -10747,7 +10840,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10747
10840
  WHERE id IN (${inPlaceholders(messageIds.length)})
10748
10841
  ORDER BY "createdAt" DESC
10749
10842
  `;
10750
- const resultRows = await this.#db.client.manyOrNone(query, messageIds);
10843
+ const resultRows = await this.#db.readClient.manyOrNone(query, messageIds);
10751
10844
  return { messages: new MessageList().add(resultRows.map((row) => this.parseRow(row)), "memory").get.all.db() };
10752
10845
  } catch (error) {
10753
10846
  const mastraError = new MastraError({
@@ -10778,7 +10871,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10778
10871
  perPage,
10779
10872
  offset
10780
10873
  ];
10781
- const rows = await this.#db.client.manyOrNone(`${selectStatement}, COUNT(*) OVER () AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
10874
+ const rows = await this.#db.readClient.manyOrNone(`${selectStatement}, COUNT(*) OVER () AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
10782
10875
  if (rows.length > 0) return {
10783
10876
  total: Number(rows[0].__total),
10784
10877
  messages: rows
@@ -10787,7 +10880,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10787
10880
  total: 0,
10788
10881
  messages: []
10789
10882
  };
10790
- const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
10883
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
10791
10884
  return {
10792
10885
  total: parseInt(countResult.count, 10),
10793
10886
  messages: []
@@ -10881,7 +10974,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10881
10974
  let total;
10882
10975
  let messages;
10883
10976
  if (metadataFilter) {
10884
- const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
10977
+ const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
10885
10978
  total = filteredRows.length;
10886
10979
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
10887
10980
  } else ({total, messages} = await this.#fetchMessagePage({
@@ -11027,7 +11120,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11027
11120
  let total;
11028
11121
  let messages;
11029
11122
  if (metadataFilter) {
11030
- const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
11123
+ const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
11031
11124
  total = filteredRows.length;
11032
11125
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
11033
11126
  } else ({total, messages} = await this.#fetchMessagePage({
@@ -11102,7 +11195,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11102
11195
  if (!message.resourceId) throw new Error(`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`);
11103
11196
  threadIds.add(message.threadId);
11104
11197
  }
11105
- for (const threadIdToCheck of threadIds) if (!await this.getThreadById({ threadId: threadIdToCheck })) throw new MastraError({
11198
+ for (const threadIdToCheck of threadIds) if (!await this.#getThreadById(this.#db.client, { threadId: threadIdToCheck })) throw new MastraError({
11106
11199
  id: createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
11107
11200
  domain: ErrorDomain.STORAGE,
11108
11201
  category: ErrorCategory.THIRD_PARTY,
@@ -11270,11 +11363,14 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11270
11363
  }
11271
11364
  }
11272
11365
  async getResourceById({ resourceId }) {
11366
+ return this.#getResourceById(this.#db.readClient, resourceId);
11367
+ }
11368
+ async #getResourceById(client, resourceId) {
11273
11369
  const tableName = getTableName$3({
11274
11370
  indexName: TABLE_RESOURCES,
11275
11371
  schemaName: getSchemaName$3(this.#schema)
11276
11372
  });
11277
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [resourceId]);
11373
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [resourceId]);
11278
11374
  if (!result) return null;
11279
11375
  return {
11280
11376
  id: result.id,
@@ -11299,7 +11395,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11299
11395
  return resource;
11300
11396
  }
11301
11397
  async updateResource({ resourceId, workingMemory, metadata }) {
11302
- const existingResource = await this.getResourceById({ resourceId });
11398
+ const existingResource = await this.#getResourceById(this.#db.client, resourceId);
11303
11399
  if (!existingResource) {
11304
11400
  const newResource = {
11305
11401
  id: resourceId,
@@ -11347,7 +11443,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11347
11443
  }
11348
11444
  async cloneThread(args) {
11349
11445
  const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
11350
- const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
11446
+ const sourceThread = await this.#getThreadById(this.#db.client, { threadId: sourceThreadId });
11351
11447
  if (!sourceThread) throw new MastraError({
11352
11448
  id: createStorageErrorId("PG", "CLONE_THREAD", "SOURCE_NOT_FOUND"),
11353
11449
  domain: ErrorDomain.STORAGE,
@@ -11356,7 +11452,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11356
11452
  details: { sourceThreadId }
11357
11453
  });
11358
11454
  const newThreadId = providedThreadId || crypto.randomUUID();
11359
- if (await this.getThreadById({ threadId: newThreadId })) throw new MastraError({
11455
+ if (await this.#getThreadById(this.#db.client, { threadId: newThreadId })) throw new MastraError({
11360
11456
  id: createStorageErrorId("PG", "CLONE_THREAD", "THREAD_EXISTS"),
11361
11457
  domain: ErrorDomain.STORAGE,
11362
11458
  category: ErrorCategory.USER,
@@ -11531,7 +11627,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11531
11627
  indexName: OM_TABLE,
11532
11628
  schemaName: getSchemaName$3(this.#schema)
11533
11629
  });
11534
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "lookupKey" = $1 ORDER BY "generationCount" DESC LIMIT 1`, [lookupKey]);
11630
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "lookupKey" = $1 ORDER BY "generationCount" DESC LIMIT 1`, [lookupKey]);
11535
11631
  if (!result) return null;
11536
11632
  return this.parseOMRow(result);
11537
11633
  } catch (error) {
@@ -11573,7 +11669,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11573
11669
  params.push(options.offset);
11574
11670
  sql += ` OFFSET $${paramIndex}`;
11575
11671
  }
11576
- const result = await this.#db.client.manyOrNone(sql, params);
11672
+ const result = await this.#db.readClient.manyOrNone(sql, params);
11577
11673
  if (!result) return [];
11578
11674
  return result.map((row) => this.parseOMRow(row));
11579
11675
  } catch (error) {
@@ -12514,9 +12610,10 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12514
12610
  } };
12515
12611
  constructor(config) {
12516
12612
  super();
12517
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12613
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12518
12614
  this.#db = new PgDB({
12519
12615
  client,
12616
+ readClient,
12520
12617
  schemaName,
12521
12618
  skipDefaultIndexes
12522
12619
  });
@@ -12685,7 +12782,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12685
12782
  coalescedCount: (existing.coalescedCount ?? 1) + 1,
12686
12783
  metadata: metadata ?? null
12687
12784
  });
12688
- const updated = await this.getNotification({
12785
+ const updated = await this.#getNotification(this.#db.client, {
12689
12786
  threadId: existing.threadId,
12690
12787
  id: existing.id
12691
12788
  });
@@ -12751,7 +12848,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12751
12848
  indexName: TABLE_NOTIFICATIONS,
12752
12849
  schemaName: getSchemaName$5(this.#schema)
12753
12850
  });
12754
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`, args)).map((row) => rowToNotification(row));
12851
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`, args)).map((row) => rowToNotification(row));
12755
12852
  }
12756
12853
  async listDueNotifications(input) {
12757
12854
  const conditions = ["\"status\" = $1", "((\"deliverAt\" IS NOT NULL AND \"deliverAt\" <= $2) OR (\"summaryAt\" IS NOT NULL AND \"summaryAt\" <= $3))"];
@@ -12774,18 +12871,25 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12774
12871
  indexName: TABLE_NOTIFICATIONS,
12775
12872
  schemaName: getSchemaName$5(this.#schema)
12776
12873
  });
12777
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY CASE WHEN "deliverAt" IS NULL THEN "summaryAt" WHEN "summaryAt" IS NULL THEN "deliverAt" WHEN "deliverAt" <= "summaryAt" THEN "deliverAt" ELSE "summaryAt" END ASC, "updatedAt" ASC${limit}`, args)).map((row) => rowToNotification(row));
12874
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY CASE WHEN "deliverAt" IS NULL THEN "summaryAt" WHEN "summaryAt" IS NULL THEN "deliverAt" WHEN "deliverAt" <= "summaryAt" THEN "deliverAt" ELSE "summaryAt" END ASC, "updatedAt" ASC${limit}`, args)).map((row) => rowToNotification(row));
12778
12875
  }
12779
12876
  async getNotification(input) {
12877
+ return this.#getNotification(this.#db.readClient, input);
12878
+ }
12879
+ /**
12880
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
12881
+ * lagging read replica cannot yield stale or missing rows mid-update.
12882
+ */
12883
+ async #getNotification(client, input) {
12780
12884
  const tableName = getTableName$5({
12781
12885
  indexName: TABLE_NOTIFICATIONS,
12782
12886
  schemaName: getSchemaName$5(this.#schema)
12783
12887
  });
12784
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`, [input.threadId, input.id]);
12888
+ const row = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`, [input.threadId, input.id]);
12785
12889
  return row ? rowToNotification(row) : null;
12786
12890
  }
12787
12891
  async updateNotification(input) {
12788
- if (!await this.getNotification({
12892
+ if (!await this.#getNotification(this.#db.client, {
12789
12893
  threadId: input.threadId,
12790
12894
  id: input.id
12791
12895
  })) throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
@@ -12809,7 +12913,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12809
12913
  ...input.summarySignalId !== void 0 ? { summarySignalId: input.summarySignalId } : {},
12810
12914
  updatedAt: now
12811
12915
  });
12812
- const updated = await this.getNotification({
12916
+ const updated = await this.#getNotification(this.#db.client, {
12813
12917
  threadId: input.threadId,
12814
12918
  id: input.id
12815
12919
  });
@@ -12856,9 +12960,10 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
12856
12960
  static MANAGED_TABLES = [TABLE_SPANS];
12857
12961
  constructor(config) {
12858
12962
  super();
12859
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12963
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12860
12964
  this.#db = new PgDB({
12861
12965
  client,
12966
+ readClient,
12862
12967
  schemaName,
12863
12968
  skipDefaultIndexes
12864
12969
  });
@@ -13091,7 +13196,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13091
13196
  indexName: TABLE_SPANS,
13092
13197
  schemaName: getSchemaName$5(this.#schema)
13093
13198
  });
13094
- const row = await this.#db.client.oneOrNone(`SELECT
13199
+ const row = await this.#db.readClient.oneOrNone(`SELECT
13095
13200
  "traceId", "spanId", "parentSpanId", "name",
13096
13201
  "entityType", "entityId", "entityName",
13097
13202
  "userId", "organizationId", "resourceId",
@@ -13127,7 +13232,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13127
13232
  indexName: TABLE_SPANS,
13128
13233
  schemaName: getSchemaName$5(this.#schema)
13129
13234
  });
13130
- const row = await this.#db.client.oneOrNone(`SELECT
13235
+ const row = await this.#db.readClient.oneOrNone(`SELECT
13131
13236
  "traceId", "spanId", "parentSpanId", "name",
13132
13237
  "entityType", "entityId", "entityName",
13133
13238
  "userId", "organizationId", "resourceId",
@@ -13160,7 +13265,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13160
13265
  indexName: TABLE_SPANS,
13161
13266
  schemaName: getSchemaName$5(this.#schema)
13162
13267
  });
13163
- const spans = await this.#db.client.manyOrNone(`SELECT
13268
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13164
13269
  "traceId", "spanId", "parentSpanId", "name",
13165
13270
  "entityType", "entityId", "entityName",
13166
13271
  "userId", "organizationId", "resourceId",
@@ -13197,7 +13302,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13197
13302
  indexName: TABLE_SPANS,
13198
13303
  schemaName: getSchemaName$5(this.#schema)
13199
13304
  });
13200
- const spans = await this.#db.client.manyOrNone(`SELECT
13305
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13201
13306
  "traceId", "spanId", "parentSpanId", "name",
13202
13307
  "entityType", "entityId", "entityName",
13203
13308
  "spanType", "error", "isEvent",
@@ -13381,7 +13486,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13381
13486
  let orderClause;
13382
13487
  if (orderField === "endedAt") orderClause = `ORDER BY r."${sortField}" ${sortDirection} ${sortDirection === "DESC" ? "NULLS FIRST" : "NULLS LAST"}`;
13383
13488
  else orderClause = `ORDER BY r."${sortField}" ${sortDirection}`;
13384
- const countResult = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${tableName} r ${whereClause}`, params);
13489
+ const countResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${tableName} r ${whereClause}`, params);
13385
13490
  const count = Number(countResult?.count ?? 0);
13386
13491
  if (count === 0) return {
13387
13492
  pagination: {
@@ -13392,7 +13497,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13392
13497
  },
13393
13498
  spans: []
13394
13499
  };
13395
- const spans = await this.#db.client.manyOrNone(`SELECT
13500
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13396
13501
  r."traceId", r."spanId", r."parentSpanId", r."name",
13397
13502
  r."entityType", r."entityId", r."entityName",
13398
13503
  r."userId", r."organizationId", r."resourceId",
@@ -13489,6 +13594,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13489
13594
  }
13490
13595
  }
13491
13596
  async batchDeleteTraces(args) {
13597
+ this.assertUnscopedBatchDeleteTraces(args);
13492
13598
  try {
13493
13599
  const tableName = getTableName$5({
13494
13600
  indexName: TABLE_SPANS,
@@ -17671,11 +17777,39 @@ async function getTraceLight(client, schema, args) {
17671
17777
  spans: rows.map(rowToLightSpanRecord)
17672
17778
  };
17673
17779
  }
17780
+ /**
17781
+ * Delete traces by traceId, cascading to trace-linked signal events
17782
+ * (metrics, logs, scores, feedback). Signal rows with a NULL traceId are
17783
+ * never affected. When the optional tenant scope (`organizationId` /
17784
+ * `resourceId`) is set, every DELETE additionally requires the row's tenant
17785
+ * columns to match.
17786
+ */
17674
17787
  async function batchDeleteTraces(client, schema, args) {
17675
17788
  if (args.traceIds.length === 0) return;
17676
- const span = qualifiedTable(schema, TABLE_SPAN_EVENTS);
17789
+ const params = [...args.traceIds];
17677
17790
  const placeholders = args.traceIds.map((_, i) => `$${i + 1}`).join(", ");
17678
- await client.query(`DELETE FROM ${span} WHERE "traceId" IN (${placeholders})`, args.traceIds);
17791
+ let scopeCondition = "";
17792
+ if (args.organizationId !== void 0) {
17793
+ params.push(args.organizationId);
17794
+ scopeCondition += ` AND "organizationId" = $${params.length}`;
17795
+ }
17796
+ if (args.resourceId !== void 0) {
17797
+ params.push(args.resourceId);
17798
+ scopeCondition += ` AND "resourceId" = $${params.length}`;
17799
+ }
17800
+ const tables = [
17801
+ TABLE_SPAN_EVENTS,
17802
+ TABLE_METRIC_EVENTS,
17803
+ TABLE_LOG_EVENTS,
17804
+ TABLE_SCORE_EVENTS,
17805
+ TABLE_FEEDBACK_EVENTS
17806
+ ];
17807
+ await client.tx(async (t) => {
17808
+ for (const tableName of tables) {
17809
+ const table = qualifiedTable(schema, tableName);
17810
+ await t.query(`DELETE FROM ${table} WHERE "traceId" IN (${placeholders})${scopeCondition}`, params);
17811
+ }
17812
+ });
17679
17813
  }
17680
17814
  /** Truncate the span_events table. */
17681
17815
  async function dangerouslyClearTracing(client, schema) {
@@ -17718,6 +17852,8 @@ function wrapError(op, error, details) {
17718
17852
  }
17719
17853
  var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext extends ObservabilityStorage {
17720
17854
  #client;
17855
+ /** Reader-backed client for standalone reads; writes, DDL, and discovery-cache refresh stay on #client. */
17856
+ #readClient;
17721
17857
  #schema;
17722
17858
  #partitioning;
17723
17859
  #discoveryConfig;
@@ -17725,8 +17861,9 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17725
17861
  #partitionMode;
17726
17862
  constructor(config) {
17727
17863
  super();
17728
- const { client, schemaName } = resolvePgConfig(config);
17864
+ const { client, readClient, schemaName } = resolvePgConfig(config);
17729
17865
  this.#client = client;
17866
+ this.#readClient = readClient;
17730
17867
  this.#schema = schemaName ?? "public";
17731
17868
  this.#partitioning = config.partitioning ?? {};
17732
17869
  this.#discoveryConfig = config.discovery ?? {};
@@ -17911,34 +18048,34 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17911
18048
  await this.#run("BATCH_CREATE_SPANS", () => batchCreateSpans(this.#client, this.#schema, args), { count: args.records.length });
17912
18049
  }
17913
18050
  async getSpan(args) {
17914
- return this.#run("GET_SPAN", () => getSpan(this.#client, this.#schema, args), {
18051
+ return this.#run("GET_SPAN", () => getSpan(this.#readClient, this.#schema, args), {
17915
18052
  traceId: args.traceId,
17916
18053
  spanId: args.spanId
17917
18054
  });
17918
18055
  }
17919
18056
  async getSpans(args) {
17920
- return this.#run("GET_SPANS", () => getSpans(this.#client, this.#schema, args), {
18057
+ return this.#run("GET_SPANS", () => getSpans(this.#readClient, this.#schema, args), {
17921
18058
  traceId: args.traceId,
17922
18059
  count: args.spanIds.length
17923
18060
  });
17924
18061
  }
17925
18062
  async getRootSpan(args) {
17926
- return this.#run("GET_ROOT_SPAN", () => getRootSpan(this.#client, this.#schema, args), { traceId: args.traceId });
18063
+ return this.#run("GET_ROOT_SPAN", () => getRootSpan(this.#readClient, this.#schema, args), { traceId: args.traceId });
17927
18064
  }
17928
18065
  async getTrace(args) {
17929
- return this.#run("GET_TRACE", () => getTrace(this.#client, this.#schema, args), { traceId: args.traceId });
18066
+ return this.#run("GET_TRACE", () => getTrace(this.#readClient, this.#schema, args), { traceId: args.traceId });
17930
18067
  }
17931
18068
  async getTraceLight(args) {
17932
- return this.#run("GET_TRACE_LIGHT", () => getTraceLight(this.#client, this.#schema, args), { traceId: args.traceId });
18069
+ return this.#run("GET_TRACE_LIGHT", () => getTraceLight(this.#readClient, this.#schema, args), { traceId: args.traceId });
17933
18070
  }
17934
18071
  async listTraces(args) {
17935
- return this.#run("LIST_TRACES", () => listTraces(this.#client, this.#schema, args));
18072
+ return this.#run("LIST_TRACES", () => listTraces(this.#readClient, this.#schema, args));
17936
18073
  }
17937
18074
  async queryTraces(plan) {
17938
- return this.#run("QUERY_TRACES", () => queryTraces(this.#client, this.#schema, plan, this.#traceQueryTimeoutMs));
18075
+ return this.#run("QUERY_TRACES", () => queryTraces(this.#readClient, this.#schema, plan, this.#traceQueryTimeoutMs));
17939
18076
  }
17940
18077
  async listBranches(args) {
17941
- return this.#run("LIST_BRANCHES", () => listBranches(this.#client, this.#schema, args));
18078
+ return this.#run("LIST_BRANCHES", () => listBranches(this.#readClient, this.#schema, args));
17942
18079
  }
17943
18080
  async batchCreateLogs(args) {
17944
18081
  await this.#run("BATCH_CREATE_LOGS", () => batchCreateLogs(this.#client, this.#schema, args), { count: args.logs.length });
@@ -17959,58 +18096,58 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17959
18096
  await this.#run("BATCH_CREATE_FEEDBACK", () => batchCreateFeedback(this.#client, this.#schema, args), { count: args.feedbacks.length });
17960
18097
  }
17961
18098
  async listLogs(args) {
17962
- return this.#run("LIST_LOGS", () => listLogs(this.#client, this.#schema, args));
18099
+ return this.#run("LIST_LOGS", () => listLogs(this.#readClient, this.#schema, args));
17963
18100
  }
17964
18101
  async listMetrics(args) {
17965
- return this.#run("LIST_METRICS", () => listMetrics(this.#client, this.#schema, args));
18102
+ return this.#run("LIST_METRICS", () => listMetrics(this.#readClient, this.#schema, args));
17966
18103
  }
17967
18104
  async listScores(args) {
17968
- return this.#run("LIST_SCORES", () => listScores(this.#client, this.#schema, args));
18105
+ return this.#run("LIST_SCORES", () => listScores(this.#readClient, this.#schema, args));
17969
18106
  }
17970
18107
  async getScoreById(scoreId) {
17971
- return this.#run("GET_SCORE_BY_ID", () => getScoreById(this.#client, this.#schema, scoreId), { scoreId });
18108
+ return this.#run("GET_SCORE_BY_ID", () => getScoreById(this.#readClient, this.#schema, scoreId), { scoreId });
17972
18109
  }
17973
18110
  async listFeedback(args) {
17974
- return this.#run("LIST_FEEDBACK", () => listFeedback(this.#client, this.#schema, args));
18111
+ return this.#run("LIST_FEEDBACK", () => listFeedback(this.#readClient, this.#schema, args));
17975
18112
  }
17976
18113
  async updateFeedbackReviewStatus(args) {
17977
18114
  return this.#run("UPDATE_FEEDBACK_REVIEW_STATUS", () => updateFeedbackReviewStatus(this.#client, this.#schema, args), { feedbackId: args.feedbackId });
17978
18115
  }
17979
18116
  async getMetricAggregate(args) {
17980
- return this.#run("GET_METRIC_AGGREGATE", () => getMetricAggregate(this.#client, this.#schema, args));
18117
+ return this.#run("GET_METRIC_AGGREGATE", () => getMetricAggregate(this.#readClient, this.#schema, args));
17981
18118
  }
17982
18119
  async getMetricBreakdown(args) {
17983
- return this.#run("GET_METRIC_BREAKDOWN", () => getMetricBreakdown(this.#client, this.#schema, args));
18120
+ return this.#run("GET_METRIC_BREAKDOWN", () => getMetricBreakdown(this.#readClient, this.#schema, args));
17984
18121
  }
17985
18122
  async getMetricTimeSeries(args) {
17986
- return this.#run("GET_METRIC_TIME_SERIES", () => getMetricTimeSeries(this.#client, this.#schema, args));
18123
+ return this.#run("GET_METRIC_TIME_SERIES", () => getMetricTimeSeries(this.#readClient, this.#schema, args));
17987
18124
  }
17988
18125
  async getMetricPercentiles(args) {
17989
- return this.#run("GET_METRIC_PERCENTILES", () => getMetricPercentiles(this.#client, this.#schema, args));
18126
+ return this.#run("GET_METRIC_PERCENTILES", () => getMetricPercentiles(this.#readClient, this.#schema, args));
17990
18127
  }
17991
18128
  async getScoreAggregate(args) {
17992
- return this.#run("GET_SCORE_AGGREGATE", () => getScoreAggregate(this.#client, this.#schema, args));
18129
+ return this.#run("GET_SCORE_AGGREGATE", () => getScoreAggregate(this.#readClient, this.#schema, args));
17993
18130
  }
17994
18131
  async getScoreBreakdown(args) {
17995
- return this.#run("GET_SCORE_BREAKDOWN", () => getScoreBreakdown(this.#client, this.#schema, args));
18132
+ return this.#run("GET_SCORE_BREAKDOWN", () => getScoreBreakdown(this.#readClient, this.#schema, args));
17996
18133
  }
17997
18134
  async getScoreTimeSeries(args) {
17998
- return this.#run("GET_SCORE_TIME_SERIES", () => getScoreTimeSeries(this.#client, this.#schema, args));
18135
+ return this.#run("GET_SCORE_TIME_SERIES", () => getScoreTimeSeries(this.#readClient, this.#schema, args));
17999
18136
  }
18000
18137
  async getScorePercentiles(args) {
18001
- return this.#run("GET_SCORE_PERCENTILES", () => getScorePercentiles(this.#client, this.#schema, args));
18138
+ return this.#run("GET_SCORE_PERCENTILES", () => getScorePercentiles(this.#readClient, this.#schema, args));
18002
18139
  }
18003
18140
  async getFeedbackAggregate(args) {
18004
- return this.#run("GET_FEEDBACK_AGGREGATE", () => getFeedbackAggregate(this.#client, this.#schema, args));
18141
+ return this.#run("GET_FEEDBACK_AGGREGATE", () => getFeedbackAggregate(this.#readClient, this.#schema, args));
18005
18142
  }
18006
18143
  async getFeedbackBreakdown(args) {
18007
- return this.#run("GET_FEEDBACK_BREAKDOWN", () => getFeedbackBreakdown(this.#client, this.#schema, args));
18144
+ return this.#run("GET_FEEDBACK_BREAKDOWN", () => getFeedbackBreakdown(this.#readClient, this.#schema, args));
18008
18145
  }
18009
18146
  async getFeedbackTimeSeries(args) {
18010
- return this.#run("GET_FEEDBACK_TIME_SERIES", () => getFeedbackTimeSeries(this.#client, this.#schema, args));
18147
+ return this.#run("GET_FEEDBACK_TIME_SERIES", () => getFeedbackTimeSeries(this.#readClient, this.#schema, args));
18011
18148
  }
18012
18149
  async getFeedbackPercentiles(args) {
18013
- return this.#run("GET_FEEDBACK_PERCENTILES", () => getFeedbackPercentiles(this.#client, this.#schema, args));
18150
+ return this.#run("GET_FEEDBACK_PERCENTILES", () => getFeedbackPercentiles(this.#readClient, this.#schema, args));
18014
18151
  }
18015
18152
  async getEntityTypes(args) {
18016
18153
  return this.#run("GET_ENTITY_TYPES", () => getEntityTypes(this.#client, this.#schema, args, this.#discovery));
@@ -18069,9 +18206,10 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18069
18206
  static MANAGED_TABLES = [TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS];
18070
18207
  constructor(config) {
18071
18208
  super();
18072
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18209
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18073
18210
  this.#db = new PgDB({
18074
18211
  client,
18212
+ readClient,
18075
18213
  schemaName,
18076
18214
  skipDefaultIndexes
18077
18215
  });
@@ -18148,12 +18286,19 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18148
18286
  await this.#db.clearTable({ tableName: TABLE_PROMPT_BLOCKS });
18149
18287
  }
18150
18288
  async getById(id) {
18289
+ return this.#getById(this.#db.readClient, id);
18290
+ }
18291
+ /**
18292
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
18293
+ * lagging read replica cannot yield stale or missing rows mid-update.
18294
+ */
18295
+ async #getById(client, id) {
18151
18296
  try {
18152
18297
  const tableName = getTableName$5({
18153
18298
  indexName: TABLE_PROMPT_BLOCKS,
18154
18299
  schemaName: getSchemaName$5(this.#schema)
18155
18300
  });
18156
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18301
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18157
18302
  if (!result) return null;
18158
18303
  return this.parseBlockRow(result);
18159
18304
  } catch (error) {
@@ -18232,7 +18377,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18232
18377
  indexName: TABLE_PROMPT_BLOCKS,
18233
18378
  schemaName: getSchemaName$5(this.#schema)
18234
18379
  });
18235
- const existingBlock = await this.getById(id);
18380
+ const existingBlock = await this.#getById(this.#db.client, id);
18236
18381
  if (!existingBlock) throw new MastraError({
18237
18382
  id: createStorageErrorId("PG", "UPDATE_PROMPT_BLOCK", "NOT_FOUND"),
18238
18383
  domain: ErrorDomain.STORAGE,
@@ -18271,7 +18416,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18271
18416
  values.push(now);
18272
18417
  values.push(id);
18273
18418
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
18274
- const updatedBlock = await this.getById(id);
18419
+ const updatedBlock = await this.#getById(this.#db.client, id);
18275
18420
  if (!updatedBlock) throw new MastraError({
18276
18421
  id: createStorageErrorId("PG", "UPDATE_PROMPT_BLOCK", "NOT_FOUND_AFTER_UPDATE"),
18277
18422
  domain: ErrorDomain.STORAGE,
@@ -18340,7 +18485,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18340
18485
  queryParams.push(JSON.stringify(metadata));
18341
18486
  }
18342
18487
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
18343
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
18488
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
18344
18489
  const total = parseInt(countResult.count, 10);
18345
18490
  if (total === 0) return {
18346
18491
  promptBlocks: [],
@@ -18351,7 +18496,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18351
18496
  };
18352
18497
  const limitValue = perPageInput === false ? total : perPage;
18353
18498
  return {
18354
- promptBlocks: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
18499
+ promptBlocks: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
18355
18500
  ...queryParams,
18356
18501
  limitValue,
18357
18502
  offset
@@ -18430,7 +18575,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18430
18575
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18431
18576
  schemaName: getSchemaName$5(this.#schema)
18432
18577
  });
18433
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18578
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18434
18579
  if (!result) return null;
18435
18580
  return this.parseVersionRow(result);
18436
18581
  } catch (error) {
@@ -18449,7 +18594,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18449
18594
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18450
18595
  schemaName: getSchemaName$5(this.#schema)
18451
18596
  });
18452
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 AND "versionNumber" = $2`, [blockId, versionNumber]);
18597
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 AND "versionNumber" = $2`, [blockId, versionNumber]);
18453
18598
  if (!result) return null;
18454
18599
  return this.parseVersionRow(result);
18455
18600
  } catch (error) {
@@ -18471,7 +18616,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18471
18616
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18472
18617
  schemaName: getSchemaName$5(this.#schema)
18473
18618
  });
18474
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [blockId]);
18619
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [blockId]);
18475
18620
  if (!result) return null;
18476
18621
  return this.parseVersionRow(result);
18477
18622
  } catch (error) {
@@ -18500,7 +18645,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18500
18645
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18501
18646
  schemaName: getSchemaName$5(this.#schema)
18502
18647
  });
18503
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18648
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18504
18649
  const total = parseInt(countResult.count, 10);
18505
18650
  if (total === 0) return {
18506
18651
  versions: [],
@@ -18511,7 +18656,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18511
18656
  };
18512
18657
  const limitValue = perPageInput === false ? total : perPage;
18513
18658
  return {
18514
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
18659
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
18515
18660
  blockId,
18516
18661
  limitValue,
18517
18662
  offset
@@ -18581,7 +18726,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18581
18726
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18582
18727
  schemaName: getSchemaName$5(this.#schema)
18583
18728
  });
18584
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18729
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18585
18730
  return parseInt(result.count, 10);
18586
18731
  } catch (error) {
18587
18732
  if (error instanceof MastraError) throw error;
@@ -18682,6 +18827,7 @@ function rowToTrigger(row) {
18682
18827
  var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18683
18828
  #db;
18684
18829
  #client;
18830
+ #readClient;
18685
18831
  #schema;
18686
18832
  #skipDefaultIndexes;
18687
18833
  #indexes;
@@ -18701,10 +18847,12 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18701
18847
  } };
18702
18848
  constructor(config) {
18703
18849
  super();
18704
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18850
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18705
18851
  this.#client = client;
18852
+ this.#readClient = readClient;
18706
18853
  this.#db = new PgDB({
18707
18854
  client,
18855
+ readClient,
18708
18856
  schemaName,
18709
18857
  skipDefaultIndexes
18710
18858
  });
@@ -18828,7 +18976,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18828
18976
  return getTableName$2(tableName, getSchemaName$2(parseSqlIdentifier(this.#schema, "schema name")));
18829
18977
  }
18830
18978
  async createSchedule(schedule) {
18831
- if (await this.getSchedule(schedule.id)) throw new Error(`Schedule with id "${schedule.id}" already exists`);
18979
+ if (await this.#getSchedule(this.#client, schedule.id)) throw new Error(`Schedule with id "${schedule.id}" already exists`);
18832
18980
  await this.#db.insert({
18833
18981
  tableName: TABLE_SCHEDULES,
18834
18982
  record: {
@@ -18850,7 +18998,14 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18850
18998
  return schedule;
18851
18999
  }
18852
19000
  async getSchedule(id) {
18853
- const row = await this.#client.oneOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} WHERE id = $1`, [id]);
19001
+ return this.#getSchedule(this.#readClient, id);
19002
+ }
19003
+ /**
19004
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
19005
+ * lagging read replica cannot yield stale or missing rows mid-update.
19006
+ */
19007
+ async #getSchedule(client, id) {
19008
+ const row = await client.oneOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} WHERE id = $1`, [id]);
18854
19009
  return row ? rowToSchedule(row) : null;
18855
19010
  }
18856
19011
  async listSchedules(filter) {
@@ -18875,7 +19030,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18875
19030
  conditions.push(`owner_id = $${params.length}`);
18876
19031
  }
18877
19032
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
18878
- return (await this.#client.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} ${where} ORDER BY created_at ASC`, params)).map(rowToSchedule);
19033
+ return (await this.#readClient.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} ${where} ORDER BY created_at ASC`, params)).map(rowToSchedule);
18879
19034
  }
18880
19035
  async listDueSchedules(now, limit) {
18881
19036
  const cap = limit ?? 100;
@@ -18905,13 +19060,13 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18905
19060
  if ("ownerId" in patch) push("owner_id = ?", patch.ownerId ?? null);
18906
19061
  push("updated_at = ?", Date.now());
18907
19062
  if (setClauses.length === 1) {
18908
- const existing = await this.getSchedule(id);
19063
+ const existing = await this.#getSchedule(this.#client, id);
18909
19064
  if (!existing) throw new Error(`Schedule ${id} not found`);
18910
19065
  return existing;
18911
19066
  }
18912
19067
  params.push(id);
18913
19068
  await this.#client.none(`UPDATE ${this.#table(TABLE_SCHEDULES)} SET ${setClauses.join(", ")} WHERE id = $${params.length}`, params);
18914
- const updated = await this.getSchedule(id);
19069
+ const updated = await this.#getSchedule(this.#client, id);
18915
19070
  if (!updated) throw new Error(`Schedule ${id} not found`);
18916
19071
  return updated;
18917
19072
  }
@@ -18968,7 +19123,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18968
19123
  params.push(Math.floor(opts.limit));
18969
19124
  limitClause = `LIMIT $${params.length}`;
18970
19125
  }
18971
- return (await this.#client.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULE_TRIGGERS)}
19126
+ return (await this.#readClient.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULE_TRIGGERS)}
18972
19127
  WHERE ${conditions.join(" AND ")}
18973
19128
  ORDER BY actual_fire_at DESC
18974
19129
  ${limitClause}`, params)).map(rowToTrigger);
@@ -18994,9 +19149,10 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
18994
19149
  static MANAGED_TABLES = [TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS];
18995
19150
  constructor(config) {
18996
19151
  super();
18997
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19152
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18998
19153
  this.#db = new PgDB({
18999
19154
  client,
19155
+ readClient,
19000
19156
  schemaName,
19001
19157
  skipDefaultIndexes
19002
19158
  });
@@ -19073,12 +19229,19 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19073
19229
  await this.#db.clearTable({ tableName: TABLE_SCORER_DEFINITIONS });
19074
19230
  }
19075
19231
  async getById(id) {
19232
+ return this.#getById(this.#db.readClient, id);
19233
+ }
19234
+ /**
19235
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
19236
+ * lagging read replica cannot yield stale or missing rows mid-update.
19237
+ */
19238
+ async #getById(client, id) {
19076
19239
  try {
19077
19240
  const tableName = getTableName$5({
19078
19241
  indexName: TABLE_SCORER_DEFINITIONS,
19079
19242
  schemaName: getSchemaName$5(this.#schema)
19080
19243
  });
19081
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19244
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19082
19245
  if (!result) return null;
19083
19246
  return this.parseScorerRow(result);
19084
19247
  } catch (error) {
@@ -19161,7 +19324,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19161
19324
  indexName: TABLE_SCORER_DEFINITIONS,
19162
19325
  schemaName: getSchemaName$5(this.#schema)
19163
19326
  });
19164
- const existingScorer = await this.getById(id);
19327
+ const existingScorer = await this.#getById(this.#db.client, id);
19165
19328
  if (!existingScorer) throw new MastraError({
19166
19329
  id: createStorageErrorId("PG", "UPDATE_SCORER_DEFINITION", "NOT_FOUND"),
19167
19330
  domain: ErrorDomain.STORAGE,
@@ -19200,7 +19363,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19200
19363
  values.push(now);
19201
19364
  values.push(id);
19202
19365
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
19203
- const updatedScorer = await this.getById(id);
19366
+ const updatedScorer = await this.#getById(this.#db.client, id);
19204
19367
  if (!updatedScorer) throw new MastraError({
19205
19368
  id: createStorageErrorId("PG", "UPDATE_SCORER_DEFINITION", "NOT_FOUND_AFTER_UPDATE"),
19206
19369
  domain: ErrorDomain.STORAGE,
@@ -19277,7 +19440,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19277
19440
  queryParams.push(JSON.stringify(metadata));
19278
19441
  }
19279
19442
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
19280
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
19443
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
19281
19444
  const total = parseInt(countResult.count, 10);
19282
19445
  if (total === 0) return {
19283
19446
  scorerDefinitions: [],
@@ -19288,7 +19451,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19288
19451
  };
19289
19452
  const limitValue = perPageInput === false ? total : perPage;
19290
19453
  return {
19291
- scorerDefinitions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
19454
+ scorerDefinitions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
19292
19455
  ...queryParams,
19293
19456
  limitValue,
19294
19457
  offset
@@ -19370,7 +19533,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19370
19533
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19371
19534
  schemaName: getSchemaName$5(this.#schema)
19372
19535
  });
19373
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19536
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19374
19537
  if (!result) return null;
19375
19538
  return this.parseVersionRow(result);
19376
19539
  } catch (error) {
@@ -19389,7 +19552,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19389
19552
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19390
19553
  schemaName: getSchemaName$5(this.#schema)
19391
19554
  });
19392
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 AND "versionNumber" = $2`, [scorerDefinitionId, versionNumber]);
19555
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 AND "versionNumber" = $2`, [scorerDefinitionId, versionNumber]);
19393
19556
  if (!result) return null;
19394
19557
  return this.parseVersionRow(result);
19395
19558
  } catch (error) {
@@ -19411,7 +19574,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19411
19574
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19412
19575
  schemaName: getSchemaName$5(this.#schema)
19413
19576
  });
19414
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [scorerDefinitionId]);
19577
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [scorerDefinitionId]);
19415
19578
  if (!result) return null;
19416
19579
  return this.parseVersionRow(result);
19417
19580
  } catch (error) {
@@ -19440,7 +19603,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19440
19603
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19441
19604
  schemaName: getSchemaName$5(this.#schema)
19442
19605
  });
19443
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19606
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19444
19607
  const total = parseInt(countResult.count, 10);
19445
19608
  if (total === 0) return {
19446
19609
  versions: [],
@@ -19451,7 +19614,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19451
19614
  };
19452
19615
  const limitValue = perPageInput === false ? total : perPage;
19453
19616
  return {
19454
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
19617
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
19455
19618
  scorerDefinitionId,
19456
19619
  limitValue,
19457
19620
  offset
@@ -19521,7 +19684,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19521
19684
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19522
19685
  schemaName: getSchemaName$5(this.#schema)
19523
19686
  });
19524
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19687
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19525
19688
  return parseInt(result.count, 10);
19526
19689
  } catch (error) {
19527
19690
  if (error instanceof MastraError) throw error;
@@ -19618,9 +19781,10 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19618
19781
  } };
19619
19782
  constructor(config) {
19620
19783
  super();
19621
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19784
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19622
19785
  this.#db = new PgDB({
19623
19786
  client,
19787
+ readClient,
19624
19788
  schemaName,
19625
19789
  skipDefaultIndexes
19626
19790
  });
@@ -19754,7 +19918,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19754
19918
  }
19755
19919
  async getScoreById({ id }) {
19756
19920
  try {
19757
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${getTableName$1({
19921
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${getTableName$1({
19758
19922
  indexName: TABLE_SCORERS,
19759
19923
  schemaName: getSchemaName$1(this.#schema)
19760
19924
  })} WHERE id = $1`, [id]);
@@ -19786,7 +19950,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19786
19950
  }
19787
19951
  paramIndex = applyTenancyFilters(conditions, queryParams, paramIndex, filters);
19788
19952
  const whereClause = conditions.join(" AND ");
19789
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19953
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19790
19954
  indexName: TABLE_SCORERS,
19791
19955
  schemaName: getSchemaName$1(this.#schema)
19792
19956
  })} WHERE ${whereClause}`, queryParams);
@@ -19804,7 +19968,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19804
19968
  };
19805
19969
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19806
19970
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19807
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
19971
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19808
19972
  indexName: TABLE_SCORERS,
19809
19973
  schemaName: getSchemaName$1(this.#schema)
19810
19974
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -19894,7 +20058,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19894
20058
  const queryParams = [runId];
19895
20059
  let paramIndex = applyTenancyFilters(conditions, queryParams, 2, filters);
19896
20060
  const whereClause = conditions.join(" AND ");
19897
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
20061
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19898
20062
  indexName: TABLE_SCORERS,
19899
20063
  schemaName: getSchemaName$1(this.#schema)
19900
20064
  })} WHERE ${whereClause}`, queryParams);
@@ -19912,7 +20076,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19912
20076
  };
19913
20077
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19914
20078
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19915
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
20079
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19916
20080
  indexName: TABLE_SCORERS,
19917
20081
  schemaName: getSchemaName$1(this.#schema)
19918
20082
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -19943,7 +20107,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19943
20107
  const queryParams = [entityId, entityType];
19944
20108
  let paramIndex = applyTenancyFilters(conditions, queryParams, 3, filters);
19945
20109
  const whereClause = conditions.join(" AND ");
19946
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
20110
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19947
20111
  indexName: TABLE_SCORERS,
19948
20112
  schemaName: getSchemaName$1(this.#schema)
19949
20113
  })} WHERE ${whereClause}`, queryParams);
@@ -19961,7 +20125,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19961
20125
  };
19962
20126
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19963
20127
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19964
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
20128
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19965
20129
  indexName: TABLE_SCORERS,
19966
20130
  schemaName: getSchemaName$1(this.#schema)
19967
20131
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -19996,14 +20160,14 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19996
20160
  const queryParams = [traceId, spanId];
19997
20161
  let paramIndex = applyTenancyFilters(conditions, queryParams, 3, filters);
19998
20162
  const whereClause = conditions.join(" AND ");
19999
- const countSQLResult = await this.#db.client.oneOrNone(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`, queryParams);
20163
+ const countSQLResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`, queryParams);
20000
20164
  const total = Number(countSQLResult?.count ?? 0);
20001
20165
  const { page, perPage: perPageInput } = pagination;
20002
20166
  const perPage = normalizePerPage(perPageInput, 100);
20003
20167
  const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
20004
20168
  const limitValue = perPageInput === false ? total : perPage;
20005
20169
  const end = perPageInput === false ? total : start + perPage;
20006
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
20170
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
20007
20171
  ...queryParams,
20008
20172
  limitValue,
20009
20173
  start
@@ -20051,9 +20215,10 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20051
20215
  static MANAGED_TABLES = [TABLE_SKILLS, TABLE_SKILL_VERSIONS];
20052
20216
  constructor(config) {
20053
20217
  super();
20054
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20218
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20055
20219
  this.#db = new PgDB({
20056
20220
  client,
20221
+ readClient,
20057
20222
  schemaName,
20058
20223
  skipDefaultIndexes
20059
20224
  });
@@ -20127,12 +20292,19 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20127
20292
  await this.#db.clearTable({ tableName: TABLE_SKILLS });
20128
20293
  }
20129
20294
  async getById(id) {
20295
+ return this.#getById(this.#db.readClient, id);
20296
+ }
20297
+ /**
20298
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
20299
+ * lagging read replica cannot yield stale or missing rows mid-update.
20300
+ */
20301
+ async #getById(client, id) {
20130
20302
  try {
20131
20303
  const tableName = getTableName$5({
20132
20304
  indexName: TABLE_SKILLS,
20133
20305
  schemaName: getSchemaName$5(this.#schema)
20134
20306
  });
20135
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20307
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20136
20308
  if (!result) return null;
20137
20309
  return this.parseSkillRow(result);
20138
20310
  } catch (error) {
@@ -20214,7 +20386,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20214
20386
  indexName: TABLE_SKILLS,
20215
20387
  schemaName: getSchemaName$5(this.#schema)
20216
20388
  });
20217
- if (!await this.getById(id)) throw new MastraError({
20389
+ if (!await this.#getById(this.#db.client, id)) throw new MastraError({
20218
20390
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND"),
20219
20391
  domain: ErrorDomain.STORAGE,
20220
20392
  category: ErrorCategory.USER,
@@ -20226,7 +20398,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20226
20398
  const configFields = {};
20227
20399
  for (const [key, value] of Object.entries(rawConfigFields)) if (value !== void 0) configFields[key] = value;
20228
20400
  if (SNAPSHOT_FIELDS$1.some((field) => field in configFields)) {
20229
- const latestVersion = await this.getLatestVersion(id);
20401
+ const latestVersion = await this.#getLatestVersion(this.#db.client, id);
20230
20402
  if (!latestVersion) throw new MastraError({
20231
20403
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NO_VERSIONS"),
20232
20404
  domain: ErrorDomain.STORAGE,
@@ -20283,7 +20455,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20283
20455
  values.push(now);
20284
20456
  values.push(id);
20285
20457
  if (setClauses.length > 2 || versionCreated) await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
20286
- const updatedSkill = await this.getById(id);
20458
+ const updatedSkill = await this.#getById(this.#db.client, id);
20287
20459
  if (!updatedSkill) throw new MastraError({
20288
20460
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND_AFTER_UPDATE"),
20289
20461
  domain: ErrorDomain.STORAGE,
@@ -20376,7 +20548,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20376
20548
  const joinClause = useJoin && joinSqlIdx !== null ? `LEFT JOIN ${favoritesTable} sr ON sr."entityType" = 'skill' AND sr."entityId" = s.id AND sr."userId" = $${joinSqlIdx}` : "";
20377
20549
  const joinParams = useJoin && joinUserId ? [joinUserId] : [];
20378
20550
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
20379
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} s ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
20551
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} s ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
20380
20552
  const total = parseInt(countResult.count, 10);
20381
20553
  if (total === 0) return {
20382
20554
  skills: [],
@@ -20394,7 +20566,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20394
20566
  const limitIdx = paramIdx++;
20395
20567
  const offsetIdx = paramIdx++;
20396
20568
  return {
20397
- skills: (await this.#db.client.manyOrNone(`SELECT s.* FROM ${tableName} s ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
20569
+ skills: (await this.#db.readClient.manyOrNone(`SELECT s.* FROM ${tableName} s ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
20398
20570
  ...joinParams,
20399
20571
  ...queryParams,
20400
20572
  limitValue,
@@ -20482,7 +20654,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20482
20654
  indexName: TABLE_SKILL_VERSIONS,
20483
20655
  schemaName: getSchemaName$5(this.#schema)
20484
20656
  });
20485
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20657
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20486
20658
  if (!result) return null;
20487
20659
  return this.parseVersionRow(result);
20488
20660
  } catch (error) {
@@ -20503,7 +20675,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20503
20675
  schemaName: getSchemaName$5(this.#schema)
20504
20676
  });
20505
20677
  const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
20506
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
20678
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
20507
20679
  } catch (error) {
20508
20680
  if (error instanceof MastraError) throw error;
20509
20681
  throw new MastraError({
@@ -20520,7 +20692,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20520
20692
  indexName: TABLE_SKILL_VERSIONS,
20521
20693
  schemaName: getSchemaName$5(this.#schema)
20522
20694
  });
20523
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 AND "versionNumber" = $2`, [skillId, versionNumber]);
20695
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 AND "versionNumber" = $2`, [skillId, versionNumber]);
20524
20696
  if (!result) return null;
20525
20697
  return this.parseVersionRow(result);
20526
20698
  } catch (error) {
@@ -20537,12 +20709,19 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20537
20709
  }
20538
20710
  }
20539
20711
  async getLatestVersion(skillId) {
20712
+ return this.#getLatestVersion(this.#db.readClient, skillId);
20713
+ }
20714
+ /**
20715
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
20716
+ * lagging read replica cannot yield stale or missing rows mid-update.
20717
+ */
20718
+ async #getLatestVersion(client, skillId) {
20540
20719
  try {
20541
20720
  const tableName = getTableName$5({
20542
20721
  indexName: TABLE_SKILL_VERSIONS,
20543
20722
  schemaName: getSchemaName$5(this.#schema)
20544
20723
  });
20545
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [skillId]);
20724
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [skillId]);
20546
20725
  if (!result) return null;
20547
20726
  return this.parseVersionRow(result);
20548
20727
  } catch (error) {
@@ -20571,7 +20750,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20571
20750
  indexName: TABLE_SKILL_VERSIONS,
20572
20751
  schemaName: getSchemaName$5(this.#schema)
20573
20752
  });
20574
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20753
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20575
20754
  const total = parseInt(countResult.count, 10);
20576
20755
  if (total === 0) return {
20577
20756
  versions: [],
@@ -20582,7 +20761,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20582
20761
  };
20583
20762
  const limitValue = perPageInput === false ? total : perPage;
20584
20763
  return {
20585
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
20764
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
20586
20765
  skillId,
20587
20766
  limitValue,
20588
20767
  offset
@@ -20652,7 +20831,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20652
20831
  indexName: TABLE_SKILL_VERSIONS,
20653
20832
  schemaName: getSchemaName$5(this.#schema)
20654
20833
  });
20655
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20834
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20656
20835
  return parseInt(result.count, 10);
20657
20836
  } catch (error) {
20658
20837
  if (error instanceof MastraError) throw error;
@@ -20727,9 +20906,10 @@ var ThreadStatePG = class ThreadStatePG extends ThreadStateStorage {
20727
20906
  } };
20728
20907
  constructor(config) {
20729
20908
  super();
20730
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
20909
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
20731
20910
  this.#db = new PgDB({
20732
20911
  client,
20912
+ readClient,
20733
20913
  schemaName,
20734
20914
  skipDefaultIndexes
20735
20915
  });
@@ -20892,9 +21072,10 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
20892
21072
  static MANAGED_TABLES = [TABLE_TOOL_PROVIDER_CONNECTIONS];
20893
21073
  constructor(config) {
20894
21074
  super();
20895
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21075
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20896
21076
  this.#db = new PgDB({
20897
21077
  client,
21078
+ readClient,
20898
21079
  schemaName,
20899
21080
  skipDefaultIndexes
20900
21081
  });
@@ -20973,7 +21154,7 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
20973
21154
  schemaName: getSchemaName$5(this.#schema)
20974
21155
  });
20975
21156
  try {
20976
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "authorId" = $1 AND "providerId" = $2 AND "connectionId" = $3 LIMIT 1`, [
21157
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "authorId" = $1 AND "providerId" = $2 AND "connectionId" = $3 LIMIT 1`, [
20977
21158
  authorId,
20978
21159
  providerId,
20979
21160
  connectionId
@@ -21080,7 +21261,7 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
21080
21261
  clauses.push(`scope = $${args.length}`);
21081
21262
  }
21082
21263
  const whereClause = clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "";
21083
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName}${whereClause}`, args)).map((row) => rowToToolProviderConnection(row));
21264
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName}${whereClause}`, args)).map((row) => rowToToolProviderConnection(row));
21084
21265
  } catch (error) {
21085
21266
  throw new MastraError({
21086
21267
  id: createStorageErrorId("PG", "TOOL_PROVIDER_CONNECTION_LIST", "FAILED"),
@@ -21156,9 +21337,10 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21156
21337
  static MANAGED_TABLES = [TABLE_WORKFLOW_DEFINITIONS];
21157
21338
  constructor(config) {
21158
21339
  super();
21159
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21340
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21160
21341
  this.#db = new PgDB({
21161
21342
  client,
21343
+ readClient,
21162
21344
  schemaName,
21163
21345
  skipDefaultIndexes
21164
21346
  });
@@ -21215,7 +21397,7 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21215
21397
  }
21216
21398
  async upsert(input) {
21217
21399
  const now = /* @__PURE__ */ new Date();
21218
- if (!await this.get(input.id)) {
21400
+ if (!await this.#get(this.#db.client, input.id)) {
21219
21401
  if (!("inputSchema" in input) || !input.inputSchema) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
21220
21402
  if (!("outputSchema" in input) || !input.outputSchema) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
21221
21403
  if (!("graph" in input) || !input.graph) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
@@ -21241,10 +21423,10 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21241
21423
  record
21242
21424
  });
21243
21425
  } catch (error) {
21244
- if (!await this.get(input.id)) throw error;
21426
+ if (!await this.#get(this.#db.client, input.id)) throw error;
21245
21427
  return this.applyUpdate(input, now);
21246
21428
  }
21247
- const created = await this.get(input.id);
21429
+ const created = await this.#get(this.#db.client, input.id);
21248
21430
  if (!created) throw new Error(`Failed to persist workflow definition "${input.id}".`);
21249
21431
  return created;
21250
21432
  }
@@ -21267,16 +21449,23 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21267
21449
  keys: { id: input.id },
21268
21450
  data
21269
21451
  });
21270
- const updated = await this.get(input.id);
21452
+ const updated = await this.#get(this.#db.client, input.id);
21271
21453
  if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
21272
21454
  return updated;
21273
21455
  }
21274
21456
  async get(id) {
21457
+ return this.#get(this.#db.readClient, id);
21458
+ }
21459
+ /**
21460
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
21461
+ * lagging read replica cannot yield stale or missing rows mid-update.
21462
+ */
21463
+ async #get(client, id) {
21275
21464
  const tableName = getTableName$5({
21276
21465
  indexName: TABLE_WORKFLOW_DEFINITIONS,
21277
21466
  schemaName: getSchemaName$5(this.#schema)
21278
21467
  });
21279
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
21468
+ const row = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
21280
21469
  return row ? rowToDefinition(row) : null;
21281
21470
  }
21282
21471
  async list(args) {
@@ -21295,7 +21484,7 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21295
21484
  conditions.push(`"authorId" = $${params.length}`);
21296
21485
  }
21297
21486
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
21298
- const definitions = (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${where} ORDER BY "updatedAt" DESC`, params)).map((row) => rowToDefinition(row));
21487
+ const definitions = (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${where} ORDER BY "updatedAt" DESC`, params)).map((row) => rowToDefinition(row));
21299
21488
  return {
21300
21489
  definitions,
21301
21490
  total: definitions.length
@@ -21360,9 +21549,10 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
21360
21549
  } };
21361
21550
  constructor(config) {
21362
21551
  super();
21363
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21552
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21364
21553
  this.#db = new PgDB({
21365
21554
  client,
21555
+ readClient,
21366
21556
  schemaName,
21367
21557
  skipDefaultIndexes
21368
21558
  });
@@ -21685,7 +21875,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
21685
21875
  ORDER BY "createdAt" DESC LIMIT 1
21686
21876
  `;
21687
21877
  const queryValues = values;
21688
- const result = await this.#db.client.oneOrNone(query, queryValues);
21878
+ const result = await this.#db.readClient.oneOrNone(query, queryValues);
21689
21879
  if (!result) return null;
21690
21880
  return this.parseWorkflowRun(result);
21691
21881
  } catch (error) {
@@ -21814,9 +22004,10 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21814
22004
  static MANAGED_TABLES = [TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS];
21815
22005
  constructor(config) {
21816
22006
  super();
21817
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
22007
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21818
22008
  this.#db = new PgDB({
21819
22009
  client,
22010
+ readClient,
21820
22011
  schemaName,
21821
22012
  skipDefaultIndexes
21822
22013
  });
@@ -21880,12 +22071,19 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21880
22071
  await this.#db.clearTable({ tableName: TABLE_WORKSPACES });
21881
22072
  }
21882
22073
  async getById(id) {
22074
+ return this.#getById(this.#db.readClient, id);
22075
+ }
22076
+ /**
22077
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
22078
+ * lagging read replica cannot yield stale or missing rows mid-update.
22079
+ */
22080
+ async #getById(client, id) {
21883
22081
  try {
21884
22082
  const tableName = getTableName$5({
21885
22083
  indexName: TABLE_WORKSPACES,
21886
22084
  schemaName: getSchemaName$5(this.#schema)
21887
22085
  });
21888
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22086
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
21889
22087
  if (!result) return null;
21890
22088
  return this.parseWorkspaceRow(result);
21891
22089
  } catch (error) {
@@ -21964,7 +22162,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21964
22162
  indexName: TABLE_WORKSPACES,
21965
22163
  schemaName: getSchemaName$5(this.#schema)
21966
22164
  });
21967
- const existingWorkspace = await this.getById(id);
22165
+ const existingWorkspace = await this.#getById(this.#db.client, id);
21968
22166
  if (!existingWorkspace) throw new MastraError({
21969
22167
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND"),
21970
22168
  domain: ErrorDomain.STORAGE,
@@ -21977,7 +22175,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21977
22175
  const configFields = {};
21978
22176
  for (const [key, value] of Object.entries(rawConfigFields)) if (value !== void 0) configFields[key] = value;
21979
22177
  if (SNAPSHOT_FIELDS.some((field) => field in configFields)) {
21980
- const latestVersion = await this.getLatestVersion(id);
22178
+ const latestVersion = await this.#getLatestVersion(this.#db.client, id);
21981
22179
  if (!latestVersion) throw new MastraError({
21982
22180
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NO_VERSIONS"),
21983
22181
  domain: ErrorDomain.STORAGE,
@@ -22038,7 +22236,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22038
22236
  values.push(now);
22039
22237
  values.push(id);
22040
22238
  if (setClauses.length > 2 || versionCreated) await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
22041
- const updatedWorkspace = await this.getById(id);
22239
+ const updatedWorkspace = await this.#getById(this.#db.client, id);
22042
22240
  if (!updatedWorkspace) throw new MastraError({
22043
22241
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND_AFTER_UPDATE"),
22044
22242
  domain: ErrorDomain.STORAGE,
@@ -22103,7 +22301,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22103
22301
  queryParams.push(JSON.stringify(metadata));
22104
22302
  }
22105
22303
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
22106
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
22304
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
22107
22305
  const total = parseInt(countResult.count, 10);
22108
22306
  if (total === 0) return {
22109
22307
  workspaces: [],
@@ -22114,7 +22312,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22114
22312
  };
22115
22313
  const limitValue = perPageInput === false ? total : perPage;
22116
22314
  return {
22117
- workspaces: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
22315
+ workspaces: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
22118
22316
  ...queryParams,
22119
22317
  limitValue,
22120
22318
  offset
@@ -22199,7 +22397,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22199
22397
  indexName: TABLE_WORKSPACE_VERSIONS,
22200
22398
  schemaName: getSchemaName$5(this.#schema)
22201
22399
  });
22202
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22400
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22203
22401
  if (!result) return null;
22204
22402
  return this.parseVersionRow(result);
22205
22403
  } catch (error) {
@@ -22218,7 +22416,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22218
22416
  indexName: TABLE_WORKSPACE_VERSIONS,
22219
22417
  schemaName: getSchemaName$5(this.#schema)
22220
22418
  });
22221
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 AND "versionNumber" = $2`, [workspaceId, versionNumber]);
22419
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 AND "versionNumber" = $2`, [workspaceId, versionNumber]);
22222
22420
  if (!result) return null;
22223
22421
  return this.parseVersionRow(result);
22224
22422
  } catch (error) {
@@ -22235,12 +22433,19 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22235
22433
  }
22236
22434
  }
22237
22435
  async getLatestVersion(workspaceId) {
22436
+ return this.#getLatestVersion(this.#db.readClient, workspaceId);
22437
+ }
22438
+ /**
22439
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
22440
+ * lagging read replica cannot yield stale or missing rows mid-update.
22441
+ */
22442
+ async #getLatestVersion(client, workspaceId) {
22238
22443
  try {
22239
22444
  const tableName = getTableName$5({
22240
22445
  indexName: TABLE_WORKSPACE_VERSIONS,
22241
22446
  schemaName: getSchemaName$5(this.#schema)
22242
22447
  });
22243
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [workspaceId]);
22448
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [workspaceId]);
22244
22449
  if (!result) return null;
22245
22450
  return this.parseVersionRow(result);
22246
22451
  } catch (error) {
@@ -22269,7 +22474,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22269
22474
  indexName: TABLE_WORKSPACE_VERSIONS,
22270
22475
  schemaName: getSchemaName$5(this.#schema)
22271
22476
  });
22272
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22477
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22273
22478
  const total = parseInt(countResult.count, 10);
22274
22479
  if (total === 0) return {
22275
22480
  versions: [],
@@ -22280,7 +22485,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22280
22485
  };
22281
22486
  const limitValue = perPageInput === false ? total : perPage;
22282
22487
  return {
22283
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
22488
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
22284
22489
  workspaceId,
22285
22490
  limitValue,
22286
22491
  offset
@@ -22350,7 +22555,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22350
22555
  indexName: TABLE_WORKSPACE_VERSIONS,
22351
22556
  schemaName: getSchemaName$5(this.#schema)
22352
22557
  });
22353
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22558
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22354
22559
  return parseInt(result.count, 10);
22355
22560
  } catch (error) {
22356
22561
  if (error instanceof MastraError) throw error;
@@ -22926,10 +23131,12 @@ function exportSchemas(schemaName) {
22926
23131
  * ```
22927
23132
  */
22928
23133
  var PostgresStore = class extends MastraCompositeStore {
22929
- #pool;
23134
+ #writePool;
23135
+ #readPool;
22930
23136
  #db;
22931
- #ownsPool;
22932
- #poolClosed = false;
23137
+ #readDb;
23138
+ #ownsWritePool;
23139
+ #writePoolClosed = false;
22933
23140
  schema;
22934
23141
  isInitialized = false;
22935
23142
  #initPromise = null;
@@ -22945,15 +23152,21 @@ var PostgresStore = class extends MastraCompositeStore {
22945
23152
  });
22946
23153
  this.schema = parseSqlIdentifier(config.schemaName || "public", "schema name");
22947
23154
  if (isPoolConfig(config)) {
22948
- this.#pool = config.pool;
22949
- this.#ownsPool = false;
23155
+ this.#writePool = config.pool;
23156
+ this.#ownsWritePool = false;
23157
+ } else if (isWritePoolConfig(config)) {
23158
+ this.#writePool = config.writePool;
23159
+ this.#ownsWritePool = false;
22950
23160
  } else {
22951
- this.#pool = this.createPool(config);
22952
- this.#ownsPool = true;
23161
+ this.#writePool = this.createPool(config);
23162
+ this.#ownsWritePool = true;
22953
23163
  }
22954
- this.#db = new RoutingDbClient(new PoolAdapter(this.#pool));
23164
+ this.#readPool = config.readPool ?? this.#writePool;
23165
+ this.#db = new RoutingDbClient(new PoolAdapter(this.#writePool));
23166
+ this.#readDb = this.#readPool === this.#writePool ? this.#db : new PoolAdapter(this.#readPool);
22955
23167
  const domainConfig = {
22956
23168
  client: this.#db,
23169
+ readClient: this.#readDb,
22957
23170
  schemaName: this.schema,
22958
23171
  skipDefaultIndexes: config.skipDefaultIndexes,
22959
23172
  indexes: config.indexes
@@ -23013,8 +23226,8 @@ var PostgresStore = class extends MastraCompositeStore {
23013
23226
  async #runPinnedInit() {
23014
23227
  let pinnedClient;
23015
23228
  try {
23016
- pinnedClient = await this.#pool.connect();
23017
- const pinned = new PinnedClientAdapter(this.#pool, pinnedClient);
23229
+ pinnedClient = await this.#writePool.connect();
23230
+ const pinned = new PinnedClientAdapter(this.#writePool, pinnedClient);
23018
23231
  this.#db.pin(pinned);
23019
23232
  this.#db.setSchemaSnapshot(await loadSchemaSnapshot(pinned, this.schema));
23020
23233
  await super.init();
@@ -23047,21 +23260,27 @@ var PostgresStore = class extends MastraCompositeStore {
23047
23260
  get db() {
23048
23261
  return this.#db;
23049
23262
  }
23050
- /**
23051
- * The underlying pg.Pool for direct database access or ORM integration.
23052
- */
23263
+ /** Database client for queries that may run against the configured read replica. */
23264
+ get readDb() {
23265
+ return this.#readDb;
23266
+ }
23267
+ /** The underlying writer pg.Pool for direct database access or ORM integration. */
23053
23268
  get pool() {
23054
- return this.#pool;
23269
+ return this.#writePool;
23270
+ }
23271
+ /** The underlying reader pg.Pool, falling back to the writer pool when unset. */
23272
+ get readPool() {
23273
+ return this.#readPool;
23055
23274
  }
23056
23275
  /**
23057
- * Closes the connection pool if it was created by this store.
23058
- * If a pool was passed in via config, it will not be closed.
23276
+ * Closes the writer connection pool if it was created by this store.
23277
+ * Caller-provided writer and reader pools are not closed.
23059
23278
  * Safe to call multiple times — subsequent calls are no-ops.
23060
23279
  */
23061
23280
  async close() {
23062
- if (this.#ownsPool && !this.#poolClosed) {
23063
- this.#poolClosed = true;
23064
- await this.#pool.end();
23281
+ if (this.#ownsWritePool && !this.#writePoolClosed) {
23282
+ this.#writePoolClosed = true;
23283
+ await this.#writePool.end();
23065
23284
  }
23066
23285
  }
23067
23286
  };