@mastra/pg 1.20.0-alpha.1 → 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
  )`);
@@ -9477,7 +9489,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9477
9489
  hasMore: false
9478
9490
  };
9479
9491
  if (perPage === 0 && include && include.length > 0) {
9480
- const includeMessages = await this._getIncludedMessages({ include });
9492
+ const includeMessages = await this._getIncludedMessages({
9493
+ include,
9494
+ resourceId
9495
+ });
9481
9496
  if (!includeMessages || includeMessages.length === 0) return {
9482
9497
  messages: [],
9483
9498
  total: 0,
@@ -9496,7 +9511,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9496
9511
  };
9497
9512
  }
9498
9513
  let includeFailure;
9499
- const includePromise = include && include.length > 0 ? this._getIncludedMessages({ include }).catch((error) => {
9514
+ const includePromise = include && include.length > 0 ? this._getIncludedMessages({
9515
+ include,
9516
+ resourceId
9517
+ }).catch((error) => {
9500
9518
  includeFailure = error;
9501
9519
  return null;
9502
9520
  }) : null;
@@ -9617,7 +9635,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9617
9635
  hasMore: false
9618
9636
  };
9619
9637
  if (perPage === 0 && include && include.length > 0) {
9620
- const includeMessages = await this._getIncludedMessages({ include });
9638
+ const includeMessages = await this._getIncludedMessages({
9639
+ include,
9640
+ resourceId
9641
+ });
9621
9642
  if (!includeMessages || includeMessages.length === 0) return {
9622
9643
  messages: [],
9623
9644
  total: 0,
@@ -9636,7 +9657,10 @@ var MemoryPG = class MemoryPG extends MemoryStorage {
9636
9657
  };
9637
9658
  }
9638
9659
  let includeFailure;
9639
- const includePromise = include && include.length > 0 ? this._getIncludedMessages({ include }).catch((error) => {
9660
+ const includePromise = include && include.length > 0 ? this._getIncludedMessages({
9661
+ include,
9662
+ resourceId
9663
+ }).catch((error) => {
9640
9664
  includeFailure = error;
9641
9665
  return null;
9642
9666
  }) : null;
@@ -18664,6 +18688,171 @@ var SkillsPG = class SkillsPG extends SkillsStorage {
18664
18688
  }
18665
18689
  };
18666
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
18667
18856
  //#region src/storage/domains/tool-provider-connections/index.ts
18668
18857
  function normaliseScope(raw) {
18669
18858
  const value = raw == null ? "per-author" : String(raw);
@@ -20598,7 +20787,8 @@ const ALL_DOMAINS = [
20598
20787
  BackgroundTasksPG,
20599
20788
  FavoritesPG,
20600
20789
  ChannelsPG,
20601
- SchedulesPG
20790
+ SchedulesPG,
20791
+ ThreadStatePG
20602
20792
  ];
20603
20793
  /**
20604
20794
  * Exports the Mastra database schema as SQL DDL statements, including tables, indexes, and triggers.
@@ -20692,7 +20882,8 @@ var PostgresStore = class extends MastraCompositeStore {
20692
20882
  experiments: new ExperimentsPG(domainConfig),
20693
20883
  backgroundTasks: new BackgroundTasksPG(domainConfig),
20694
20884
  channels: new ChannelsPG(domainConfig),
20695
- schedules: new SchedulesPG(domainConfig)
20885
+ schedules: new SchedulesPG(domainConfig),
20886
+ threadState: new ThreadStatePG(domainConfig)
20696
20887
  };
20697
20888
  } catch (e) {
20698
20889
  throw new MastraError({
@@ -20999,6 +21190,6 @@ Example Complex Query:
20999
21190
  ]
21000
21191
  }`;
21001
21192
  //#endregion
21002
- 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 };
21003
21194
 
21004
21195
  //# sourceMappingURL=index.js.map