@mastra/clickhouse 1.25.2-alpha.0 → 1.26.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/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +146 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +146 -33
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts +3 -3
- package/dist/storage/domains/observability/v-next/ddl.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/filters.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/helpers.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/preview-compat.d.ts +18 -12
- package/dist/storage/domains/observability/v-next/preview-compat.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/span-query.d.ts +18 -12
- package/dist/storage/domains/observability/v-next/span-query.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -2720,6 +2720,7 @@ CREATE TABLE IF NOT EXISTS ${TABLE_SPAN_EVENTS} (
|
|
|
2720
2720
|
isEvent Bool DEFAULT false,
|
|
2721
2721
|
startedAt DateTime64(3, 'UTC'),
|
|
2722
2722
|
endedAt DateTime64(3, 'UTC'),
|
|
2723
|
+
timeToFirstChunkMs Nullable(Float64),
|
|
2723
2724
|
|
|
2724
2725
|
-- Query-relevant flexible fields
|
|
2725
2726
|
tags Array(LowCardinality(String)) DEFAULT [],
|
|
@@ -2793,6 +2794,7 @@ CREATE TABLE IF NOT EXISTS ${TABLE_TRACE_ROOTS} (
|
|
|
2793
2794
|
isEvent Bool DEFAULT false,
|
|
2794
2795
|
startedAt DateTime64(3, 'UTC'),
|
|
2795
2796
|
endedAt DateTime64(3, 'UTC'),
|
|
2797
|
+
timeToFirstChunkMs Nullable(Float64),
|
|
2796
2798
|
|
|
2797
2799
|
-- Query-relevant flexible fields
|
|
2798
2800
|
tags Array(LowCardinality(String)) DEFAULT [],
|
|
@@ -2878,6 +2880,7 @@ CREATE TABLE IF NOT EXISTS ${TABLE_TRACE_BRANCHES} (
|
|
|
2878
2880
|
isEvent Bool DEFAULT false,
|
|
2879
2881
|
startedAt DateTime64(3, 'UTC'),
|
|
2880
2882
|
endedAt DateTime64(3, 'UTC'),
|
|
2883
|
+
timeToFirstChunkMs Nullable(Float64),
|
|
2881
2884
|
|
|
2882
2885
|
-- Query-relevant flexible fields
|
|
2883
2886
|
tags Array(LowCardinality(String)) DEFAULT [],
|
|
@@ -3683,7 +3686,10 @@ const ALL_MIGRATIONS = [
|
|
|
3683
3686
|
addBloomIndex(TABLE_METRIC_EVENTS, "idx_sessionId", "sessionId"),
|
|
3684
3687
|
addBloomIndex(TABLE_METRIC_EVENTS, "idx_requestId", "requestId"),
|
|
3685
3688
|
...LOG_SKIP_INDEX_COLUMNS.map((column) => addBloomIndex(TABLE_LOG_EVENTS, `idx_${column}`, column)),
|
|
3686
|
-
addBloomIndex(TABLE_DELETION_REQUESTS, "idx_predicateValues", "predicateValues")
|
|
3689
|
+
addBloomIndex(TABLE_DELETION_REQUESTS, "idx_predicateValues", "predicateValues"),
|
|
3690
|
+
addColumn(TABLE_TRACE_ROOTS, "timeToFirstChunkMs", "Nullable(Float64)"),
|
|
3691
|
+
addColumn(TABLE_TRACE_BRANCHES, "timeToFirstChunkMs", "Nullable(Float64)"),
|
|
3692
|
+
addColumn(TABLE_SPAN_EVENTS, "timeToFirstChunkMs", "Nullable(Float64)")
|
|
3687
3693
|
];
|
|
3688
3694
|
const ALL_TABLE_NAMES = [
|
|
3689
3695
|
TABLE_SPAN_EVENTS,
|
|
@@ -3815,9 +3821,27 @@ function readPreview(preview, payload, jsonEncoded = false) {
|
|
|
3815
3821
|
}
|
|
3816
3822
|
/** Older response builders may shorten previews or turn empty strings into null. */
|
|
3817
3823
|
function buildSpanQueryResponse(...args) {
|
|
3818
|
-
|
|
3819
|
-
const
|
|
3820
|
-
|
|
3824
|
+
const [plan, selected, payloads, metrics = []] = args;
|
|
3825
|
+
const compatibleSelected = coreStorage.SPAN_QUERY_FIELD_REGISTRY ? selected : selected.map((row) => ({
|
|
3826
|
+
organizationId: row.organizationId,
|
|
3827
|
+
resourceId: row.resourceId,
|
|
3828
|
+
traceId: row.traceId,
|
|
3829
|
+
spanId: row.spanId,
|
|
3830
|
+
parentSpanId: row.parentSpanId,
|
|
3831
|
+
name: row.name,
|
|
3832
|
+
spanType: row.spanType,
|
|
3833
|
+
status: row.status,
|
|
3834
|
+
startedAt: row.startedAt,
|
|
3835
|
+
endedAt: row.endedAt,
|
|
3836
|
+
durationMs: row.durationMs,
|
|
3837
|
+
entityType: row.entityType,
|
|
3838
|
+
entityId: row.entityId,
|
|
3839
|
+
entityName: row.entityName,
|
|
3840
|
+
model: row.model,
|
|
3841
|
+
provider: row.provider
|
|
3842
|
+
}));
|
|
3843
|
+
if (canGeneratePreviews) return coreStorage.buildSpanQueryResponse(plan, compatibleSelected, payloads, metrics);
|
|
3844
|
+
const response = coreStorage.buildSpanQueryResponse(plan, compatibleSelected, [], metrics);
|
|
3821
3845
|
const byIdentity = new Map(payloads.map((payload) => [coreStorage.spanQueryIdentityKey(payload), payload]));
|
|
3822
3846
|
for (const span of response.spans) {
|
|
3823
3847
|
const payload = byIdentity.get(coreStorage.spanQueryIdentityKey(span));
|
|
@@ -4114,6 +4138,7 @@ function spanRecordToRow(span) {
|
|
|
4114
4138
|
isEvent: span.isEvent,
|
|
4115
4139
|
startedAt: toISOString(span.startedAt),
|
|
4116
4140
|
endedAt: toISOString(endedAt),
|
|
4141
|
+
timeToFirstChunkMs: span.timeToFirstChunkMs ?? null,
|
|
4117
4142
|
tags: normalizeTags(span.tags),
|
|
4118
4143
|
metadataSearch: buildMetadataSearch(metadata),
|
|
4119
4144
|
metadataRaw: jsonEncode(metadata),
|
|
@@ -4769,6 +4794,7 @@ function buildMetricsFilterConditions(filters, tableAlias) {
|
|
|
4769
4794
|
assertNoDeprecatedSourceFilter(filters.source, "executionSource", "metrics");
|
|
4770
4795
|
addCommonFilterFields(filters, tableAlias, out);
|
|
4771
4796
|
addIn(col("traceId"), filters.traceIds, "traceIds", out);
|
|
4797
|
+
addIn(col("experimentId"), filters.experimentIds, "experimentIds", out);
|
|
4772
4798
|
addIn(col("name"), filters.name, "metricNames", out);
|
|
4773
4799
|
addEq(col("provider"), filters.provider, "provider", "String", out);
|
|
4774
4800
|
addEq(col("model"), filters.model, "model", "String", out);
|
|
@@ -6962,6 +6988,73 @@ const SPAN_FIELDS = {
|
|
|
6962
6988
|
parameterType: "String"
|
|
6963
6989
|
}
|
|
6964
6990
|
};
|
|
6991
|
+
const SPAN_QUERY_FIELDS = {
|
|
6992
|
+
...SPAN_FIELDS,
|
|
6993
|
+
traceId: {
|
|
6994
|
+
sql: "s.traceId",
|
|
6995
|
+
parameterType: "String"
|
|
6996
|
+
},
|
|
6997
|
+
spanId: {
|
|
6998
|
+
sql: "s.spanId",
|
|
6999
|
+
parameterType: "String"
|
|
7000
|
+
},
|
|
7001
|
+
parentSpanId: {
|
|
7002
|
+
sql: "s.parentSpanId",
|
|
7003
|
+
parameterType: "String"
|
|
7004
|
+
},
|
|
7005
|
+
threadId: {
|
|
7006
|
+
sql: "s.threadId",
|
|
7007
|
+
parameterType: "String"
|
|
7008
|
+
},
|
|
7009
|
+
resourceId: {
|
|
7010
|
+
sql: "s.resourceId",
|
|
7011
|
+
parameterType: "String"
|
|
7012
|
+
},
|
|
7013
|
+
requestId: {
|
|
7014
|
+
sql: "s.requestId",
|
|
7015
|
+
parameterType: "String"
|
|
7016
|
+
},
|
|
7017
|
+
serviceName: {
|
|
7018
|
+
sql: "s.serviceName",
|
|
7019
|
+
parameterType: "String"
|
|
7020
|
+
},
|
|
7021
|
+
experimentId: {
|
|
7022
|
+
sql: "s.experimentId",
|
|
7023
|
+
parameterType: "String"
|
|
7024
|
+
},
|
|
7025
|
+
environment: {
|
|
7026
|
+
sql: "s.environment",
|
|
7027
|
+
parameterType: "String"
|
|
7028
|
+
},
|
|
7029
|
+
executionSource: {
|
|
7030
|
+
sql: "s.executionSource",
|
|
7031
|
+
parameterType: "String"
|
|
7032
|
+
},
|
|
7033
|
+
parentEntityType: {
|
|
7034
|
+
sql: "s.parentEntityType",
|
|
7035
|
+
parameterType: "String"
|
|
7036
|
+
},
|
|
7037
|
+
parentEntityId: {
|
|
7038
|
+
sql: "s.parentEntityId",
|
|
7039
|
+
parameterType: "String"
|
|
7040
|
+
},
|
|
7041
|
+
parentEntityName: {
|
|
7042
|
+
sql: "s.parentEntityName",
|
|
7043
|
+
parameterType: "String"
|
|
7044
|
+
},
|
|
7045
|
+
rootEntityType: {
|
|
7046
|
+
sql: "s.rootEntityType",
|
|
7047
|
+
parameterType: "String"
|
|
7048
|
+
},
|
|
7049
|
+
rootEntityId: {
|
|
7050
|
+
sql: "s.rootEntityId",
|
|
7051
|
+
parameterType: "String"
|
|
7052
|
+
},
|
|
7053
|
+
rootEntityName: {
|
|
7054
|
+
sql: "s.rootEntityName",
|
|
7055
|
+
parameterType: "String"
|
|
7056
|
+
}
|
|
7057
|
+
};
|
|
6965
7058
|
const SCORE_FIELDS = {
|
|
6966
7059
|
scorerId: {
|
|
6967
7060
|
sql: "s.scorerId",
|
|
@@ -7833,11 +7926,11 @@ async function queryThreads(client, plan, timeoutMs) {
|
|
|
7833
7926
|
}) : null }
|
|
7834
7927
|
});
|
|
7835
7928
|
}
|
|
7836
|
-
/** Compile a span-
|
|
7929
|
+
/** Compile a direct span-query filter using its dedicated field mapping. */
|
|
7837
7930
|
function compileSpanQueryPredicate(predicate) {
|
|
7838
7931
|
const parameters = new ParameterBuilder();
|
|
7839
7932
|
return {
|
|
7840
|
-
sql: compileScalarPredicate(predicate,
|
|
7933
|
+
sql: compileScalarPredicate(predicate, SPAN_QUERY_FIELDS, parameters),
|
|
7841
7934
|
params: parameters.params
|
|
7842
7935
|
};
|
|
7843
7936
|
}
|
|
@@ -7851,7 +7944,6 @@ const identityFields = [
|
|
|
7851
7944
|
];
|
|
7852
7945
|
const identities = identityFields.join(", ");
|
|
7853
7946
|
const identitySetColumns = "isNull(organizationId), ifNull(organizationId, ''), isNull(resourceId), ifNull(resourceId, ''), traceId, spanId";
|
|
7854
|
-
const identitySetKey = `tuple(${identitySetColumns})`;
|
|
7855
7947
|
const displayFields = [
|
|
7856
7948
|
"parentSpanId",
|
|
7857
7949
|
"name",
|
|
@@ -7859,6 +7951,24 @@ const displayFields = [
|
|
|
7859
7951
|
"entityType",
|
|
7860
7952
|
"entityId",
|
|
7861
7953
|
"entityName",
|
|
7954
|
+
"entityVersionId",
|
|
7955
|
+
"parentEntityType",
|
|
7956
|
+
"parentEntityId",
|
|
7957
|
+
"parentEntityName",
|
|
7958
|
+
"parentEntityVersionId",
|
|
7959
|
+
"rootEntityType",
|
|
7960
|
+
"rootEntityId",
|
|
7961
|
+
"rootEntityName",
|
|
7962
|
+
"rootEntityVersionId",
|
|
7963
|
+
"threadId",
|
|
7964
|
+
"runId",
|
|
7965
|
+
"sessionId",
|
|
7966
|
+
"userId",
|
|
7967
|
+
"requestId",
|
|
7968
|
+
"serviceName",
|
|
7969
|
+
"experimentId",
|
|
7970
|
+
"environment",
|
|
7971
|
+
"executionSource",
|
|
7862
7972
|
"startedAt",
|
|
7863
7973
|
"endedAt",
|
|
7864
7974
|
"model",
|
|
@@ -7937,15 +8047,11 @@ function compileClickHouseSpanQuery(plan) {
|
|
|
7937
8047
|
const expressions = selectionFields.map(fieldExpression);
|
|
7938
8048
|
const after = afterCursor(plan, parameters);
|
|
7939
8049
|
return {
|
|
7940
|
-
query: `WITH
|
|
7941
|
-
SELECT ${identitySetKey} AS identity FROM ${TABLE_SPAN_EVENTS}
|
|
7942
|
-
PREWHERE endedAt >= ${from}
|
|
7943
|
-
WHERE startedAt >= ${from} AND startedAt < ${to} ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
|
|
7944
|
-
), candidates AS (
|
|
8050
|
+
query: `WITH candidates AS (
|
|
7945
8051
|
SELECT ${identities}, ${selectionFields.map((field, index) => `${expressions[index]} AS ${field}`).join(", ")}
|
|
7946
8052
|
FROM ${TABLE_SPAN_EVENTS} e
|
|
7947
8053
|
PREWHERE e.endedAt >= ${from}
|
|
7948
|
-
WHERE ${
|
|
8054
|
+
WHERE e.startedAt >= ${from} AND e.startedAt < ${to} ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
|
|
7949
8055
|
ORDER BY ${identities}, e.endedAt DESC
|
|
7950
8056
|
LIMIT 1 BY ${identities}
|
|
7951
8057
|
)
|
|
@@ -7963,6 +8069,7 @@ function compileClickHouseSpanQuery(plan) {
|
|
|
7963
8069
|
}
|
|
7964
8070
|
};
|
|
7965
8071
|
}
|
|
8072
|
+
const LEGACY_PAYLOAD_BATCH_ROWS = 32;
|
|
7966
8073
|
function iso(value) {
|
|
7967
8074
|
return new Date(value.includes("T") ? value : `${value.replace(" ", "T")}Z`).toISOString();
|
|
7968
8075
|
}
|
|
@@ -7996,34 +8103,25 @@ async function querySpans(client, plan, timeoutMs) {
|
|
|
7996
8103
|
});
|
|
7997
8104
|
const missingKeys = new Set(rowsWithPreviews.filter(needsPreviewPayloads).map(coreStorage.spanQueryIdentityKey));
|
|
7998
8105
|
const missing = page.filter((row) => missingKeys.has(coreStorage.spanQueryIdentityKey(row)));
|
|
7999
|
-
const
|
|
8000
|
-
|
|
8106
|
+
const storedByIdentity = new Map(rowsWithPreviews.map((row) => [coreStorage.spanQueryIdentityKey(row), row]));
|
|
8107
|
+
for (let start = 0; start < missing.length; start += LEGACY_PAYLOAD_BATCH_ROWS) {
|
|
8001
8108
|
const rows = await run({
|
|
8002
8109
|
query: `SELECT ${identities}, data.1 AS input, data.2 AS output, data.3 AS error
|
|
8003
8110
|
FROM (SELECT ${identities}, any(tuple(input, output, error)) AS data
|
|
8004
8111
|
FROM ${TABLE_SPAN_EVENTS} e WHERE ${payloadWhere} GROUP BY ${identities})`,
|
|
8005
|
-
query_params: { page: pageParameter(missing) }
|
|
8112
|
+
query_params: { page: pageParameter(missing.slice(start, start + LEGACY_PAYLOAD_BATCH_ROWS)) }
|
|
8006
8113
|
});
|
|
8007
|
-
for (const row of rows)
|
|
8114
|
+
for (const row of rows) {
|
|
8115
|
+
const stored = storedByIdentity.get(coreStorage.spanQueryIdentityKey(row));
|
|
8116
|
+
if (stored) Object.assign(stored, resolveStoredPreviews(stored, row));
|
|
8117
|
+
}
|
|
8008
8118
|
}
|
|
8009
8119
|
const payloads = rowsWithPreviews.map((row) => ({
|
|
8010
8120
|
...row,
|
|
8011
|
-
...resolveStoredPreviews(row
|
|
8121
|
+
...resolveStoredPreviews(row)
|
|
8012
8122
|
}));
|
|
8013
|
-
const metricWhere = `${identitySetKey} IN {page:Array(Tuple(UInt8, String, UInt8, String, String, String))}`;
|
|
8014
|
-
const metrics = await run({
|
|
8015
|
-
query: `SELECT ${identities}, data.1 AS name, data.2 AS estimatedCost,
|
|
8016
|
-
data.3 AS costUnit, data.4 AS allocation, data.5 AS costError
|
|
8017
|
-
FROM (SELECT ${identities}, metricId, argMax(tuple(name, estimatedCost, costUnit,
|
|
8018
|
-
JSONExtractString(costMetadata, 'allocation'), JSONHas(costMetadata, 'error')), timestamp) AS data
|
|
8019
|
-
FROM ${TABLE_METRIC_EVENTS} WHERE (${metricWhere}) AND name LIKE 'mastra_model_%'
|
|
8020
|
-
GROUP BY ${identities}, metricId)
|
|
8021
|
-
LIMIT ${coreStorage.SPAN_QUERY_MAX_COST_METRICS + 1}`,
|
|
8022
|
-
query_params: { page: page.map((row) => new TupleParam(identityValues(row))) }
|
|
8023
|
-
});
|
|
8024
|
-
if (metrics.length > coreStorage.SPAN_QUERY_MAX_COST_METRICS) throw new coreStorage.TraceQueryResourceLimitError();
|
|
8025
8123
|
const byIdentity = new Map(payloads.map((row) => [coreStorage.spanQueryIdentityKey(row), row]));
|
|
8026
|
-
const
|
|
8124
|
+
const hydrated = page.flatMap((identity) => {
|
|
8027
8125
|
const row = byIdentity.get(coreStorage.spanQueryIdentityKey(identity));
|
|
8028
8126
|
if (!row) return [];
|
|
8029
8127
|
const { inputPreview: _input, outputPreview: _output, errorPreview: _error, ...metadata } = row;
|
|
@@ -8032,7 +8130,22 @@ async function querySpans(client, plan, timeoutMs) {
|
|
|
8032
8130
|
...identity,
|
|
8033
8131
|
durationMs: Number(row.durationMs)
|
|
8034
8132
|
}];
|
|
8035
|
-
})
|
|
8133
|
+
});
|
|
8134
|
+
let metrics = [];
|
|
8135
|
+
if (!coreStorage.SPAN_QUERY_FIELD_REGISTRY) {
|
|
8136
|
+
metrics = await run({
|
|
8137
|
+
query: `SELECT ${identities}, data.1 AS name, data.2 AS estimatedCost,
|
|
8138
|
+
data.3 AS costUnit, data.4 AS allocation, data.5 AS costError
|
|
8139
|
+
FROM (SELECT ${identities}, metricId, argMax(tuple(name, estimatedCost, costUnit,
|
|
8140
|
+
JSONExtractString(costMetadata, 'allocation'), JSONHas(costMetadata, 'error')), timestamp) AS data
|
|
8141
|
+
FROM ${TABLE_METRIC_EVENTS} WHERE (${`tuple(${identitySetColumns}) IN {page:Array(Tuple(UInt8, String, UInt8, String, String, String))}`}) AND name LIKE 'mastra_model_%'
|
|
8142
|
+
GROUP BY ${identities}, metricId)
|
|
8143
|
+
LIMIT ${coreStorage.SPAN_QUERY_MAX_COST_METRICS + 1}`,
|
|
8144
|
+
query_params: { page: page.map((row) => new TupleParam(identityValues(row))) }
|
|
8145
|
+
});
|
|
8146
|
+
if (metrics.length > coreStorage.SPAN_QUERY_MAX_COST_METRICS) throw new coreStorage.TraceQueryResourceLimitError();
|
|
8147
|
+
}
|
|
8148
|
+
const result = buildSpanQueryResponse(plan, hydrated, payloads, metrics);
|
|
8036
8149
|
const last = page.at(-1);
|
|
8037
8150
|
result.page.next = selected.length > plan.limit ? coreStorage.encodeSpanQueryCursor(plan, {
|
|
8038
8151
|
organizationId: last.organizationId,
|
|
@@ -9191,7 +9304,7 @@ function buildBranchCursor(row) {
|
|
|
9191
9304
|
}
|
|
9192
9305
|
//#endregion
|
|
9193
9306
|
//#region src/storage/domains/observability/v-next/index.ts
|
|
9194
|
-
const spanQueryFeatures = typeof coreStorage.planSpanQuery === "function" ? ["span-query"] : [];
|
|
9307
|
+
const spanQueryFeatures = typeof coreStorage.planSpanQuery === "function" ? ["span-query", "span-query-context-fields"] : [];
|
|
9195
9308
|
function buildSignalMigrationRequiredMessage(args) {
|
|
9196
9309
|
const tableList = args.tables.map((table) => ` - ${table.table} (${table.engine})`).join("\n");
|
|
9197
9310
|
return `
|