@mastra/pg 1.26.0 → 1.27.0-alpha.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.
@@ -3,7 +3,7 @@ name: mastra-pg
3
3
  description: Documentation for @mastra/pg. Use when working with @mastra/pg APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/pg"
6
- version: "1.26.0"
6
+ version: "1.27.0-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.26.0",
2
+ "version": "1.27.0-alpha.1",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -45,6 +45,8 @@ export const agent = new Agent({
45
45
 
46
46
  **options.readOnly** (`boolean`): When true, prevents memory from saving new messages and provides working memory as read-only context (without the updateWorkingMemory tool). Useful for read-only operations like previews, internal routing agents, or sub agents that should reference but not modify memory.
47
47
 
48
+ **options.retainFullInput** (`boolean`): When true, the request input is processed exactly as supplied instead of being filtered against stored history. Use this when you assemble the input yourself and need the message sequence preserved. Stored history is still loaded underneath, and every input message that isn't already stored is saved to the thread, including few-shot examples. Can be set per call on memory.options or agent-wide in the memory constructor options.
49
+
48
50
  **options.semanticRecall** (`boolean | { topK: number; messageRange: number | { before: number; after: number }; scope?: 'thread' | 'resource' }`): Enable semantic search in message history. Can be a boolean or an object with configuration options. When enabled, requires both vector store and embedder to be configured. Default topK is 4, default messageRange is {before: 1, after: 1}.
49
51
 
50
52
  **options.workingMemory** (`WorkingMemory`): Configuration for working memory feature. Can be { enabled: boolean; template?: string; schema?: ZodObject\<any> | JSONSchema7; scope?: 'thread' | 'resource' } or { enabled: boolean } to disable.
@@ -15,7 +15,7 @@ Storage adapters use the shared core retention contract for `prune()`, or a data
15
15
  | Adapter | Mechanism | Retention support |
16
16
  | -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
17
17
  | libSQL | `prune()` | All supported growth domains |
18
- | PostgreSQL | `prune()` | All supported growth domains. V-next observability drops expired partitions or chunks |
18
+ | PostgreSQL | `prune()` | All supported growth domains. vNext observability drops expired partitions or chunks |
19
19
  | MongoDB | `prune()` or native TTL | All supported growth domains. Native TTL indexes are also available |
20
20
  | DuckDB | `prune()` | Observability spans, metrics, logs, scores, and feedback |
21
21
  | MySQL | `prune()` | Observability spans |
@@ -102,10 +102,10 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
102
102
  | `memory` | `resources` | `createdAt` | Resource age |
103
103
  | `threadState` | `threadState` | `updatedAt` | Inactivity: state for still-active threads survives |
104
104
  | `observability` | `spans` | `startedAt` | Span age |
105
- | `observability` | `metrics` | `timestamp` | Metric event age (v-next only) |
106
- | `observability` | `logs` | `timestamp` | Log event age (v-next only) |
107
- | `observability` | `scores` | `timestamp` | Score event age (v-next only) |
108
- | `observability` | `feedback` | `timestamp` | Feedback event age (v-next only) |
105
+ | `observability` | `metrics` | `timestamp` | Metric event age (vNext only) |
106
+ | `observability` | `logs` | `timestamp` | Log event age (vNext only) |
107
+ | `observability` | `scores` | `timestamp` | Score event age (vNext only) |
108
+ | `observability` | `feedback` | `timestamp` | Feedback event age (vNext only) |
109
109
  | `scores` | `scorers` | `createdAt` | Score record age |
110
110
  | `workflows` | `workflowSnapshot` | `updatedAt` | Inactivity, suspended or long-running workflows survive |
111
111
  | `backgroundTasks` | `backgroundTasks` | `completedAt` | Time since completion, in-flight tasks (`NULL`) are never pruned |
@@ -122,7 +122,7 @@ Each domain specifies its age-prunable tables and the timestamp column that anch
122
122
  > - On PostgreSQL, timestamp anchors use the timezone-aware mirror columns (for example `createdAtZ`, `completedAtZ`).
123
123
  > - DuckDB observability stores append-only events for all five signals. Its `spans` policy uses the event `timestamp` column rather than `startedAt`.
124
124
  > - LibSQL and PostgreSQL support all domains above except `harness`, which PostgreSQL doesn't implement. MongoDB supports all except `threadState` and `harness`. DuckDB, MySQL, Microsoft SQL Server, Oracle Database, Amazon Aurora DSQL, and Google Cloud Spanner currently support retention only in their `observability` domains, with the signal coverage shown in the support matrix.
125
- > - The v-next PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
125
+ > - The vNext PostgreSQL observability domain stores signal events in day-partitioned tables (`spans`, `metrics`, `logs`, `scores`, `feedback`). For it, `prune()` drops whole day partitions (or TimescaleDB chunks) that are entirely older than the cutoff instead of deleting rows: effective level of detail is one day, and a partition is only dropped once its entire day is past `maxAge`. `PruneResult.deleted` reports the number of rows in the dropped partitions.
126
126
 
127
127
  ## Methods
128
128
 
@@ -208,7 +208,9 @@ You can also cancel a long-running prune with an `AbortSignal`: the loop stops b
208
208
 
209
209
  ClickHouse observability storage uses native table TTLs instead of `prune()`. Configure retention as days per signal. `init()` applies the TTLs to new and existing tables and skips `ALTER TABLE` statements when the configured TTL is already present.
210
210
 
211
- For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the v-next observability store:
211
+ Omitted signals, and signals set to zero or less, get no TTL. When you remove a signal from `retention`, the next `init()` or `applyRetention()` removes that table's TTL. If Mastra can't read the current TTLs from `system.tables`, it applies the configured TTLs and leaves the others unchanged.
212
+
213
+ For deployments that need to update TTL configuration without running the full initialization path, call `applyRetention()` on the vNext observability store:
212
214
 
213
215
  ```typescript
214
216
  import { ObservabilityStorageClickhouseVNext } from '@mastra/clickhouse'
package/dist/index.cjs CHANGED
@@ -5666,6 +5666,19 @@ var ChannelsPG = class ChannelsPG extends _mastra_core_storage.ChannelsStorage {
5666
5666
  function jsonbArg(value) {
5667
5667
  return value === void 0 || value === null ? null : JSON.stringify(value);
5668
5668
  }
5669
+ /** Preserve JSON null as data, rather than converting it to an absent SQL value. */
5670
+ function jsonDataArg(value) {
5671
+ return value === void 0 ? null : JSON.stringify(value);
5672
+ }
5673
+ const ITEM_SELECT_COLUMNS = [
5674
+ ...Object.keys(_mastra_core_storage.DATASET_ITEMS_SCHEMA),
5675
+ "createdAtZ",
5676
+ "updatedAtZ"
5677
+ ].map((column) => [
5678
+ "input",
5679
+ "groundTruth",
5680
+ "expectedTrajectory"
5681
+ ].includes(column) ? `"${column}"::text AS "${column}"` : `"${column}"`).join(", ");
5669
5682
  function parseStoredJSON(value) {
5670
5683
  if (typeof value === "string") try {
5671
5684
  return JSON.parse(value);
@@ -5840,9 +5853,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
5840
5853
  groundTruthSchema: row.groundTruthSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.groundTruthSchema) : void 0,
5841
5854
  requestContextSchema: row.requestContextSchema ? (0, _mastra_core_storage.safelyParseJSON)(row.requestContextSchema) : void 0,
5842
5855
  tags: row.tags ? (0, _mastra_core_storage.safelyParseJSON)(row.tags) : void 0,
5843
- targetType: row.targetType || null,
5844
- targetIds: row.targetIds || null,
5845
- scorerIds: row.scorerIds || null,
5856
+ targetType: row.targetType || void 0,
5857
+ targetIds: row.targetIds ?? void 0,
5858
+ scorerIds: row.scorerIds ?? void 0,
5846
5859
  organizationId: row.organizationId ?? null,
5847
5860
  projectId: row.projectId ?? null,
5848
5861
  candidateKey: row.candidateKey ?? null,
@@ -5944,9 +5957,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
5944
5957
  inputSchema: input.inputSchema ?? void 0,
5945
5958
  groundTruthSchema: input.groundTruthSchema ?? void 0,
5946
5959
  requestContextSchema: input.requestContextSchema ?? void 0,
5947
- targetType: input.targetType ?? null,
5948
- targetIds: input.targetIds ?? null,
5949
- scorerIds: input.scorerIds ?? null,
5960
+ targetType: input.targetType ?? void 0,
5961
+ targetIds: input.targetIds ?? void 0,
5962
+ scorerIds: input.scorerIds ?? void 0,
5950
5963
  organizationId: input.organizationId ?? null,
5951
5964
  projectId: input.projectId ?? null,
5952
5965
  candidateKey: input.candidateKey ?? null,
@@ -6073,9 +6086,9 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6073
6086
  groundTruthSchema: (args.groundTruthSchema !== void 0 ? args.groundTruthSchema : existing.groundTruthSchema) ?? void 0,
6074
6087
  requestContextSchema: (args.requestContextSchema !== void 0 ? args.requestContextSchema : existing.requestContextSchema) ?? void 0,
6075
6088
  tags: (args.tags !== void 0 ? args.tags : existing.tags) ?? void 0,
6076
- targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? null,
6077
- targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? null,
6078
- scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? null,
6089
+ targetType: (args.targetType !== void 0 ? args.targetType : existing.targetType) ?? void 0,
6090
+ targetIds: (args.targetIds !== void 0 ? args.targetIds : existing.targetIds) ?? void 0,
6091
+ scorerIds: (args.scorerIds !== void 0 ? args.scorerIds : existing.scorerIds) ?? void 0,
6079
6092
  organizationId: existing.organizationId ?? null,
6080
6093
  projectId: existing.projectId ?? null,
6081
6094
  candidateKey: existing.candidateKey ?? null,
@@ -6253,8 +6266,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6253
6266
  parentOrganizationId,
6254
6267
  parentProjectId,
6255
6268
  JSON.stringify(args.input),
6256
- jsonbArg(args.groundTruth),
6257
- jsonbArg(args.expectedTrajectory),
6269
+ jsonDataArg(args.groundTruth),
6270
+ jsonDataArg(args.expectedTrajectory),
6258
6271
  jsonbArg(args.toolMocks),
6259
6272
  args.unmockedToolPolicy ?? null,
6260
6273
  jsonbArg(args.scorerIds),
@@ -6370,8 +6383,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6370
6383
  parentOrganizationId,
6371
6384
  parentProjectId,
6372
6385
  JSON.stringify(mergedInput),
6373
- jsonbArg(mergedGroundTruth),
6374
- jsonbArg(mergedExpectedTrajectory),
6386
+ jsonDataArg(mergedGroundTruth),
6387
+ jsonDataArg(mergedExpectedTrajectory),
6375
6388
  jsonbArg(mergedToolMocks),
6376
6389
  mergedUnmockedToolPolicy ?? null,
6377
6390
  jsonbArg(mergedScorerIds),
@@ -6460,8 +6473,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6460
6473
  parentOrganizationId,
6461
6474
  parentProjectId,
6462
6475
  JSON.stringify(existing.input),
6463
- jsonbArg(existing.groundTruth),
6464
- jsonbArg(existing.expectedTrajectory),
6476
+ jsonDataArg(existing.groundTruth),
6477
+ jsonDataArg(existing.expectedTrajectory),
6465
6478
  jsonbArg(existing.toolMocks),
6466
6479
  existing.unmockedToolPolicy ?? null,
6467
6480
  jsonbArg(existing.scorerIds),
@@ -6561,7 +6574,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6561
6574
  details: { datasetId: input.datasetId }
6562
6575
  });
6563
6576
  const externalIds = [...new Set(input.items.flatMap((item) => item.externalId ? [item.externalId] : []))];
6564
- const historyRows = externalIds.length ? await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6577
+ const historyRows = externalIds.length ? await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "datasetId" = $1 AND "externalId" = ANY($2::text[]) ORDER BY "datasetVersion"`, [input.datasetId, externalIds]) : [];
6565
6578
  const plan = this.planDatasetItemBatch(input.items, historyRows.map((row) => this.transformItemRowFull(row)), () => crypto.randomUUID());
6566
6579
  const resolved = new Map([...plan.existingCurrentItems].map(([id, row]) => [id, this.datasetItemFromRow(row)]));
6567
6580
  if (plan.inserts.length > 0) {
@@ -6578,8 +6591,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6578
6591
  dataset.organizationId ?? null,
6579
6592
  dataset.projectId ?? null,
6580
6593
  JSON.stringify(item.input),
6581
- jsonbArg(item.groundTruth),
6582
- jsonbArg(item.expectedTrajectory),
6594
+ jsonDataArg(item.groundTruth),
6595
+ jsonDataArg(item.expectedTrajectory),
6583
6596
  jsonbArg(item.toolMocks),
6584
6597
  item.unmockedToolPolicy ?? null,
6585
6598
  jsonbArg(item.scorerIds),
@@ -6656,7 +6669,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6656
6669
  category: _mastra_core_error.ErrorCategory.USER,
6657
6670
  details: { datasetId: input.datasetId }
6658
6671
  });
