@mastra/pg 1.23.0-alpha.1 → 1.23.0-alpha.3

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 (31) 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 +468 -279
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.js +468 -279
  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/v-next/index.d.ts.map +1 -1
  22. package/dist/storage/domains/prompt-blocks/index.d.ts.map +1 -1
  23. package/dist/storage/domains/schedules/index.d.ts.map +1 -1
  24. package/dist/storage/domains/scorer-definitions/index.d.ts.map +1 -1
  25. package/dist/storage/domains/skills/index.d.ts.map +1 -1
  26. package/dist/storage/domains/workflow-definitions/index.d.ts.map +1 -1
  27. package/dist/storage/domains/workspaces/index.d.ts.map +1 -1
  28. package/dist/storage/index.d.ts +7 -5
  29. package/dist/storage/index.d.ts.map +1 -1
  30. package/dist/vector/index.d.ts.map +1 -1
  31. 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)) {
@@ -910,12 +912,12 @@ var PgVector = class extends MastraVector {
910
912
  client.release();
911
913
  }
912
914
  }
915
+ const indexInfo = await this.getIndexMetadata({ indexName });
913
916
  const client = await this.pool.connect();
914
917
  try {
915
918
  await this.ensureSearchPath(client);
916
919
  await client.query("BEGIN");
917
920
  const { sql: filterQuery, values: filterValues } = buildFilterQuery(this.transformFilter(filter), minScore, topK);
918
- const indexInfo = await this.getIndexMetadata({ indexName });
919
921
  const metric = indexInfo.metric ?? "cosine";
920
922
  const ops = this.getVectorOps(indexInfo.vectorType, metric);
921
923
  const vectorStr = ops.formatVector(queryVector, indexInfo.dimension);
@@ -990,6 +992,7 @@ var PgVector = class extends MastraVector {
990
992
  async upsert({ indexName, vectors, metadata, ids, deleteFilter, namespace = DEFAULT_NAMESPACE }) {
991
993
  validateUpsertInput("PG", vectors, metadata, ids);
992
994
  const { tableName } = this.getTableName(indexName);
995
+ const indexInfo = await this.getIndexMetadata({ indexName });
993
996
  const client = await this.pool.connect();
994
997
  try {
995
998
  await this.ensureSearchPath(client);
@@ -1011,7 +1014,6 @@ var PgVector = class extends MastraVector {
1011
1014
  }
1012
1015
  }
1013
1016
  const vectorIds = ids || vectors.map(() => crypto.randomUUID());
1014
- const indexInfo = await this.getIndexMetadata({ indexName });
1015
1017
  const qualifiedVectorType = this.getVectorTypeName(indexInfo.vectorType, indexInfo.dimension);
1016
1018
  const ops = this.getVectorOps(indexInfo.vectorType, indexInfo.metric ?? "cosine");
1017
1019
  if (new Set(vectorIds).size !== vectorIds.length) for (let i = 0; i < vectors.length; i++) {
@@ -1299,7 +1301,7 @@ var PgVector = class extends MastraVector {
1299
1301
  let existingIndexInfo = null;
1300
1302
  let dimension = 0;
1301
1303
  try {
1302
- existingIndexInfo = await this.getIndexMetadata({ indexName });
1304
+ existingIndexInfo = await this.describeIndexMetadata({ indexName }, client);
1303
1305
  dimension = existingIndexInfo.dimension;
1304
1306
  if (isConfigEmpty && existingIndexInfo.metric === metric) if (existingIndexInfo.type === "flat") this.logger?.debug(`No index exists for ${vectorIndexName}, will create default ivfflat index`);
1305
1307
  else {
@@ -1503,8 +1505,8 @@ var PgVector = class extends MastraVector {
1503
1505
  * {@link describeIndex} it issues no `COUNT(*)`, so its cost does not grow with the
1504
1506
  * number of rows in the table.
1505
1507
  */
1506
- async describeIndexMetadata({ indexName }) {
1507
- const client = await this.pool.connect();
1508
+ async describeIndexMetadata({ indexName }, existingClient) {
1509
+ const client = existingClient ?? await this.pool.connect();
1508
1510
  try {
1509
1511
  const { tableName, parsedIndexName } = this.getTableName(indexName);
1510
1512
  const tableExists = await client.query(`
@@ -1564,7 +1566,6 @@ var PgVector = class extends MastraVector {
1564
1566
  config
1565
1567
  };
1566
1568
  } catch (e) {
1567
- await client.query("ROLLBACK");
1568
1569
  const mastraError = new MastraError({
1569
1570
  id: createVectorErrorId("PG", "DESCRIBE_INDEX", "FAILED"),
1570
1571
  domain: ErrorDomain.MASTRA_VECTOR,
@@ -1574,7 +1575,7 @@ var PgVector = class extends MastraVector {
1574
1575
  this.logger?.trackException(mastraError);
1575
1576
  throw mastraError;
1576
1577
  } finally {
1577
- client.release();
1578
+ if (!existingClient) client.release();
1578
1579
  }
1579
1580
  }
1580
1581
  /**
@@ -1679,10 +1680,10 @@ var PgVector = class extends MastraVector {
1679
1680
  category: ErrorCategory.USER,
1680
1681
  details: { indexName }
1681
1682
  });
1683
+ const indexInfo = await this.getIndexMetadata({ indexName });
1682
1684
  client = await this.pool.connect();
1683
1685
  await this.ensureSearchPath(client);
1684
1686
  const { tableName } = this.getTableName(indexName);
1685
- const indexInfo = await this.getIndexMetadata({ indexName });
1686
1687
  const qualifiedVectorType = this.getVectorTypeName(indexInfo.vectorType, indexInfo.dimension);
1687
1688
  const ops = this.getVectorOps(indexInfo.vectorType, indexInfo.metric ?? "cosine");
1688
1689
  let updateParts = [];
@@ -2359,16 +2360,21 @@ async function loadSchemaSnapshot(client, schemaName) {
2359
2360
  function resolvePgConfig(config) {
2360
2361
  if ("client" in config) return {
2361
2362
  client: config.client,
2363
+ readClient: config.readClient ?? config.client,
2362
2364
  schemaName: config.schemaName,
2363
2365
  skipDefaultIndexes: config.skipDefaultIndexes,
2364
2366
  indexes: config.indexes
2365
2367
  };
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
- };
2368
+ if ("pool" in config) {
2369
+ const client = new PoolAdapter(config.pool);
2370
+ return {
2371
+ client,
2372
+ readClient: config.readPool && config.readPool !== config.pool ? new PoolAdapter(config.readPool) : client,
2373
+ schemaName: config.schemaName,
2374
+ skipDefaultIndexes: config.skipDefaultIndexes,
2375
+ indexes: config.indexes
2376
+ };
2377
+ }
2372
2378
  let pool;
2373
2379
  if ("connectionString" in config) pool = new Pool({
2374
2380
  connectionString: config.connectionString,
@@ -2385,8 +2391,10 @@ function resolvePgConfig(config) {
2385
2391
  pool.on("error", (err) => {
2386
2392
  console.warn(`resolvePgConfig: idle pool client error (pool discards the client and reconnects on next checkout): ${err instanceof Error ? err.message : String(err)}`);
2387
2393
  });
2394
+ const client = new PoolAdapter(pool);
2388
2395
  return {
2389
- client: new PoolAdapter(pool),
2396
+ client,
2397
+ readClient: client,
2390
2398
  schemaName: config.schemaName,
2391
2399
  skipDefaultIndexes: config.skipDefaultIndexes,
2392
2400
  indexes: config.indexes
@@ -2594,6 +2602,7 @@ function assertPositiveLimit(limit) {
2594
2602
  }
2595
2603
  var PgDB = class extends MastraBase {
2596
2604
  client;
2605
+ readClient;
2597
2606
  schemaName;
2598
2607
  skipDefaultIndexes;
2599
2608
  /** Cache of actual table columns: tableName -> Set<columnName> */
@@ -2606,6 +2615,7 @@ var PgDB = class extends MastraBase {
2606
2615
  name: "PG_DB_LAYER"
2607
2616
  });
2608
2617
  this.client = config.client;
2618
+ this.readClient = config.readClient ?? config.client;
2609
2619
  this.schemaName = config.schemaName;
2610
2620
  this.skipDefaultIndexes = config.skipDefaultIndexes;
2611
2621
  }
@@ -3861,9 +3871,10 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
3861
3871
  static MANAGED_TABLES = [TABLE_AGENTS, TABLE_AGENT_VERSIONS];
3862
3872
  constructor(config) {
3863
3873
  super();
3864
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
3874
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
3865
3875
  this.#db = new PgDB({
3866
3876
  client,
3877
+ readClient,
3867
3878
  schemaName,
3868
3879
  skipDefaultIndexes
3869
3880
  });
@@ -4122,12 +4133,19 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4122
4133
  };
4123
4134
  }
4124
4135
  async getById(id) {
4136
+ return this.#getById(this.#db.readClient, id);
4137
+ }
4138
+ /**
4139
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
4140
+ * lagging read replica cannot yield stale or missing rows mid-update.
4141
+ */
4142
+ async #getById(client, id) {
4125
4143
  try {
4126
4144
  const tableName = getTableName$5({
4127
4145
  indexName: TABLE_AGENTS,
4128
4146
  schemaName: getSchemaName$5(this.#schema)
4129
4147
  });
4130
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4148
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4131
4149
  if (!result) return null;
4132
4150
  return this.parseRow(result);
4133
4151
  } catch (error) {
@@ -4212,7 +4230,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4212
4230
  indexName: TABLE_AGENTS,
4213
4231
  schemaName: getSchemaName$5(this.#schema)
4214
4232
  });
4215
- if (!await this.getById(id)) throw new MastraError({
4233
+ if (!await this.#getById(this.#db.client, id)) throw new MastraError({
4216
4234
  id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND"),
4217
4235
  domain: ErrorDomain.STORAGE,
4218
4236
  category: ErrorCategory.USER,
@@ -4250,7 +4268,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4250
4268
  values.push(now);
4251
4269
  values.push(id);
4252
4270
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
4253
- const updatedAgent = await this.getById(id);
4271
+ const updatedAgent = await this.#getById(this.#db.client, id);
4254
4272
  if (!updatedAgent) throw new MastraError({
4255
4273
  id: createStorageErrorId("PG", "UPDATE_AGENT", "NOT_FOUND_AFTER_UPDATE"),
4256
4274
  domain: ErrorDomain.STORAGE,
@@ -4347,7 +4365,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4347
4365
  const joinClause = useJoin && joinSqlIdx !== null ? `LEFT JOIN ${favoritesTable} s ON s."entityType" = 'agent' AND s."entityId" = a.id AND s."userId" = $${joinSqlIdx}` : "";
4348
4366
  const joinParams = useJoin && joinUserId ? [joinUserId] : [];
4349
4367
  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]);
4368
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} a ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
4351
4369
  const total = parseInt(countResult.count, 10);
4352
4370
  if (total === 0) return {
4353
4371
  agents: [],
@@ -4365,7 +4383,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4365
4383
  const limitIdx = paramIdx++;
4366
4384
  const offsetIdx = paramIdx++;
4367
4385
  return {
4368
- agents: (await this.#db.client.manyOrNone(`SELECT a.* FROM ${tableName} a ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
4386
+ agents: (await this.#db.readClient.manyOrNone(`SELECT a.* FROM ${tableName} a ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
4369
4387
  ...joinParams,
4370
4388
  ...queryParams,
4371
4389
  limitValue,
@@ -4465,7 +4483,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4465
4483
  indexName: TABLE_AGENT_VERSIONS,
4466
4484
  schemaName: getSchemaName$5(this.#schema)
4467
4485
  });
4468
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4486
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
4469
4487
  if (!result) return null;
4470
4488
  return this.parseVersionRow(result);
4471
4489
  } catch (error) {
@@ -4486,7 +4504,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4486
4504
  schemaName: getSchemaName$5(this.#schema)
4487
4505
  });
4488
4506
  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));
4507
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
4490
4508
  } catch (error) {
4491
4509
  if (error instanceof MastraError) throw error;
4492
4510
  throw new MastraError({
@@ -4503,7 +4521,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4503
4521
  indexName: TABLE_AGENT_VERSIONS,
4504
4522
  schemaName: getSchemaName$5(this.#schema)
4505
4523
  });
4506
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`, [agentId, versionNumber]);
4524
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 AND "versionNumber" = $2`, [agentId, versionNumber]);
4507
4525
  if (!result) return null;
4508
4526
  return this.parseVersionRow(result);
4509
4527
  } catch (error) {
@@ -4525,7 +4543,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4525
4543
  indexName: TABLE_AGENT_VERSIONS,
4526
4544
  schemaName: getSchemaName$5(this.#schema)
4527
4545
  });
4528
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [agentId]);
4546
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [agentId]);
4529
4547
  if (!result) return null;
4530
4548
  return this.parseVersionRow(result);
4531
4549
  } catch (error) {
@@ -4554,7 +4572,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4554
4572
  indexName: TABLE_AGENT_VERSIONS,
4555
4573
  schemaName: getSchemaName$5(this.#schema)
4556
4574
  });
4557
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4575
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4558
4576
  const total = parseInt(countResult.count, 10);
4559
4577
  if (total === 0) return {
4560
4578
  versions: [],
@@ -4565,7 +4583,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4565
4583
  };
4566
4584
  const limitValue = perPageInput === false ? total : perPage;
4567
4585
  return {
4568
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
4586
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "agentId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
4569
4587
  agentId,
4570
4588
  limitValue,
4571
4589
  offset
@@ -4635,7 +4653,7 @@ var AgentsPG = class AgentsPG extends AgentsStorage {
4635
4653
  indexName: TABLE_AGENT_VERSIONS,
4636
4654
  schemaName: getSchemaName$5(this.#schema)
4637
4655
  });
4638
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4656
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "agentId" = $1`, [agentId]);
4639
4657
  return parseInt(result.count, 10);
4640
4658
  } catch (error) {
4641
4659
  if (error instanceof MastraError) throw error;
@@ -4892,9 +4910,10 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
4892
4910
  } };
4893
4911
  constructor(config) {
4894
4912
  super();
4895
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4913
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
4896
4914
  this.#db = new PgDB({
4897
4915
  client,
4916
+ readClient,
4898
4917
  schemaName,
4899
4918
  skipDefaultIndexes
4900
4919
  });
@@ -5146,7 +5165,7 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5146
5165
  params.push(filter.toDate.toISOString());
5147
5166
  }
5148
5167
  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));
5168
+ const countResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) as count FROM ${table} ${where}`, params.slice(0, paramIdx - 1));
5150
5169
  const total = Number(countResult?.count ?? 0);
5151
5170
  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
5171
  if (filter.perPage != null) {
@@ -5158,7 +5177,7 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5158
5177
  }
5159
5178
  }
5160
5179
  return {
5161
- tasks: (await this.#db.client.manyOrNone(sql, params)).map(rowToTask),
5180
+ tasks: (await this.#db.readClient.manyOrNone(sql, params)).map(rowToTask),
5162
5181
  total
5163
5182
  };
5164
5183
  }
@@ -5195,12 +5214,12 @@ var BackgroundTasksPG = class BackgroundTasksPG extends BackgroundTasksStorage {
5195
5214
  }
5196
5215
  async getRunningCount() {
5197
5216
  const table = getTableName$4(getSchemaName$4(this.#schema));
5198
- const result = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running'`);
5217
+ const result = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running'`);
5199
5218
  return Number(result?.count ?? 0);
5200
5219
  }
5201
5220
  async getRunningCountByAgent(agentId) {
5202
5221
  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]);
5222
+ const result = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${table} WHERE "status" = 'running' AND "agent_id" = $1`, [agentId]);
5204
5223
  return Number(result?.count ?? 0);
5205
5224
  }
5206
5225
  };
@@ -5212,9 +5231,10 @@ var BlobsPG = class extends BlobStore {
5212
5231
  static MANAGED_TABLES = [TABLE_SKILL_BLOBS];
5213
5232
  constructor(config) {
5214
5233
  super();
5215
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
5234
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
5216
5235
  this.#db = new PgDB({
5217
5236
  client,
5237
+ readClient,
5218
5238
  schemaName,
5219
5239
  skipDefaultIndexes
5220
5240
  });
@@ -5256,7 +5276,7 @@ var BlobsPG = class extends BlobStore {
5256
5276
  indexName: TABLE_SKILL_BLOBS,
5257
5277
  schemaName: getSchemaName$5(this.#schema)
5258
5278
  });
5259
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "hash" = $1`, [hash]);
5279
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "hash" = $1`, [hash]);
5260
5280
  if (!row) return null;
5261
5281
  return this.#parseRow(row);
5262
5282
  }
@@ -5265,7 +5285,7 @@ var BlobsPG = class extends BlobStore {
5265
5285
  indexName: TABLE_SKILL_BLOBS,
5266
5286
  schemaName: getSchemaName$5(this.#schema)
5267
5287
  });
5268
- return await this.#db.client.oneOrNone(`SELECT 1 FROM ${tableName} WHERE "hash" = $1 LIMIT 1`, [hash]) !== null;
5288
+ return await this.#db.readClient.oneOrNone(`SELECT 1 FROM ${tableName} WHERE "hash" = $1 LIMIT 1`, [hash]) !== null;
5269
5289
  }
5270
5290
  async delete(hash) {
5271
5291
  const tableName = getTableName$5({
@@ -5286,7 +5306,7 @@ var BlobsPG = class extends BlobStore {
5286
5306
  schemaName: getSchemaName$5(this.#schema)
5287
5307
  });
5288
5308
  const placeholders = hashes.map((_, i) => `$${i + 1}`).join(", ");
5289
- const rows = await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "hash" IN (${placeholders})`, hashes);
5309
+ const rows = await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "hash" IN (${placeholders})`, hashes);
5290
5310
  for (const row of rows) {
5291
5311
  const entry = this.#parseRow(row);
5292
5312
  result.set(entry.hash, entry);
@@ -5316,9 +5336,10 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5316
5336
  static MANAGED_TABLES = [TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG];
5317
5337
  constructor(config) {
5318
5338
  super();
5319
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5339
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5320
5340
  this.#db = new PgDB({
5321
5341
  client,
5342
+ readClient,
5322
5343
  schemaName,
5323
5344
  skipDefaultIndexes
5324
5345
  });
@@ -5425,7 +5446,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5425
5446
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5426
5447
  schemaName: getSchemaName$5(this.#schema)
5427
5448
  });
5428
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5449
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
5429
5450
  return row ? this.#parseInstallationRow(row) : null;
5430
5451
  }
5431
5452
  async getInstallationByAgent(platform, agentId) {
@@ -5433,7 +5454,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5433
5454
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5434
5455
  schemaName: getSchemaName$5(this.#schema)
5435
5456
  });
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]);
5457
+ 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
5458
  return row ? this.#parseInstallationRow(row) : null;
5438
5459
  }
5439
5460
  async getInstallationByWebhookId(webhookId) {
@@ -5441,7 +5462,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5441
5462
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5442
5463
  schemaName: getSchemaName$5(this.#schema)
5443
5464
  });
5444
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "webhookId" = $1`, [webhookId]);
5465
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "webhookId" = $1`, [webhookId]);
5445
5466
  return row ? this.#parseInstallationRow(row) : null;
5446
5467
  }
5447
5468
  async listInstallations(platform) {
@@ -5449,7 +5470,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5449
5470
  indexName: TABLE_CHANNEL_INSTALLATIONS,
5450
5471
  schemaName: getSchemaName$5(this.#schema)
5451
5472
  });
5452
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 ORDER BY "createdAt" DESC`, [platform])).map((row) => this.#parseInstallationRow(row));
5473
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1 ORDER BY "createdAt" DESC`, [platform])).map((row) => this.#parseInstallationRow(row));
5453
5474
  }
5454
5475
  async deleteInstallation(id) {
5455
5476
  const tableName = getTableName$5({
@@ -5481,7 +5502,7 @@ var ChannelsPG = class ChannelsPG extends ChannelsStorage {
5481
5502
  indexName: TABLE_CHANNEL_CONFIG,
5482
5503
  schemaName: getSchemaName$5(this.#schema)
5483
5504
  });
5484
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1`, [platform]);
5505
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "platform" = $1`, [platform]);
5485
5506
  if (!row) return null;
5486
5507
  return {
5487
5508
  platform: row.platform,
@@ -5529,9 +5550,10 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5529
5550
  ];
5530
5551
  constructor(config) {
5531
5552
  super();
5532
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5553
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
5533
5554
  this.#db = new PgDB({
5534
5555
  client,
5556
+ readClient,
5535
5557
  schemaName,
5536
5558
  skipDefaultIndexes
5537
5559
  });
@@ -5792,7 +5814,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5792
5814
  };
5793
5815
  } catch (error) {
5794
5816
  if (input.id !== void 0 && hasErrorCode(error, /* @__PURE__ */ new Set(["23505"]))) {
5795
- const existing = await this.getDatasetById({ id: input.id });
5817
+ const existing = await this.#getDatasetById(this.#db.client, { id: input.id });
5796
5818
  if (existing) return this.resolveExistingDataset(existing, {
5797
5819
  ...input,
5798
5820
  id: input.id
@@ -5806,7 +5828,20 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5806
5828
  }, error);
5807
5829
  }
5808
5830
  }
5809
- async getDatasetById({ id, filters }) {
5831
+ async getDatasetById(args) {
5832
+ return this.#getDatasetById(this.#db.readClient, args);
5833
+ }
5834
+ getDatasetForMutation(args) {
5835
+ return this.#getDatasetById(this.#db.client, args);
5836
+ }
5837
+ listItemsForMutation(args) {
5838
+ return this.#listItems(this.#db.client, args);
5839
+ }
5840
+ /**
5841
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
5842
+ * lagging read replica cannot yield stale or missing rows mid-update.
5843
+ */
5844
+ async #getDatasetById(client, { id, filters }) {
5810
5845
  try {
5811
5846
  const tableName = getTableName$5({
5812
5847
  indexName: TABLE_DATASETS,
@@ -5814,7 +5849,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5814
5849
  });
5815
5850
  const { conditions, params } = tenancyWhere(filters, 2);
5816
5851
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
5817
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
5852
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
5818
5853
  return result ? this.transformDatasetRow(result) : null;
5819
5854
  } catch (error) {
5820
5855
  throw new MastraError({
@@ -5826,7 +5861,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5826
5861
  }
5827
5862
  async _doUpdateDataset(args) {
5828
5863
  try {
5829
- const existing = await this.getDatasetById({
5864
+ const existing = await this.#getDatasetById(this.#db.client, {
5830
5865
  id: args.id,
5831
5866
  filters: args.filters
5832
5867
  });
@@ -5998,7 +6033,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
5998
6033
  }
5999
6034
  }
6000
6035
  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);
6036
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6002
6037
  const total = parseInt(countResult.count, 10);
6003
6038
  if (total === 0) return {
6004
6039
  datasets: [],
@@ -6013,7 +6048,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6013
6048
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6014
6049
  const limitValue = perPageInput === false ? total : perPage;
6015
6050
  return {
6016
- datasets: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6051
+ datasets: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6017
6052
  ...queryParams,
6018
6053
  limitValue,
6019
6054
  offset
@@ -6117,7 +6152,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6117
6152
  }
6118
6153
  async _doUpdateItem(args) {
6119
6154
  try {
6120
- const existing = await this.getItemById({ id: args.id });
6155
+ const existing = await this.#getItemById(this.#db.client, { id: args.id });
6121
6156
  if (!existing) throw new MastraError({
6122
6157
  id: createStorageErrorId("PG", "UPDATE_ITEM", "NOT_FOUND"),
6123
6158
  domain: ErrorDomain.STORAGE,
@@ -6223,7 +6258,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6223
6258
  }
6224
6259
  async _doDeleteItem({ id, datasetId }) {
6225
6260
  try {
6226
- const existing = await this.getItemById({ id });
6261
+ const existing = await this.#getItemById(this.#db.client, { id });
6227
6262
  if (!existing) return;
6228
6263
  if (existing.datasetId !== datasetId) throw new MastraError({
6229
6264
  id: createStorageErrorId("PG", "DELETE_ITEM", "DATASET_MISMATCH"),
@@ -6390,7 +6425,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6390
6425
  }
6391
6426
  async _doBatchDeleteItems(input) {
6392
6427
  try {
6393
- const dataset = await this.getDatasetById({ id: input.datasetId });
6428
+ const dataset = await this.#getDatasetById(this.#db.client, { id: input.datasetId });
6394
6429
  if (!dataset) throw new MastraError({
6395
6430
  id: createStorageErrorId("PG", "BULK_DELETE_ITEMS", "DATASET_NOT_FOUND"),
6396
6431
  domain: ErrorDomain.STORAGE,
@@ -6399,7 +6434,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6399
6434
  });
6400
6435
  const currentItems = [];
6401
6436
  for (const itemId of input.itemIds) {
6402
- const item = await this.getItemById({ id: itemId });
6437
+ const item = await this.#getItemById(this.#db.client, { id: itemId });
6403
6438
  if (item && item.datasetId === input.datasetId) currentItems.push(item);
6404
6439
  }
6405
6440
  if (currentItems.length === 0) return;
@@ -6463,14 +6498,17 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6463
6498
  }
6464
6499
  }
6465
6500
  async getItemById(args) {
6501
+ return this.#getItemById(this.#db.readClient, args);
6502
+ }
6503
+ async #getItemById(client, args) {
6466
6504
  try {
6467
6505
  const tableName = getTableName$5({
6468
6506
  indexName: TABLE_DATASET_ITEMS,
6469
6507
  schemaName: getSchemaName$5(this.#schema)
6470
6508
  });
6471
6509
  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]);
6510
+ 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]);
6511
+ else result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6474
6512
  return result ? this.transformItemRow(result) : null;
6475
6513
  } catch (error) {
6476
6514
  throw new MastraError({
@@ -6486,7 +6524,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6486
6524
  indexName: TABLE_DATASET_ITEMS,
6487
6525
  schemaName: getSchemaName$5(this.#schema)
6488
6526
  });
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`, [
6527
+ 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
6528
  datasetId,
6491
6529
  version,
6492
6530
  version
@@ -6505,7 +6543,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6505
6543
  indexName: TABLE_DATASET_ITEMS,
6506
6544
  schemaName: getSchemaName$5(this.#schema)
6507
6545
  });
6508
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6546
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6509
6547
  } catch (error) {
6510
6548
  throw new MastraError({
6511
6549
  id: createStorageErrorId("PG", "GET_ITEM_HISTORY", "FAILED"),
@@ -6515,6 +6553,13 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6515
6553
  }
6516
6554
  }
6517
6555
  async listItems(args) {
6556
+ return this.#listItems(this.#db.readClient, args);
6557
+ }
6558
+ /**
6559
+ * Same listing against an explicit client. `updateDataset` validates existing
6560
+ * items on the writer so a lagging replica cannot hide freshly inserted rows.
6561
+ */
6562
+ async #listItems(client, args) {
6518
6563
  try {
6519
6564
  const { page, perPage: perPageInput } = args.pagination;
6520
6565
  const tableName = getTableName$5({
@@ -6551,7 +6596,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6551
6596
  }
6552
6597
  }
6553
6598
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
6554
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6599
+ const countResult = await client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
6555
6600
  const total = parseInt(countResult.count, 10);
6556
6601
  if (total === 0) return {
6557
6602
  items: [],
@@ -6566,7 +6611,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6566
6611
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6567
6612
  const limitValue = perPageInput === false ? total : perPage;
6568
6613
  return {
6569
- items: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6614
+ items: (await client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6570
6615
  ...queryParams,
6571
6616
  limitValue,
6572
6617
  offset
@@ -6621,7 +6666,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6621
6666
  indexName: TABLE_DATASET_VERSIONS,
6622
6667
  schemaName: getSchemaName$5(this.#schema)
6623
6668
  });
6624
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`, [input.datasetId]);
6669
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "datasetId" = $1`, [input.datasetId]);
6625
6670
  const total = parseInt(countResult.count, 10);
6626
6671
  if (total === 0) return {
6627
6672
  versions: [],
@@ -6636,7 +6681,7 @@ var DatasetsPG = class DatasetsPG extends DatasetsStorage {
6636
6681
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
6637
6682
  const limitValue = perPageInput === false ? total : perPage;
6638
6683
  return {
6639
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`, [
6684
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 ORDER BY "version" DESC LIMIT $2 OFFSET $3`, [
6640
6685
  input.datasetId,
6641
6686
  limitValue,
6642
6687
  offset
@@ -6686,9 +6731,10 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
6686
6731
  } };
6687
6732
  constructor(config) {
6688
6733
  super();
6689
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
6734
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
6690
6735
  this.#db = new PgDB({
6691
6736
  client,
6737
+ readClient,
6692
6738
  schemaName,
6693
6739
  skipDefaultIndexes
6694
6740
  });
@@ -7026,7 +7072,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7026
7072
  }
7027
7073
  async updateExperiment(input) {
7028
7074
  try {
7029
- if (!await this.getExperimentById({ id: input.id })) throw new MastraError({
7075
+ if (!await this.#getExperimentById(this.#db.client, { id: input.id })) throw new MastraError({
7030
7076
  id: createStorageErrorId("PG", "UPDATE_EXPERIMENT", "NOT_FOUND"),
7031
7077
  domain: ErrorDomain.STORAGE,
7032
7078
  category: ErrorCategory.USER,
@@ -7082,7 +7128,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7082
7128
  }
7083
7129
  values.push(input.id);
7084
7130
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE "id" = $${paramIndex}`, values);
7085
- return await this.getExperimentById({ id: input.id });
7131
+ return await this.#getExperimentById(this.#db.client, { id: input.id });
7086
7132
  } catch (error) {
7087
7133
  if (error instanceof MastraError) throw error;
7088
7134
  throw new MastraError({
@@ -7092,7 +7138,14 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7092
7138
  }, error);
7093
7139
  }
7094
7140
  }
7095
- async getExperimentById({ id, filters }) {
7141
+ async getExperimentById(args) {
7142
+ return this.#getExperimentById(this.#db.readClient, args);
7143
+ }
7144
+ /**
7145
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
7146
+ * lagging read replica cannot yield stale or missing rows mid-update.
7147
+ */
7148
+ async #getExperimentById(client, { id, filters }) {
7096
7149
  try {
7097
7150
  const tableName = getTableName$5({
7098
7151
  indexName: TABLE_EXPERIMENTS,
@@ -7100,7 +7153,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7100
7153
  });
7101
7154
  const { conditions, params } = tenancyWhere(filters, 2);
7102
7155
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
7103
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7156
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7104
7157
  return result ? this.transformExperimentRow(result) : null;
7105
7158
  } catch (error) {
7106
7159
  throw new MastraError({
@@ -7168,7 +7221,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7168
7221
  }
7169
7222
  }
7170
7223
  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);
7224
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7172
7225
  const total = parseInt(countResult.count, 10);
7173
7226
  if (total === 0) return {
7174
7227
  experiments: [],
@@ -7183,7 +7236,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7183
7236
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
7184
7237
  const limitValue = perPageInput === false ? total : perPage;
7185
7238
  return {
7186
- experiments: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7239
+ experiments: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7187
7240
  ...queryParams,
7188
7241
  limitValue,
7189
7242
  offset
@@ -7387,7 +7440,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7387
7440
  values.push(input.comment);
7388
7441
  }
7389
7442
  if (setClauses.length === 0) {
7390
- const existing = await this.getExperimentResultById({ id: input.id });
7443
+ const existing = await this.#getExperimentResultById(this.#db.client, { id: input.id });
7391
7444
  if (!existing) throw new MastraError({
7392
7445
  id: createStorageErrorId("PG", "UPDATE_EXPERIMENT_RESULT", "NOT_FOUND"),
7393
7446
  domain: ErrorDomain.STORAGE,
@@ -7420,7 +7473,14 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7420
7473
  }, error);
7421
7474
  }
7422
7475
  }
7423
- async getExperimentResultById({ id, filters }) {
7476
+ async getExperimentResultById(args) {
7477
+ return this.#getExperimentResultById(this.#db.readClient, args);
7478
+ }
7479
+ /**
7480
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
7481
+ * lagging read replica cannot yield stale or missing rows mid-update.
7482
+ */
7483
+ async #getExperimentResultById(client, { id, filters }) {
7424
7484
  try {
7425
7485
  const tableName = getTableName$5({
7426
7486
  indexName: TABLE_EXPERIMENT_RESULTS,
@@ -7428,7 +7488,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7428
7488
  });
7429
7489
  const { conditions, params } = tenancyWhere(filters, 2);
7430
7490
  const whereSql = ["\"id\" = $1", ...conditions].join(" AND ");
7431
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7491
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE ${whereSql}`, [id, ...params]);
7432
7492
  return result ? this.transformExperimentResultRow(result) : null;
7433
7493
  } catch (error) {
7434
7494
  throw new MastraError({
@@ -7468,7 +7528,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7468
7528
  }
7469
7529
  }
7470
7530
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
7471
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7531
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
7472
7532
  const total = parseInt(countResult.count, 10);
7473
7533
  if (total === 0) return {
7474
7534
  results: [],
@@ -7483,7 +7543,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7483
7543
  const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
7484
7544
  const limitValue = perPageInput === false ? total : perPage;
7485
7545
  return {
7486
- results: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "startedAt" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7546
+ results: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "startedAt" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
7487
7547
  ...queryParams,
7488
7548
  limitValue,
7489
7549
  offset
@@ -7537,7 +7597,7 @@ var ExperimentsPG = class ExperimentsPG extends ExperimentsStorage {
7537
7597
  indexName: TABLE_EXPERIMENT_RESULTS,
7538
7598
  schemaName: getSchemaName$5(this.#schema)
7539
7599
  });
7540
- return (await this.#db.client.manyOrNone(`SELECT
7600
+ return (await this.#db.readClient.manyOrNone(`SELECT
7541
7601
  "experimentId",
7542
7602
  COUNT(*)::int as total,
7543
7603
  SUM(CASE WHEN status = 'needs-review' THEN 1 ELSE 0 END)::int as "needsReview",
@@ -7579,9 +7639,10 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7579
7639
  static MANAGED_TABLES = [TABLE_FAVORITES];
7580
7640
  constructor(config) {
7581
7641
  super();
7582
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
7642
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
7583
7643
  this.#db = new PgDB({
7584
7644
  client,
7645
+ readClient,
7585
7646
  schemaName,
7586
7647
  skipDefaultIndexes
7587
7648
  });
@@ -7747,7 +7808,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7747
7808
  schemaName: getSchemaName$5(this.#schema)
7748
7809
  });
7749
7810
  try {
7750
- return await this.#db.client.oneOrNone(`SELECT 1 FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" = $3 LIMIT 1`, [
7811
+ return await this.#db.readClient.oneOrNone(`SELECT 1 FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" = $3 LIMIT 1`, [
7751
7812
  input.userId,
7752
7813
  input.entityType,
7753
7814
  input.entityId
@@ -7770,7 +7831,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7770
7831
  });
7771
7832
  try {
7772
7833
  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})`, [
7834
+ const rows = await this.#db.readClient.manyOrNone(`SELECT "entityId" FROM ${fullFavoritesTable} WHERE "userId" = $1 AND "entityType" = $2 AND "entityId" IN (${placeholders})`, [
7774
7835
  userId,
7775
7836
  entityType,
7776
7837
  ...entityIds
@@ -7793,7 +7854,7 @@ var FavoritesPG = class FavoritesPG extends FavoritesStorage {
7793
7854
  schemaName: getSchemaName$5(this.#schema)
7794
7855
  });
7795
7856
  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);
7857
+ 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
7858
  } catch (error) {
7798
7859
  if (error instanceof MastraError) throw error;
7799
7860
  throw new MastraError({
@@ -8096,16 +8157,20 @@ var KnowledgePG = class extends KnowledgeStorage {
8096
8157
  }
8097
8158
  #client;
8098
8159
  #executor;
8160
+ /** Reader-backed executor for standalone reads; mutations and read-modify-write stay on #executor. */
8161
+ #readExecutor;
8099
8162
  #db;
8100
8163
  #schemaName;
8101
8164
  constructor(config) {
8102
8165
  super();
8103
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
8166
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
8104
8167
  this.#client = client;
8105
8168
  this.#schemaName = schemaName;
8106
8169
  this.#executor = createExecutor(client, schemaName);
8170
+ this.#readExecutor = createExecutor(readClient, schemaName);
8107
8171
  this.#db = new PgDB({
8108
8172
  client,
8173
+ readClient,
8109
8174
  schemaName,
8110
8175
  skipDefaultIndexes
8111
8176
  });
@@ -8207,13 +8272,13 @@ var KnowledgePG = class extends KnowledgeStorage {
8207
8272
  });
8208
8273
  }
8209
8274
  async getNode(id) {
8210
- return this.#getNode(this.#executor, id);
8275
+ return this.#getNode(this.#readExecutor, id);
8211
8276
  }
8212
8277
  async getNodeByName(input) {
8213
- return this.#getNodeByName(this.#executor, input.name, canonicalizeKnowledgeScope(input.scope));
8278
+ return this.#getNodeByName(this.#readExecutor, input.name, canonicalizeKnowledgeScope(input.scope));
8214
8279
  }
8215
8280
  async resolveNode(input) {
8216
- return this.#resolveNode(this.#executor, input.name, canonicalizeKnowledgeScope(input.scope));
8281
+ return this.#resolveNode(this.#readExecutor, input.name, canonicalizeKnowledgeScope(input.scope));
8217
8282
  }
8218
8283
  async listNodes(input) {
8219
8284
  const key = knowledgeScopeKey(canonicalizeKnowledgeScope(input.scope));
@@ -8243,7 +8308,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8243
8308
  args.push(updatedAt, updatedAt, cursor.name, cursor.name, cursor.id);
8244
8309
  }
8245
8310
  args.push(input.limit ?? 100);
8246
- return (await this.#executor.execute({
8311
+ return (await this.#readExecutor.execute({
8247
8312
  sql: `SELECT *, scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_NODES}" WHERE ${clauses.join(" AND ")} ORDER BY updatedAt DESC, name ASC, id ASC LIMIT ?`,
8248
8313
  args
8249
8314
  })).rows.map(parseNode);
@@ -8409,7 +8474,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8409
8474
  });
