@mastra/pg 1.20.0-alpha.0 → 1.20.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
2
- import { AgentsStorage, BRANCH_SPAN_TYPES, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, EntityType, ExperimentsStorage, FactoryStorage, FavoritesStorage, MCPClientsStorage, MCPServersStorage, METRIC_DISTINCT_COLUMNS, MastraCompositeStore, MemoryStorage, NotificationsStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PromptBlocksStorage, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_CONFIGS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, ToolProviderConnectionsStorage, TraceStatus, UniqueViolationError, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, calculatePagination, createStorageErrorId, createVectorErrorId, ensureDate, getDefaultValue, getSqlType, hasErrorCode, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, mergeWorkflowStepResult, normalizePerPage, normalizeScheduleTarget, parseDuration, safelyParseJSON, storageMessageMatchesMetadataFilter, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
2
+ import { AgentsStorage, BRANCH_SPAN_TYPES, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, EntityType, ExperimentsStorage, FactoryStorage, FavoritesStorage, MCPClientsStorage, MCPServersStorage, METRIC_DISTINCT_COLUMNS, MastraCompositeStore, MemoryStorage, NotificationsStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PromptBlocksStorage, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_CONFIGS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, ThreadStateStorage, ToolProviderConnectionsStorage, TraceStatus, UniqueViolationError, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, calculatePagination, createStorageErrorId, createVectorErrorId, ensureDate, getDefaultValue, getSqlType, hasErrorCode, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, mergeWorkflowStepResult, normalizePerPage, normalizeScheduleTarget, parseDuration, safelyParseJSON, storageMessageMatchesMetadataFilter, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
3
3
  import { parseFieldKey, parseSqlIdentifier } from "@mastra/core/utils";
4
4
  import { MastraVector, validateTopK, validateUpsertInput } from "@mastra/core/vector";
5
5
  import { Mutex } from "async-mutex";
@@ -9283,7 +9283,13 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9283
9283
  return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
9284
9284
  });
9285
9285
  }
9286
- async _getIncludedMessages({ include }) {
9286
+ /**
9287
+ * Fetches included messages by ID, discovering their thread automatically.
9288
+ * This handles cross-thread includes where the include item doesn't specify a threadId.
9289
+ * When a resourceId is given, both the target lookup and the surrounding window stay
9290
+ * inside that resource, so an include never leaks another resource's messages.
9291
+ */
9292
+ async _getIncludedMessages({ include, resourceId }) {
9287
9293
  if (!include || include.length === 0) return null;
9288
9294
  const tableName = getTableName$3({
9289
9295
  indexName: TABLE_MESSAGES,
@@ -9293,7 +9299,8 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9293
9299
  const targetIds = include.map((inc) => inc.id).filter(Boolean);
9294
9300
  if (targetIds.length === 0) return null;
9295
9301
  const idPlaceholders = targetIds.map((_, i) => "$" + (i + 1)).join(", ");
9296
- const targetRows = await this.#db.client.manyOrNone(`SELECT id, thread_id, "createdAt" FROM ${tableName} WHERE id IN (${idPlaceholders})`, targetIds);
9302
+ const targetResourceCondition = resourceId ? ` AND "resourceId" = $${targetIds.length + 1}` : "";
9303
+ const targetRows = await this.#db.client.manyOrNone(`SELECT id, thread_id, "createdAt" FROM ${tableName} WHERE id IN (${idPlaceholders})${targetResourceCondition}`, resourceId ? [...targetIds, resourceId] : targetIds);
9297
9304
  if (targetRows.length === 0) return null;
9298
9305
  const targetMap = new Map(targetRows.map((r) => [r.id, {
9299
9306
  threadId: r.thread_id,
@@ -9301,7 +9308,12 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9301
9308
  }]));
9302
9309
  const unionQueries = [];
9303
9310
  const params = [];
9304
- let paramIdx = 1;
9311
+ let resourceCondition = "";
9312
+ if (resourceId) {
9313
+ params.push(resourceId);
9314
+ resourceCondition = ` AND m."resourceId" = $1`;
9315
+ }
9316
+ let paramIdx = params.length + 1;
9305
9317
  for (const inc of include) {
9306
9318
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
9307
9319
  const target = targetMap.get(id);
@@ -9313,7 +9325,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9313
9325
  SELECT ${selectColumns}
9314
9326
  FROM ${tableName} m
9315
9327
  WHERE m.thread_id = ${p1}
9316
- AND m."createdAt" <= ${p2}
9328
+ AND m."createdAt" <= ${p2}${resourceCondition}
9317
9329
  ORDER BY m."createdAt" DESC, m.id DESC
9318
9330
  LIMIT ${p3}
9319
9331
  )`);
@@ -9327,7 +9339,7 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9327
9339
  SELECT ${selectColumns}
9328
9340
  FROM ${tableName} m
9329
9341
  WHERE m.thread_id = ${p4}
9330
- AND m."createdAt" > ${p5}
9342
+ AND m."createdAt" > ${p5}${resourceCondition}
9331
9343
  ORDER BY m."createdAt" ASC, m.id ASC
9332
9344
  LIMIT ${p6}
9333
9345
  )`);
@@ -9389,6 +9401,38 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9389
9401
  throw mastraError;
9390
9402
  }
9391
9403
  }
9404
+ /**
9405
+ * Reads one page of messages together with the total row count.
9406
+ *
9407
+ * `COUNT(*) OVER ()` reports the count over the whole WHERE result on the same
9408
+ * statement as the page, so the page costs one database round-trip instead of
9409
+ * two. The page and the count also come from one snapshot, so the count always
9410
+ * describes the returned rows. A separate `COUNT(*)` runs only when the page is
9411
+ * empty and the caller asked for a page after the last row, because a window
9412
+ * function has no row to carry the count on.
9413
+ */
9414
+ async #fetchMessagePage({ selectStatement, tableName, whereClause, orderByStatement, queryParams, perPageInput, perPage, offset }) {
9415
+ const limitClause = perPageInput === false ? "" : ` LIMIT $${queryParams.length + 1} OFFSET $${queryParams.length + 2}`;
9416
+ const dataParams = perPageInput === false ? queryParams : [
9417
+ ...queryParams,
9418
+ perPage,
9419
+ offset
9420
+ ];
9421
+ const rows = await this.#db.client.manyOrNone(`${selectStatement}, COUNT(*) OVER () AS "__total" FROM ${tableName} ${whereClause} ${orderByStatement}${limitClause}`, dataParams) || [];
9422
+ if (rows.length > 0) return {
9423
+ total: Number(rows[0].__total),
9424
+ messages: rows
9425
+ };
9426
+ if (offset === 0) return {
9427
+ total: 0,
9428
+ messages: []
9429
+ };
9430
+ const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
9431
+ return {
9432
+ total: parseInt(countResult.count, 10),
9433
+ messages: []
9434
+ };
9435
+ }
9392
9436
  async listMessages(args) {
9393
9437
  const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
9394
9438
  const threadIds = (Array.isArray(threadId) ? threadId : [threadId]).filter((id) => typeof id === "string");
@@ -9445,7 +9489,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9445
9489
  hasMore: false
9446
9490
  };
