@mastra/pg 1.32.0 → 1.33.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.
- package/dist/_types/@internal_core/dist/knowledge-compat/index.d.ts +48 -48
- package/dist/_types/@internal_core/dist/memory/index.d.ts +12 -13
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/docs/references/docs-memory-semantic-recall.md +2 -2
- package/dist/docs/references/docs-memory-working-memory.md +2 -2
- package/dist/docs/references/docs-storage.md +1 -1
- package/dist/docs/references/integrations-databases-postgresql.md +1 -1
- package/dist/docs/references/reference-memory-memory-class.md +3 -3
- package/dist/docs/references/reference-processors-message-history-processor.md +2 -2
- package/dist/docs/references/reference-processors-semantic-recall-processor.md +2 -2
- package/dist/docs/references/reference-processors-working-memory-processor.md +2 -2
- package/dist/docs/references/reference-rag-chunking-and-embedding.md +1 -1
- package/dist/docs/references/reference-rag-metadata-filters.md +1 -1
- package/dist/docs/references/reference-rag-retrieval.md +13 -13
- package/dist/docs/references/reference-storage-retention.md +1 -1
- package/dist/docs/references/reference-tools-vector-query-tool.md +1 -1
- package/dist/docs/references/reference-vectors-pg.md +1 -1
- package/dist/index.cjs +151 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +152 -35
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +3 -2
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/span-query.d.ts +9 -0
- package/dist/storage/domains/observability/v-next/span-query.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-aggregate.d.ts +7 -1
- package/dist/storage/domains/observability/v-next/trace-aggregate.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +5 -2
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/package.json +9 -9
|
@@ -148,7 +148,7 @@ const queryTool = createVectorQueryTool({
|
|
|
148
148
|
indexName: 'documentation',
|
|
149
149
|
model: new ModelRouterEmbeddingModel('openai/text-embedding-3-small'),
|
|
150
150
|
reranker: {
|
|
151
|
-
model: 'openai/gpt-
|
|
151
|
+
model: 'openai/gpt-6.1-sol',
|
|
152
152
|
options: {
|
|
153
153
|
weights: {
|
|
154
154
|
semantic: 0.5, // Semantic relevance weight
|
|
@@ -412,7 +412,7 @@ export const pgAgent = new Agent({
|
|
|
412
412
|
name: 'PG Agent',
|
|
413
413
|
instructions:
|
|
414
414
|
'You are an AI agent with the ability to automatically recall memories from previous interactions.',
|
|
415
|
-
model: 'openai/gpt-
|
|
415
|
+
model: 'openai/gpt-6.1-sol',
|
|
416
416
|
memory: new Memory({
|
|
417
417
|
storage: new PostgresStore({
|
|
418
418
|
id: 'pg-agent-storage',
|
package/dist/index.cjs
CHANGED
|
@@ -20280,7 +20280,12 @@ function afterCursor(plan, values) {
|
|
|
20280
20280
|
}
|
|
20281
20281
|
return `(${terms.join(" OR ")})`;
|
|
20282
20282
|
}
|
|
20283
|
-
|
|
20283
|
+
/**
|
|
20284
|
+
* The spans `querySpans()` pages through, as a `selected` CTE: the latest completed copy of each
|
|
20285
|
+
* span that starts in the window and matches `where`. `aggregateSpans()` groups the same CTE.
|
|
20286
|
+
* `values` holds the CTEs' parameters; callers append their own.
|
|
20287
|
+
*/
|
|
20288
|
+
function compilePostgresSpanSelection(schema, plan) {
|
|
20284
20289
|
const values = [plan.timeRange.from, plan.timeRange.to];
|
|
20285
20290
|
const scope = [];
|
|
20286
20291
|
if (plan.scope) {
|
|
@@ -20296,17 +20301,17 @@ function compilePostgresSpanQuery(schema, plan) {
|
|
|
20296
20301
|
values: []
|
|
20297
20302
|
};
|
|
20298
20303
|
values.push(...predicate.values);
|
|
20299
|
-
const after = afterCursor(plan, values);
|
|
20300
|
-
values.push(plan.limit + 1);
|
|
20301
20304
|
const table = qualifiedTable(schema, TABLE_SPAN_EVENTS);
|
|
20302
20305
|
const legacyModelFields = _mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY ? "" : `CASE WHEN jsonb_typeof(attributes -> 'model') = 'string' THEN attributes ->> 'model' END AS model,
|
|
20303
20306
|
CASE WHEN jsonb_typeof(attributes -> 'provider') = 'string' THEN attributes ->> 'provider' END AS provider,`;
|
|
20304
20307
|
return {
|
|
20305
|
-
|
|
20308
|
+
ctes: [
|
|
20309
|
+
`candidate_ids AS MATERIALIZED (
|
|
20306
20310
|
SELECT DISTINCT ${identities} FROM ${table}
|
|
20307
20311
|
WHERE "startedAt" >= $1 AND "startedAt" < $2 AND "endedAt" >= $1 AND NOT "isPending"
|
|
20308
20312
|
${scope.length ? `AND ${scope.join(" AND ")}` : ""}
|
|
20309
|
-
)
|
|
20313
|
+
)`,
|
|
20314
|
+
`current_spans AS MATERIALIZED (
|
|
20310
20315
|
SELECT DISTINCT ON (${identities})
|
|
20311
20316
|
${fields.map((field) => `"${field}"`).join(", ")}, "startedAt", "endedAt", "cursorId"::text AS version,
|
|
20312
20317
|
${legacyModelFields}
|
|
@@ -20320,9 +20325,23 @@ function compilePostgresSpanQuery(schema, plan) {
|
|
|
20320
20325
|
SELECT "organizationId" IS NULL, COALESCE("organizationId", ''), "resourceId" IS NULL, COALESCE("resourceId", ''), "traceId", "spanId" FROM candidate_ids
|
|
20321
20326
|
) ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
|
|
20322
20327
|
ORDER BY ${identities}, "endedAt" DESC, "cursorId" DESC
|
|
20323
|
-
)
|
|
20328
|
+
)`,
|
|
20329
|
+
`candidates AS (
|
|
20324
20330
|
SELECT *, CASE WHEN "hasError" THEN 'error' ELSE NULL END AS error FROM current_spans
|
|
20325
|
-
)
|
|
20331
|
+
)`,
|
|
20332
|
+
`selected AS (
|
|
20333
|
+
SELECT * FROM candidates s WHERE s."startedAt" >= $1 AND s."startedAt" < $2 AND (${predicate.sql})
|
|
20334
|
+
)`
|
|
20335
|
+
],
|
|
20336
|
+
values
|
|
20337
|
+
};
|
|
20338
|
+
}
|
|
20339
|
+
function compilePostgresSpanQuery(schema, plan) {
|
|
20340
|
+
const { ctes, values } = compilePostgresSpanSelection(schema, plan);
|
|
20341
|
+
const after = afterCursor(plan, values);
|
|
20342
|
+
values.push(plan.limit + 1);
|
|
20343
|
+
return {
|
|
20344
|
+
text: `WITH ${ctes.join(", ")}
|
|
20326
20345
|
SELECT ${[
|
|
20327
20346
|
...fields,
|
|
20328
20347
|
"startedAt",
|
|
@@ -20331,7 +20350,7 @@ function compilePostgresSpanQuery(schema, plan) {
|
|
|
20331
20350
|
"status",
|
|
20332
20351
|
"version"
|
|
20333
20352
|
].map((field) => `s."${field}"`).join(", ")}
|
|
20334
|
-
FROM
|
|
20353
|
+
FROM selected s WHERE ${after}
|
|
20335
20354
|
ORDER BY s."${plan.orderBy.field}" ${plan.orderBy.direction === "asc" ? "ASC" : "DESC"} NULLS LAST, ${identityOrder}
|
|
20336
20355
|
LIMIT $${values.length}`,
|
|
20337
20356
|
values
|
|
@@ -20665,6 +20684,28 @@ const DIMENSION_SQL = {
|
|
|
20665
20684
|
organizationId: "r.\"organizationId\"",
|
|
20666
20685
|
experimentId: "r.\"experimentId\""
|
|
20667
20686
|
};
|
|
20687
|
+
/** Span column expressions (alias `r`, a `selected` span row) for each groupable span dimension. */
|
|
20688
|
+
const SPAN_DIMENSION_SQL = Object.fromEntries([
|
|
20689
|
+
"name",
|
|
20690
|
+
"spanType",
|
|
20691
|
+
"entityType",
|
|
20692
|
+
"entityId",
|
|
20693
|
+
"entityName",
|
|
20694
|
+
"parentEntityType",
|
|
20695
|
+
"parentEntityName",
|
|
20696
|
+
"rootEntityType",
|
|
20697
|
+
"rootEntityName",
|
|
20698
|
+
"environment",
|
|
20699
|
+
"status",
|
|
20700
|
+
"serviceName",
|
|
20701
|
+
"executionSource",
|
|
20702
|
+
"threadId",
|
|
20703
|
+
"resourceId",
|
|
20704
|
+
"userId",
|
|
20705
|
+
"sessionId",
|
|
20706
|
+
"organizationId",
|
|
20707
|
+
"experimentId"
|
|
20708
|
+
].map((field) => [field, `r."${field}"`]));
|
|
20668
20709
|
const PERCENTILES = {
|
|
20669
20710
|
"duration.p50": .5,
|
|
20670
20711
|
"duration.p90": .9,
|
|
@@ -20690,16 +20731,43 @@ const COMPARISON_SQL = {
|
|
|
20690
20731
|
*/
|
|
20691
20732
|
function compilePostgresTraceAggregate(schema, plan) {
|
|
20692
20733
|
const { ctes, values } = compilePostgresTraceCandidates(schema, plan, "r.*");
|
|
20734
|
+
return compilePostgresAggregate(schema, plan, {
|
|
20735
|
+
ctes,
|
|
20736
|
+
values,
|
|
20737
|
+
from: "candidates",
|
|
20738
|
+
dimensionSql: (field, param) => {
|
|
20739
|
+
if (field.startsWith("metadata.")) return traceMetadataValueSql(param(field.slice(9)));
|
|
20740
|
+
return lookupDimensionSql(DIMENSION_SQL, field);
|
|
20741
|
+
},
|
|
20742
|
+
usageKey: ["traceId"]
|
|
20743
|
+
});
|
|
20744
|
+
}
|
|
20745
|
+
/**
|
|
20746
|
+
* Compiles a trusted span aggregate plan over the spans `querySpans()` selects. Usage is
|
|
20747
|
+
* attributed by `(traceId, spanId)`, so only the span that recorded a metric row carries it.
|
|
20748
|
+
*/
|
|
20749
|
+
function compilePostgresSpanAggregate(schema, plan) {
|
|
20750
|
+
const { ctes, values } = compilePostgresSpanSelection(schema, plan);
|
|
20751
|
+
return compilePostgresAggregate(schema, plan, {
|
|
20752
|
+
ctes,
|
|
20753
|
+
values,
|
|
20754
|
+
from: "selected",
|
|
20755
|
+
dimensionSql: (field) => lookupDimensionSql(SPAN_DIMENSION_SQL, field),
|
|
20756
|
+
usageKey: ["traceId", "spanId"]
|
|
20757
|
+
});
|
|
20758
|
+
}
|
|
20759
|
+
function lookupDimensionSql(columns, field) {
|
|
20760
|
+
const sql = Object.hasOwn(columns, field) ? columns[field] : void 0;
|
|
20761
|
+
if (sql === void 0) throw new Error(`Unsupported trusted aggregate field: ${field}`);
|
|
20762
|
+
return sql;
|
|
20763
|
+
}
|
|
20764
|
+
function compilePostgresAggregate(schema, plan, source) {
|
|
20765
|
+
const { ctes, values } = source;
|
|
20693
20766
|
const param = (value) => {
|
|
20694
20767
|
values.push(value);
|
|
20695
20768
|
return `$${values.length}`;
|
|
20696
20769
|
};
|
|
20697
|
-
const dimensionSql = (field) =>
|
|
20698
|
-
if (field.startsWith("metadata.")) return traceMetadataValueSql(param(field.slice(9)));
|
|
20699
|
-
const sql = Object.hasOwn(DIMENSION_SQL, field) ? DIMENSION_SQL[field] : void 0;
|
|
20700
|
-
if (sql === void 0) throw new Error(`Unsupported trusted trace-aggregate field: ${field}`);
|
|
20701
|
-
return sql;
|
|
20702
|
-
};
|
|
20770
|
+
const dimensionSql = (field) => source.dimensionSql(field, param);
|
|
20703
20771
|
const distinctSql = (field) => field === "traceId" ? "r.\"traceId\"" : dimensionSql(field);
|
|
20704
20772
|
const dimensionColumns = plan.dimensions.map((_, index) => `"d${index}"`);
|
|
20705
20773
|
const distinctColumns = /* @__PURE__ */ new Map();
|
|
@@ -20720,14 +20788,14 @@ function compilePostgresTraceAggregate(schema, plan) {
|
|
|
20720
20788
|
const hasCost = measureKinds.has("cost");
|
|
20721
20789
|
let usageJoin = "";
|
|
20722
20790
|
if (hasCost || measureKinds.has("tokens")) {
|
|
20723
|
-
ctes.push(...compileUsageCtes(schema, plan, param));
|
|
20724
|
-
usageJoin =
|
|
20791
|
+
ctes.push(...compileUsageCtes(schema, plan, source, param));
|
|
20792
|
+
usageJoin = `\n LEFT JOIN usage u ON ${source.usageKey.map((key) => `u."${key}" = r."${key}"`).join(" AND ")}`;
|
|
20725
20793
|
USAGE_METRIC_NAMES.forEach((_, index) => factColumns.push(`CASE WHEN u."traceId" IS NOT NULL THEN COALESCE(u."t${index}", 0) END AS "t${index}"`));
|
|
20726
20794
|
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"`);
|
|
20727
20795
|
}
|
|
20728
20796
|
ctes.push(`facts AS (
|
|
20729
20797
|
SELECT ${factColumns.join(",\n ")}
|
|
20730
|
-
FROM
|
|
20798
|
+
FROM ${source.from} r${usageJoin}
|
|
20731
20799
|
)`);
|
|
20732
20800
|
const mixedUnitsSql = (alias) => `MIN(${alias}"unitMin" COLLATE "C") <> MAX(${alias}"unitMax" COLLATE "C")`;
|
|
20733
20801
|
const measureSql = (name, alias = "") => {
|
|
@@ -20843,36 +20911,39 @@ function usageMetricIndex(name) {
|
|
|
20843
20911
|
return index;
|
|
20844
20912
|
}
|
|
20845
20913
|
/**
|
|
20846
|
-
* Builds `usage`: one row per
|
|
20847
|
-
* per-name token sums (`t<i>`, indexed by `TRACE_AGGREGATE_USAGE_METRIC_NAMES`) and
|
|
20848
|
-
* pricing state. Metric rows are matched by
|
|
20849
|
-
* `timestamp >= from` only: a trace that starts in the window can emit metrics
|
|
20850
|
-
* the
|
|
20914
|
+
* Builds `usage`: one row per population row (trace, or span) that has at least one token metric
|
|
20915
|
+
* row, holding per-name token sums (`t<i>`, indexed by `TRACE_AGGREGATE_USAGE_METRIC_NAMES`) and
|
|
20916
|
+
* its pricing state. Metric rows are matched by the source's usage key, usage metric name, tenant
|
|
20917
|
+
* scope, and `timestamp >= from` only: a trace or span that starts in the window can emit metrics
|
|
20918
|
+
* after `to`, and the population semi-join already bounds the scan.
|
|
20851
20919
|
*
|
|
20852
20920
|
* Rows are deduplicated on `metricId` alone. The primary key is (`metricId`, `timestamp`)
|
|
20853
20921
|
* because the table is partitioned by timestamp, so retried copies with different timestamps
|
|
20854
20922
|
* are both stored.
|
|
20855
20923
|
*/
|
|
20856
|
-
function compileUsageCtes(schema, plan, param) {
|
|
20924
|
+
function compileUsageCtes(schema, plan, source, param) {
|
|
20925
|
+
const key = source.usageKey.map((column) => `"${column}"`).join(", ");
|
|
20926
|
+
const metricKey = source.usageKey.map((column) => `m."${column}"`).join(", ");
|
|
20857
20927
|
const scopeConditions = plan.scope ? [`m."organizationId" = ${param(plan.scope.organizationId)}`, ...plan.scope.resourceId === void 0 ? [] : [`m."resourceId" = ${param(plan.scope.resourceId)}`]] : [];
|
|
20858
20928
|
const rowConditions = [
|
|
20859
|
-
|
|
20929
|
+
`${source.usageKey.length === 1 ? metricKey : `(${metricKey})`} IN (SELECT ${key} FROM ${source.from})`,
|
|
20860
20930
|
`m."name" = ANY(${param(USAGE_METRIC_NAMES)}::text[])`,
|
|
20861
20931
|
`m."timestamp" >= ${param(plan.timeRange.from)}::timestamptz`,
|
|
20862
20932
|
...scopeConditions
|
|
20863
20933
|
];
|
|
20864
20934
|
const costRow = `"name" = ANY(${param(_mastra_core_storage.TRACE_AGGREGATE_COST_METRIC_NAMES)}::text[])`;
|
|
20865
|
-
const priced = `${costRow} AND "estimatedCost" IS NOT NULL AND "costUnit" IS NOT NULL AND NOT "hasError"`;
|
|
20935
|
+
const priced = `${costRow} AND "estimatedCost" IS NOT NULL AND "costUnit" IS NOT NULL AND (NOT "hasError" OR "partialCost")`;
|
|
20866
20936
|
const failed = `${costRow} AND ("hasError" OR ("estimatedCost" IS NOT NULL AND "costUnit" IS NULL))`;
|
|
20867
20937
|
const tokenColumns = USAGE_METRIC_NAMES.map((name, index) => `SUM("value") FILTER (WHERE "name" = ${param(name)}) AS "t${index}"`);
|
|
20868
20938
|
return [`usage_rows AS (
|
|
20869
|
-
SELECT DISTINCT ON (m."metricId")
|
|
20870
|
-
COALESCE(jsonb_typeof(m."costMetadata" -> 'error'), 'null') <> 'null' AS "hasError"
|
|
20939
|
+
SELECT DISTINCT ON (m."metricId") ${metricKey}, m."name", m."value", m."estimatedCost", m."costUnit",
|
|
20940
|
+
COALESCE(jsonb_typeof(m."costMetadata" -> 'error'), 'null') <> 'null' AS "hasError",
|
|
20941
|
+
COALESCE(m."costMetadata" ->> 'error' = 'partial_cost', FALSE) AS "partialCost"
|
|
20871
20942
|
FROM ${qualifiedTable(schema, TABLE_METRIC_EVENTS)} m
|
|
20872
20943
|
WHERE ${rowConditions.join("\n AND ")}
|
|
20873
20944
|
ORDER BY m."metricId", m."timestamp"
|
|
20874
20945
|
)`, `usage AS (
|
|
20875
|
-
SELECT
|
|
20946
|
+
SELECT ${key},
|
|
20876
20947
|
${tokenColumns.join(",\n ")},
|
|
20877
20948
|
SUM("estimatedCost") FILTER (WHERE ${priced}) AS "cost",
|
|
20878
20949
|
bool_or(${priced}) AS "priced",
|
|
@@ -20880,7 +20951,7 @@ function compileUsageCtes(schema, plan, param) {
|
|
|
20880
20951
|
MIN("costUnit" COLLATE "C") FILTER (WHERE ${priced}) AS "unitMin",
|
|
20881
20952
|
MAX("costUnit" COLLATE "C") FILTER (WHERE ${priced}) AS "unitMax"
|
|
20882
20953
|
FROM usage_rows
|
|
20883
|
-
GROUP BY
|
|
20954
|
+
GROUP BY ${key}
|
|
20884
20955
|
)`];
|
|
20885
20956
|
}
|
|
20886
20957
|
function nullableNumber(value) {
|
|
@@ -20890,7 +20961,12 @@ function toIsoTimestamp(value) {
|
|
|
20890
20961
|
return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
|
|
20891
20962
|
}
|
|
20892
20963
|
async function aggregateTraces(client, schema, plan, timeoutMs) {
|
|
20893
|
-
|
|
20964
|
+
return runAggregate(client, plan, compilePostgresTraceAggregate(schema, plan), timeoutMs);
|
|
20965
|
+
}
|
|
20966
|
+
async function aggregateSpans(client, schema, plan, timeoutMs) {
|
|
20967
|
+
return runAggregate(client, plan, compilePostgresSpanAggregate(schema, plan), timeoutMs);
|
|
20968
|
+
}
|
|
20969
|
+
async function runAggregate(client, plan, compiled, timeoutMs) {
|
|
20894
20970
|
const result = await runWithPostgresTraceQueryTimeout(client, timeoutMs, (transaction) => transaction.any(compiled.text, compiled.values));
|
|
20895
20971
|
let truncated;
|
|
20896
20972
|
let resultRows;
|
|
@@ -21686,6 +21762,7 @@ async function dangerouslyClearTracing(client, schema) {
|
|
|
21686
21762
|
* Use it through `MastraCompositeStore` with a dedicated Postgres connection.
|
|
21687
21763
|
*/
|
|
21688
21764
|
const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? ["span-query", "span-query-context-fields"] : [];
|
|
21765
|
+
const spanAggregateFeatures = typeof _mastra_core_storage.planSpanAggregate === "function" ? ["span-aggregate"] : [];
|
|
21689
21766
|
function wrapError(op, error, details) {
|
|
21690
21767
|
if (error instanceof _mastra_core_error.MastraError || error instanceof _mastra_core_storage.TraceQueryCursorError || error instanceof _mastra_core_storage.TraceQueryExecutionError || error instanceof _mastra_core_storage.TraceQueryResourceLimitError) throw error;
|
|
21691
21768
|
throw new _mastra_core_error.MastraError({
|
|
@@ -21876,6 +21953,7 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
|
|
|
21876
21953
|
"trace-query",
|
|
21877
21954
|
"trace-aggregate",
|
|
21878
21955
|
...spanQueryFeatures,
|
|
21956
|
+
...spanAggregateFeatures,
|
|
21879
21957
|
...typeof _mastra_core_storage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [],
|
|
21880
21958
|
"trace-query-root-duration",
|
|
21881
21959
|
"trace-query-discovery",
|
|
@@ -21900,6 +21978,7 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
|
|
|
21900
21978
|
"trace-query",
|
|
21901
21979
|
"trace-aggregate",
|
|
21902
21980
|
...spanQueryFeatures,
|
|
21981
|
+
...spanAggregateFeatures,
|
|
21903
21982
|
...typeof _mastra_core_storage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [],
|
|
21904
21983
|
"trace-query-root-duration",
|
|
21905
21984
|
"trace-query-discovery",
|
|
@@ -21964,6 +22043,9 @@ var ObservabilityStoragePostgresVNext = class ObservabilityStoragePostgresVNext
|
|
|
21964
22043
|
async aggregateTraces(plan) {
|
|
21965
22044
|
return this.#run("AGGREGATE_TRACES", () => aggregateTraces(this.#readClient, this.#schema, plan, this.#traceQueryTimeoutMs));
|
|
21966
22045
|
}
|
|
22046
|
+
async aggregateSpans(plan) {
|
|
22047
|
+
return this.#run("AGGREGATE_SPANS", () => aggregateSpans(this.#readClient, this.#schema, plan, this.#traceQueryTimeoutMs));
|
|
22048
|
+
}
|
|
21967
22049
|
async getTraceQueryObservedFields(plan) {
|
|
21968
22050
|
return this.#run("GET_TRACE_QUERY_OBSERVED_FIELDS", () => getTraceQueryObservedFields(this.#readClient, this.#schema, plan, this.#traceQueryTimeoutMs));
|
|
21969
22051
|
}
|
|
@@ -25826,7 +25908,10 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
25826
25908
|
throw this.#ownershipError("GET_RUN_OWNERSHIP", runId, error);
|
|
25827
25909
|
}
|
|
25828
25910
|
}
|
|
25829
|
-
|
|
25911
|
+
supportsWorkflowStepGuards() {
|
|
25912
|
+
return true;
|
|
25913
|
+
}
|
|
25914
|
+
async updateWorkflowResults({ workflowName, runId, stepId, result, requestContext, state, fence: explicitFence, startGuard, completionGuard }) {
|
|
25830
25915
|
const fence = (0, _mastra_core_storage.resolveRunFence)(this, explicitFence, runId);
|
|
25831
25916
|
try {
|
|
25832
25917
|
return await this.#db.client.tx(async (t) => {
|
|
@@ -25836,16 +25921,48 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
25836
25921
|
schemaName: getSchemaName(this.#schema)
|
|
25837
25922
|
});
|
|
25838
25923
|
const existingSnapshotResult = await t.oneOrNone(`SELECT snapshot FROM ${tableName} WHERE workflow_name = $1 AND run_id = $2 FOR UPDATE`, [workflowName, runId]);
|
|
25839
|
-
if (!existingSnapshotResult)
|
|
25924
|
+
if (!existingSnapshotResult) {
|
|
25925
|
+
(0, _mastra_core_storage.assertWorkflowStepGuard)({
|
|
25926
|
+
snapshot: null,
|
|
25927
|
+
stepId,
|
|
25928
|
+
startGuard,
|
|
25929
|
+
completionGuard
|
|
25930
|
+
});
|
|
25931
|
+
return {};
|
|
25932
|
+
}
|
|
25840
25933
|
const existingSnapshot = existingSnapshotResult.snapshot;
|
|
25841
25934
|
const snapshot = typeof existingSnapshot === "string" ? JSON.parse(existingSnapshot) : existingSnapshot;
|
|
25842
|
-
(0, _mastra_core_storage.
|
|
25935
|
+
(0, _mastra_core_storage.assertWorkflowStepGuard)({
|
|
25936
|
+
snapshot,
|
|
25937
|
+
stepId,
|
|
25938
|
+
startGuard,
|
|
25939
|
+
completionGuard
|
|
25940
|
+
});
|
|
25941
|
+
if (completionGuard?.pruneOnly) snapshot.context[stepId] = {
|
|
25942
|
+
...result,
|
|
25943
|
+
metadata: {
|
|
25944
|
+
...snapshot.context[stepId]?.metadata,
|
|
25945
|
+
...result.metadata,
|
|
25946
|
+
__continuationStarted: true
|
|
25947
|
+
}
|
|
25948
|
+
};
|
|
25949
|
+
else (0, _mastra_core_storage.mergeWorkflowStepResult)({
|
|
25843
25950
|
snapshot,
|
|
25844
25951
|
stepId,
|
|
25845
25952
|
result,
|
|
25846
25953
|
requestContext,
|
|
25847
25954
|
state
|
|
25848
25955
|
});
|
|
25956
|
+
const previous = startGuard?.previousStep;
|
|
25957
|
+
const previousResult = previous && snapshot.context[previous.stepId];
|
|
25958
|
+
if (previous && previous.stepId !== stepId && previousResult?.status === "success" && previousResult.metadata?.startedBy === previous.eventId) snapshot.context[previous.stepId] = {
|
|
25959
|
+
...previous.result,
|
|
25960
|
+
metadata: {
|
|
25961
|
+
...previousResult.metadata,
|
|
25962
|
+
...previous.result.metadata,
|
|
25963
|
+
__continuationStarted: true
|
|
25964
|
+
}
|
|
25965
|
+
};
|
|
25849
25966
|
const now = /* @__PURE__ */ new Date();
|
|
25850
25967
|
const sanitizedSnapshot = toPgJson(snapshot);
|
|
25851
25968
|
await t.none(`INSERT INTO ${tableName}
|
|
@@ -25864,7 +25981,7 @@ var WorkflowsPG = class WorkflowsPG extends _mastra_core_storage.WorkflowsStorag
|
|
|
25864
25981
|
return snapshot.context;
|
|
25865
25982
|
});
|
|
25866
25983
|
} catch (error) {
|
|
25867
|
-
if ((0, _mastra_core_storage.isRunFenceConflictError)(error)) throw error;
|
|
25984
|
+
if ((0, _mastra_core_storage.isRunFenceConflictError)(error) || (0, _mastra_core_storage.isWorkflowStepConflictError)(error)) throw error;
|
|
25868
25985
|
throw new _mastra_core_error.MastraError({
|
|
25869
25986
|
id: (0, _mastra_core_storage.createStorageErrorId)("PG", "UPDATE_WORKFLOW_RESULTS", "FAILED"),
|
|
25870
25987
|
domain: _mastra_core_error.ErrorDomain.STORAGE,
|