8410
8475
  }
8411
8476
  async getKnowledge(input) {
8412
- const result = await this.#executor.execute({
8477
+ const result = await this.#readExecutor.execute({
8413
8478
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_RECORDS}" WHERE id=?${input.includeDeleted ? "" : " AND deletedAt IS NULL"}`,
8414
8479
  args: [input.id]
8415
8480
  });
@@ -8434,7 +8499,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8434
8499
  if (input.after) args.push(input.after);
8435
8500
  const limit = input.limit ?? 100;
8436
8501
  args.push(limit + 1);
8437
- const records = (await this.#executor.execute({
8502
+ const records = (await this.#readExecutor.execute({
8438
8503
  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
8504
  args
8440
8505
  })).rows.map(parseKnowledge);
@@ -8529,7 +8594,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8529
8594
  const normalizedQuery = input.query.trim().toLocaleLowerCase();
8530
8595
  if (!normalizedQuery) return [];
8531
8596
  const query = `%${escapeLikePattern(normalizedQuery)}%`;
8532
- const results = (await this.#executor.execute({
8597
+ const results = (await this.#readExecutor.execute({
8533
8598
  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
8599
  args: [
8535
8600
  key,
@@ -8553,7 +8618,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8553
8618
  scope: parseJson$1(row.scopeJson)
8554
8619
  }));