6659
- const currentItems = (await t.manyOrNone(`SELECT * FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6672
+ const currentItems = (await t.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${itemsTable} WHERE "id" = ANY($1::text[]) AND "datasetId" = $2 AND "validTo" IS NULL AND "isDeleted" = false`, [input.itemIds, input.datasetId])).map((row) => this.transformItemRow(row));
6660
6673
  if (currentItems.length === 0) return;
6661
6674
  const parentOrganizationId = dataset.organizationId ?? null;
6662
6675
  const parentProjectId = dataset.projectId ?? null;
@@ -6671,8 +6684,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6671
6684
  parentOrganizationId,
6672
6685
  parentProjectId,
6673
6686
  JSON.stringify(item.input),
6674
- jsonbArg(item.groundTruth),
6675
- jsonbArg(item.expectedTrajectory),
6687
+ jsonDataArg(item.groundTruth),
6688
+ jsonDataArg(item.expectedTrajectory),
6676
6689
  jsonbArg(item.toolMocks),
6677
6690
  item.unmockedToolPolicy ?? null,
6678
6691
  jsonbArg(item.scorerIds),
@@ -6712,8 +6725,8 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6712
6725
  schemaName: getSchemaName$5(this.#schema)
6713
6726
  });
6714
6727
  let result;
