@mastra/pg 1.12.0 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-working-memory.md +27 -0
- package/dist/docs/references/reference-storage-postgresql.md +3 -0
- package/dist/index.cjs +345 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +346 -2
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/notifications/index.d.ts +26 -0
- package/dist/storage/domains/notifications/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +2 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @mastra/pg
|
|
2
2
|
|
|
3
|
+
## 1.12.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Added notification inbox storage support for Postgres stores. ([#17241](https://github.com/mastra-ai/mastra/pull/17241))
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { PostgresStore } from '@mastra/pg';
|
|
11
|
+
|
|
12
|
+
const storage = new PostgresStore({ connectionString: process.env.POSTGRES_URL! });
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Agents using this store can persist thread-scoped notification inbox records for notification signals.
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
18
|
+
- @mastra/core@1.39.0
|
|
19
|
+
|
|
20
|
+
## 1.12.1-alpha.0
|
|
21
|
+
|
|
22
|
+
### Patch Changes
|
|
23
|
+
|
|
24
|
+
- Added notification inbox storage support for Postgres stores. ([#17241](https://github.com/mastra-ai/mastra/pull/17241))
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { PostgresStore } from '@mastra/pg';
|
|
28
|
+
|
|
29
|
+
const storage = new PostgresStore({ connectionString: process.env.POSTGRES_URL! });
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Agents using this store can persist thread-scoped notification inbox records for notification signals.
|
|
33
|
+
|
|
34
|
+
- Updated dependencies [[`c973db4`](https://github.com/mastra-ai/mastra/commit/c973db428df1b564ff0c35d4b2a90e8f4f1e13fd), [`552285e`](https://github.com/mastra-ai/mastra/commit/552285e5af43cfc680a0972032cab8de8776c6a0), [`77e686c`](https://github.com/mastra-ai/mastra/commit/77e686c264e493e99ae5024e4dfe3ea5d5a09718), [`ece8dba`](https://github.com/mastra-ai/mastra/commit/ece8dba7ec1a5089eee8c33167cd762bfa91e509), [`e751af2`](https://github.com/mastra-ai/mastra/commit/e751af219433fbf4c7035b2d771b4c9ec8813b05), [`e2a8380`](https://github.com/mastra-ai/mastra/commit/e2a838017a7657850404c1e94c70d79ffdc6f14a), [`be3f1cd`](https://github.com/mastra-ai/mastra/commit/be3f1cd81f0e2a649e8eac15a024d542d814aef8), [`a34d9db`](https://github.com/mastra-ai/mastra/commit/a34d9dbc39fedb722f271318e9355ecee70489ab)]:
|
|
35
|
+
- @mastra/core@1.39.0-alpha.0
|
|
36
|
+
|
|
3
37
|
## 1.12.0
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
package/dist/docs/SKILL.md
CHANGED
|
@@ -393,6 +393,33 @@ const response = await agent.generate('What do you know about me?', {
|
|
|
393
393
|
})
|
|
394
394
|
```
|
|
395
395
|
|
|
396
|
+
## Opt in to state signals (experimental)
|
|
397
|
+
|
|
398
|
+
By default, working memory reaches the model as part of the system message. You can opt into delivering it as a [state signal](https://mastra.ai/docs/agents/signals) instead by setting `useStateSignals: true`:
|
|
399
|
+
|
|
400
|
+
```typescript
|
|
401
|
+
const memory = new Memory({
|
|
402
|
+
storage: new LibSQLStore({ url: 'file:./mastra.db' }),
|
|
403
|
+
options: {
|
|
404
|
+
workingMemory: {
|
|
405
|
+
enabled: true,
|
|
406
|
+
template: '# User\n- name:\n- location:',
|
|
407
|
+
useStateSignals: true, // experimental: deliver as state signal
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
})
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
What changes:
|
|
414
|
+
|
|
415
|
+
- **Storage is identical.** The same resource/thread `workingMemory` field is read and written.
|
|
416
|
+
- **The tool is the same shape, exposed under a new name.** Writes still flow through the same underlying tool; on this path it is registered as `setWorkingMemory` (instead of `updateWorkingMemory`). The rename keeps legacy strip filters from removing tool-call parts so they persist as a normal audit trail and the next model step picks the new value up automatically.
|
|
417
|
+
- **Delivery only.** Instead of folding into the system prompt, `Memory` auto-attaches a `WorkingMemoryStateProcessor` that emits the current working memory as a `state` signal with `stateId: 'working-memory'`.
|
|
418
|
+
|
|
419
|
+
You inherit the standard state-signal benefits: thread-scoped tracking metadata, `cacheKey` dedup so identical snapshots are only emitted once, and `contextWindow.hasSnapshot` re-injection when an older snapshot rolls out of the window.
|
|
420
|
+
|
|
421
|
+
The default (`useStateSignals: false`) keeps the existing system-message behavior unchanged. `useStateSignals` is not supported with template working memory `version: 'vnext'`.
|
|
422
|
+
|
|
396
423
|
## Examples
|
|
397
424
|
|
|
398
425
|
- [Working memory with template](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-template)
|
|
@@ -132,6 +132,9 @@ The storage implementation handles schema creation and updates automatically. It
|
|
|
132
132
|
- `mastra_traces`: Stores telemetry and tracing data
|
|
133
133
|
- `mastra_scorers`: Stores scoring and evaluation data
|
|
134
134
|
- `mastra_resources`: Stores resource working memory data
|
|
135
|
+
- `mastra_notifications`: Stores notification inbox records and delivery metadata
|
|
136
|
+
|
|
137
|
+
`PostgresStore` exposes notification storage through `getStore('notifications')`.
|
|
135
138
|
|
|
136
139
|
### Observability
|
|
137
140
|
|
package/dist/index.cjs
CHANGED
|
@@ -10426,6 +10426,348 @@ ${unreflectedContent}` : bufferedReflection;
|
|
|
10426
10426
|
}
|
|
10427
10427
|
}
|
|
10428
10428
|
};
|
|
10429
|
+
var statusTimestamp = (status, now) => {
|
|
10430
|
+
if (status === "delivered") return { deliveredAt: now };
|
|
10431
|
+
if (status === "seen") return { seenAt: now };
|
|
10432
|
+
if (status === "dismissed") return { dismissedAt: now };
|
|
10433
|
+
if (status === "archived") return { archivedAt: now };
|
|
10434
|
+
if (status === "discarded") return { discardedAt: now };
|
|
10435
|
+
return {};
|
|
10436
|
+
};
|
|
10437
|
+
var parseDate = (value) => {
|
|
10438
|
+
if (value == null) return void 0;
|
|
10439
|
+
return value instanceof Date ? value : new Date(String(value));
|
|
10440
|
+
};
|
|
10441
|
+
var cloneValue = (value) => value === void 0 ? void 0 : structuredClone(value);
|
|
10442
|
+
function rowToNotification(row) {
|
|
10443
|
+
return {
|
|
10444
|
+
id: String(row.id),
|
|
10445
|
+
threadId: String(row.threadId),
|
|
10446
|
+
source: String(row.source),
|
|
10447
|
+
kind: String(row.kind),
|
|
10448
|
+
priority: String(row.priority),
|
|
10449
|
+
status: String(row.status),
|
|
10450
|
+
summary: String(row.summary),
|
|
10451
|
+
payload: parseJsonResilient(row.payload),
|
|
10452
|
+
resourceId: row.resourceId == null ? void 0 : String(row.resourceId),
|
|
10453
|
+
agentId: row.agentId == null ? void 0 : String(row.agentId),
|
|
10454
|
+
sourceId: row.sourceId == null ? void 0 : String(row.sourceId),
|
|
10455
|
+
dedupeKey: row.dedupeKey == null ? void 0 : String(row.dedupeKey),
|
|
10456
|
+
coalesceKey: row.coalesceKey == null ? void 0 : String(row.coalesceKey),
|
|
10457
|
+
coalescedCount: Number(row.coalescedCount ?? 1),
|
|
10458
|
+
attributes: parseJsonResilient(row.attributes),
|
|
10459
|
+
createdAt: parseDate(row.createdAt) ?? /* @__PURE__ */ new Date(),
|
|
10460
|
+
updatedAt: parseDate(row.updatedAt) ?? /* @__PURE__ */ new Date(),
|
|
10461
|
+
deliveredAt: parseDate(row.deliveredAt),
|
|
10462
|
+
seenAt: parseDate(row.seenAt),
|
|
10463
|
+
dismissedAt: parseDate(row.dismissedAt),
|
|
10464
|
+
archivedAt: parseDate(row.archivedAt),
|
|
10465
|
+
discardedAt: parseDate(row.discardedAt),
|
|
10466
|
+
deliverAt: parseDate(row.deliverAt),
|
|
10467
|
+
summaryAt: parseDate(row.summaryAt),
|
|
10468
|
+
deliveryReason: row.deliveryReason == null ? void 0 : String(row.deliveryReason),
|
|
10469
|
+
deliveryAttempts: Number(row.deliveryAttempts ?? 0),
|
|
10470
|
+
lastDeliveryAttemptAt: parseDate(row.lastDeliveryAttemptAt),
|
|
10471
|
+
lastDeliveryError: row.lastDeliveryError == null ? void 0 : String(row.lastDeliveryError),
|
|
10472
|
+
deliveredSignalId: row.deliveredSignalId == null ? void 0 : String(row.deliveredSignalId),
|
|
10473
|
+
summarySignalId: row.summarySignalId == null ? void 0 : String(row.summarySignalId),
|
|
10474
|
+
metadata: parseJsonResilient(row.metadata)
|
|
10475
|
+
};
|
|
10476
|
+
}
|
|
10477
|
+
function addArrayFilter(conditions, args, column, value) {
|
|
10478
|
+
if (!value) return;
|
|
10479
|
+
const values = Array.isArray(value) ? value : [value];
|
|
10480
|
+
const start = args.length + 1;
|
|
10481
|
+
conditions.push(`"${column}" IN (${values.map((_, index) => `$${start + index}`).join(", ")})`);
|
|
10482
|
+
args.push(...values);
|
|
10483
|
+
}
|
|
10484
|
+
function normalizeRecordForInsert(record) {
|
|
10485
|
+
return {
|
|
10486
|
+
...record,
|
|
10487
|
+
payload: record.payload ?? null,
|
|
10488
|
+
attributes: record.attributes ?? null,
|
|
10489
|
+
metadata: record.metadata ?? null,
|
|
10490
|
+
resourceId: record.resourceId ?? null,
|
|
10491
|
+
agentId: record.agentId ?? null,
|
|
10492
|
+
sourceId: record.sourceId ?? null,
|
|
10493
|
+
dedupeKey: record.dedupeKey ?? null,
|
|
10494
|
+
coalesceKey: record.coalesceKey ?? null,
|
|
10495
|
+
deliveredAt: record.deliveredAt ?? null,
|
|
10496
|
+
seenAt: record.seenAt ?? null,
|
|
10497
|
+
dismissedAt: record.dismissedAt ?? null,
|
|
10498
|
+
archivedAt: record.archivedAt ?? null,
|
|
10499
|
+
discardedAt: record.discardedAt ?? null,
|
|
10500
|
+
deliverAt: record.deliverAt ?? null,
|
|
10501
|
+
summaryAt: record.summaryAt ?? null,
|
|
10502
|
+
deliveryReason: record.deliveryReason ?? null,
|
|
10503
|
+
lastDeliveryAttemptAt: record.lastDeliveryAttemptAt ?? null,
|
|
10504
|
+
lastDeliveryError: record.lastDeliveryError ?? null,
|
|
10505
|
+
deliveredSignalId: record.deliveredSignalId ?? null,
|
|
10506
|
+
summarySignalId: record.summarySignalId ?? null
|
|
10507
|
+
};
|
|
10508
|
+
}
|
|
10509
|
+
var NotificationsPG = class _NotificationsPG extends storage.NotificationsStorage {
|
|
10510
|
+
#db;
|
|
10511
|
+
#schema;
|
|
10512
|
+
#skipDefaultIndexes;
|
|
10513
|
+
#indexes;
|
|
10514
|
+
static MANAGED_TABLES = [storage.TABLE_NOTIFICATIONS];
|
|
10515
|
+
constructor(config) {
|
|
10516
|
+
super();
|
|
10517
|
+
const { client, schemaName, skipDefaultIndexes, indexes } = resolvePgConfig(config);
|
|
10518
|
+
this.#db = new PgDB({ client, schemaName, skipDefaultIndexes });
|
|
10519
|
+
this.#schema = schemaName || "public";
|
|
10520
|
+
this.#skipDefaultIndexes = skipDefaultIndexes;
|
|
10521
|
+
this.#indexes = indexes?.filter((idx) => _NotificationsPG.MANAGED_TABLES.includes(idx.table));
|
|
10522
|
+
}
|
|
10523
|
+
async init() {
|
|
10524
|
+
await this.#db.createTable({
|
|
10525
|
+
tableName: storage.TABLE_NOTIFICATIONS,
|
|
10526
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_NOTIFICATIONS]
|
|
10527
|
+
});
|
|
10528
|
+
await this.createDefaultIndexes();
|
|
10529
|
+
await this.createCustomIndexes();
|
|
10530
|
+
}
|
|
10531
|
+
static getDefaultIndexDefs(schemaPrefix) {
|
|
10532
|
+
return [
|
|
10533
|
+
{
|
|
10534
|
+
name: `${schemaPrefix}idx_notifications_thread_status_updated`,
|
|
10535
|
+
table: storage.TABLE_NOTIFICATIONS,
|
|
10536
|
+
columns: ["threadId", "status", "updatedAt"]
|
|
10537
|
+
},
|
|
10538
|
+
{
|
|
10539
|
+
name: `${schemaPrefix}idx_notifications_coalescing`,
|
|
10540
|
+
table: storage.TABLE_NOTIFICATIONS,
|
|
10541
|
+
columns: ["threadId", "source", "kind", "status", "agentId", "resourceId", "dedupeKey", "coalesceKey"]
|
|
10542
|
+
},
|
|
10543
|
+
{
|
|
10544
|
+
name: `${schemaPrefix}idx_notifications_due`,
|
|
10545
|
+
table: storage.TABLE_NOTIFICATIONS,
|
|
10546
|
+
columns: ["status", "deliverAt", "summaryAt"]
|
|
10547
|
+
}
|
|
10548
|
+
];
|
|
10549
|
+
}
|
|
10550
|
+
static getExportDDL(schemaName) {
|
|
10551
|
+
const statements = [];
|
|
10552
|
+
const parsedSchema = schemaName ? utils.parseSqlIdentifier(schemaName, "schema name") : "";
|
|
10553
|
+
const schemaPrefix = parsedSchema && parsedSchema !== "public" ? `${parsedSchema}_` : "";
|
|
10554
|
+
statements.push(
|
|
10555
|
+
generateTableSQL({
|
|
10556
|
+
tableName: storage.TABLE_NOTIFICATIONS,
|
|
10557
|
+
schema: storage.TABLE_SCHEMAS[storage.TABLE_NOTIFICATIONS],
|
|
10558
|
+
schemaName,
|
|
10559
|
+
includeAllConstraints: true
|
|
10560
|
+
})
|
|
10561
|
+
);
|
|
10562
|
+
for (const idx of _NotificationsPG.getDefaultIndexDefs(schemaPrefix)) {
|
|
10563
|
+
statements.push(generateIndexSQL(idx, schemaName));
|
|
10564
|
+
}
|
|
10565
|
+
return statements;
|
|
10566
|
+
}
|
|
10567
|
+
getDefaultIndexDefinitions() {
|
|
10568
|
+
const schemaPrefix = this.#schema !== "public" ? `${this.#schema}_` : "";
|
|
10569
|
+
return _NotificationsPG.getDefaultIndexDefs(schemaPrefix);
|
|
10570
|
+
}
|
|
10571
|
+
async createDefaultIndexes() {
|
|
10572
|
+
if (this.#skipDefaultIndexes) return;
|
|
10573
|
+
for (const indexDef of this.getDefaultIndexDefinitions()) {
|
|
10574
|
+
try {
|
|
10575
|
+
await this.#db.createIndex(indexDef);
|
|
10576
|
+
} catch (error) {
|
|
10577
|
+
this.logger?.warn?.(`Failed to create index ${indexDef.name}:`, error);
|
|
10578
|
+
}
|
|
10579
|
+
}
|
|
10580
|
+
}
|
|
10581
|
+
async createCustomIndexes() {
|
|
10582
|
+
if (!this.#indexes || this.#indexes.length === 0) return;
|
|
10583
|
+
for (const indexDef of this.#indexes) {
|
|
10584
|
+
try {
|
|
10585
|
+
await this.#db.createIndex(indexDef);
|
|
10586
|
+
} catch (error) {
|
|
10587
|
+
this.logger?.warn?.(`Failed to create custom index ${indexDef.name}:`, error);
|
|
10588
|
+
}
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
async dangerouslyClearAll() {
|
|
10592
|
+
await this.#db.clearTable({ tableName: storage.TABLE_NOTIFICATIONS });
|
|
10593
|
+
}
|
|
10594
|
+
async updateNotificationRow(threadId, id, data) {
|
|
10595
|
+
const entries = Object.entries(data).filter(([, value]) => value !== void 0);
|
|
10596
|
+
if (entries.length === 0) return;
|
|
10597
|
+
const schemaName = getSchemaName2(this.#schema);
|
|
10598
|
+
const tableName = getTableName2({ indexName: storage.TABLE_NOTIFICATIONS, schemaName });
|
|
10599
|
+
const setColumns = entries.map(([key], index) => `"${utils.parseSqlIdentifier(key, "column name")}" = $${index + 1}`);
|
|
10600
|
+
const values = entries.map(([key, value]) => {
|
|
10601
|
+
const columnSchema = storage.TABLE_SCHEMAS[storage.TABLE_NOTIFICATIONS][key];
|
|
10602
|
+
if (columnSchema?.type === "jsonb" && value !== null) return JSON.stringify(value);
|
|
10603
|
+
return value;
|
|
10604
|
+
});
|
|
10605
|
+
await this.#db.client.none(
|
|
10606
|
+
`UPDATE ${tableName} SET ${setColumns.join(", ")} WHERE "threadId" = $${values.length + 1} AND "id" = $${values.length + 2}`,
|
|
10607
|
+
[...values, threadId, id]
|
|
10608
|
+
);
|
|
10609
|
+
}
|
|
10610
|
+
async createNotification(input) {
|
|
10611
|
+
const existing = await this.findCoalescable(input);
|
|
10612
|
+
if (existing) {
|
|
10613
|
+
const now2 = /* @__PURE__ */ new Date();
|
|
10614
|
+
const attributes = input.attributes ? { ...cloneValue(existing.attributes), ...cloneValue(input.attributes) } : cloneValue(existing.attributes);
|
|
10615
|
+
const metadata = input.metadata ? { ...cloneValue(existing.metadata), ...cloneValue(input.metadata) } : cloneValue(existing.metadata);
|
|
10616
|
+
await this.updateNotificationRow(existing.threadId, existing.id, {
|
|
10617
|
+
summary: input.summary,
|
|
10618
|
+
payload: cloneValue(input.payload ?? existing.payload) ?? null,
|
|
10619
|
+
priority: input.priority ?? existing.priority,
|
|
10620
|
+
attributes: attributes ?? null,
|
|
10621
|
+
updatedAt: now2,
|
|
10622
|
+
deliverAt: input.deliverAt ?? existing.deliverAt ?? null,
|
|
10623
|
+
summaryAt: input.summaryAt ?? existing.summaryAt ?? null,
|
|
10624
|
+
deliveryReason: input.deliveryReason ?? existing.deliveryReason ?? null,
|
|
10625
|
+
coalescedCount: (existing.coalescedCount ?? 1) + 1,
|
|
10626
|
+
metadata: metadata ?? null
|
|
10627
|
+
});
|
|
10628
|
+
const updated = await this.getNotification({ threadId: existing.threadId, id: existing.id });
|
|
10629
|
+
if (!updated) throw new Error(`Notification ${existing.id} was not found for thread ${existing.threadId}`);
|
|
10630
|
+
return updated;
|
|
10631
|
+
}
|
|
10632
|
+
const now = input.createdAt ?? /* @__PURE__ */ new Date();
|
|
10633
|
+
const record = {
|
|
10634
|
+
id: input.id ?? crypto$1.randomUUID(),
|
|
10635
|
+
threadId: input.threadId,
|
|
10636
|
+
source: input.source,
|
|
10637
|
+
kind: input.kind,
|
|
10638
|
+
priority: input.priority ?? "medium",
|
|
10639
|
+
status: "pending",
|
|
10640
|
+
summary: input.summary,
|
|
10641
|
+
payload: cloneValue(input.payload),
|
|
10642
|
+
resourceId: input.resourceId,
|
|
10643
|
+
agentId: input.agentId,
|
|
10644
|
+
sourceId: input.sourceId,
|
|
10645
|
+
dedupeKey: input.dedupeKey,
|
|
10646
|
+
coalesceKey: input.coalesceKey,
|
|
10647
|
+
coalescedCount: 1,
|
|
10648
|
+
attributes: cloneValue(input.attributes),
|
|
10649
|
+
createdAt: now,
|
|
10650
|
+
updatedAt: now,
|
|
10651
|
+
deliverAt: input.deliverAt,
|
|
10652
|
+
summaryAt: input.summaryAt,
|
|
10653
|
+
deliveryReason: input.deliveryReason,
|
|
10654
|
+
deliveryAttempts: 0,
|
|
10655
|
+
metadata: cloneValue(input.metadata)
|
|
10656
|
+
};
|
|
10657
|
+
await this.#db.insert({ tableName: storage.TABLE_NOTIFICATIONS, record: normalizeRecordForInsert(record) });
|
|
10658
|
+
return record;
|
|
10659
|
+
}
|
|
10660
|
+
async listNotifications(input) {
|
|
10661
|
+
const conditions = ['"threadId" = $1'];
|
|
10662
|
+
const args = [input.threadId];
|
|
10663
|
+
addArrayFilter(conditions, args, "status", input.status);
|
|
10664
|
+
addArrayFilter(conditions, args, "priority", input.priority);
|
|
10665
|
+
if (input.source) {
|
|
10666
|
+
args.push(input.source);
|
|
10667
|
+
conditions.push(`"source" = $${args.length}`);
|
|
10668
|
+
}
|
|
10669
|
+
if (input.resourceId) {
|
|
10670
|
+
args.push(input.resourceId);
|
|
10671
|
+
conditions.push(`"resourceId" = $${args.length}`);
|
|
10672
|
+
}
|
|
10673
|
+
if (input.agentId) {
|
|
10674
|
+
args.push(input.agentId);
|
|
10675
|
+
conditions.push(`"agentId" = $${args.length}`);
|
|
10676
|
+
}
|
|
10677
|
+
if (input.search) {
|
|
10678
|
+
const search = `%${input.search.toLowerCase()}%`;
|
|
10679
|
+
args.push(search, search);
|
|
10680
|
+
conditions.push(`(LOWER("summary") LIKE $${args.length - 1} OR LOWER("kind") LIKE $${args.length})`);
|
|
10681
|
+
}
|
|
10682
|
+
const limit = input.limit ? ` LIMIT $${args.length + 1}` : "";
|
|
10683
|
+
if (input.limit) args.push(input.limit);
|
|
10684
|
+
const schemaName = getSchemaName2(this.#schema);
|
|
10685
|
+
const tableName = getTableName2({ indexName: storage.TABLE_NOTIFICATIONS, schemaName });
|
|
10686
|
+
const rows = await this.#db.client.manyOrNone(
|
|
10687
|
+
`SELECT * FROM ${tableName} WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`,
|
|
10688
|
+
args
|
|
10689
|
+
);
|
|
10690
|
+
return rows.map((row) => rowToNotification(row));
|
|
10691
|
+
}
|
|
10692
|
+
async listDueNotifications(input) {
|
|
10693
|
+
const conditions = [
|
|
10694
|
+
'"status" = $1',
|
|
10695
|
+
'(("deliverAt" IS NOT NULL AND "deliverAt" <= $2) OR ("summaryAt" IS NOT NULL AND "summaryAt" <= $3))'
|
|
10696
|
+
];
|
|
10697
|
+
const args = ["pending", input.now, input.now];
|
|
10698
|
+
if (input.agentId) {
|
|
10699
|
+
args.push(input.agentId);
|
|
10700
|
+
conditions.push(`"agentId" = $${args.length}`);
|
|
10701
|
+
}
|
|
10702
|
+
if (input.resourceId) {
|
|
10703
|
+
args.push(input.resourceId);
|
|
10704
|
+
conditions.push(`"resourceId" = $${args.length}`);
|
|
10705
|
+
}
|
|
10706
|
+
const limit = input.limit ? ` LIMIT $${args.length + 1}` : "";
|
|
10707
|
+
if (input.limit) args.push(input.limit);
|
|
10708
|
+
const schemaName = getSchemaName2(this.#schema);
|
|
10709
|
+
const tableName = getTableName2({ indexName: storage.TABLE_NOTIFICATIONS, schemaName });
|
|
10710
|
+
const rows = await this.#db.client.manyOrNone(
|
|
10711
|
+
`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}`,
|
|
10712
|
+
args
|
|
10713
|
+
);
|
|
10714
|
+
return rows.map((row) => rowToNotification(row));
|
|
10715
|
+
}
|
|
10716
|
+
async getNotification(input) {
|
|
10717
|
+
const schemaName = getSchemaName2(this.#schema);
|
|
10718
|
+
const tableName = getTableName2({ indexName: storage.TABLE_NOTIFICATIONS, schemaName });
|
|
10719
|
+
const row = await this.#db.client.oneOrNone(
|
|
10720
|
+
`SELECT * FROM ${tableName} WHERE "threadId" = $1 AND "id" = $2 LIMIT 1`,
|
|
10721
|
+
[input.threadId, input.id]
|
|
10722
|
+
);
|
|
10723
|
+
return row ? rowToNotification(row) : null;
|
|
10724
|
+
}
|
|
10725
|
+
async updateNotification(input) {
|
|
10726
|
+
const existing = await this.getNotification({ threadId: input.threadId, id: input.id });
|
|
10727
|
+
if (!existing) {
|
|
10728
|
+
throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
|
|
10729
|
+
}
|
|
10730
|
+
const now = /* @__PURE__ */ new Date();
|
|
10731
|
+
await this.updateNotificationRow(input.threadId, input.id, {
|
|
10732
|
+
...input.status ? { status: input.status, ...statusTimestamp(input.status, now) } : {},
|
|
10733
|
+
...input.summary !== void 0 ? { summary: input.summary } : {},
|
|
10734
|
+
...input.payload !== void 0 ? { payload: cloneValue(input.payload) } : {},
|
|
10735
|
+
...input.attributes !== void 0 ? { attributes: cloneValue(input.attributes) } : {},
|
|
10736
|
+
...input.metadata !== void 0 ? { metadata: cloneValue(input.metadata) } : {},
|
|
10737
|
+
...input.deliverAt !== void 0 ? { deliverAt: input.deliverAt } : {},
|
|
10738
|
+
...input.summaryAt !== void 0 ? { summaryAt: input.summaryAt } : {},
|
|
10739
|
+
...input.deliveryReason !== void 0 ? { deliveryReason: input.deliveryReason } : {},
|
|
10740
|
+
...input.deliveryAttempts !== void 0 ? { deliveryAttempts: input.deliveryAttempts } : {},
|
|
10741
|
+
...input.lastDeliveryAttemptAt !== void 0 ? { lastDeliveryAttemptAt: input.lastDeliveryAttemptAt } : {},
|
|
10742
|
+
...input.lastDeliveryError !== void 0 ? { lastDeliveryError: input.lastDeliveryError } : {},
|
|
10743
|
+
...input.deliveredSignalId !== void 0 ? { deliveredSignalId: input.deliveredSignalId } : {},
|
|
10744
|
+
...input.summarySignalId !== void 0 ? { summarySignalId: input.summarySignalId } : {},
|
|
10745
|
+
updatedAt: now
|
|
10746
|
+
});
|
|
10747
|
+
const updated = await this.getNotification({ threadId: input.threadId, id: input.id });
|
|
10748
|
+
if (!updated) throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
|
|
10749
|
+
return updated;
|
|
10750
|
+
}
|
|
10751
|
+
async findCoalescable(input) {
|
|
10752
|
+
if (!input.dedupeKey && !input.coalesceKey) return void 0;
|
|
10753
|
+
const schemaName = getSchemaName2(this.#schema);
|
|
10754
|
+
const tableName = getTableName2({ indexName: storage.TABLE_NOTIFICATIONS, schemaName });
|
|
10755
|
+
const row = await this.#db.client.oneOrNone(
|
|
10756
|
+
`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`,
|
|
10757
|
+
[
|
|
10758
|
+
input.threadId,
|
|
10759
|
+
input.source,
|
|
10760
|
+
input.kind,
|
|
10761
|
+
"pending",
|
|
10762
|
+
input.agentId ?? null,
|
|
10763
|
+
input.resourceId ?? null,
|
|
10764
|
+
input.dedupeKey ?? null,
|
|
10765
|
+
input.coalesceKey ?? null
|
|
10766
|
+
]
|
|
10767
|
+
);
|
|
10768
|
+
return row ? rowToNotification(row) : void 0;
|
|
10769
|
+
}
|
|
10770
|
+
};
|
|
10429
10771
|
var ObservabilityPG = class _ObservabilityPG extends storage.ObservabilityStorage {
|
|
10430
10772
|
#db;
|
|
10431
10773
|
#schema;
|
|
@@ -15005,6 +15347,7 @@ var DEFAULT_MAX_CONNECTIONS = 20;
|
|
|
15005
15347
|
var DEFAULT_IDLE_TIMEOUT_MS = 3e4;
|
|
15006
15348
|
var ALL_DOMAINS = [
|
|
15007
15349
|
MemoryPG,
|
|
15350
|
+
NotificationsPG,
|
|
15008
15351
|
ObservabilityPG,
|
|
15009
15352
|
ScoresPG,
|
|
15010
15353
|
ScorerDefinitionsPG,
|
|
@@ -15060,6 +15403,7 @@ var PostgresStore = class extends storage.MastraCompositeStore {
|
|
|
15060
15403
|
scores: new ScoresPG(domainConfig),
|
|
15061
15404
|
workflows: new WorkflowsPG(domainConfig),
|
|
15062
15405
|
memory: new MemoryPG(domainConfig),
|
|
15406
|
+
notifications: new NotificationsPG(domainConfig),
|
|
15063
15407
|
observability: new ObservabilityPG(domainConfig),
|
|
15064
15408
|
agents: new AgentsPG(domainConfig),
|
|
15065
15409
|
promptBlocks: new PromptBlocksPG(domainConfig),
|
|
@@ -15273,6 +15617,7 @@ exports.FavoritesPG = FavoritesPG;
|
|
|
15273
15617
|
exports.MCPClientsPG = MCPClientsPG;
|
|
15274
15618
|
exports.MCPServersPG = MCPServersPG;
|
|
15275
15619
|
exports.MemoryPG = MemoryPG;
|
|
15620
|
+
exports.NotificationsPG = NotificationsPG;
|
|
15276
15621
|
exports.ObservabilityPG = ObservabilityPG;
|
|
15277
15622
|
exports.PGVECTOR_PROMPT = PGVECTOR_PROMPT;
|
|
15278
15623
|
exports.PgVector = PgVector;
|