8555
8620
  if (results.length < (input.limit ?? 20)) {
8556
- const records = await this.#executor.execute({
8621
+ const records = await this.#readExecutor.execute({
8557
8622
  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
8623
  args: [
8559
8624
  key,
@@ -8606,7 +8671,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8606
8671
  }
8607
8672
  async listActivity(input) {
8608
8673
  const key = knowledgeScopeKey(canonicalizeKnowledgeScope(input.scope));
8609
- return (await this.#executor.execute({
8674
+ return (await this.#readExecutor.execute({
8610
8675
  sql: `SELECT *,scope AS "scopeJson" FROM "${TABLE_KNOWLEDGE_ACTIVITY}" WHERE ${visibleSql}${input.after ? " AND id < ?" : ""} ORDER BY id DESC LIMIT ?`,
8611
8676
  args: [
8612
8677
  key,
@@ -8750,7 +8815,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8750
8815
  }
8751
8816
  async #queryKnowledge(input, relationship) {
8752
8817
  const scope = canonicalizeKnowledgeScope(input.scope);
8753
- const node = await this.#resolveTerminalNode(this.#executor, nodeReferenceId(input.node));
8818
+ const node = await this.#resolveTerminalNode(this.#readExecutor, nodeReferenceId(input.node));
8754
8819
  if (!node) return { records: [] };
8755
8820
  const key = knowledgeScopeKey(scope);
8756
8821
  const args = [
@@ -8761,7 +8826,7 @@ var KnowledgePG = class extends KnowledgeStorage {
8761
8826
  ];
8762
8827
  if (input.after) args.push(input.after);
8763
8828
  args.push((input.limit ?? 100) + 1);
8764
- const records = (await this.#executor.execute({
8829
+ const records = (await this.#readExecutor.execute({
8765
8830
  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
8831
  args
8767
8832
  })).rows.map(parseKnowledge);
@@ -8873,9 +8938,10 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
8873
8938
  static MANAGED_TABLES = [TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS];
8874
8939
  constructor(config) {
8875
8940
  super();
8876
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
8941
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
8877
8942
  this.#db = new PgDB({
8878
8943
  client,
8944
+ readClient,
8879
8945
  schemaName,
8880
8946
  skipDefaultIndexes
8881
8947
  });
@@ -8939,12 +9005,19 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
8939
9005
  await this.#db.clearTable({ tableName: TABLE_MCP_CLIENTS });
8940
9006
  }
8941
9007
  async getById(id) {
9008
+ return this.#getById(this.#db.readClient, id);
9009
+ }
9010
+ /**
9011
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
9012
+ * lagging read replica cannot yield stale or missing rows mid-update.
9013
+ */
9014
+ async #getById(client, id) {
8942
9015
  try {
8943
9016
  const tableName = getTableName$5({
8944
9017
  indexName: TABLE_MCP_CLIENTS,
8945
9018
  schemaName: getSchemaName$5(this.#schema)
8946
9019
  });
8947
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9020
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
8948
9021
  if (!result) return null;
8949
9022
  return this.parseMCPClientRow(result);
8950
9023
  } catch (error) {
@@ -9023,7 +9096,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9023
9096
  indexName: TABLE_MCP_CLIENTS,
9024
9097
  schemaName: getSchemaName$5(this.#schema)
9025
9098
  });
9026
- const existingClient = await this.getById(id);
9099
+ const existingClient = await this.#getById(this.#db.client, id);
9027
9100
  if (!existingClient) throw new MastraError({
9028
9101
  id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND"),
9029
9102
  domain: ErrorDomain.STORAGE,
@@ -9062,7 +9135,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9062
9135
  values.push(now);
9063
9136
  values.push(id);
9064
9137
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9065
- const updatedClient = await this.getById(id);
9138
+ const updatedClient = await this.#getById(this.#db.client, id);
9066
9139
  if (!updatedClient) throw new MastraError({
9067
9140
  id: createStorageErrorId("PG", "UPDATE_MCP_CLIENT", "NOT_FOUND_AFTER_UPDATE"),
9068
9141
  domain: ErrorDomain.STORAGE,
@@ -9129,7 +9202,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9129
9202
  queryParams.push(JSON.stringify(metadata));
9130
9203
  }
9131
9204
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9132
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9205
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9133
9206
  const total = parseInt(countResult.count, 10);
9134
9207
  if (total === 0) return {
9135
9208
  mcpClients: [],
@@ -9140,7 +9213,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9140
9213
  };
9141
9214
  const limitValue = perPageInput === false ? total : perPage;
9142
9215
  return {
9143
- mcpClients: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9216
+ mcpClients: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9144
9217
  ...queryParams,
9145
9218
  limitValue,
9146
9219
  offset
@@ -9217,7 +9290,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9217
9290
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9218
9291
  schemaName: getSchemaName$5(this.#schema)
9219
9292
  });
9220
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9293
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9221
9294
  if (!result) return null;
9222
9295
  return this.parseVersionRow(result);
9223
9296
  } catch (error) {
@@ -9236,7 +9309,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9236
9309
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9237
9310
  schemaName: getSchemaName$5(this.#schema)
9238
9311
  });
9239
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`, [mcpClientId, versionNumber]);
9312
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 AND "versionNumber" = $2`, [mcpClientId, versionNumber]);
9240
9313
  if (!result) return null;
9241
9314
  return this.parseVersionRow(result);
9242
9315
  } catch (error) {
@@ -9258,7 +9331,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9258
9331
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9259
9332
  schemaName: getSchemaName$5(this.#schema)
9260
9333
  });
9261
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpClientId]);
9334
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpClientId]);
9262
9335
  if (!result) return null;
9263
9336
  return this.parseVersionRow(result);
9264
9337
  } catch (error) {
@@ -9287,7 +9360,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9287
9360
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9288
9361
  schemaName: getSchemaName$5(this.#schema)
9289
9362
  });
9290
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9363
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9291
9364
  const total = parseInt(countResult.count, 10);
9292
9365
  if (total === 0) return {
9293
9366
  versions: [],
@@ -9298,7 +9371,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9298
9371
  };
9299
9372
  const limitValue = perPageInput === false ? total : perPage;