6715
- if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6716
- else result = await client.oneOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6728
+ if (args.datasetVersion !== void 0) result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $2) AND "isDeleted" = false ORDER BY "datasetVersion" DESC LIMIT 1`, [args.id, args.datasetVersion]);
6729
+ else result = await client.oneOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 AND "validTo" IS NULL AND "isDeleted" = false`, [args.id]);
6717
6730
  return result ? this.transformItemRow(result) : null;
6718
6731
  } catch (error) {
6719
6732
  throw new _mastra_core_error.MastraError({
@@ -6729,7 +6742,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6729
6742
  indexName: _mastra_core_storage.TABLE_DATASET_ITEMS,
6730
6743
  schemaName: getSchemaName$5(this.#schema)
6731
6744
  });
6732
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6745
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "datasetId" = $1 AND "datasetVersion" <= $2 AND ("validTo" IS NULL OR "validTo" > $3) AND "isDeleted" = false ORDER BY "createdAt" DESC, "id" ASC`, [
6733
6746
  datasetId,
6734
6747
  version,
6735
6748
  version
@@ -6748,7 +6761,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6748
6761
  indexName: _mastra_core_storage.TABLE_DATASET_ITEMS,
6749
6762
  schemaName: getSchemaName$5(this.#schema)
6750
6763
  });
6751
- return (await this.#db.readClient.manyOrNone(`SELECT * FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6764
+ return (await this.#db.readClient.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} WHERE "id" = $1 ORDER BY "datasetVersion" DESC`, [itemId]) || []).map((row) => this.transformItemRowFull(row));
6752
6765
  } catch (error) {
6753
6766
  throw new _mastra_core_error.MastraError({
6754
6767
  id: (0, _mastra_core_storage.createStorageErrorId)("PG", "GET_ITEM_HISTORY", "FAILED"),
@@ -6820,7 +6833,7 @@ var DatasetsPG = class DatasetsPG extends _mastra_core_storage.DatasetsStorage {
6820
6833
  const { offset, perPage: perPageForResponse } = (0, _mastra_core_storage.calculatePagination)(page, perPageInput, perPage);
6821
6834
  const limitValue = perPageInput === false ? total : perPage;
6822
6835
  return {
6823
- items: (await client.manyOrNone(`SELECT * FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6836
+ items: (await client.manyOrNone(`SELECT ${ITEM_SELECT_COLUMNS} FROM ${tableName} ${whereClause} ORDER BY "${orderBy.field}" ${orderBy.direction}, "id" ASC LIMIT $${paramIndex} OFFSET $${paramIndex + 1}`, [
6824
6837
  ...queryParams,
6825
6838
  limitValue,
6826
6839
  offset
@@ -17270,7 +17283,8 @@ const TRACE_FIELDS = {
17270
17283
  entityName: "r.\"entityName\"",
17271
17284
  entityType: "r.\"entityType\"",
17272
17285
  environment: "r.\"environment\"",
17273
- status: TRACE_STATUS_SQL
17286
+ status: TRACE_STATUS_SQL,
17287
+ tags: "r.\"tags\""
17274
17288
  };
17275
17289
  const SPAN_FIELDS = {
17276
17290
  name: "s.\"name\"",
@@ -17372,6 +17386,19 @@ function compileScalarPredicate(predicate, registry, parameterOffset, allowMetad
17372
17386
  sql: `${field} IS ${predicate.operator === "exists" ? "NOT " : ""}NULL`,
17373
17387
  values: fieldValues
17374
17388
  };
17389
+ if (predicate.type === "collection") {
17390
+ if (predicate.operator === "includes" || predicate.operator === "notIncludes") {
17391
+ const contains = `${field} @> ARRAY[$${parameterOffset}]::text[]`;
17392
+ return {
17393
+ sql: predicate.operator === "includes" ? contains : `cardinality(${field}) > 0 AND NOT (${contains})`,
17394
+ values: [...fieldValues, predicate.value]
17395
+ };
17396
+ }
17397
+ return {
17398
+ sql: `cardinality(${field}) ${predicate.operator === "empty" ? "=" : ">"} 0`,
17399
+ values: fieldValues
17400
+ };
17401
+ }
17375
17402
  if (predicate.type === "membership") {
17376
17403
  const list = placeholders(predicate.values, parameterOffset);
17377
17404
  if (predicate.operator === "in") return {
@@ -17425,6 +17452,7 @@ function compileFeedbackScalarPredicate(predicate, parameterOffset) {
17425
17452
  };
17426
17453
  }
17427
17454
  if (predicate.field !== "value") return compileScalarPredicate(predicate, FEEDBACK_FIELDS, parameterOffset);
17455
+ if (predicate.type === "collection") throw new Error(`Unsupported trusted trace-query field: ${predicate.field}`);
17428
17456
  if (predicate.type === "presence") {
17429
17457
  const present = `(s."valueString" IS NOT NULL OR s."valueNumber" IS NOT NULL)`;
17430
17458
  return {
@@ -17535,27 +17563,39 @@ function compileThreadPredicate(predicate, parameterOffset) {
17535
17563
  values: compiled.values
17536
17564
  };
17537
17565
  }
17538
- function compilePostgresTraceScope(schema, selection, relationCollections, deltaWindow) {
17566
+ function compilePostgresTraceScope(schema, selection, relationCollections, scope, deltaWindow) {
17539
17567
  const spanTable = qualifiedTable(schema, TABLE_SPAN_EVENTS);
17540
17568
  const scoreTable = qualifiedTable(schema, TABLE_SCORE_EVENTS);
17541
17569
  const feedbackTable = qualifiedTable(schema, TABLE_FEEDBACK_EVENTS);
17542
17570
  const values = [selection.timeRange.from, selection.timeRange.to];
17543
- const rootConditions = [
17544
- `r."parentSpanId" IS NULL`,
17545
- latestRootPredicate$1(spanTable),
17546
- `NOT r."isPending"`,
17547
- `r."endedAt" IS NOT NULL`,
17548
- `r."startedAt" >= $1`,
17549
- `r."startedAt" < $2`
17550
- ];
17571
+ const deltaConditions = [];
17551
17572
  if (deltaWindow) {
17552
17573
  values.push(deltaWindow.xactId, deltaWindow.cursorId, deltaWindow.safeHorizon);
17553
- rootConditions.push(`(r."xactId", r."cursorId") > ($3::xid8, $4::bigint)`, `r."xactId" < $5::xid8`);
17574
+ deltaConditions.push(`(r."xactId", r."cursorId") > ($3::xid8, $4::bigint)`, `r."xactId" < $5::xid8`);
17575
+ }
17576
+ const scopeConditions = [];
17577
+ if (scope) {
17578
+ values.push(scope.organizationId);
17579
+ scopeConditions.push(`"organizationId" = $${values.length}`);
17580
+ if (scope.resourceId !== void 0) {
17581
+ values.push(scope.resourceId);
17582
+ scopeConditions.push(`"resourceId" = $${values.length}`);
17583
+ }
17554
17584
  }
17585
+ const scopeSql = (alias) => scopeConditions.map((condition) => `\n AND ${alias}.${condition}`).join("");
17555
17586
  const ctes = [`root_scope AS MATERIALIZED (
17556
17587
  SELECT *
17557
17588
  FROM ${spanTable} r
17558
- WHERE ${rootConditions.join("\n AND ")}
17589
+ WHERE ${[
17590
+ `r."parentSpanId" IS NULL`,
17591
+ latestRootPredicate$1(spanTable),
17592
+ `NOT r."isPending"`,
17593
+ `r."endedAt" IS NOT NULL`,
17594
+ `r."startedAt" >= $1`,
17595
+ `r."startedAt" < $2`,
17596
+ ...deltaConditions,
17597
+ ...scopeConditions.map((condition) => `r.${condition}`)
17598
+ ].join("\n AND ")}
17559
17599
  )`];
17560
17600
  if (relationCollections.has("spans")) ctes.push(`current_spans AS MATERIALIZED (
17561
17601
  SELECT
@@ -17581,7 +17621,7 @@ function compilePostgresTraceScope(schema, selection, relationCollections, delta
17581
17621
  FROM ${spanTable} s
17582
17622
  WHERE s."traceId" IS NOT NULL
17583
17623
  AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17584
- AND ${latestSpanPredicate$1(spanTable)}
17624
+ AND ${latestSpanPredicate$1(spanTable)}${scopeSql("s")}
17585
17625
  )`);
17586
17626
  if (relationCollections.has("scores")) ctes.push(`current_scores AS MATERIALIZED (
17587
17627
  SELECT
@@ -17598,7 +17638,7 @@ function compilePostgresTraceScope(schema, selection, relationCollections, delta
17598
17638
  FROM ${scoreTable} s
17599
17639
  WHERE s."traceId" IS NOT NULL
17600
17640
  AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17601
- AND ${latestScorePredicate(scoreTable)}
17641
+ AND ${latestScorePredicate(scoreTable)}${scopeSql("s")}
17602
17642
  )`);
17603
17643
  if (relationCollections.has("feedback")) ctes.push(`current_feedback AS MATERIALIZED (
17604
17644
  SELECT
@@ -17617,7 +17657,7 @@ function compilePostgresTraceScope(schema, selection, relationCollections, delta
17617
17657
  FROM ${feedbackTable} s
17618
17658
  WHERE s."traceId" IS NOT NULL
17619
17659
  AND s."traceId" IN (SELECT "traceId" FROM root_scope)
17620
- AND ${latestFeedbackPredicate(feedbackTable)}
17660
+ AND ${latestFeedbackPredicate(feedbackTable)}${scopeSql("s")}
17621
17661
  )`);
17622
17662
  return {
17623
17663
  ctes,
@@ -17635,7 +17675,7 @@ function compilePostgresTraceQuery(schema, plan, mode = "data", safeHorizon) {
17635
17675
  safeHorizon
17636
17676
  };
17637
17677
  }
17638
- const { ctes, values } = compilePostgresTraceScope(schema, plan, relationCollections, deltaWindow);
17678
+ const { ctes, values } = compilePostgresTraceScope(schema, plan, relationCollections, plan.scope, deltaWindow);
17639
17679
  let predicateSql = "TRUE";
17640
17680
  if (plan.where) {
17641
17681
  const predicate = compilePredicate(plan.where, values.length + 1);
@@ -17713,7 +17753,7 @@ LIMIT $${values.length}`,
17713
17753
  function compilePostgresThreadQuery(schema, plan) {
17714
17754
  const relationCollections = collectRelationCollections(plan.traces.where);
17715
17755
  collectThreadRelationCollections(plan.where, relationCollections);
17716
- const { ctes, values } = compilePostgresTraceScope(schema, plan.traces, relationCollections);
17756
+ const { ctes, values } = compilePostgresTraceScope(schema, plan.traces, relationCollections, plan.scope);
17717
17757
  let eligibilitySql = "TRUE";
17718
17758
  if (plan.traces.where) {
17719
17759
  const eligibility = compilePredicate(plan.traces.where, values.length + 1);
@@ -17771,7 +17811,7 @@ function discoveryCollections(scope) {
17771
17811
  return scope === "trace" ? /* @__PURE__ */ new Set() : /* @__PURE__ */ new Set([scope]);
17772
17812
  }
17773
17813
  function compilePostgresTraceQueryObservedFields(schema, plan) {
17774
- const { ctes, values } = compilePostgresTraceScope(schema, plan, /* @__PURE__ */ new Set());
17814
+ const { ctes, values } = compilePostgresTraceScope(schema, plan, /* @__PURE__ */ new Set(), plan.scope);
17775
17815
  const searchParameter = values.length + 1;
17776
17816
  const search = plan.search ? `AND strpos(lower('metadata.' || entry.key), lower($${searchParameter})) > 0` : "";
17777
17817
  if (plan.search) values.push(plan.search);
@@ -17795,23 +17835,24 @@ LIMIT $${values.length}`,
17795
17835
  };
17796
17836
  }
17797
17837
  function compilePostgresTraceQueryValues(schema, plan) {
17798
- const { ctes, values } = compilePostgresTraceScope(schema, plan, discoveryCollections(plan.predicateScope));
17799
- let field;
17800
- if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17838
+ const { ctes, values } = compilePostgresTraceScope(schema, plan, discoveryCollections(plan.predicateScope), plan.scope);
17839
+ let extracted;
17840
+ if (plan.predicateScope === "trace" && plan.path === "tags") extracted = `SELECT value FROM (SELECT DISTINCT r."traceId", UNNEST(r."tags") AS value FROM root_scope r) t`;
17841
+ else if (plan.predicateScope === "trace" && plan.path.startsWith("metadata.")) {
17801
17842
  const keyParameter = `$${values.length + 1}`;
17802
- field = `COALESCE(
17843
+ extracted = `SELECT COALESCE(
17803
17844
  CASE WHEN jsonb_typeof(r."metadataSearch" -> ${keyParameter}) = 'string' THEN r."metadataSearch" ->> ${keyParameter} END,
17804
17845
  CASE WHEN jsonb_typeof(r."metadataRaw" -> ${keyParameter}) = 'string' THEN NULLIF(btrim(r."metadataRaw" ->> ${keyParameter}), '') END
17805
- )`;
17846
+ )::text AS value FROM root_scope r`;
17806
17847
  values.push(plan.path.slice(9));
17807
- } else field = fieldSql(discoveryRegistry(plan.predicateScope), plan.path);
17848
+ } else extracted = `SELECT ${fieldSql(discoveryRegistry(plan.predicateScope), plan.path)}::text AS value FROM ${discoverySource(plan.predicateScope)}`;
17808
17849
  const searchParameter = values.length + 1;
17809
17850
  const search = plan.search ? `AND strpos(lower(value), lower($${searchParameter})) > 0` : "";
17810
17851
  if (plan.search) values.push(plan.search);
17811
17852
  values.push(plan.limit + 1);
17812
17853
  return {
17813
17854
  text: `WITH ${ctes.join(",\n")}, extracted AS (
17814
- SELECT ${field}::text AS value FROM ${discoverySource(plan.predicateScope)}
17855
+ ${extracted}
17815
17856
  )
17816
17857
  SELECT value, count(*)::bigint AS count
17817
17858
  FROM extracted
@@ -18910,7 +18951,8 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
18910
18951
  "logs",
18911
18952
  "trace-query",
18912
18953
  "trace-query-discovery",
18913
- "thread-query"
18954
+ "thread-query",
18955
+ "trace-query-tenant-scope"
18914
18956
  ];
18915
18957
  return [
18916
18958
  "metrics",
@@ -18918,7 +18960,8 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
18918
18960
  "delta-polling",
18919
18961
  "trace-query",
18920
18962
  "trace-query-discovery",
18921
- "thread-query"
18963
+ "thread-query",
18964
+ "trace-query-tenant-scope"
18922
18965
  ];
18923
18966
  }
18924
18967
  async #run(op, fn, details) {