@mastra/pg 1.12.0-alpha.0 → 1.12.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
- import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, DATASETS_SCHEMA, TABLE_CONFIGS, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, ensureDate, safelyParseJSON, ExperimentsStorage, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, TABLE_FAVORITES, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, TraceStatus, getDefaultValue, transformScoreRow as transformScoreRow$1, getSqlType } from '@mastra/core/storage';
2
+ import { createVectorErrorId, AgentsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_SCHEMAS, createStorageErrorId, normalizePerPage, calculatePagination, BackgroundTasksStorage, TABLE_BACKGROUND_TASKS, BlobStore, TABLE_SKILL_BLOBS, ChannelsStorage, TABLE_CHANNEL_INSTALLATIONS, TABLE_CHANNEL_CONFIG, DatasetsStorage, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, DATASETS_SCHEMA, TABLE_CONFIGS, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, ensureDate, safelyParseJSON, ExperimentsStorage, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, FavoritesStorage, TABLE_FAVORITES, MCPClientsStorage, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, MCPServersStorage, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, MemoryStorage, TABLE_THREADS, TABLE_MESSAGES, TABLE_RESOURCES, NotificationsStorage, TABLE_NOTIFICATIONS, ObservabilityStorage, TABLE_SPANS, listTracesArgsSchema, toTraceSpans, PromptBlocksStorage, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, SchedulesStorage, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, ScorerDefinitionsStorage, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, ScoresStorage, TABLE_SCORERS, SkillsStorage, TABLE_SKILLS, TABLE_SKILL_VERSIONS, WorkflowsStorage, TABLE_WORKFLOW_SNAPSHOT, WorkspacesStorage, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, MastraCompositeStore, TraceStatus, getDefaultValue, transformScoreRow as transformScoreRow$1, getSqlType } from '@mastra/core/storage';
3
3
  import { parseSqlIdentifier, parseFieldKey } from '@mastra/core/utils';
4
4
  import { MastraVector, validateTopK, validateUpsertInput } from '@mastra/core/vector';
5
5
  import { Mutex } from 'async-mutex';
@@ -4375,10 +4375,10 @@ function rowToTask(row) {
4375
4375
  retryCount: Number(row.retry_count),
4376
4376
  maxRetries: Number(row.max_retries),
4377
4377
  timeoutMs: Number(row.timeout_ms),
4378
- createdAt: row.createdAt instanceof Date ? row.createdAt : new Date(row.createdAt),
4379
- startedAt: row.startedAt ? row.startedAt instanceof Date ? row.startedAt : new Date(row.startedAt) : void 0,
4380
- suspendedAt: row.suspendedAt ? row.suspendedAt instanceof Date ? row.suspendedAt : new Date(row.suspendedAt) : void 0,
4381
- completedAt: row.completedAt ? row.completedAt instanceof Date ? row.completedAt : new Date(row.completedAt) : void 0
4378
+ createdAt: new Date(row.createdAtZ || row.createdAt),
4379
+ startedAt: row.startedAtZ || row.startedAt ? new Date(row.startedAtZ || row.startedAt) : void 0,
4380
+ suspendedAt: row.suspendedAtZ || row.suspendedAt ? new Date(row.suspendedAtZ || row.suspendedAt) : void 0,
4381
+ completedAt: row.completedAtZ || row.completedAt ? new Date(row.completedAtZ || row.completedAt) : void 0
4382
4382
  };
4383
4383
  }
4384
4384
  var BackgroundTasksPG = class _BackgroundTasksPG extends BackgroundTasksStorage {
@@ -4528,15 +4528,21 @@ var BackgroundTasksPG = class _BackgroundTasksPG extends BackgroundTasksStorage
4528
4528
  }
4529
4529
  if ("startedAt" in update) {
4530
4530
  setClauses.push(`"startedAt" = $${paramIdx++}`);
4531
- params.push(update.startedAt?.toISOString() ?? null);
4531
+ setClauses.push(`"startedAtZ" = $${paramIdx++}`);
4532
+ const val = update.startedAt?.toISOString() ?? null;
4533
+ params.push(val, val);
4532
4534
  }
4533
4535
  if ("suspendedAt" in update) {
4534
4536
  setClauses.push(`"suspendedAt" = $${paramIdx++}`);
4535
- params.push(update.suspendedAt?.toISOString() ?? null);
4537
+ setClauses.push(`"suspendedAtZ" = $${paramIdx++}`);
4538
+ const val = update.suspendedAt?.toISOString() ?? null;
4539
+ params.push(val, val);
4536
4540
  }