9447
9491
  if (perPage === 0 && include && include.length > 0) {
9448
- const includeMessages = await this._getIncludedMessages({ include });
9492
+ const includeMessages = await this._getIncludedMessages({
9493
+ include,
9494
+ resourceId
9495
+ });
9449
9496
  if (!includeMessages || includeMessages.length === 0) return {
9450
9497
  messages: [],
9451
9498
  total: 0,
@@ -9463,23 +9510,30 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9463
9510
  hasMore: false
9464
9511
  };
9465
9512
  }
9513
+ let includeFailure;
9514
+ const includePromise = include && include.length > 0 ? this._getIncludedMessages({
9515
+ include,
9516
+ resourceId
9517
+ }).catch((error) => {
9518
+ includeFailure = error;
9519
+ return null;
9520
+ }) : null;
9466
9521
  let total;
9467
9522
  let messages;
9468
9523
  if (metadataFilter) {
9469
9524
  const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
9470
9525
  total = filteredRows.length;
9471
9526
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
9472
- } else {
9473
- const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
9474
- total = parseInt(countResult.count, 10);
9475
- const limitValue = perPageInput === false ? total : perPage;
9476
- const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9477
- messages = [...await this.#db.client.manyOrNone(dataQuery, [
9478
- ...queryParams,
9479
- limitValue,
9480
- offset
9481
- ]) || []];
9482
- }
9527
+ } else ({total, messages} = await this.#fetchMessagePage({
9528
+ selectStatement,
9529
+ tableName,
9530
+ whereClause,
9531
+ orderByStatement,
9532
+ queryParams,
9533
+ perPageInput,
9534
+ perPage,
9535
+ offset
9536
+ }));
9483
9537
  const primaryPageCount = messages.length;
9484
9538
  if (total === 0 && messages.length === 0 && (!include || include.length === 0)) return {
9485
9539
  messages: [],
@@ -9490,7 +9544,8 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9490
9544
  };
9491
9545
  const messageIds = new Set(messages.map((m) => m.id));
