@mastra/pg 1.30.0-alpha.2 → 1.30.0-alpha.3

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.30.0-alpha.2"
6
+ version: "1.30.0-alpha.3"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.30.0-alpha.2",
2
+ "version": "1.30.0-alpha.3",
3
3
  "package": "@mastra/pg",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -18508,13 +18508,32 @@ function compilePostgresTraceAggregate(schema, plan) {
18508
18508
  if (intervalMs === void 0) throw new Error(`Unsupported trusted trace-aggregate interval: ${plan.interval}`);
18509
18509
  factColumns.push(`to_timestamp(floor(EXTRACT(EPOCH FROM r."startedAt") * 1000 / ${intervalMs}) * ${intervalMs} / 1000.0) AS "bucket"`);
18510
18510
  }
18511
+ const measureKinds = new Set(plan.measures.map((measure) => measureRule(measure.name)?.kind));
18512
+ const hasCost = measureKinds.has("cost");
18513
+ let usageJoin = "";
18514
+ if (hasCost || measureKinds.has("tokens")) {
18515
+ ctes.push(...compileUsageCtes(schema, plan, param));
18516
+ usageJoin = "\n LEFT JOIN usage u ON u.\"traceId\" = r.\"traceId\"";
18517
+ USAGE_METRIC_NAMES.forEach((_, index) => factColumns.push(`CASE WHEN u."traceId" IS NOT NULL THEN COALESCE(u."t${index}", 0) END AS "t${index}"`));
18518
+ factColumns.push(`u."traceId" IS NOT NULL AS "usageBearing"`, `CASE WHEN u."priced" THEN u."cost" END AS "traceCost"`, `COALESCE(u."priced" AND NOT u."pricingFailure", FALSE) AS "covered"`, `u."unitMin"`, `u."unitMax"`);
18519
+ }
18511
18520
  ctes.push(`facts AS (
18512
18521
  SELECT ${factColumns.join(",\n ")}
18513
- FROM candidates r
18522
+ FROM candidates r${usageJoin}
18514
18523
  )`);