9300
9373
  return {
9301
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9374
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpClientId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9302
9375
  mcpClientId,
9303
9376
  limitValue,
9304
9377
  offset
@@ -9368,7 +9441,7 @@ var MCPClientsPG = class MCPClientsPG extends MCPClientsStorage {
9368
9441
  indexName: TABLE_MCP_CLIENT_VERSIONS,
9369
9442
  schemaName: getSchemaName$5(this.#schema)
9370
9443
  });
9371
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9444
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpClientId" = $1`, [mcpClientId]);
9372
9445
  return parseInt(result.count, 10);
9373
9446
  } catch (error) {
9374
9447
  if (error instanceof MastraError) throw error;
@@ -9428,9 +9501,10 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9428
9501
  static MANAGED_TABLES = [TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS];
9429
9502
  constructor(config) {
9430
9503
  super();
9431
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
9504
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
9432
9505
  this.#db = new PgDB({
9433
9506
  client,
9507
+ readClient,
9434
9508
  schemaName,
9435
9509
  skipDefaultIndexes
9436
9510
  });
@@ -9494,12 +9568,19 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9494
9568
  await this.#db.clearTable({ tableName: TABLE_MCP_SERVERS });
9495
9569
  }
9496
9570
  async getById(id) {
9571
+ return this.#getById(this.#db.readClient, id);
9572
+ }
9573
+ /**
9574
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
9575
+ * lagging read replica cannot yield stale or missing rows mid-update.
9576
+ */
9577
+ async #getById(client, id) {
9497
9578
  try {
9498
9579
  const tableName = getTableName$5({
9499
9580
  indexName: TABLE_MCP_SERVERS,
9500
9581
  schemaName: getSchemaName$5(this.#schema)
9501
9582
  });
9502
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9583
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9503
9584
  if (!result) return null;
9504
9585
  return this.parseMCPServerRow(result);
9505
9586
  } catch (error) {
@@ -9578,7 +9659,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9578
9659
  indexName: TABLE_MCP_SERVERS,
9579
9660
  schemaName: getSchemaName$5(this.#schema)
9580
9661
  });
9581
- const existingServer = await this.getById(id);
9662
+ const existingServer = await this.#getById(this.#db.client, id);
9582
9663
  if (!existingServer) throw new MastraError({
9583
9664
  id: createStorageErrorId("PG", "UPDATE_MCP_SERVER", "NOT_FOUND"),
9584
9665
  domain: ErrorDomain.STORAGE,
@@ -9617,7 +9698,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9617
9698
  values.push(now);
9618
9699
  values.push(id);
9619
9700
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
9620
- const updatedServer = await this.getById(id);
9701
+ const updatedServer = await this.#getById(this.#db.client, id);
9621
9702
  if (!updatedServer) throw new MastraError({
9622
9703
  id: createStorageErrorId("PG", "UPDATE_MCP_SERVER", "NOT_FOUND_AFTER_UPDATE"),
9623
9704
  domain: ErrorDomain.STORAGE,
@@ -9684,7 +9765,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9684
9765
  queryParams.push(JSON.stringify(metadata));
9685
9766
  }
9686
9767
  const whereClause = `WHERE ${conditions.join(" AND ")}`;
9687
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9768
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
9688
9769
  const total = parseInt(countResult.count, 10);
9689
9770
  if (total === 0) return {
9690
9771
  mcpServers: [],
@@ -9695,7 +9776,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9695
9776
  };
9696
9777
  const limitValue = perPageInput === false ? total : perPage;
9697
9778
  return {
9698
- mcpServers: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9779
+ mcpServers: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
9699
9780
  ...queryParams,
9700
9781
  limitValue,
9701
9782
  offset
@@ -9782,7 +9863,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9782
9863
  indexName: TABLE_MCP_SERVER_VERSIONS,
9783
9864
  schemaName: getSchemaName$5(this.#schema)
9784
9865
  });
9785
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9866
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
9786
9867
  if (!result) return null;
9787
9868
  return this.parseVersionRow(result);
9788
9869
  } catch (error) {
@@ -9801,7 +9882,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9801
9882
  indexName: TABLE_MCP_SERVER_VERSIONS,
9802
9883
  schemaName: getSchemaName$5(this.#schema)
9803
9884
  });
9804
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 AND "versionNumber" = $2`, [mcpServerId, versionNumber]);
9885
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 AND "versionNumber" = $2`, [mcpServerId, versionNumber]);
9805
9886
  if (!result) return null;
9806
9887
  return this.parseVersionRow(result);
9807
9888
  } catch (error) {
@@ -9823,7 +9904,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9823
9904
  indexName: TABLE_MCP_SERVER_VERSIONS,
9824
9905
  schemaName: getSchemaName$5(this.#schema)
9825
9906
  });
9826
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpServerId]);
9907
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [mcpServerId]);
9827
9908
  if (!result) return null;
9828
9909
  return this.parseVersionRow(result);
9829
9910
  } catch (error) {
@@ -9852,7 +9933,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9852
9933
  indexName: TABLE_MCP_SERVER_VERSIONS,
9853
9934
  schemaName: getSchemaName$5(this.#schema)
9854
9935
  });
9855
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9936
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9856
9937
  const total = parseInt(countResult.count, 10);
9857
9938
  if (total === 0) return {
9858
9939
  versions: [],
@@ -9863,7 +9944,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9863
9944
  };
9864
9945
  const limitValue = perPageInput === false ? total : perPage;
9865
9946
  return {
9866
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9947
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "mcpServerId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
9867
9948
  mcpServerId,
9868
9949
  limitValue,
9869
9950
  offset
@@ -9933,7 +10014,7 @@ var MCPServersPG = class MCPServersPG extends MCPServersStorage {
9933
10014
  indexName: TABLE_MCP_SERVER_VERSIONS,
9934
10015
  schemaName: getSchemaName$5(this.#schema)
9935
10016
  });
9936
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
10017
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "mcpServerId" = $1`, [mcpServerId]);
9937
10018
  return parseInt(result.count, 10);
9938
10019
  } catch (error) {
9939
10020
  if (error instanceof MastraError) throw error;
@@ -10102,9 +10183,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10102
10183
  ];
10103
10184
  constructor(config) {
10104
10185
  super();
10105
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10186
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10106
10187
  this.#db = new PgDB({
10107
10188
  client,
10189
+ readClient,
10108
10190
  schemaName,
10109
10191
  skipDefaultIndexes
10110
10192
  });
@@ -10353,6 +10435,16 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10353
10435
  };
10354
10436
  }
10355
10437
  async getThreadById({ threadId, resourceId }) {
10438
+ return this.#getThreadById(this.#db.readClient, {
10439
+ threadId,
10440
+ resourceId
10441
+ });
10442
+ }
10443
+ /**
10444
+ * Thread lookup against an explicit client. Mutation paths pass the writer so
10445
+ * a lagging read replica cannot produce false not-found or stale metadata.
10446
+ */
10447
+ async #getThreadById(client, { threadId, resourceId }) {
10356
10448
  try {
10357
10449
  let query = `SELECT * FROM ${getTableName$3({
10358
10450
  indexName: TABLE_THREADS,
@@ -10363,7 +10455,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10363
10455
  query += ` AND "resourceId" = $2`;
10364
10456
  params.push(resourceId);
10365
10457
  }
10366
- const thread = await this.#db.client.oneOrNone(query, params);
10458
+ const thread = await client.oneOrNone(query, params);
10367
10459
  if (!thread) return null;
10368
10460
  return {
10369
10461
  id: thread.id,
@@ -10432,7 +10524,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10432
10524
  }
10433
10525
  const baseQuery = `FROM ${tableName} ${whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : ""}`;
10434
10526
  const countQuery = `SELECT COUNT(*) ${baseQuery}`;
10435
- const countResult = await this.#db.client.one(countQuery, queryParams);
10527
+ const countResult = await this.#db.readClient.one(countQuery, queryParams);
10436
10528
  const total = parseInt(countResult.count, 10);
10437
10529
  if (total === 0) return {
10438
10530
  threads: [],
@@ -10444,7 +10536,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10444
10536
  const limitValue = perPageInput === false ? total : perPage;
10445
10537
  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
10538
  return {
10447
- threads: (await this.#db.client.manyOrNone(dataQuery, [
10539
+ threads: (await this.#db.readClient.manyOrNone(dataQuery, [
10448
10540
  ...queryParams,
10449
10541
  limitValue,
10450
10542
  offset
@@ -10528,7 +10620,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10528
10620
  indexName: TABLE_THREADS,
10529
10621
  schemaName: getSchemaName$3(this.#schema)
10530
10622
  });
10531
- const existingThread = await this.getThreadById({ threadId: id });
10623
+ const existingThread = await this.#getThreadById(this.#db.client, { threadId: id });
10532
10624
  if (!existingThread) throw new MastraError({
10533
10625
  id: createStorageErrorId("PG", "UPDATE_THREAD", "FAILED"),
10534
10626
  domain: ErrorDomain.STORAGE,
@@ -10660,7 +10752,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10660
10752
  if (targetIds.length === 0) return null;
10661
10753
  const idPlaceholders = targetIds.map((_, i) => "$" + (i + 1)).join(", ");
10662
10754
  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);
10755
+ const targetRows = await this.#db.readClient.manyOrNone(`SELECT id, thread_id, "createdAt" FROM ${tableName} WHERE id IN (${idPlaceholders})${targetResourceCondition}`, resourceId ? [...targetIds, resourceId] : targetIds);
10664
10756
  if (targetRows.length === 0) return null;
10665
10757
  const targetMap = new Map(targetRows.map((r) => [r.id, {
10666
10758
  threadId: r.thread_id,
@@ -10711,7 +10803,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10711
10803
  let finalQuery;
10712
10804
  if (unionQueries.length === 1) finalQuery = unionQueries[0].slice(1, -1);
10713
10805
  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);
10806
+ const includedRows = await this.#db.readClient.manyOrNone(finalQuery, params);
10715
10807
  const seen = /* @__PURE__ */ new Set();
10716
10808
  return includedRows.filter((row) => {
10717
10809
  if (seen.has(row.id)) return false;
@@ -10747,7 +10839,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10747
10839
  WHERE id IN (${inPlaceholders(messageIds.length)})
10748
10840
  ORDER BY "createdAt" DESC
10749
10841
  `;
10750
- const resultRows = await this.#db.client.manyOrNone(query, messageIds);
10842
+ const resultRows = await this.#db.readClient.manyOrNone(query, messageIds);
10751
10843
  return { messages: new MessageList().add(resultRows.map((row) => this.parseRow(row)), "memory").get.all.db() };
10752
10844
  } catch (error) {
10753
10845
  const mastraError = new MastraError({
@@ -10778,7 +10870,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10778
10870
  perPage,
10779
10871
  offset
10780
10872
  ];
10781
- const rows = await this.#db.client.manyOrNone(`${selectStatement}, COUNT(*) OVER () AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
10873
+ const rows = await this.#db.readClient.manyOrNone(`${selectStatement}, COUNT(*) OVER () AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
10782
10874
  if (rows.length > 0) return {
10783
10875
  total: Number(rows[0].__total),
10784
10876
  messages: rows
@@ -10787,7 +10879,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10787
10879
  total: 0,
10788
10880
  messages: []
10789
10881
  };
10790
- const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
10882
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
10791
10883
  return {
10792
10884
  total: parseInt(countResult.count, 10),
10793
10885
  messages: []
@@ -10881,7 +10973,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
10881
10973
  let total;
10882
10974
  let messages;
10883
10975
  if (metadataFilter) {
10884
- const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
10976
+ const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
10885
10977
  total = filteredRows.length;
10886
10978
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
10887
10979
  } else ({total, messages} = await this.#fetchMessagePage({
@@ -11027,7 +11119,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11027
11119
  let total;
11028
11120
  let messages;
11029
11121
  if (metadataFilter) {
11030
- const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
11122
+ const filteredRows = (await this.#db.readClient.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
11031
11123
  total = filteredRows.length;
11032
11124
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
11033
11125
  } else ({total, messages} = await this.#fetchMessagePage({
@@ -11102,7 +11194,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11102
11194
  if (!message.resourceId) throw new Error(`Expected to find a resourceId for message, but couldn't find one. An unexpected error has occurred.`);
11103
11195
  threadIds.add(message.threadId);
11104
11196
  }
11105
- for (const threadIdToCheck of threadIds) if (!await this.getThreadById({ threadId: threadIdToCheck })) throw new MastraError({
11197
+ for (const threadIdToCheck of threadIds) if (!await this.#getThreadById(this.#db.client, { threadId: threadIdToCheck })) throw new MastraError({
11106
11198
  id: createStorageErrorId("PG", "SAVE_MESSAGES", "FAILED"),
11107
11199
  domain: ErrorDomain.STORAGE,
11108
11200
  category: ErrorCategory.THIRD_PARTY,
@@ -11270,11 +11362,14 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11270
11362
  }
11271
11363
  }
11272
11364
  async getResourceById({ resourceId }) {
11365
+ return this.#getResourceById(this.#db.readClient, resourceId);
11366
+ }
11367
+ async #getResourceById(client, resourceId) {
11273
11368
  const tableName = getTableName$3({
11274
11369
  indexName: TABLE_RESOURCES,
11275
11370
  schemaName: getSchemaName$3(this.#schema)
11276
11371
  });
11277
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [resourceId]);
11372
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [resourceId]);
11278
11373
  if (!result) return null;
11279
11374
  return {
11280
11375
  id: result.id,
@@ -11299,7 +11394,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11299
11394
  return resource;
11300
11395
  }
11301
11396
  async updateResource({ resourceId, workingMemory, metadata }) {
11302
- const existingResource = await this.getResourceById({ resourceId });
11397
+ const existingResource = await this.#getResourceById(this.#db.client, resourceId);
11303
11398
  if (!existingResource) {
11304
11399
  const newResource = {
11305
11400
  id: resourceId,
@@ -11347,7 +11442,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11347
11442
  }
11348
11443
  async cloneThread(args) {
11349
11444
  const { sourceThreadId, newThreadId: providedThreadId, resourceId, title, metadata, options } = args;
11350
- const sourceThread = await this.getThreadById({ threadId: sourceThreadId });
11445
+ const sourceThread = await this.#getThreadById(this.#db.client, { threadId: sourceThreadId });
11351
11446
  if (!sourceThread) throw new MastraError({
11352
11447
  id: createStorageErrorId("PG", "CLONE_THREAD", "SOURCE_NOT_FOUND"),
11353
11448
  domain: ErrorDomain.STORAGE,
@@ -11356,7 +11451,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11356
11451
  details: { sourceThreadId }
11357
11452
  });
11358
11453
  const newThreadId = providedThreadId || crypto.randomUUID();
11359
- if (await this.getThreadById({ threadId: newThreadId })) throw new MastraError({
11454
+ if (await this.#getThreadById(this.#db.client, { threadId: newThreadId })) throw new MastraError({
11360
11455
  id: createStorageErrorId("PG", "CLONE_THREAD", "THREAD_EXISTS"),
11361
11456
  domain: ErrorDomain.STORAGE,
11362
11457
  category: ErrorCategory.USER,
@@ -11531,7 +11626,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11531
11626
  indexName: OM_TABLE,
11532
11627
  schemaName: getSchemaName$3(this.#schema)
11533
11628
  });
11534
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "lookupKey" = $1 ORDER BY "generationCount" DESC LIMIT 1`, [lookupKey]);
11629
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "lookupKey" = $1 ORDER BY "generationCount" DESC LIMIT 1`, [lookupKey]);
11535
11630
  if (!result) return null;
11536
11631
  return this.parseOMRow(result);
11537
11632
  } catch (error) {
@@ -11573,7 +11668,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
11573
11668
  params.push(options.offset);
11574
11669
  sql += ` OFFSET $${paramIndex}`;
11575
11670
  }
11576
- const result = await this.#db.client.manyOrNone(sql, params);
11671
+ const result = await this.#db.readClient.manyOrNone(sql, params);
11577
11672
  if (!result) return [];
11578
11673
  return result.map((row) => this.parseOMRow(row));
11579
11674
  } catch (error) {
@@ -12514,9 +12609,10 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12514
12609
  } };
12515
12610
  constructor(config) {
12516
12611
  super();
12517
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12612
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12518
12613
  this.#db = new PgDB({
12519
12614
  client,
12615
+ readClient,
12520
12616
  schemaName,
12521
12617
  skipDefaultIndexes
12522
12618
  });
@@ -12685,7 +12781,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12685
12781
  coalescedCount: (existing.coalescedCount ?? 1) + 1,
12686
12782
  metadata: metadata ?? null
12687
12783
  });
12688
- const updated = await this.getNotification({
12784
+ const updated = await this.#getNotification(this.#db.client, {
12689
12785
  threadId: existing.threadId,
12690
12786
  id: existing.id
12691
12787
  });
@@ -12751,7 +12847,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12751
12847
  indexName: TABLE_NOTIFICATIONS,
12752
12848
  schemaName: getSchemaName$5(this.#schema)
12753
12849
  });
12754
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`, args)).map((row) => rowToNotification(row));
12850
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`, args)).map((row) => rowToNotification(row));
12755
12851
  }
12756
12852
  async listDueNotifications(input) {
12757
12853
  const conditions = ["\"status\" = $1", "((\"deliverAt\" IS NOT NULL AND \"deliverAt\" <= $2) OR (\"summaryAt\" IS NOT NULL AND \"summaryAt\" <= $3))"];
@@ -12774,18 +12870,25 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12774
12870
  indexName: TABLE_NOTIFICATIONS,
12775
12871
  schemaName: getSchemaName$5(this.#schema)
12776
12872
  });
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));
12873
+ 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
12874
  }
12779
12875
  async getNotification(input) {
12876
+ return this.#getNotification(this.#db.readClient, input);
12877
+ }
12878
+ /**
12879
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
12880
+ * lagging read replica cannot yield stale or missing rows mid-update.
12881
+ */
12882
+ async #getNotification(client, input) {
12780
12883
  const tableName = getTableName$5({
12781
12884
  indexName: TABLE_NOTIFICATIONS,
12782
12885
  schemaName: getSchemaName$5(this.#schema)
12783
12886
  });
12784
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`, [input.threadId, input.id]);
12887
+ const row = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`, [input.threadId, input.id]);
12785
12888
  return row ? rowToNotification(row) : null;
12786
12889
  }
12787
12890
  async updateNotification(input) {
12788
- if (!await this.getNotification({
12891
+ if (!await this.#getNotification(this.#db.client, {
12789
12892
  threadId: input.threadId,
12790
12893
  id: input.id
12791
12894
  })) throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
@@ -12809,7 +12912,7 @@ var NotificationsPG = class NotificationsPG extends NotificationsStorage {
12809
12912
  ...input.summarySignalId !== void 0 ? { summarySignalId: input.summarySignalId } : {},
12810
12913
  updatedAt: now
12811
12914
  });
12812
- const updated = await this.getNotification({
12915
+ const updated = await this.#getNotification(this.#db.client, {
12813
12916
  threadId: input.threadId,
12814
12917
  id: input.id
12815
12918
  });
@@ -12856,9 +12959,10 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
12856
12959
  static MANAGED_TABLES = [TABLE_SPANS];
12857
12960
  constructor(config) {
12858
12961
  super();
12859
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12962
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
12860
12963
  this.#db = new PgDB({
12861
12964
  client,
12965
+ readClient,
12862
12966
  schemaName,
12863
12967
  skipDefaultIndexes
12864
12968
  });
@@ -13091,7 +13195,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13091
13195
  indexName: TABLE_SPANS,
13092
13196
  schemaName: getSchemaName$5(this.#schema)
13093
13197
  });
13094
- const row = await this.#db.client.oneOrNone(`SELECT
13198
+ const row = await this.#db.readClient.oneOrNone(`SELECT
13095
13199
  "traceId", "spanId", "parentSpanId", "name",
13096
13200
  "entityType", "entityId", "entityName",
13097
13201
  "userId", "organizationId", "resourceId",
@@ -13127,7 +13231,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13127
13231
  indexName: TABLE_SPANS,
13128
13232
  schemaName: getSchemaName$5(this.#schema)
13129
13233
  });
13130
- const row = await this.#db.client.oneOrNone(`SELECT
13234
+ const row = await this.#db.readClient.oneOrNone(`SELECT
13131
13235
  "traceId", "spanId", "parentSpanId", "name",
13132
13236
  "entityType", "entityId", "entityName",
13133
13237
  "userId", "organizationId", "resourceId",
@@ -13160,7 +13264,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13160
13264
  indexName: TABLE_SPANS,
13161
13265
  schemaName: getSchemaName$5(this.#schema)
13162
13266
  });
13163
- const spans = await this.#db.client.manyOrNone(`SELECT
13267
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13164
13268
  "traceId", "spanId", "parentSpanId", "name",
13165
13269
  "entityType", "entityId", "entityName",
13166
13270
  "userId", "organizationId", "resourceId",
@@ -13197,7 +13301,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13197
13301
  indexName: TABLE_SPANS,
13198
13302
  schemaName: getSchemaName$5(this.#schema)
13199
13303
  });
13200
- const spans = await this.#db.client.manyOrNone(`SELECT
13304
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13201
13305
  "traceId", "spanId", "parentSpanId", "name",
13202
13306
  "entityType", "entityId", "entityName",
13203
13307
  "spanType", "error", "isEvent",
@@ -13381,7 +13485,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13381
13485
  let orderClause;
13382
13486
  if (orderField === "endedAt") orderClause = `ORDER BY r."${sortField}" ${sortDirection} ${sortDirection === "DESC" ? "NULLS FIRST" : "NULLS LAST"}`;
13383
13487
  else orderClause = `ORDER BY r."${sortField}" ${sortDirection}`;
13384
- const countResult = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${tableName} r ${whereClause}`, params);
13488
+ const countResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${tableName} r ${whereClause}`, params);
13385
13489
  const count = Number(countResult?.count ?? 0);