9492
9546
  if (include && include.length > 0) {
9493
- const includeMessages = await this._getIncludedMessages({ include });
9547
+ const includeMessages = await includePromise;
9548
+ if (includeFailure) throw includeFailure;
9494
9549
  if (includeMessages) {
9495
9550
  for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
9496
9551
  messages.push(includeMsg);
@@ -9580,7 +9635,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9580
9635
  hasMore: false
9581
9636
  };
9582
9637
  if (perPage === 0 && include && include.length > 0) {
9583
- const includeMessages = await this._getIncludedMessages({ include });
9638
+ const includeMessages = await this._getIncludedMessages({
9639
+ include,
9640
+ resourceId
9641
+ });
9584
9642
  if (!includeMessages || includeMessages.length === 0) return {
9585
9643
  messages: [],
9586
9644
  total: 0,
@@ -9598,23 +9656,30 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9598
9656
  hasMore: false
9599
9657
  };
9600
9658
  }
9659
+ let includeFailure;
9660
+ const includePromise = include && include.length > 0 ? this._getIncludedMessages({
9661
+ include,
9662
+ resourceId
9663
+ }).catch((error) => {
9664
+ includeFailure = error;
9665
+ return null;
9666
+ }) : null;
9601
9667
  let total;
9602
9668
  let messages;
9603
9669
  if (metadataFilter) {
9604
9670
  const filteredRows = (await this.#db.client.manyOrNone(`${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement}`, queryParams) || []).filter((row) => storageMessageMatchesMetadataFilter(row.content, metadataFilter));
9605
9671
  total = filteredRows.length;
9606
9672
  messages = perPageInput === false ? filteredRows : filteredRows.slice(offset, offset + perPage);
9607
- } else {
9608
- const countResult = await this.#db.client.one(`SELECT COUNT(*) FROM ${tableName} ${whereClause}`, queryParams);
9609
- total = parseInt(countResult.count, 10);
9610
- const limitValue = perPageInput === false ? total : perPage;
9611
- const dataQuery = `${selectStatement} FROM ${tableName} ${whereClause} ${orderByStatement} LIMIT $${paramIndex++} OFFSET $${paramIndex++}`;
9612
- messages = [...await this.#db.client.manyOrNone(dataQuery, [
9613
- ...queryParams,
9614
- limitValue,
9615
- offset
9616
- ]) || []];
9617
- }
9673
+ } else ({total, messages} = await this.#fetchMessagePage({
9674
+ selectStatement,
9675
+ tableName,
9676
+ whereClause,
9677
+ orderByStatement,
9678
+ queryParams,
9679
+ perPageInput,
9680
+ perPage,
9681
+ offset
9682
+ }));
9618
9683
  if (total === 0 && messages.length === 0 && (!include || include.length === 0)) return {
9619
9684
  messages: [],
9620
9685
  total: 0,
@@ -9624,7 +9689,8 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9624
9689
  };
9625
9690
  const messageIds = new Set(messages.map((m) => m.id));