4537
4541
  if ("completedAt" in update) {
4538
4542
  setClauses.push(`"completedAt" = $${paramIdx++}`);
4539
- params.push(update.completedAt?.toISOString() ?? null);
4543
+ setClauses.push(`"completedAtZ" = $${paramIdx++}`);
4544
+ const val = update.completedAt?.toISOString() ?? null;
4545
+ params.push(val, val);
4540
4546
  }
4541
4547
  if (setClauses.length === 0) return;
4542
4548
  const table = getTableName3(getSchemaName3(this.#schema));
@@ -4828,9 +4834,10 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4828
4834
  const schemaName = getSchemaName2(this.#schema);
4829
4835
  const tableName = getTableName2({ indexName: TABLE_CHANNEL_INSTALLATIONS, schemaName });
4830
4836
  const now = (/* @__PURE__ */ new Date()).toISOString();
4837
+ const createdAt = installation.createdAt?.toISOString() ?? now;
4831
4838
  await this.#db.client.none(
4832
- `INSERT INTO ${tableName} ("id", "platform", "agentId", "status", "webhookId", "data", "configHash", "error", "createdAt", "updatedAt")
4833
- VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8, $9, $10)
4839
+ `INSERT INTO ${tableName} ("id", "platform", "agentId", "status", "webhookId", "data", "configHash", "error", "createdAt", "createdAtZ", "updatedAt", "updatedAtZ")
4840
+ VALUES ($1, $2, $3, $4, $5, $6::jsonb, $7, $8, $9, $10, $11, $12)
4834
4841
  ON CONFLICT ("id") DO UPDATE SET
4835
4842
  "platform" = EXCLUDED."platform",
4836
4843
  "agentId" = EXCLUDED."agentId",
@@ -4839,7 +4846,8 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4839
4846
  "data" = EXCLUDED."data",
4840
4847
  "configHash" = EXCLUDED."configHash",
4841
4848
  "error" = EXCLUDED."error",
4842
- "updatedAt" = EXCLUDED."updatedAt"`,
4849
+ "updatedAt" = EXCLUDED."updatedAt",
4850
+ "updatedAtZ" = EXCLUDED."updatedAtZ"`,
4843
4851
  [
4844
4852
  installation.id,
4845
4853
  installation.platform,
@@ -4849,7 +4857,9 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4849
4857
  JSON.stringify(installation.data),
4850
4858
  installation.configHash ?? null,
4851
4859
  installation.error ?? null,
4852
- installation.createdAt?.toISOString() ?? now,
4860
+ createdAt,
4861
+ createdAt,
4862
+ now,
4853
4863
  now
4854
4864
  ]
4855
4865
  );
@@ -4892,13 +4902,15 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4892
4902
  async saveConfig(config) {
4893
4903
  const schemaName = getSchemaName2(this.#schema);
4894
4904
  const tableName = getTableName2({ indexName: TABLE_CHANNEL_CONFIG, schemaName });
4905
+ const now = config.updatedAt.toISOString();
4895
4906
  await this.#db.client.none(
4896
- `INSERT INTO ${tableName} ("platform", "data", "updatedAt")
4897
- VALUES ($1, $2::jsonb, $3)
4907
+ `INSERT INTO ${tableName} ("platform", "data", "updatedAt", "updatedAtZ")
4908
+ VALUES ($1, $2::jsonb, $3, $4)
4898
4909
  ON CONFLICT ("platform") DO UPDATE SET
4899
4910
  "data" = EXCLUDED."data",
4900
- "updatedAt" = EXCLUDED."updatedAt"`,
4901
- [config.platform, JSON.stringify(config.data), config.updatedAt.toISOString()]
4911
+ "updatedAt" = EXCLUDED."updatedAt",
4912
+ "updatedAtZ" = EXCLUDED."updatedAtZ"`,
4913
+ [config.platform, JSON.stringify(config.data), now, now]
4902
4914
  );
4903
4915
  }
4904
4916
  async getConfig(platform) {
@@ -4909,7 +4921,7 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4909
4921
  return {
4910
4922
  platform: row.platform,
4911
4923
  data: typeof row.data === "string" ? JSON.parse(row.data) : row.data,
4912
- updatedAt: new Date(row.updatedAt)
4924
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
4913
4925
  };
4914
4926
  }
4915
4927
  async deleteConfig(platform) {
@@ -4927,8 +4939,8 @@ var ChannelsPG = class _ChannelsPG extends ChannelsStorage {
4927
4939
  data: typeof row.data === "string" ? JSON.parse(row.data) : row.data,
4928
4940
  configHash: row.configHash || void 0,
4929
4941
  error: row.error || void 0,
4930
- createdAt: row.createdAt instanceof Date ? row.createdAt : new Date(row.createdAt),
4931
- updatedAt: row.updatedAt instanceof Date ? row.updatedAt : new Date(row.updatedAt)
4942
+ createdAt: new Date(row.createdAtZ || row.createdAt),
4943
+ updatedAt: new Date(row.updatedAtZ || row.updatedAt)
4932
4944
  };
4933
4945
  }
4934
4946
  };
@@ -10389,6 +10401,348 @@ ${unreflectedContent}` : bufferedReflection;
10389
10401
  }
10390
10402
  }
10391
10403
  };
10404
+ var statusTimestamp = (status, now) => {
10405
+ if (status === "delivered") return { deliveredAt: now };
10406
+ if (status === "seen") return { seenAt: now };
10407
+ if (status === "dismissed") return { dismissedAt: now };
10408
+ if (status === "archived") return { archivedAt: now };
10409
+ if (status === "discarded") return { discardedAt: now };
10410
+ return {};
10411
+ };
10412
+ var parseDate = (value) => {
10413
+ if (value == null) return void 0;
10414
+ return value instanceof Date ? value : new Date(String(value));
10415
+ };
10416
+ var cloneValue = (value) => value === void 0 ? void 0 : structuredClone(value);
10417
+ function rowToNotification(row) {
10418
+ return {
10419
+ id: String(row.id),
10420
+ threadId: String(row.threadId),
10421
+ source: String(row.source),
10422
+ kind: String(row.kind),
10423
+ priority: String(row.priority),
10424
+ status: String(row.status),
10425
+ summary: String(row.summary),
10426
+ payload: parseJsonResilient(row.payload),
10427
+ resourceId: row.resourceId == null ? void 0 : String(row.resourceId),
10428
+ agentId: row.agentId == null ? void 0 : String(row.agentId),
10429
+ sourceId: row.sourceId == null ? void 0 : String(row.sourceId),
10430
+ dedupeKey: row.dedupeKey == null ? void 0 : String(row.dedupeKey),
10431
+ coalesceKey: row.coalesceKey == null ? void 0 : String(row.coalesceKey),
10432
+ coalescedCount: Number(row.coalescedCount ?? 1),
10433
+ attributes: parseJsonResilient(row.attributes),
10434
+ createdAt: parseDate(row.createdAt) ?? /* @__PURE__ */ new Date(),
10435
+ updatedAt: parseDate(row.updatedAt) ?? /* @__PURE__ */ new Date(),
10436
+ deliveredAt: parseDate(row.deliveredAt),
10437
+ seenAt: parseDate(row.seenAt),
10438
+ dismissedAt: parseDate(row.dismissedAt),
10439
+ archivedAt: parseDate(row.archivedAt),
10440
+ discardedAt: parseDate(row.discardedAt),
10441
+ deliverAt: parseDate(row.deliverAt),
10442
+ summaryAt: parseDate(row.summaryAt),
10443
+ deliveryReason: row.deliveryReason == null ? void 0 : String(row.deliveryReason),
10444
+ deliveryAttempts: Number(row.deliveryAttempts ?? 0),
10445
+ lastDeliveryAttemptAt: parseDate(row.lastDeliveryAttemptAt),
10446
+ lastDeliveryError: row.lastDeliveryError == null ? void 0 : String(row.lastDeliveryError),
10447
+ deliveredSignalId: row.deliveredSignalId == null ? void 0 : String(row.deliveredSignalId),
10448
+ summarySignalId: row.summarySignalId == null ? void 0 : String(row.summarySignalId),
10449
+ metadata: parseJsonResilient(row.metadata)
10450
+ };
10451
+ }
10452
+ function addArrayFilter(conditions, args, column, value) {
10453
+ if (!value) return;
10454
+ const values = Array.isArray(value) ? value : [value];
10455
+ const start = args.length + 1;
10456
+ conditions.push(`"${column}" IN (${values.map((_, index) => `$${start + index}`).join(", ")})`);
10457
+ args.push(...values);
10458
+ }
10459
+ function normalizeRecordForInsert(record) {
10460
+ return {
10461
+ ...record,
10462
+ payload: record.payload ?? null,
10463
+ attributes: record.attributes ?? null,
10464
+ metadata: record.metadata ?? null,
10465
+ resourceId: record.resourceId ?? null,
10466
+ agentId: record.agentId ?? null,
10467
+ sourceId: record.sourceId ?? null,
10468
+ dedupeKey: record.dedupeKey ?? null,
10469
+ coalesceKey: record.coalesceKey ?? null,
10470
+ deliveredAt: record.deliveredAt ?? null,
10471
+ seenAt: record.seenAt ?? null,
10472
+ dismissedAt: record.dismissedAt ?? null,
10473
+ archivedAt: record.archivedAt ?? null,
10474
+ discardedAt: record.discardedAt ?? null,
10475
+ deliverAt: record.deliverAt ?? null,
10476
+ summaryAt: record.summaryAt ?? null,
10477
+ deliveryReason: record.deliveryReason ?? null,
10478
+ lastDeliveryAttemptAt: record.lastDeliveryAttemptAt ?? null,
10479
+ lastDeliveryError: record.lastDeliveryError ?? null,
10480
+ deliveredSignalId: record.deliveredSignalId ?? null,
10481
+ summarySignalId: record.summarySignalId ?? null
10482
+ };
10483
+ }
10484
+ var NotificationsPG = class _NotificationsPG extends NotificationsStorage {
10485
+ #db;
10486
+ #schema;
10487
+ #skipDefaultIndexes;
10488
+ #indexes;
10489
+ static MANAGED_TABLES = [TABLE_NOTIFICATIONS];
10490
+ constructor(config) {
10491
+ super();
10492
+ const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
10493
+ this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
10494
+ this.#schema = schemaName || "public";
10495
+ this.#skipDefaultIndexes = skipDefaultIndexes;
10496
+ this.#indexes = indexes?.filter((idx) => _NotificationsPG.MANAGED_TABLES.includes(idx.table));
10497
+ }
10498
+ async init() {
10499
+ await this.#db.createTable({
10500
+ tableName: TABLE_NOTIFICATIONS,
10501
+ schema: TABLE_SCHEMAS[TABLE_NOTIFICATIONS]
10502
+ });
10503
+ await this.createDefaultIndexes();
10504
+ await this.createCustomIndexes();
10505
+ }
10506
+ static getDefaultIndexDefs(schemaPrefix) {
10507
+ return [
10508
+ {
10509
+ name: `${schemaPrefix}idx_notifications_thread_status_updated`,
10510
+ table: TABLE_NOTIFICATIONS,
10511
+ columns: ["threadId", "status", "updatedAt"]
10512
+ },
10513
+ {
10514
+ name: `${schemaPrefix}idx_notifications_coalescing`,
10515
+ table: TABLE_NOTIFICATIONS,
10516
+ columns: ["threadId", "source", "kind", "status", "agentId", "resourceId", "dedupeKey", "coalesceKey"]
10517
+ },
10518
+ {
10519
+ name: `${schemaPrefix}idx_notifications_due`,
10520
+ table: TABLE_NOTIFICATIONS,
10521
+ columns: ["status", "deliverAt", "summaryAt"]
10522
+ }
10523
+ ];
10524
+ }
10525
+ static getExportDDL(schemaName) {
10526
+ const statements = [];
10527
+ const parsedSchema = schemaName ? parseSqlIdentifier(schemaName, "schema name") : "";
10528
+ const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
10529
+ statements.push(
10530
+ generateTableSQL({
10531
+ tableName: TABLE_NOTIFICATIONS,
10532
+ schema: TABLE_SCHEMAS[TABLE_NOTIFICATIONS],
10533
+ schemaName,
10534
+ includeAllConstraints: true
10535
+ })
10536
+ );
10537
+ for (const idx of _NotificationsPG.getDefaultIndexDefs(schemaPrefix)) {
10538
+ statements.push(generateIndexSQL(idx, schemaName));
10539
+ }
10540
+ return statements;
10541
+ }
10542
+ getDefaultIndexDefinitions() {
10543
+ const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
10544
+ return _NotificationsPG.getDefaultIndexDefs(schemaPrefix);
10545
+ }
10546
+ async createDefaultIndexes() {
10547
+ if (this.#skipDefaultIndexes) return;
10548
+ for (const indexDef of this.getDefaultIndexDefinitions()) {
10549
+ try {
10550
+ await this.#db.createIndex(indexDef);
10551
+ } catch (error) {
10552
+ this.logger?.warn?.(`Failed to create index ${indexDef.name}:`, error);
10553
+ }
10554
+ }
10555
+ }
10556
+ async createCustomIndexes() {
10557
+ if (!this.#indexes || this.#indexes.length === 0) return;
10558
+ for (const indexDef of this.#indexes) {
10559
+ try {
10560
+ await this.#db.createIndex(indexDef);
10561
+ } catch (error) {
10562
+ this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
10563
+ }
10564
+ }
10565
+ }
10566
+ async dangerouslyClearAll() {
10567
+ await this.#db.clearTable({ tableName: TABLE_NOTIFICATIONS });
10568
+ }
10569
+ async updateNotificationRow(threadId, id, data) {
10570
+ const entries = Object.entries(data).filter(([, value]) => value !== void 0);
10571
+ if (entries.length === 0) return;
10572
+ const schemaName = getSchemaName2(this.#schema);
10573
+ const tableName = getTableName2({ indexName: TABLE_NOTIFICATIONS, schemaName });
10574
+ const setColumns = entries.map(([key], index) => `"${parseSqlIdentifier(key, "column name")}" = $${index + 1}`);
10575
+ const values = entries.map(([key, value]) => {
10576
+ const columnSchema = TABLE_SCHEMAS[TABLE_NOTIFICATIONS][key];
10577
+ if (columnSchema?.type === "jsonb" && value !== null) return JSON.stringify(value);
10578
+ return value;
10579
+ });
10580
+ await this.#db.client.none(
10581
+ `UPDATE ${tableName} SET ${setColumns.join(", ")} WHERE "threadId" = $${values.length + 1} AND "id" = $${values.length + 2}`,
10582
+ [...values, threadId, id]
10583
+ );
10584
+ }
10585
+ async createNotification(input) {
10586
+ const existing = await this.findCoalescable(input);
10587
+ if (existing) {
10588
+ const now2 = /* @__PURE__ */ new Date();
10589
+ const attributes = input.attributes ? { ...cloneValue(existing.attributes), ...cloneValue(input.attributes) } : cloneValue(existing.attributes);
10590
+ const metadata = input.metadata ? { ...cloneValue(existing.metadata), ...cloneValue(input.metadata) } : cloneValue(existing.metadata);
10591
+ await this.updateNotificationRow(existing.threadId, existing.id, {
10592
+ summary: input.summary,
10593
+ payload: cloneValue(input.payload ?? existing.payload) ?? null,
10594
+ priority: input.priority ?? existing.priority,
10595
+ attributes: attributes ?? null,
10596
+ updatedAt: now2,
10597
+ deliverAt: input.deliverAt ?? existing.deliverAt ?? null,
10598
+ summaryAt: input.summaryAt ?? existing.summaryAt ?? null,
10599
+ deliveryReason: input.deliveryReason ?? existing.deliveryReason ?? null,
10600
+ coalescedCount: (existing.coalescedCount ?? 1) + 1,
10601
+ metadata: metadata ?? null
10602
+ });
10603
+ const updated = await this.getNotification({ threadId: existing.threadId, id: existing.id });
10604
+ if (!updated) throw new Error(`Notification ${existing.id} was not found for thread ${existing.threadId}`);
10605
+ return updated;
10606
+ }
10607
+ const now = input.createdAt ?? /* @__PURE__ */ new Date();
10608
+ const record = {
10609
+ id: input.id ?? randomUUID(),
10610
+ threadId: input.threadId,
10611
+ source: input.source,
10612
+ kind: input.kind,
10613
+ priority: input.priority ?? "medium",
10614
+ status: "pending",
10615
+ summary: input.summary,
10616
+ payload: cloneValue(input.payload),
10617
+ resourceId: input.resourceId,
10618
+ agentId: input.agentId,
10619
+ sourceId: input.sourceId,
10620
+ dedupeKey: input.dedupeKey,
10621
+ coalesceKey: input.coalesceKey,
10622
+ coalescedCount: 1,
10623
+ attributes: cloneValue(input.attributes),
10624
+ createdAt: now,
10625
+ updatedAt: now,
10626
+ deliverAt: input.deliverAt,
10627
+ summaryAt: input.summaryAt,
10628
+ deliveryReason: input.deliveryReason,
10629
+ deliveryAttempts: 0,
10630
+ metadata: cloneValue(input.metadata)
10631
+ };
10632
+ await this.#db.insert({ tableName: TABLE_NOTIFICATIONS, record: normalizeRecordForInsert(record) });
10633
+ return record;
10634
+ }
10635
+ async listNotifications(input) {
10636
+ const conditions = ['"threadId" = $1'];
10637
+ const args = [input.threadId];
10638
+ addArrayFilter(conditions, args, "status", input.status);
10639
+ addArrayFilter(conditions, args, "priority", input.priority);
10640
+ if (input.source) {
10641
+ args.push(input.source);
10642
+ conditions.push(`"source" = $${args.length}`);
10643
+ }
10644
+ if (input.resourceId) {
10645
+ args.push(input.resourceId);
10646
+ conditions.push(`"resourceId" = $${args.length}`);
10647
+ }
10648
+ if (input.agentId) {
10649
+ args.push(input.agentId);
10650
+ conditions.push(`"agentId" = $${args.length}`);
10651
+ }
10652
+ if (input.search) {
10653
+ const search = `%${input.search.toLowerCase()}%`;
10654
+ args.push(search, search);
10655
+ conditions.push(`(LOWER("summary") LIKE $${args.length - 1} OR LOWER("kind") LIKE $${args.length})`);
10656
+ }
10657
+ const limit = input.limit ? ` LIMIT $${args.length + 1}` : "";
10658
+ if (input.limit) args.push(input.limit);
10659
+ const schemaName = getSchemaName2(this.#schema);
10660
+ const tableName = getTableName2({ indexName: TABLE_NOTIFICATIONS, schemaName });
10661
+ const rows = await this.#db.client.manyOrNone(
10662
+ `SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`,
10663
+ args
10664
+ );
10665
+ return rows.map((row) => rowToNotification(row));
10666
+ }
10667
+ async listDueNotifications(input) {
10668
+ const conditions = [
10669
+ '"status" = $1',
10670
+ '(("deliverAt" IS NOT NULL AND "deliverAt" <= $2) OR ("summaryAt" IS NOT NULL AND "summaryAt" <= $3))'
10671
+ ];
10672
+ const args = ["pending", input.now, input.now];
10673
+ if (input.agentId) {
10674
+ args.push(input.agentId);
10675
+ conditions.push(`"agentId" = $${args.length}`);
10676
+ }
10677
+ if (input.resourceId) {
10678
+ args.push(input.resourceId);
10679
+ conditions.push(`"resourceId" = $${args.length}`);
10680
+ }
10681
+ const limit = input.limit ? ` LIMIT $${args.length + 1}` : "";
10682
+ if (input.limit) args.push(input.limit);
10683
+ const schemaName = getSchemaName2(this.#schema);
10684
+ const tableName = getTableName2({ indexName: TABLE_NOTIFICATIONS, schemaName });
10685
+ const rows = await this.#db.client.manyOrNone(
10686
+ `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}`,
10687
+ args
10688
+ );
10689
+ return rows.map((row) => rowToNotification(row));
10690
+ }
10691
+ async getNotification(input) {
10692
+ const schemaName = getSchemaName2(this.#schema);
10693
+ const tableName = getTableName2({ indexName: TABLE_NOTIFICATIONS, schemaName });
10694
+ const row = await this.#db.client.oneOrNone(
10695
+ `SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`,
10696
+ [input.threadId, input.id]
10697
+ );
10698
+ return row ? rowToNotification(row) : null;
10699
+ }
10700
+ async updateNotification(input) {
10701
+ const existing = await this.getNotification({ threadId: input.threadId, id: input.id });
10702
+ if (!existing) {
10703
+ throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
10704
+ }
10705
+ const now = /* @__PURE__ */ new Date();
10706
+ await this.updateNotificationRow(input.threadId, input.id, {
10707
+ ...input.status ? { status: input.status, ...statusTimestamp(input.status, now) } : {},
10708
+ ...input.summary !== void 0 ? { summary: input.summary } : {},
10709
+ ...input.payload !== void 0 ? { payload: cloneValue(input.payload) } : {},
10710
+ ...input.attributes !== void 0 ? { attributes: cloneValue(input.attributes) } : {},
10711
+ ...input.metadata !== void 0 ? { metadata: cloneValue(input.metadata) } : {},
10712
+ ...input.deliverAt !== void 0 ? { deliverAt: input.deliverAt } : {},
10713
+ ...input.summaryAt !== void 0 ? { summaryAt: input.summaryAt } : {},
10714
+ ...input.deliveryReason !== void 0 ? { deliveryReason: input.deliveryReason } : {},
10715
+ ...input.deliveryAttempts !== void 0 ? { deliveryAttempts: input.deliveryAttempts } : {},
10716
+ ...input.lastDeliveryAttemptAt !== void 0 ? { lastDeliveryAttemptAt: input.lastDeliveryAttemptAt } : {},
10717
+ ...input.lastDeliveryError !== void 0 ? { lastDeliveryError: input.lastDeliveryError } : {},
10718
+ ...input.deliveredSignalId !== void 0 ? { deliveredSignalId: input.deliveredSignalId } : {},
10719
+ ...input.summarySignalId !== void 0 ? { summarySignalId: input.summarySignalId } : {},
10720
+ updatedAt: now
10721
+ });
10722
+ const updated = await this.getNotification({ threadId: input.threadId, id: input.id });
10723
+ if (!updated) throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
10724
+ return updated;
10725
+ }
10726
+ async findCoalescable(input) {
10727
+ if (!input.dedupeKey && !input.coalesceKey) return void 0;
10728
+ const schemaName = getSchemaName2(this.#schema);
10729
+ const tableName = getTableName2({ indexName: TABLE_NOTIFICATIONS, schemaName });
10730
+ const row = await this.#db.client.oneOrNone(
10731
+ `SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "source" = $2 AND "kind" = $3 AND "status" = $4 AND (("agentId" = $5::text) OR ("agentId" IS NULL AND $5::text IS NULL)) AND (("resourceId" = $6::text) OR ("resourceId" IS NULL AND $6::text IS NULL)) AND (($7::text IS NOT NULL AND "dedupeKey" = $7::text) OR ($8::text IS NOT NULL AND "coalesceKey" = $8::text)) ORDER BY "updatedAt" DESC LIMIT 1`,
10732
+ [
10733
+ input.threadId,
10734
+ input.source,
10735
+ input.kind,
10736
+ "pending",
10737
+ input.agentId ?? null,
10738
+ input.resourceId ?? null,
10739
+ input.dedupeKey ?? null,
10740
+ input.coalesceKey ?? null
10741
+ ]
10742
+ );
10743
+ return row ? rowToNotification(row) : void 0;
10744
+ }
10745
+ };
10392
10746
  var ObservabilityPG = class _ObservabilityPG extends ObservabilityStorage {
10393
10747
  #db;
10394
10748
  #schema;
@@ -14968,6 +15322,7 @@ var DEFAULT_MAX_CONNECTIONS = 20;
14968
15322
  var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
14969
15323
  var ALL_DOMAINS = [
14970
15324
  MemoryPG,
15325
+ NotificationsPG,
14971
15326
  ObservabilityPG,
14972
15327
  ScoresPG,
14973
15328
  ScorerDefinitionsPG,
@@ -15023,6 +15378,7 @@ var PostgresStore = class extends MastraCompositeStore {
15023
15378
  scores: new ScoresPG(domainConfig),
15024
15379
  workflows: new WorkflowsPG(domainConfig),
15025
15380
  memory: new MemoryPG(domainConfig),
15381
+ notifications: new NotificationsPG(domainConfig),
15026
15382
  observability: new ObservabilityPG(domainConfig),
15027
15383
  agents: new AgentsPG(domainConfig),
15028
15384
  promptBlocks: new PromptBlocksPG(domainConfig),
@@ -15226,6 +15582,6 @@ Example Complex Query:
15226
15582
  ]
15227
15583
  }`;
15228
15584
 
15229
- export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PoolAdapter, PostgresStore, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, WorkflowsPG, WorkspacesPG, exportSchemas };
15585
+ export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, NotificationsPG, ObservabilityPG, PGVECTOR_PROMPT, PgVector, PoolAdapter, PostgresStore, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, WorkflowsPG, WorkspacesPG, exportSchemas };
15230
15586
  //# sourceMappingURL=index.js.map
15231
15587
  //# sourceMappingURL=index.js.map