13386
13490
  if (count === 0) return {
13387
13491
  pagination: {
@@ -13392,7 +13496,7 @@ var ObservabilityPG = class ObservabilityPG extends ObservabilityStorage {
13392
13496
  },
13393
13497
  spans: []
13394
13498
  };
13395
- const spans = await this.#db.client.manyOrNone(`SELECT
13499
+ const spans = await this.#db.readClient.manyOrNone(`SELECT
13396
13500
  r."traceId", r."spanId", r."parentSpanId", r."name",
13397
13501
  r."entityType", r."entityId", r."entityName",
13398
13502
  r."userId", r."organizationId", r."resourceId",
@@ -17747,6 +17851,8 @@ function wrapError(op, error, details) {
17747
17851
  }
17748
17852
  var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext extends ObservabilityStorage {
17749
17853
  #client;
17854
+ /** Reader-backed client for standalone reads; writes, DDL, and discovery-cache refresh stay on #client. */
17855
+ #readClient;
17750
17856
  #schema;
17751
17857
  #partitioning;
17752
17858
  #discoveryConfig;
@@ -17754,8 +17860,9 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17754
17860
  #partitionMode;
17755
17861
  constructor(config) {
17756
17862
  super();
17757
- const { client, schemaName } = resolvePgConfig(config);
17863
+ const { client, readClient, schemaName } = resolvePgConfig(config);
17758
17864
  this.#client = client;
17865
+ this.#readClient = readClient;
17759
17866
  this.#schema = schemaName ?? "public";
17760
17867
  this.#partitioning = config.partitioning ?? {};
17761
17868
  this.#discoveryConfig = config.discovery ?? {};
@@ -17940,34 +18047,34 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17940
18047
  await this.#run("BATCH_CREATE_SPANS", () => batchCreateSpans(this.#client, this.#schema, args), { count: args.records.length });
17941
18048
  }
17942
18049
  async getSpan(args) {
17943
- return this.#run("GET_SPAN", () => getSpan(this.#client, this.#schema, args), {
18050
+ return this.#run("GET_SPAN", () => getSpan(this.#readClient, this.#schema, args), {
17944
18051
  traceId: args.traceId,
17945
18052
  spanId: args.spanId
17946
18053
  });
17947
18054
  }
17948
18055
  async getSpans(args) {
17949
- return this.#run("GET_SPANS", () => getSpans(this.#client, this.#schema, args), {
18056
+ return this.#run("GET_SPANS", () => getSpans(this.#readClient, this.#schema, args), {
17950
18057
  traceId: args.traceId,
17951
18058
  count: args.spanIds.length
17952
18059
  });
17953
18060
  }
17954
18061
  async getRootSpan(args) {
17955
- return this.#run("GET_ROOT_SPAN", () => getRootSpan(this.#client, this.#schema, args), { traceId: args.traceId });
18062
+ return this.#run("GET_ROOT_SPAN", () => getRootSpan(this.#readClient, this.#schema, args), { traceId: args.traceId });
17956
18063
  }
17957
18064
  async getTrace(args) {
17958
- return this.#run("GET_TRACE", () => getTrace(this.#client, this.#schema, args), { traceId: args.traceId });
18065
+ return this.#run("GET_TRACE", () => getTrace(this.#readClient, this.#schema, args), { traceId: args.traceId });
17959
18066
  }
17960
18067
  async getTraceLight(args) {
17961
- return this.#run("GET_TRACE_LIGHT", () => getTraceLight(this.#client, this.#schema, args), { traceId: args.traceId });
18068
+ return this.#run("GET_TRACE_LIGHT", () => getTraceLight(this.#readClient, this.#schema, args), { traceId: args.traceId });
17962
18069
  }
17963
18070
  async listTraces(args) {
17964
- return this.#run("LIST_TRACES", () => listTraces(this.#client, this.#schema, args));
18071
+ return this.#run("LIST_TRACES", () => listTraces(this.#readClient, this.#schema, args));
17965
18072
  }
17966
18073
  async queryTraces(plan) {
17967
- return this.#run("QUERY_TRACES", () => queryTraces(this.#client, this.#schema, plan, this.#traceQueryTimeoutMs));
18074
+ return this.#run("QUERY_TRACES", () => queryTraces(this.#readClient, this.#schema, plan, this.#traceQueryTimeoutMs));
17968
18075
  }
17969
18076
  async listBranches(args) {
17970
- return this.#run("LIST_BRANCHES", () => listBranches(this.#client, this.#schema, args));
18077
+ return this.#run("LIST_BRANCHES", () => listBranches(this.#readClient, this.#schema, args));
17971
18078
  }
17972
18079
  async batchCreateLogs(args) {
17973
18080
  await this.#run("BATCH_CREATE_LOGS", () => batchCreateLogs(this.#client, this.#schema, args), { count: args.logs.length });
@@ -17988,58 +18095,58 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
17988
18095
  await this.#run("BATCH_CREATE_FEEDBACK", () => batchCreateFeedback(this.#client, this.#schema, args), { count: args.feedbacks.length });
17989
18096
  }
17990
18097
  async listLogs(args) {
17991
- return this.#run("LIST_LOGS", () => listLogs(this.#client, this.#schema, args));
18098
+ return this.#run("LIST_LOGS", () => listLogs(this.#readClient, this.#schema, args));
17992
18099
  }
17993
18100
  async listMetrics(args) {
17994
- return this.#run("LIST_METRICS", () => listMetrics(this.#client, this.#schema, args));
18101
+ return this.#run("LIST_METRICS", () => listMetrics(this.#readClient, this.#schema, args));
17995
18102
  }
17996
18103
  async listScores(args) {
17997
- return this.#run("LIST_SCORES", () => listScores(this.#client, this.#schema, args));
18104
+ return this.#run("LIST_SCORES", () => listScores(this.#readClient, this.#schema, args));
17998
18105
  }
17999
18106
  async getScoreById(scoreId) {
18000
- return this.#run("GET_SCORE_BY_ID", () => getScoreById(this.#client, this.#schema, scoreId), { scoreId });
18107
+ return this.#run("GET_SCORE_BY_ID", () => getScoreById(this.#readClient, this.#schema, scoreId), { scoreId });
18001
18108
  }
18002
18109
  async listFeedback(args) {
18003
- return this.#run("LIST_FEEDBACK", () => listFeedback(this.#client, this.#schema, args));
18110
+ return this.#run("LIST_FEEDBACK", () => listFeedback(this.#readClient, this.#schema, args));
18004
18111
  }
18005
18112
  async updateFeedbackReviewStatus(args) {
18006
18113
  return this.#run("UPDATE_FEEDBACK_REVIEW_STATUS", () => updateFeedbackReviewStatus(this.#client, this.#schema, args), { feedbackId: args.feedbackId });
18007
18114
  }
18008
18115
  async getMetricAggregate(args) {
18009
- return this.#run("GET_METRIC_AGGREGATE", () => getMetricAggregate(this.#client, this.#schema, args));
18116
+ return this.#run("GET_METRIC_AGGREGATE", () => getMetricAggregate(this.#readClient, this.#schema, args));
18010
18117
  }
18011
18118
  async getMetricBreakdown(args) {
18012
- return this.#run("GET_METRIC_BREAKDOWN", () => getMetricBreakdown(this.#client, this.#schema, args));
18119
+ return this.#run("GET_METRIC_BREAKDOWN", () => getMetricBreakdown(this.#readClient, this.#schema, args));
18013
18120
  }
18014
18121
  async getMetricTimeSeries(args) {
18015
- return this.#run("GET_METRIC_TIME_SERIES", () => getMetricTimeSeries(this.#client, this.#schema, args));
18122
+ return this.#run("GET_METRIC_TIME_SERIES", () => getMetricTimeSeries(this.#readClient, this.#schema, args));
18016
18123
  }
18017
18124
  async getMetricPercentiles(args) {
18018
- return this.#run("GET_METRIC_PERCENTILES", () => getMetricPercentiles(this.#client, this.#schema, args));
18125
+ return this.#run("GET_METRIC_PERCENTILES", () => getMetricPercentiles(this.#readClient, this.#schema, args));
18019
18126
  }
18020
18127
  async getScoreAggregate(args) {
18021
- return this.#run("GET_SCORE_AGGREGATE", () => getScoreAggregate(this.#client, this.#schema, args));
18128
+ return this.#run("GET_SCORE_AGGREGATE", () => getScoreAggregate(this.#readClient, this.#schema, args));
18022
18129
  }
18023
18130
  async getScoreBreakdown(args) {
18024
- return this.#run("GET_SCORE_BREAKDOWN", () => getScoreBreakdown(this.#client, this.#schema, args));
18131
+ return this.#run("GET_SCORE_BREAKDOWN", () => getScoreBreakdown(this.#readClient, this.#schema, args));
18025
18132
  }