9626
9691
  if (include && include.length > 0) {
9627
- const includeMessages = await this._getIncludedMessages({ include });
9692
+ const includeMessages = await includePromise;
9693
+ if (includeFailure) throw includeFailure;
9628
9694
  if (includeMessages) {
9629
9695
  for (const includeMsg of includeMessages) if (!messageIds.has(includeMsg.id)) {
9630
9696
  messages.push(includeMsg);
@@ -18622,6 +18688,171 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
18622
18688
  }
18623
18689
  };
18624
18690
  //#endregion
18691
+ //#region src/storage/domains/thread-state/index.ts
18692
+ const COMPOSITE_PRIMARY_KEY = ["threadId", "type"];
18693
+ /**
18694
+ * PostgreSQL implementation of {@link ThreadStateStorage}.
18695
+ *
18696
+ * Stores per-thread, per-type state in `mastra_thread_state`, keyed by the
18697
+ * composite primary key `(threadId, type)`. The `value` column is `jsonb`, so
18698
+ * payloads (the task list for `type = 'task'`, the goal objective for
18699
+ * `type = 'goal'`) come back already parsed.
18700
+ */
18701
+ var ThreadStatePG = class ThreadStatePG extends ThreadStateStorage {
18702
+ #db;
18703
+ #schema;
18704
+ static MANAGED_TABLES = [TABLE_THREAD_STATE];
18705
+ /**
18706
+ * `thread_state` grows as a side effect of thread activity (one row per
18707
+ * thread per state type). It anchors on `updatedAtZ` (last activity), so
18708
+ * state for a thread that is still being written to is not pruned by
18709
+ * creation age.
18710
+ */
18711
+ static retentionTables = { threadState: {
18712
+ table: TABLE_THREAD_STATE,
18713
+ column: "updatedAtZ",
18714
+ indexed: true
18715
+ } };
18716
+ constructor(config) {
18717
+ super();
18718
+ const { client, schemaName, skipDefaultIndexes } = resolvePgConfig(config);
18719
+ this.#db = new PgDB({
18720
+ client,
18721
+ schemaName,
18722
+ skipDefaultIndexes
18723
+ });
18724
+ this.#schema = schemaName || "public";
18725
+ }
18726
+ static getExportDDL(schemaName) {
18727
+ return [generateTableSQL({
18728
+ tableName: TABLE_THREAD_STATE,
18729
+ schema: TABLE_SCHEMAS[TABLE_THREAD_STATE],
18730
+ schemaName,
18731
+ compositePrimaryKey: COMPOSITE_PRIMARY_KEY,
18732
+ includeAllConstraints: true
18733
+ })];
18734
+ }
18735
+ async init() {
18736
+ await this.#db.createTable({
18737
+ tableName: TABLE_THREAD_STATE,
18738
+ schema: TABLE_SCHEMAS[TABLE_THREAD_STATE],
18739
+ compositePrimaryKey: COMPOSITE_PRIMARY_KEY
18740
+ });
18741
+ }
18742
+ get #table() {
18743
+ return getTableName$5({
18744
+ indexName: TABLE_THREAD_STATE,
18745
+ schemaName: getSchemaName$5(this.#schema)
18746
+ });
18747
+ }
18748
+ /**
18749
+ * Create the retention index on demand, mirroring the other PG domains: only
18750
+ * deployments that configure retention pay for the extra index. Best-effort —
18751
+ * a failure here leaves pruning correct, just slower.
18752
+ */
18753
+ async #ensureRetentionIndexes(policies) {
18754
+ const prefix = this.#schema && this.#schema !== "public" ? `${this.#schema}_` : "";
18755
+ for (const [key, entry] of Object.entries(ThreadStatePG.retentionTables)) {
18756
+ if (!entry.indexed || !policies[key]) continue;
18757
+ try {
18758
+ await this.#db.ensureIndex({
18759
+ indexName: `${prefix}mastra_${key}_retention_idx`,
18760
+ tableName: entry.table,
18761
+ column: entry.column
18762
+ });
18763
+ } catch (error) {
18764
+ this.logger?.warn?.(`Failed to create retention index for ${entry.table}:`, error);
18765
+ }
18766
+ }
18767
+ }
18768
+ /** Delete thread state older than the `threadState` policy's `maxAge`, batched. */
18769
+ async prune(policies, options) {
18770
+ await this.#ensureRetentionIndexes(policies);
18771
+ const targets = resolveTargets({
18772
+ policies,
18773
+ descriptor: ThreadStatePG.retentionTables,
18774
+ order: ["threadState"]
18775
+ });
18776
+ return runPrune({
18777
+ db: this.#db,
18778
+ domain: "threadState",
18779
+ targets,
18780
+ options
18781
+ });
18782
+ }
18783
+ async dangerouslyClearAll() {
18784
+ try {
18785
+ await this.#db.client.none(`DELETE FROM ${this.#table}`);
18786
+ } catch (error) {
18787
+ throw new MastraError({
18788
+ id: createStorageErrorId("PG", "THREAD_STATE_CLEAR_ALL", "FAILED"),
18789
+ domain: ErrorDomain.STORAGE,
18790
+ category: ErrorCategory.THIRD_PARTY
18791
+ }, error);
18792
+ }
18793
+ }
18794
+ async getState({ threadId, type }) {
18795
+ try {
18796
+ const row = await this.#db.client.oneOrNone(`SELECT "value" FROM ${this.#table} WHERE "threadId" = $1 AND "type" = $2 LIMIT 1`, [threadId, type]);
18797
+ if (!row || row.value === null || row.value === void 0) return void 0;
18798
+ return typeof row.value === "string" ? JSON.parse(row.value) : row.value;
18799
+ } catch (error) {
18800
+ throw new MastraError({
18801
+ id: createStorageErrorId("PG", "THREAD_STATE_GET", "FAILED"),
18802
+ domain: ErrorDomain.STORAGE,
18803
+ category: ErrorCategory.THIRD_PARTY,
18804
+ details: {
18805
+ threadId,
18806
+ type
18807
+ }
18808
+ }, error);
18809
+ }
18810
+ }
18811
+ async setState({ threadId, type, value }) {
18812
+ const now = (/* @__PURE__ */ new Date()).toISOString();
18813
+ const serialized = JSON.stringify(value ?? null);
18814
+ try {
18815
+ await this.#db.client.none(`INSERT INTO ${this.#table} ("threadId", "type", "value", "createdAt", "createdAtZ", "updatedAt", "updatedAtZ")
18816
+ VALUES ($1, $2, $3::jsonb, $4::timestamp, $5::timestamptz, $4::timestamp, $5::timestamptz)
18817
+ ON CONFLICT ("threadId", "type")
18818
+ DO UPDATE SET "value" = EXCLUDED."value",
18819
+ "updatedAt" = EXCLUDED."updatedAt",
18820
+ "updatedAtZ" = EXCLUDED."updatedAtZ"`, [
18821
+ threadId,
18822
+ type,
18823
+ serialized,
18824
+ now,
18825
+ now
18826
+ ]);
18827
+ } catch (error) {
18828
+ throw new MastraError({
18829
+ id: createStorageErrorId("PG", "THREAD_STATE_SET", "FAILED"),
18830
+ domain: ErrorDomain.STORAGE,
18831
+ category: ErrorCategory.THIRD_PARTY,
18832
+ details: {
18833
+ threadId,
18834
+ type
18835
+ }
18836
+ }, error);
18837
+ }
18838
+ }
18839
+ async deleteState({ threadId, type }) {
18840
+ try {
18841
+ await this.#db.client.none(`DELETE FROM ${this.#table} WHERE "threadId" = $1 AND "type" = $2`, [threadId, type]);
18842
+ } catch (error) {
18843
+ throw new MastraError({
18844
+ id: createStorageErrorId("PG", "THREAD_STATE_DELETE", "FAILED"),
18845
+ domain: ErrorDomain.STORAGE,
18846
+ category: ErrorCategory.THIRD_PARTY,
18847
+ details: {
18848
+ threadId,
18849
+ type
18850
+ }
18851
+ }, error);
18852
+ }
18853
+ }
18854
+ };
18855
+ //#endregion
18625
18856
  //#region src/storage/domains/tool-provider-connections/index.ts