18524
+ const mixedUnitsSql = (alias) => `MIN(${alias}"unitMin" COLLATE "C") <> MAX(${alias}"unitMax" COLLATE "C")`;
18515
18525
  const measureSql = (name, alias = "") => {
18516
18526
  const column = (name) => `${alias}"${name}"`;
18517
18527
  if (name === "count") return "COUNT(*)::float8";
18528
+ const rule = measureRule(name);
18529
+ if (rule?.kind === "tokens" && rule.metricNames) {
18530
+ const value = rule.metricNames.map((metricName) => column(`t${usageMetricIndex(metricName)}`)).join(" + ");
18531
+ return `(${rule.statistic === "avg" ? "AVG" : "SUM"}(${value}))::float8`;
18532
+ }
18533
+ if (rule?.kind === "cost") {
18534
+ const aggregate = rule.statistic === "avg" ? "AVG" : "SUM";
18535
+ return `(CASE WHEN ${mixedUnitsSql(alias)} THEN NULL ELSE ${aggregate}(${column("traceCost")}) END)::float8`;
18536
+ }
18518
18537
  if (name === "errorCount") return `(COUNT(*) FILTER (WHERE ${column("isError")}))::float8`;
18519
18538
  if (name === "errorRate") return `(COUNT(*) FILTER (WHERE ${column("isError")}))::float8 / COUNT(*)`;
18520
18539
  if (name === "duration.avg") return `AVG(${column("durationMs")})`;
@@ -18552,8 +18571,17 @@ function compilePostgresTraceAggregate(schema, plan) {
18552
18571
  const orderSql = [`${orderTarget} ${direction} NULLS LAST`, ...dimensionColumns.map((column) => `${column} COLLATE "C" ASC NULLS LAST`)].join(", ");
18553
18572
  const groupSql = dimensionColumns.length > 0 ? dimensionColumns.join(", ") : "()";
18554
18573
  const limitParameter = param(plan.limit + 1);
18574
+ const costColumns = (alias) => {
18575
+ if (!hasCost) return [];
18576
+ const mixedUnit = param(_mastra_core_storage.TRACE_AGGREGATE_MIXED_COST_UNIT);
18577
+ return [`(COUNT(*) FILTER (WHERE ${alias}"covered"))::float8 / NULLIF(COUNT(*) FILTER (WHERE ${alias}"usageBearing"), 0) AS "costCoverage"`, `CASE WHEN ${mixedUnitsSql(alias)} THEN ${mixedUnit}::text ELSE MIN(${alias}"unitMin" COLLATE "C") END AS "costUnit"`];
18578
+ };
18555
18579
  if (plan.interval === void 0) {
18556
- const projected = [...dimensionColumns, ...plan.measures.map((measure, index) => `${measureSql(measure.name)} AS "m${index}"`)];
18580
+ const projected = [
18581
+ ...dimensionColumns,
18582
+ ...plan.measures.map((measure, index) => `${measureSql(measure.name)} AS "m${index}"`),
18583
+ ...costColumns("")
18584
+ ];
18557
18585
  return {
18558
18586
  text: `WITH ${ctes.join(",\n")}
18559
18587
  SELECT ${projected.join(", ")}
@@ -18579,6 +18607,7 @@ LIMIT ${limitParameter}`,
18579
18607
  ...dimensionColumns.map((column) => `f.${column}`),
18580
18608
  "f.\"bucket\"",
18581
18609
  ...plan.measures.map((measure, index) => `${measureSql(measure.name, "f.")} AS "m${index}"`),
18610
+ ...costColumns("f."),
18582
18611
  `(SELECT COUNT(*) FROM ranked) > ${maxRankParameter} AS "truncated"`
18583
18612
  ];
18584
18613
  return {
@@ -18596,6 +18625,59 @@ ORDER BY g."rank" ASC, f."bucket" ASC`,
18596
18625
  values
18597
18626
  };
18598
18627
  }
18628
+ const USAGE_METRIC_NAMES = _mastra_core_storage.TRACE_AGGREGATE_USAGE_METRIC_NAMES;
18629
+ function measureRule(name) {
18630
+ return _mastra_core_storage.isTraceAggregateCanonicalMeasure(name) ? _mastra_core_storage.TRACE_AGGREGATE_MEASURE_REGISTRY[name] : void 0;
18631
+ }
18632
+ function usageMetricIndex(name) {
18633
+ const index = USAGE_METRIC_NAMES.indexOf(name);
18634
+ if (index === -1) throw new Error(`Unsupported trusted trace-aggregate token metric: ${name}`);
18635
+ return index;
18636
+ }
18637
+ /**
18638
+ * Builds `usage`: one row per candidate trace that has at least one token metric row, holding
18639
+ * per-name token sums (`t<i>`, indexed by `TRACE_AGGREGATE_USAGE_METRIC_NAMES`) and the trace's
18640
+ * pricing state. Metric rows are matched by traceId, usage metric name, tenant scope, and
18641
+ * `timestamp >= from` only: a trace that starts in the window can emit metrics after `to`, and
18642
+ * the candidates semi-join already bounds the scan.
18643
+ *
18644
+ * Rows are deduplicated on `metricId` alone. The primary key is (`metricId`, `timestamp`)
18645
+ * because the table is partitioned by timestamp, so retried copies with different timestamps
18646
+ * are both stored.
18647
+ */
18648
+ function compileUsageCtes(schema, plan, param) {
18649
+ const scopeConditions = plan.scope ? [`m."organizationId" = ${param(plan.scope.organizationId)}`, ...plan.scope.resourceId === void 0 ? [] : [`m."resourceId" = ${param(plan.scope.resourceId)}`]] : [];
18650
+ const rowConditions = [
18651
+ `m."traceId" IN (SELECT "traceId" FROM candidates)`,
18652
+ `m."name" = ANY(${param(USAGE_METRIC_NAMES)}::text[])`,
18653
+ `m."timestamp" >= ${param(plan.timeRange.from)}::timestamptz`,
18654
+ ...scopeConditions
18655
+ ];
18656
+ const costRow = `"name" = ANY(${param(_mastra_core_storage.TRACE_AGGREGATE_COST_METRIC_NAMES)}::text[])`;
18657
+ const priced = `${costRow} AND "estimatedCost" IS NOT NULL AND "costUnit" IS NOT NULL AND NOT "hasError"`;
18658
+ const failed = `${costRow} AND ("hasError" OR ("estimatedCost" IS NOT NULL AND "costUnit" IS NULL))`;
18659
+ const tokenColumns = USAGE_METRIC_NAMES.map((name, index) => `SUM("value") FILTER (WHERE "name" = ${param(name)}) AS "t${index}"`);
18660
+ return [`usage_rows AS (
18661
+ SELECT DISTINCT ON (m."metricId") m."traceId", m."name", m."value", m."estimatedCost", m."costUnit",
18662
+ COALESCE(jsonb_typeof(m."costMetadata" -> 'error'), 'null') <> 'null' AS "hasError"
18663
+ FROM ${qualifiedTable(schema, TABLE_METRIC_EVENTS)} m
18664
+ WHERE ${rowConditions.join("\n AND ")}
18665
+ ORDER BY m."metricId", m."timestamp"
18666
+ )`, `usage AS (
18667
+ SELECT "traceId",
18668
+ ${tokenColumns.join(",\n ")},
18669
+ SUM("estimatedCost") FILTER (WHERE ${priced}) AS "cost",
18670
+ bool_or(${priced}) AS "priced",
18671
+ bool_or(${failed}) AS "pricingFailure",
18672
+ MIN("costUnit" COLLATE "C") FILTER (WHERE ${priced}) AS "unitMin",
18673
+ MAX("costUnit" COLLATE "C") FILTER (WHERE ${priced}) AS "unitMax"
18674
+ FROM usage_rows
18675
+ GROUP BY "traceId"
18676
+ )`];
18677
+ }
18678
+ function nullableNumber(value) {
18679
+ return value === null || value === void 0 ? null : Number(value);
18680
+ }
18599
18681
  function toIsoTimestamp(value) {
18600
18682
  return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
18601
18683
  }
@@ -18613,7 +18695,11 @@ async function aggregateTraces(client, schema, plan, timeoutMs) {
18613
18695
  }
18614
18696
  return {
18615
18697
  rows: resultRows.map((row) => {
18616
- const shaped = { measures: Object.fromEntries(plan.measures.map((measure, index) => [measure.name, Number(row[`m${index}`])])) };
18698
+ const shaped = { measures: Object.fromEntries(plan.measures.map((measure, index) => [measure.name, nullableNumber(row[`m${index}`])])) };
18699
+ if ("costCoverage" in row) shaped.cost = {
18700
+ coverage: nullableNumber(row.costCoverage),
18701
+ unit: row.costUnit ?? null
18702
+ };
18617
18703
  if (plan.dimensions.length > 0) shaped.dimensions = Object.fromEntries(plan.dimensions.map((dimension, index) => [dimension, row[`d${index}`] ?? null]));
18618
18704
  if (plan.interval !== void 0) shaped.bucket = toIsoTimestamp(row.bucket);
18619
18705
  return shaped;