18026
18133
  async getScoreTimeSeries(args) {
18027
- return this.#run("GET_SCORE_TIME_SERIES", () => getScoreTimeSeries(this.#client, this.#schema, args));
18134
+ return this.#run("GET_SCORE_TIME_SERIES", () => getScoreTimeSeries(this.#readClient, this.#schema, args));
18028
18135
  }
18029
18136
  async getScorePercentiles(args) {
18030
- return this.#run("GET_SCORE_PERCENTILES", () => getScorePercentiles(this.#client, this.#schema, args));
18137
+ return this.#run("GET_SCORE_PERCENTILES", () => getScorePercentiles(this.#readClient, this.#schema, args));
18031
18138
  }
18032
18139
  async getFeedbackAggregate(args) {
18033
- return this.#run("GET_FEEDBACK_AGGREGATE", () => getFeedbackAggregate(this.#client, this.#schema, args));
18140
+ return this.#run("GET_FEEDBACK_AGGREGATE", () => getFeedbackAggregate(this.#readClient, this.#schema, args));
18034
18141
  }
18035
18142
  async getFeedbackBreakdown(args) {
18036
- return this.#run("GET_FEEDBACK_BREAKDOWN", () => getFeedbackBreakdown(this.#client, this.#schema, args));
18143
+ return this.#run("GET_FEEDBACK_BREAKDOWN", () => getFeedbackBreakdown(this.#readClient, this.#schema, args));
18037
18144
  }
18038
18145
  async getFeedbackTimeSeries(args) {
18039
- return this.#run("GET_FEEDBACK_TIME_SERIES", () => getFeedbackTimeSeries(this.#client, this.#schema, args));
18146
+ return this.#run("GET_FEEDBACK_TIME_SERIES", () => getFeedbackTimeSeries(this.#readClient, this.#schema, args));
18040
18147
  }
18041
18148
  async getFeedbackPercentiles(args) {
18042
- return this.#run("GET_FEEDBACK_PERCENTILES", () => getFeedbackPercentiles(this.#client, this.#schema, args));
18149
+ return this.#run("GET_FEEDBACK_PERCENTILES", () => getFeedbackPercentiles(this.#readClient, this.#schema, args));
18043
18150
  }
18044
18151
  async getEntityTypes(args) {
18045
18152
  return this.#run("GET_ENTITY_TYPES", () => getEntityTypes(this.#client, this.#schema, args, this.#discovery));
@@ -18098,9 +18205,10 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18098
18205
  static MANAGED_TABLES = [TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS];
18099
18206
  constructor(config) {
18100
18207
  super();
18101
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18208
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18102
18209
  this.#db = new PgDB({
18103
18210
  client,
18211
+ readClient,
18104
18212
  schemaName,
18105
18213
  skipDefaultIndexes
18106
18214
  });
@@ -18177,12 +18285,19 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18177
18285
  await this.#db.clearTable({ tableName: TABLE_PROMPT_BLOCKS });
18178
18286
  }
18179
18287
  async getById(id) {
18288
+ return this.#getById(this.#db.readClient, id);
18289
+ }
18290
+ /**
18291
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
18292
+ * lagging read replica cannot yield stale or missing rows mid-update.
18293
+ */
18294
+ async #getById(client, id) {
18180
18295
  try {
18181
18296
  const tableName = getTableName$5({
18182
18297
  indexName: TABLE_PROMPT_BLOCKS,
18183
18298
  schemaName: getSchemaName$5(this.#schema)
18184
18299
  });
18185
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18300
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18186
18301
  if (!result) return null;
18187
18302
  return this.parseBlockRow(result);
18188
18303
  } catch (error) {
@@ -18261,7 +18376,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18261
18376
  indexName: TABLE_PROMPT_BLOCKS,
18262
18377
  schemaName: getSchemaName$5(this.#schema)
18263
18378
  });
18264
- const existingBlock = await this.getById(id);
18379
+ const existingBlock = await this.#getById(this.#db.client, id);
18265
18380
  if (!existingBlock) throw new MastraError({
18266
18381
  id: createStorageErrorId("PG", "UPDATE_PROMPT_BLOCK", "NOT_FOUND"),
18267
18382
  domain: ErrorDomain.STORAGE,
@@ -18300,7 +18415,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18300
18415
  values.push(now);
18301
18416
  values.push(id);
18302
18417
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
18303
- const updatedBlock = await this.getById(id);
18418
+ const updatedBlock = await this.#getById(this.#db.client, id);
18304
18419
  if (!updatedBlock) throw new MastraError({
18305
18420
  id: createStorageErrorId("PG", "UPDATE_PROMPT_BLOCK", "NOT_FOUND_AFTER_UPDATE"),
18306
18421
  domain: ErrorDomain.STORAGE,
@@ -18369,7 +18484,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18369
18484
  queryParams.push(JSON.stringify(metadata));
18370
18485
  }
18371
18486
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
18372
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
18487
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
18373
18488
  const total = parseInt(countResult.count, 10);
18374
18489
  if (total === 0) return {
18375
18490
  promptBlocks: [],
@@ -18380,7 +18495,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18380
18495
  };
18381
18496
  const limitValue = perPageInput === false ? total : perPage;
18382
18497
  return {
18383
- promptBlocks: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
18498
+ promptBlocks: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
18384
18499
  ...queryParams,
18385
18500
  limitValue,
18386
18501
  offset
@@ -18459,7 +18574,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18459
18574
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18460
18575
  schemaName: getSchemaName$5(this.#schema)
18461
18576
  });
18462
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18577
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
18463
18578
  if (!result) return null;
18464
18579
  return this.parseVersionRow(result);
18465
18580
  } catch (error) {
@@ -18478,7 +18593,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18478
18593
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18479
18594
  schemaName: getSchemaName$5(this.#schema)
18480
18595
  });
18481
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 AND "versionNumber" = $2`, [blockId, versionNumber]);
18596
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 AND "versionNumber" = $2`, [blockId, versionNumber]);
18482
18597
  if (!result) return null;
18483
18598
  return this.parseVersionRow(result);
18484
18599
  } catch (error) {
@@ -18500,7 +18615,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18500
18615
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18501
18616
  schemaName: getSchemaName$5(this.#schema)
18502
18617
  });
18503
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [blockId]);
18618
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [blockId]);
18504
18619
  if (!result) return null;
18505
18620
  return this.parseVersionRow(result);
18506
18621
  } catch (error) {
@@ -18529,7 +18644,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18529
18644
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18530
18645
  schemaName: getSchemaName$5(this.#schema)
18531
18646
  });
18532
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18647
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18533
18648
  const total = parseInt(countResult.count, 10);
18534
18649
  if (total === 0) return {
18535
18650
  versions: [],
@@ -18540,7 +18655,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18540
18655
  };
18541
18656
  const limitValue = perPageInput === false ? total : perPage;
18542
18657
  return {
18543
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
18658
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "blockId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
18544
18659
  blockId,
18545
18660
  limitValue,
18546
18661
  offset
@@ -18610,7 +18725,7 @@ var PromptBlocksPG = class PromptBlocksPG extends PromptBlocksStorage {
18610
18725
  indexName: TABLE_PROMPT_BLOCK_VERSIONS,
18611
18726
  schemaName: getSchemaName$5(this.#schema)
18612
18727
  });
18613
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18728
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "blockId" = $1`, [blockId]);
18614
18729
  return parseInt(result.count, 10);
18615
18730
  } catch (error) {
18616
18731
  if (error instanceof MastraError) throw error;
@@ -18711,6 +18826,7 @@ function rowToTrigger(row) {
18711
18826
  var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18712
18827
  #db;
18713
18828
  #client;
18829
+ #readClient;
18714
18830
  #schema;
18715
18831
  #skipDefaultIndexes;
18716
18832
  #indexes;
@@ -18730,10 +18846,12 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18730
18846
  } };
18731
18847
  constructor(config) {
18732
18848
  super();
18733
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18849
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
18734
18850
  this.#client = client;
18851
+ this.#readClient = readClient;
18735
18852
  this.#db = new PgDB({
18736
18853
  client,
18854
+ readClient,
18737
18855
  schemaName,
18738
18856
  skipDefaultIndexes
18739
18857
  });
@@ -18857,7 +18975,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18857
18975
  return getTableName$2(tableName, getSchemaName$2(parseSqlIdentifier(this.#schema, "schema name")));
18858
18976
  }
18859
18977
  async createSchedule(schedule) {
18860
- if (await this.getSchedule(schedule.id)) throw new Error(`Schedule with id "${schedule.id}" already exists`);
18978
+ if (await this.#getSchedule(this.#client, schedule.id)) throw new Error(`Schedule with id "${schedule.id}" already exists`);
18861
18979
  await this.#db.insert({
18862
18980
  tableName: TABLE_SCHEDULES,
18863
18981
  record: {
@@ -18879,7 +18997,14 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18879
18997
  return schedule;
18880
18998
  }
18881
18999
  async getSchedule(id) {
18882
- const row = await this.#client.oneOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} WHERE id = $1`, [id]);
19000
+ return this.#getSchedule(this.#readClient, id);
19001
+ }
19002
+ /**
19003
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
19004
+ * lagging read replica cannot yield stale or missing rows mid-update.
19005
+ */
19006
+ async #getSchedule(client, id) {
19007
+ const row = await client.oneOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} WHERE id = $1`, [id]);
18883
19008
  return row ? rowToSchedule(row) : null;
18884
19009
  }
18885
19010
  async listSchedules(filter) {
@@ -18904,7 +19029,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18904
19029
  conditions.push(`owner_id = $${params.length}`);
18905
19030
  }
18906
19031
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
18907
- return (await this.#client.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} ${where} ORDER BY created_at ASC`, params)).map(rowToSchedule);
19032
+ return (await this.#readClient.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULES)} ${where} ORDER BY created_at ASC`, params)).map(rowToSchedule);
18908
19033
  }
18909
19034
  async listDueSchedules(now, limit) {
18910
19035
  const cap = limit ?? 100;
@@ -18934,13 +19059,13 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18934
19059
  if ("ownerId" in patch) push("owner_id = ?", patch.ownerId ?? null);
18935
19060
  push("updated_at = ?", Date.now());
18936
19061
  if (setClauses.length === 1) {
18937
- const existing = await this.getSchedule(id);
19062
+ const existing = await this.#getSchedule(this.#client, id);
18938
19063
  if (!existing) throw new Error(`Schedule ${id} not found`);
18939
19064
  return existing;
18940
19065
  }
18941
19066
  params.push(id);
18942
19067
  await this.#client.none(`UPDATE ${this.#table(TABLE_SCHEDULES)} SET ${setClauses.join(", ")} WHERE id = $${params.length}`, params);
18943
- const updated = await this.getSchedule(id);
19068
+ const updated = await this.#getSchedule(this.#client, id);
18944
19069
  if (!updated) throw new Error(`Schedule ${id} not found`);
18945
19070
  return updated;
18946
19071
  }
@@ -18997,7 +19122,7 @@ var SchedulesPG = class SchedulesPG extends SchedulesStorage {
18997
19122
  params.push(Math.floor(opts.limit));
18998
19123
  limitClause = `LIMIT $${params.length}`;
18999
19124
  }
19000
- return (await this.#client.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULE_TRIGGERS)}
19125
+ return (await this.#readClient.manyOrNone(`SELECT * FROM ${this.#table(TABLE_SCHEDULE_TRIGGERS)}
19001
19126
  WHERE ${conditions.join(" AND ")}
19002
19127
  ORDER BY actual_fire_at DESC
19003
19128
  ${limitClause}`, params)).map(rowToTrigger);
@@ -19023,9 +19148,10 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19023
19148
  static MANAGED_TABLES = [TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS];
19024
19149
  constructor(config) {
19025
19150
  super();
19026
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19151
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19027
19152
  this.#db = new PgDB({
19028
19153
  client,
19154
+ readClient,
19029
19155
  schemaName,
19030
19156
  skipDefaultIndexes
19031
19157
  });
@@ -19102,12 +19228,19 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19102
19228
  await this.#db.clearTable({ tableName: TABLE_SCORER_DEFINITIONS });
19103
19229
  }
19104
19230
  async getById(id) {
19231
+ return this.#getById(this.#db.readClient, id);
19232
+ }
19233
+ /**
19234
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
19235
+ * lagging read replica cannot yield stale or missing rows mid-update.
19236
+ */
19237
+ async #getById(client, id) {
19105
19238
  try {
19106
19239
  const tableName = getTableName$5({
19107
19240
  indexName: TABLE_SCORER_DEFINITIONS,
19108
19241
  schemaName: getSchemaName$5(this.#schema)
19109
19242
  });
19110
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19243
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19111
19244
  if (!result) return null;
19112
19245
  return this.parseScorerRow(result);
19113
19246
  } catch (error) {
@@ -19190,7 +19323,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19190
19323
  indexName: TABLE_SCORER_DEFINITIONS,
19191
19324
  schemaName: getSchemaName$5(this.#schema)
19192
19325
  });
19193
- const existingScorer = await this.getById(id);
19326
+ const existingScorer = await this.#getById(this.#db.client, id);
19194
19327
  if (!existingScorer) throw new MastraError({
19195
19328
  id: createStorageErrorId("PG", "UPDATE_SCORER_DEFINITION", "NOT_FOUND"),
19196
19329
  domain: ErrorDomain.STORAGE,
@@ -19229,7 +19362,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19229
19362
  values.push(now);
19230
19363
  values.push(id);
19231
19364
  await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
19232
- const updatedScorer = await this.getById(id);
19365
+ const updatedScorer = await this.#getById(this.#db.client, id);
19233
19366
  if (!updatedScorer) throw new MastraError({
19234
19367
  id: createStorageErrorId("PG", "UPDATE_SCORER_DEFINITION", "NOT_FOUND_AFTER_UPDATE"),
19235
19368
  domain: ErrorDomain.STORAGE,
@@ -19306,7 +19439,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19306
19439
  queryParams.push(JSON.stringify(metadata));
19307
19440
  }
19308
19441
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
19309
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
19442
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
19310
19443
  const total = parseInt(countResult.count, 10);
19311
19444
  if (total === 0) return {
19312
19445
  scorerDefinitions: [],
@@ -19317,7 +19450,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19317
19450
  };
19318
19451
  const limitValue = perPageInput === false ? total : perPage;
19319
19452
  return {
19320
- scorerDefinitions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
19453
+ scorerDefinitions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
19321
19454
  ...queryParams,
19322
19455
  limitValue,
19323
19456
  offset
@@ -19399,7 +19532,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19399
19532
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19400
19533
  schemaName: getSchemaName$5(this.#schema)
19401
19534
  });
19402
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19535
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
19403
19536
  if (!result) return null;
19404
19537
  return this.parseVersionRow(result);
19405
19538
  } catch (error) {
@@ -19418,7 +19551,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19418
19551
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19419
19552
  schemaName: getSchemaName$5(this.#schema)
19420
19553
  });
19421
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 AND "versionNumber" = $2`, [scorerDefinitionId, versionNumber]);
19554
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 AND "versionNumber" = $2`, [scorerDefinitionId, versionNumber]);
19422
19555
  if (!result) return null;
19423
19556
  return this.parseVersionRow(result);
19424
19557
  } catch (error) {
@@ -19440,7 +19573,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19440
19573
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19441
19574
  schemaName: getSchemaName$5(this.#schema)
19442
19575
  });
19443
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [scorerDefinitionId]);
19576
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [scorerDefinitionId]);
19444
19577
  if (!result) return null;
19445
19578
  return this.parseVersionRow(result);
19446
19579
  } catch (error) {
@@ -19469,7 +19602,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19469
19602
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19470
19603
  schemaName: getSchemaName$5(this.#schema)
19471
19604
  });
19472
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19605
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19473
19606
  const total = parseInt(countResult.count, 10);
19474
19607
  if (total === 0) return {
19475
19608
  versions: [],
@@ -19480,7 +19613,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19480
19613
  };
19481
19614
  const limitValue = perPageInput === false ? total : perPage;
19482
19615
  return {
19483
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
19616
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "scorerDefinitionId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
19484
19617
  scorerDefinitionId,
19485
19618
  limitValue,
19486
19619
  offset
@@ -19550,7 +19683,7 @@ var ScorerDefinitionsPG = class ScorerDefinitionsPG extends ScorerDefinitionsSto
19550
19683
  indexName: TABLE_SCORER_DEFINITION_VERSIONS,
19551
19684
  schemaName: getSchemaName$5(this.#schema)
19552
19685
  });
19553
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19686
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "scorerDefinitionId" = $1`, [scorerDefinitionId]);
19554
19687
  return parseInt(result.count, 10);