18626
18857
  function normaliseScope(raw) {
18627
18858
  const value = raw == null ? "per-author" : String(raw);
@@ -20556,7 +20787,8 @@ const ALL_DOMAINS = [
20556
20787
  BackgroundTasksPG,
20557
20788
  FavoritesPG,
20558
20789
  ChannelsPG,
20559
- SchedulesPG
20790
+ SchedulesPG,
20791
+ ThreadStatePG
20560
20792
  ];
20561
20793
  /**
20562
20794
  * Exports the Mastra database schema as SQL DDL statements, including tables, indexes, and triggers.
@@ -20650,7 +20882,8 @@ var PostgresStore = class extends MastraCompositeStore {
20650
20882
  experiments: new ExperimentsPG(domainConfig),
20651
20883
  backgroundTasks: new BackgroundTasksPG(domainConfig),
20652
20884
  channels: new ChannelsPG(domainConfig),
20653
- schedules: new SchedulesPG(domainConfig)
20885
+ schedules: new SchedulesPG(domainConfig),
20886
+ threadState: new ThreadStatePG(domainConfig)
20654
20887
  };
20655
20888
  } catch (e) {
20656
20889
  throw new MastraError({
@@ -20957,6 +21190,6 @@ Example Complex Query:
20957
21190
  ]
20958
21191
  }`;
20959
21192
  //#endregion
20960
- export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, NotificationsPG, ObservabilityPG, ObservabilityStoragePostgresVNext, PGVECTOR_PROMPT, PgFactoryStorage, PgVector, PoolAdapter, PostgresStore, PostgresStoreVNext, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, ToolProviderConnectionsPG, WorkflowDefinitionsPG, WorkflowsPG, WorkspacesPG, exportSchemas };
21193
+ export { AgentsPG, BackgroundTasksPG, BlobsPG, ChannelsPG, DatasetsPG, ExperimentsPG, FavoritesPG, MCPClientsPG, MCPServersPG, MemoryPG, NotificationsPG, ObservabilityPG, ObservabilityStoragePostgresVNext, PGVECTOR_PROMPT, PgFactoryStorage, PgVector, PoolAdapter, PostgresStore, PostgresStoreVNext, PromptBlocksPG, SchedulesPG, ScorerDefinitionsPG, ScoresPG, SkillsPG, ThreadStatePG, ToolProviderConnectionsPG, WorkflowDefinitionsPG, WorkflowsPG, WorkspacesPG, exportSchemas };
20961
21194
 
20962
21195
  //# sourceMappingURL=index.js.map