19555
19688
  } catch (error) {
19556
19689
  if (error instanceof MastraError) throw error;
@@ -19647,9 +19780,10 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19647
19780
  } };
19648
19781
  constructor(config) {
19649
19782
  super();
19650
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19783
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
19651
19784
  this.#db = new PgDB({
19652
19785
  client,
19786
+ readClient,
19653
19787
  schemaName,
19654
19788
  skipDefaultIndexes
19655
19789
  });
@@ -19783,7 +19917,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19783
19917
  }
19784
19918
  async getScoreById({ id }) {
19785
19919
  try {
19786
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${getTableName$1({
19920
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${getTableName$1({
19787
19921
  indexName: TABLE_SCORERS,
19788
19922
  schemaName: getSchemaName$1(this.#schema)
19789
19923
  })} WHERE id = $1`, [id]);
@@ -19815,7 +19949,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19815
19949
  }
19816
19950
  paramIndex = applyTenancyFilters(conditions, queryParams, paramIndex, filters);
19817
19951
  const whereClause = conditions.join(" AND ");
19818
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19952
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19819
19953
  indexName: TABLE_SCORERS,
19820
19954
  schemaName: getSchemaName$1(this.#schema)
19821
19955
  })} WHERE ${whereClause}`, queryParams);
@@ -19833,7 +19967,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19833
19967
  };
19834
19968
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19835
19969
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19836
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
19970
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19837
19971
  indexName: TABLE_SCORERS,
19838
19972
  schemaName: getSchemaName$1(this.#schema)
19839
19973
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -19923,7 +20057,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19923
20057
  const queryParams = [runId];
19924
20058
  let paramIndex = applyTenancyFilters(conditions, queryParams, 2, filters);
19925
20059
  const whereClause = conditions.join(" AND ");
19926
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
20060
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19927
20061
  indexName: TABLE_SCORERS,
19928
20062
  schemaName: getSchemaName$1(this.#schema)
19929
20063
  })} WHERE ${whereClause}`, queryParams);
@@ -19941,7 +20075,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19941
20075
  };
19942
20076
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19943
20077
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19944
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
20078
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19945
20079
  indexName: TABLE_SCORERS,
19946
20080
  schemaName: getSchemaName$1(this.#schema)
19947
20081
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -19972,7 +20106,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19972
20106
  const queryParams = [entityId, entityType];
19973
20107
  let paramIndex = applyTenancyFilters(conditions, queryParams, 3, filters);
19974
20108
  const whereClause = conditions.join(" AND ");
19975
- const total = await this.#db.client.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
20109
+ const total = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) FROM ${getTableName$1({
19976
20110
  indexName: TABLE_SCORERS,
19977
20111
  schemaName: getSchemaName$1(this.#schema)
19978
20112
  })} WHERE ${whereClause}`, queryParams);
@@ -19990,7 +20124,7 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
19990
20124
  };
19991
20125
  const limitValue = perPageInput === false ? Number(total?.count) : perPage;
19992
20126
  const end = perPageInput === false ? Number(total?.count) : start + perPage;
19993
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${getTableName$1({
20127
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${getTableName$1({
19994
20128
  indexName: TABLE_SCORERS,
19995
20129
  schemaName: getSchemaName$1(this.#schema)
19996
20130
  })} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
@@ -20025,14 +20159,14 @@ var ScoresPG = class ScoresPG extends ScoresStorage {
20025
20159
  const queryParams = [traceId, spanId];
20026
20160
  let paramIndex = applyTenancyFilters(conditions, queryParams, 3, filters);
20027
20161
  const whereClause = conditions.join(" AND ");
20028
- const countSQLResult = await this.#db.client.oneOrNone(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`, queryParams);
20162
+ const countSQLResult = await this.#db.readClient.oneOrNone(`SELECT COUNT(*) as count FROM ${tableName} WHERE ${whereClause}`, queryParams);
20029
20163
  const total = Number(countSQLResult?.count ?? 0);
20030
20164
  const { page, perPage: perPageInput } = pagination;
20031
20165
  const perPage = normalizePerPage(perPageInput, 100);
20032
20166
  const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
20033
20167
  const limitValue = perPageInput === false ? total : perPage;
20034
20168
  const end = perPageInput === false ? total : start + perPage;
20035
- const result = await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
20169
+ const result = await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE ${whereClause} ORDER BY "createdAt" DESC LIMIT $${paramIndex++} OFFSET $${paramIndex++}`, [
20036
20170
  ...queryParams,
20037
20171
  limitValue,
20038
20172
  start
@@ -20080,9 +20214,10 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20080
20214
  static MANAGED_TABLES = [TABLE_SKILLS, TABLE_SKILL_VERSIONS];
20081
20215
  constructor(config) {
20082
20216
  super();
20083
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20217
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20084
20218
  this.#db = new PgDB({
20085
20219
  client,
20220
+ readClient,
20086
20221
  schemaName,
20087
20222
  skipDefaultIndexes
20088
20223
  });
@@ -20156,12 +20291,19 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20156
20291
  await this.#db.clearTable({ tableName: TABLE_SKILLS });
20157
20292
  }
20158
20293
  async getById(id) {
20294
+ return this.#getById(this.#db.readClient, id);
20295
+ }
20296
+ /**
20297
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
20298
+ * lagging read replica cannot yield stale or missing rows mid-update.
20299
+ */
20300
+ async #getById(client, id) {
20159
20301
  try {
20160
20302
  const tableName = getTableName$5({
20161
20303
  indexName: TABLE_SKILLS,
20162
20304
  schemaName: getSchemaName$5(this.#schema)
20163
20305
  });
20164
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20306
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20165
20307
  if (!result) return null;
20166
20308
  return this.parseSkillRow(result);
20167
20309
  } catch (error) {
@@ -20243,7 +20385,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20243
20385
  indexName: TABLE_SKILLS,
20244
20386
  schemaName: getSchemaName$5(this.#schema)
20245
20387
  });
20246
- if (!await this.getById(id)) throw new MastraError({
20388
+ if (!await this.#getById(this.#db.client, id)) throw new MastraError({
20247
20389
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND"),
20248
20390
  domain: ErrorDomain.STORAGE,
20249
20391
  category: ErrorCategory.USER,
@@ -20255,7 +20397,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20255
20397
  const configFields = {};
20256
20398
  for (const [key, value] of Object.entries(rawConfigFields)) if (value !== void 0) configFields[key] = value;
20257
20399
  if (SNAPSHOT_FIELDS$1.some((field) => field in configFields)) {
20258
- const latestVersion = await this.getLatestVersion(id);
20400
+ const latestVersion = await this.#getLatestVersion(this.#db.client, id);
20259
20401
  if (!latestVersion) throw new MastraError({
20260
20402
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NO_VERSIONS"),
20261
20403
  domain: ErrorDomain.STORAGE,
@@ -20312,7 +20454,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20312
20454
  values.push(now);
20313
20455
  values.push(id);
20314
20456
  if (setClauses.length > 2 || versionCreated) await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
20315
- const updatedSkill = await this.getById(id);
20457
+ const updatedSkill = await this.#getById(this.#db.client, id);
20316
20458
  if (!updatedSkill) throw new MastraError({
20317
20459
  id: createStorageErrorId("PG", "UPDATE_SKILL", "NOT_FOUND_AFTER_UPDATE"),
20318
20460
  domain: ErrorDomain.STORAGE,
@@ -20405,7 +20547,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20405
20547
  const joinClause = useJoin && joinSqlIdx !== null ? `LEFT JOIN ${favoritesTable} sr ON sr."entityType" = 'skill' AND sr."entityId" = s.id AND sr."userId" = $${joinSqlIdx}` : "";
20406
20548
  const joinParams = useJoin && joinUserId ? [joinUserId] : [];
20407
20549
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
20408
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} s ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
20550
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} s ${joinClause} ${whereClause}`, [...joinParams, ...queryParams]);
20409
20551
  const total = parseInt(countResult.count, 10);
20410
20552
  if (total === 0) return {
20411
20553
  skills: [],
@@ -20423,7 +20565,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20423
20565
  const limitIdx = paramIdx++;
20424
20566
  const offsetIdx = paramIdx++;
20425
20567
  return {
20426
- skills: (await this.#db.client.manyOrNone(`SELECT s.* FROM ${tableName} s ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
20568
+ skills: (await this.#db.readClient.manyOrNone(`SELECT s.* FROM ${tableName} s ${joinClause} ${whereClause} ${orderByClause} LIMIT $${limitIdx} OFFSET $${offsetIdx}`, [
20427
20569
  ...joinParams,
20428
20570
  ...queryParams,
20429
20571
  limitValue,
@@ -20511,7 +20653,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20511
20653
  indexName: TABLE_SKILL_VERSIONS,
20512
20654
  schemaName: getSchemaName$5(this.#schema)
20513
20655
  });
20514
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20656
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
20515
20657
  if (!result) return null;
20516
20658
  return this.parseVersionRow(result);
20517
20659
  } catch (error) {
@@ -20532,7 +20674,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20532
20674
  schemaName: getSchemaName$5(this.#schema)
20533
20675
  });
20534
20676
  const placeholders = ids.map((_, i) => `$${i + 1}`).join(", ");
20535
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
20677
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE id IN (${placeholders})`, ids)).map((row) => this.parseVersionRow(row));
20536
20678
  } catch (error) {
20537
20679
  if (error instanceof MastraError) throw error;
20538
20680
  throw new MastraError({
@@ -20549,7 +20691,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20549
20691
  indexName: TABLE_SKILL_VERSIONS,
20550
20692
  schemaName: getSchemaName$5(this.#schema)
20551
20693
  });
20552
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 AND "versionNumber" = $2`, [skillId, versionNumber]);
20694
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 AND "versionNumber" = $2`, [skillId, versionNumber]);
20553
20695
  if (!result) return null;
20554
20696
  return this.parseVersionRow(result);
20555
20697
  } catch (error) {
@@ -20566,12 +20708,19 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20566
20708
  }
20567
20709
  }
20568
20710
  async getLatestVersion(skillId) {
20711
+ return this.#getLatestVersion(this.#db.readClient, skillId);
20712
+ }
20713
+ /**
20714
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
20715
+ * lagging read replica cannot yield stale or missing rows mid-update.
20716
+ */
20717
+ async #getLatestVersion(client, skillId) {
20569
20718
  try {
20570
20719
  const tableName = getTableName$5({
20571
20720
  indexName: TABLE_SKILL_VERSIONS,
20572
20721
  schemaName: getSchemaName$5(this.#schema)
20573
20722
  });
20574
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [skillId]);
20723
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [skillId]);
20575
20724
  if (!result) return null;
20576
20725
  return this.parseVersionRow(result);
20577
20726
  } catch (error) {
@@ -20600,7 +20749,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20600
20749
  indexName: TABLE_SKILL_VERSIONS,
20601
20750
  schemaName: getSchemaName$5(this.#schema)
20602
20751
  });
20603
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20752
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20604
20753
  const total = parseInt(countResult.count, 10);
20605
20754
  if (total === 0) return {
20606
20755
  versions: [],
@@ -20611,7 +20760,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20611
20760
  };
20612
20761
  const limitValue = perPageInput === false ? total : perPage;
20613
20762
  return {
20614
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
20763
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "skillId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
20615
20764
  skillId,
20616
20765
  limitValue,
20617
20766
  offset
@@ -20681,7 +20830,7 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
20681
20830
  indexName: TABLE_SKILL_VERSIONS,
20682
20831
  schemaName: getSchemaName$5(this.#schema)
20683
20832
  });
20684
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20833
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "skillId" = $1`, [skillId]);
20685
20834
  return parseInt(result.count, 10);
20686
20835
  } catch (error) {
20687
20836
  if (error instanceof MastraError) throw error;
@@ -20756,9 +20905,10 @@ var ThreadStatePG = class ThreadStatePG extends ThreadStateStorage {
20756
20905
  } };
20757
20906
  constructor(config) {
20758
20907
  super();
20759
- const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
20908
+ const { client, readClient, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
20760
20909
  this.#db = new PgDB({
20761
20910
  client,
20911
+ readClient,
20762
20912
  schemaName,
20763
20913
  skipDefaultIndexes
20764
20914
  });
@@ -20921,9 +21071,10 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
20921
21071
  static MANAGED_TABLES = [TABLE_TOOL_PROVIDER_CONNECTIONS];
20922
21072
  constructor(config) {
20923
21073
  super();
20924
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21074
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
20925
21075
  this.#db = new PgDB({
20926
21076
  client,
21077
+ readClient,
20927
21078
  schemaName,
20928
21079
  skipDefaultIndexes
20929
21080
  });
@@ -21002,7 +21153,7 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
21002
21153
  schemaName: getSchemaName$5(this.#schema)
21003
21154
  });
21004
21155
  try {
21005
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "authorId" = $1 AND "providerId" = $2 AND "connectionId" = $3 LIMIT 1`, [
21156
+ const row = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "authorId" = $1 AND "providerId" = $2 AND "connectionId" = $3 LIMIT 1`, [
21006
21157
  authorId,
21007
21158
  providerId,
21008
21159
  connectionId
@@ -21109,7 +21260,7 @@ var ToolProviderConnectionsPG = class ToolProviderConnectionsPG extends ToolProv
21109
21260
  clauses.push(`scope = $${args.length}`);
21110
21261
  }
21111
21262
  const whereClause = clauses.length > 0 ? ` WHERE ${clauses.join(" AND ")}` : "";
21112
- return (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName}${whereClause}`, args)).map((row) => rowToToolProviderConnection(row));
21263
+ return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName}${whereClause}`, args)).map((row) => rowToToolProviderConnection(row));
21113
21264
  } catch (error) {
21114
21265
  throw new MastraError({
21115
21266
  id: createStorageErrorId("PG", "TOOL_PROVIDER_CONNECTION_LIST", "FAILED"),
@@ -21185,9 +21336,10 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21185
21336
  static MANAGED_TABLES = [TABLE_WORKFLOW_DEFINITIONS];
21186
21337
  constructor(config) {
21187
21338
  super();
21188
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21339
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21189
21340
  this.#db = new PgDB({
21190
21341
  client,
21342
+ readClient,
21191
21343
  schemaName,
21192
21344
  skipDefaultIndexes
21193
21345
  });
@@ -21244,7 +21396,7 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21244
21396
  }
21245
21397
  async upsert(input) {
21246
21398
  const now = /* @__PURE__ */ new Date();
21247
- if (!await this.get(input.id)) {
21399
+ if (!await this.#get(this.#db.client, input.id)) {
21248
21400
  if (!("inputSchema" in input) || !input.inputSchema) throw new Error(`Cannot create workflow definition "${input.id}": inputSchema is required.`);
21249
21401
  if (!("outputSchema" in input) || !input.outputSchema) throw new Error(`Cannot create workflow definition "${input.id}": outputSchema is required.`);
21250
21402
  if (!("graph" in input) || !input.graph) throw new Error(`Cannot create workflow definition "${input.id}": graph is required.`);
@@ -21270,10 +21422,10 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21270
21422
  record
21271
21423
  });
21272
21424
  } catch (error) {
21273
- if (!await this.get(input.id)) throw error;
21425
+ if (!await this.#get(this.#db.client, input.id)) throw error;
21274
21426
  return this.applyUpdate(input, now);
21275
21427
  }
21276
- const created = await this.get(input.id);
21428
+ const created = await this.#get(this.#db.client, input.id);
21277
21429
  if (!created) throw new Error(`Failed to persist workflow definition "${input.id}".`);
21278
21430
  return created;
21279
21431
  }
@@ -21296,16 +21448,23 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21296
21448
  keys: { id: input.id },
21297
21449
  data
21298
21450
  });
21299
- const updated = await this.get(input.id);
21451
+ const updated = await this.#get(this.#db.client, input.id);
21300
21452
  if (!updated) throw new Error(`Failed to update workflow definition "${input.id}".`);
21301
21453
  return updated;
21302
21454
  }
21303
21455
  async get(id) {
21456
+ return this.#get(this.#db.readClient, id);
21457
+ }
21458
+ /**
21459
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
21460
+ * lagging read replica cannot yield stale or missing rows mid-update.
21461
+ */
21462
+ async #get(client, id) {
21304
21463
  const tableName = getTableName$5({
21305
21464
  indexName: TABLE_WORKFLOW_DEFINITIONS,
21306
21465
  schemaName: getSchemaName$5(this.#schema)
21307
21466
  });
21308
- const row = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
21467
+ const row = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1`, [id]);
21309
21468
  return row ? rowToDefinition(row) : null;
21310
21469
  }
21311
21470
  async list(args) {
@@ -21324,7 +21483,7 @@ var WorkflowDefinitionsPG = class WorkflowDefinitionsPG extends WorkflowDefiniti
21324
21483
  conditions.push(`"authorId" = $${params.length}`);
21325
21484
  }
21326
21485
  const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
21327
- const definitions = (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${where} ORDER BY "updatedAt" DESC`, params)).map((row) => rowToDefinition(row));
21486
+ const definitions = (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${where} ORDER BY "updatedAt" DESC`, params)).map((row) => rowToDefinition(row));
21328
21487
  return {
21329
21488
  definitions,
21330
21489
  total: definitions.length
@@ -21389,9 +21548,10 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
21389
21548
  } };
21390
21549
  constructor(config) {
21391
21550
  super();
21392
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21551
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21393
21552
  this.#db = new PgDB({
21394
21553
  client,
21554
+ readClient,
21395
21555
  schemaName,
21396
21556
  skipDefaultIndexes
21397
21557
  });
@@ -21714,7 +21874,7 @@ var WorkflowsPG = class WorkflowsPG extends WorkflowsStorage {
21714
21874
  ORDER BY "createdAt" DESC LIMIT 1
21715
21875
  `;
21716
21876
  const queryValues = values;
21717
- const result = await this.#db.client.oneOrNone(query, queryValues);
21877
+ const result = await this.#db.readClient.oneOrNone(query, queryValues);
21718
21878
  if (!result) return null;
21719
21879
  return this.parseWorkflowRun(result);
21720
21880
  } catch (error) {
@@ -21843,9 +22003,10 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21843
22003
  static MANAGED_TABLES = [TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS];
21844
22004
  constructor(config) {
21845
22005
  super();
21846
- const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
22006
+ const { client, readClient, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
21847
22007
  this.#db = new PgDB({
21848
22008
  client,
22009
+ readClient,
21849
22010
  schemaName,
21850
22011
  skipDefaultIndexes
21851
22012
  });
@@ -21909,12 +22070,19 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21909
22070
  await this.#db.clearTable({ tableName: TABLE_WORKSPACES });
21910
22071
  }
21911
22072
  async getById(id) {
22073
+ return this.#getById(this.#db.readClient, id);
22074
+ }
22075
+ /**
22076
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
22077
+ * lagging read replica cannot yield stale or missing rows mid-update.
22078
+ */
22079
+ async #getById(client, id) {
21912
22080
  try {
21913
22081
  const tableName = getTableName$5({
21914
22082
  indexName: TABLE_WORKSPACES,
21915
22083
  schemaName: getSchemaName$5(this.#schema)
21916
22084
  });
21917
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22085
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
21918
22086
  if (!result) return null;
21919
22087
  return this.parseWorkspaceRow(result);
21920
22088
  } catch (error) {
@@ -21993,7 +22161,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
21993
22161
  indexName: TABLE_WORKSPACES,
21994
22162
  schemaName: getSchemaName$5(this.#schema)
21995
22163
  });
21996
- const existingWorkspace = await this.getById(id);
22164
+ const existingWorkspace = await this.#getById(this.#db.client, id);
21997
22165
  if (!existingWorkspace) throw new MastraError({
21998
22166
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND"),
21999
22167
  domain: ErrorDomain.STORAGE,
@@ -22006,7 +22174,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22006
22174
  const configFields = {};
22007
22175
  for (const [key, value] of Object.entries(rawConfigFields)) if (value !== void 0) configFields[key] = value;
22008
22176
  if (SNAPSHOT_FIELDS.some((field) => field in configFields)) {
22009
- const latestVersion = await this.getLatestVersion(id);
22177
+ const latestVersion = await this.#getLatestVersion(this.#db.client, id);
22010
22178
  if (!latestVersion) throw new MastraError({
22011
22179
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NO_VERSIONS"),
22012
22180
  domain: ErrorDomain.STORAGE,
@@ -22067,7 +22235,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22067
22235
  values.push(now);
22068
22236
  values.push(id);
22069
22237
  if (setClauses.length > 2 || versionCreated) await this.#db.client.none(`UPDATE ${tableName} SET ${setClauses.join(", ")} WHERE id = $${paramIndex}`, values);
22070
- const updatedWorkspace = await this.getById(id);
22238
+ const updatedWorkspace = await this.#getById(this.#db.client, id);
22071
22239
  if (!updatedWorkspace) throw new MastraError({
22072
22240
  id: createStorageErrorId("PG", "UPDATE_WORKSPACE", "NOT_FOUND_AFTER_UPDATE"),
22073
22241
  domain: ErrorDomain.STORAGE,
@@ -22132,7 +22300,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22132
22300
  queryParams.push(JSON.stringify(metadata));
22133
22301
  }
22134
22302
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
22135
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
22303
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} ${whereClause}`, queryParams);
22136
22304
  const total = parseInt(countResult.count, 10);
22137
22305
  if (total === 0) return {
22138
22306
  workspaces: [],
@@ -22143,7 +22311,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22143
22311
  };
22144
22312
  const limitValue = perPageInput === false ? total : perPage;
22145
22313
  return {
22146
- workspaces: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
22314
+ workspaces: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${field}" ${direction} LIMIT $${paramIdx++} OFFSET $${paramIdx++}`, [
22147
22315
  ...queryParams,
22148
22316
  limitValue,
22149
22317
  offset
@@ -22228,7 +22396,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22228
22396
  indexName: TABLE_WORKSPACE_VERSIONS,
22229
22397
  schemaName: getSchemaName$5(this.#schema)
22230
22398
  });
22231
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22399
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE id = $1`, [id]);
22232
22400
  if (!result) return null;
22233
22401
  return this.parseVersionRow(result);
22234
22402
  } catch (error) {
@@ -22247,7 +22415,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22247
22415
  indexName: TABLE_WORKSPACE_VERSIONS,
22248
22416
  schemaName: getSchemaName$5(this.#schema)
22249
22417
  });
22250
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 AND "versionNumber" = $2`, [workspaceId, versionNumber]);
22418
+ const result = await this.#db.readClient.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 AND "versionNumber" = $2`, [workspaceId, versionNumber]);
22251
22419
  if (!result) return null;
22252
22420
  return this.parseVersionRow(result);
22253
22421
  } catch (error) {
@@ -22264,12 +22432,19 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22264
22432
  }
22265
22433
  }
22266
22434
  async getLatestVersion(workspaceId) {
22435
+ return this.#getLatestVersion(this.#db.readClient, workspaceId);
22436
+ }
22437
+ /**
22438
+ * Same lookup against an explicit client. Mutation paths pass the writer so a
22439
+ * lagging read replica cannot yield stale or missing rows mid-update.
22440
+ */
22441
+ async #getLatestVersion(client, workspaceId) {
22267
22442
  try {
22268
22443
  const tableName = getTableName$5({
22269
22444
  indexName: TABLE_WORKSPACE_VERSIONS,
22270
22445
  schemaName: getSchemaName$5(this.#schema)
22271
22446
  });
22272
- const result = await this.#db.client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [workspaceId]);
22447
+ const result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "versionNumber" DESC LIMIT 1`, [workspaceId]);
22273
22448
  if (!result) return null;
22274
22449
  return this.parseVersionRow(result);
22275
22450
  } catch (error) {
@@ -22298,7 +22473,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22298
22473
  indexName: TABLE_WORKSPACE_VERSIONS,
22299
22474
  schemaName: getSchemaName$5(this.#schema)
22300
22475
  });
22301
- const countResult = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22476
+ const countResult = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22302
22477
  const total = parseInt(countResult.count, 10);
22303
22478
  if (total === 0) return {
22304
22479
  versions: [],
@@ -22309,7 +22484,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22309
22484
  };
22310
22485
  const limitValue = perPageInput === false ? total : perPage;
22311
22486
  return {
22312
- versions: (await this.#db.client.manyOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
22487
+ versions: (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "workspaceId" = $1 ORDER BY "${field}" ${direction} LIMIT $2 OFFSET $3`, [
22313
22488
  workspaceId,
22314
22489
  limitValue,
22315
22490
  offset
@@ -22379,7 +22554,7 @@ var WorkspacesPG = class WorkspacesPG extends WorkspacesStorage {
22379
22554
  indexName: TABLE_WORKSPACE_VERSIONS,
22380
22555
  schemaName: getSchemaName$5(this.#schema)
22381
22556
  });
22382
- const result = await this.#db.client.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22557
+ const result = await this.#db.readClient.one(`SELECT COUNT(*) as count FROM ${tableName} WHERE "workspaceId" = $1`, [workspaceId]);
22383
22558
  return parseInt(result.count, 10);
22384
22559
  } catch (error) {
22385
22560
  if (error instanceof MastraError) throw error;
@@ -22955,10 +23130,12 @@ function exportSchemas(schemaName) {
22955
23130
  * ```
22956
23131
  */
22957
23132
  var PostgresStore = class extends MastraCompositeStore {
22958
- #pool;
23133
+ #writePool;
23134
+ #readPool;
22959
23135
  #db;
22960
- #ownsPool;
22961
- #poolClosed = false;
23136
+ #readDb;
23137
+ #ownsWritePool;
23138
+ #writePoolClosed = false;
22962
23139
  schema;
22963
23140
  isInitialized = false;
22964
23141
  #initPromise = null;
@@ -22974,15 +23151,21 @@ var PostgresStore = class extends MastraCompositeStore {
22974
23151
  });
22975
23152
  this.schema = parseSqlIdentifier(config.schemaName || "public", "schema name");
22976
23153
  if (isPoolConfig(config)) {
22977
- this.#pool = config.pool;
22978
- this.#ownsPool = false;
23154
+ this.#writePool = config.pool;
23155
+ this.#ownsWritePool = false;
23156
+ } else if (isWritePoolConfig(config)) {
23157
+ this.#writePool = config.writePool;
23158
+ this.#ownsWritePool = false;
22979
23159
  } else {
22980
- this.#pool = this.createPool(config);
22981
- this.#ownsPool = true;
23160
+ this.#writePool = this.createPool(config);
23161
+ this.#ownsWritePool = true;
22982
23162
  }
22983
- this.#db = new RoutingDbClient(new PoolAdapter(this.#pool));
23163
+ this.#readPool = config.readPool ?? this.#writePool;
23164
+ this.#db = new RoutingDbClient(new PoolAdapter(this.#writePool));
23165
+ this.#readDb = this.#readPool === this.#writePool ? this.#db : new PoolAdapter(this.#readPool);
22984
23166
  const domainConfig = {
22985
23167
  client: this.#db,
23168
+ readClient: this.#readDb,
22986
23169
  schemaName: this.schema,
22987
23170
  skipDefaultIndexes: config.skipDefaultIndexes,
22988
23171
  indexes: config.indexes
@@ -23042,8 +23225,8 @@ var PostgresStore = class extends MastraCompositeStore {
23042
23225
  async #runPinnedInit() {
23043
23226
  let pinnedClient;
23044
23227
  try {
23045
- pinnedClient = await this.#pool.connect();
23046
- const pinned = new PinnedClientAdapter(this.#pool, pinnedClient);
23228
+ pinnedClient = await this.#writePool.connect();
23229
+ const pinned = new PinnedClientAdapter(this.#writePool, pinnedClient);
23047
23230
  this.#db.pin(pinned);
23048
23231
  this.#db.setSchemaSnapshot(await loadSchemaSnapshot(pinned, this.schema));
23049
23232
  await super.init();
@@ -23076,21 +23259,27 @@ var PostgresStore = class extends MastraCompositeStore {
23076
23259
  get db() {
23077
23260
  return this.#db;
23078
23261
  }
23079
- /**
23080
- * The underlying pg.Pool for direct database access or ORM integration.
23081
- */
23262
+ /** Database client for queries that may run against the configured read replica. */
23263
+ get readDb() {
23264
+ return this.#readDb;
23265
+ }
23266
+ /** The underlying writer pg.Pool for direct database access or ORM integration. */
23082
23267
  get pool() {
23083
- return this.#pool;
23268
+ return this.#writePool;
23269
+ }
23270
+ /** The underlying reader pg.Pool, falling back to the writer pool when unset. */
23271
+ get readPool() {
23272
+ return this.#readPool;
23084
23273
  }
23085
23274
  /**
23086
- * Closes the connection pool if it was created by this store.
23087
- * If a pool was passed in via config, it will not be closed.
23275
+ * Closes the writer connection pool if it was created by this store.
23276
+ * Caller-provided writer and reader pools are not closed.
23088
23277
  * Safe to call multiple times — subsequent calls are no-ops.
23089
23278
  */
23090
23279
  async close() {
23091
- if (this.#ownsPool && !this.#poolClosed) {
23092
- this.#poolClosed = true;
23093
- await this.#pool.end();
23280
+ if (this.#ownsWritePool && !this.#writePoolClosed) {
23281
+ this.#writePoolClosed = true;
23282
+ await this.#writePool.end();
23094
23283
  }
23095
23284
  }
23096
23285
  };