@mastra/clickhouse 1.25.2-alpha.0 → 1.26.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-clickhouse
3
3
  description: Documentation for @mastra/clickhouse. Use when working with @mastra/clickhouse APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/clickhouse"
6
- version: "1.25.2-alpha.0"
6
+ version: "1.26.0-alpha.1"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.25.2-alpha.0",
2
+ "version": "1.26.0-alpha.1",
3
3
  "package": "@mastra/clickhouse",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -3838,9 +3838,27 @@ function readPreview(preview, payload, jsonEncoded = false) {
3838
3838
  }
3839
3839
  /** Older response builders may shorten previews or turn empty strings into null. */
3840
3840
  function buildSpanQueryResponse(...args) {
3841
- if (canGeneratePreviews) return _mastra_core_storage.buildSpanQueryResponse(...args);
3842
- const [plan, selected, payloads, metrics] = args;
3843
- const response = _mastra_core_storage.buildSpanQueryResponse(plan, selected, [], metrics);
3841
+ const [plan, selected, payloads, metrics = []] = args;
3842
+ const compatibleSelected = _mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY ? selected : selected.map((row) => ({
3843
+ organizationId: row.organizationId,
3844
+ resourceId: row.resourceId,
3845
+ traceId: row.traceId,
3846
+ spanId: row.spanId,
3847
+ parentSpanId: row.parentSpanId,
3848
+ name: row.name,
3849
+ spanType: row.spanType,
3850
+ status: row.status,
3851
+ startedAt: row.startedAt,
3852
+ endedAt: row.endedAt,
3853
+ durationMs: row.durationMs,
3854
+ entityType: row.entityType,
3855
+ entityId: row.entityId,
3856
+ entityName: row.entityName,
3857
+ model: row.model,
3858
+ provider: row.provider
3859
+ }));
3860
+ if (canGeneratePreviews) return _mastra_core_storage.buildSpanQueryResponse(plan, compatibleSelected, payloads, metrics);
3861
+ const response = _mastra_core_storage.buildSpanQueryResponse(plan, compatibleSelected, [], metrics);
3844
3862
  const byIdentity = new Map(payloads.map((payload) => [_mastra_core_storage.spanQueryIdentityKey(payload), payload]));
3845
3863
  for (const span of response.spans) {
3846
3864
  const payload = byIdentity.get(_mastra_core_storage.spanQueryIdentityKey(span));
@@ -4792,6 +4810,7 @@ function buildMetricsFilterConditions(filters, tableAlias) {
4792
4810
  assertNoDeprecatedSourceFilter(filters.source, "executionSource", "metrics");
4793
4811
  addCommonFilterFields(filters, tableAlias, out);
4794
4812
  addIn(col("traceId"), filters.traceIds, "traceIds", out);
4813
+ addIn(col("experimentId"), filters.experimentIds, "experimentIds", out);
4795
4814
  addIn(col("name"), filters.name, "metricNames", out);
4796
4815
  addEq(col("provider"), filters.provider, "provider", "String", out);
4797
4816
  addEq(col("model"), filters.model, "model", "String", out);
@@ -6985,6 +7004,73 @@ const SPAN_FIELDS = {
6985
7004
  parameterType: "String"
6986
7005
  }
6987
7006
  };
7007
+ const SPAN_QUERY_FIELDS = {
7008
+ ...SPAN_FIELDS,
7009
+ traceId: {
7010
+ sql: "s.traceId",
7011
+ parameterType: "String"
7012
+ },
7013
+ spanId: {
7014
+ sql: "s.spanId",
7015
+ parameterType: "String"
7016
+ },
7017
+ parentSpanId: {
7018
+ sql: "s.parentSpanId",
7019
+ parameterType: "String"
7020
+ },
7021
+ threadId: {
7022
+ sql: "s.threadId",
7023
+ parameterType: "String"
7024
+ },
7025
+ resourceId: {
7026
+ sql: "s.resourceId",
7027
+ parameterType: "String"
7028
+ },
7029
+ requestId: {
7030
+ sql: "s.requestId",
7031
+ parameterType: "String"
7032
+ },
7033
+ serviceName: {
7034
+ sql: "s.serviceName",
7035
+ parameterType: "String"
7036
+ },
7037
+ experimentId: {
7038
+ sql: "s.experimentId",
7039
+ parameterType: "String"
7040
+ },
7041
+ environment: {
7042
+ sql: "s.environment",
7043
+ parameterType: "String"
7044
+ },
7045
+ executionSource: {
7046
+ sql: "s.executionSource",
7047
+ parameterType: "String"
7048
+ },
7049
+ parentEntityType: {
7050
+ sql: "s.parentEntityType",
7051
+ parameterType: "String"
7052
+ },
7053
+ parentEntityId: {
7054
+ sql: "s.parentEntityId",
7055
+ parameterType: "String"
7056
+ },
7057
+ parentEntityName: {
7058
+ sql: "s.parentEntityName",
7059
+ parameterType: "String"
7060
+ },
7061
+ rootEntityType: {
7062
+ sql: "s.rootEntityType",
7063
+ parameterType: "String"
7064
+ },
7065
+ rootEntityId: {
7066
+ sql: "s.rootEntityId",
7067
+ parameterType: "String"
7068
+ },
7069
+ rootEntityName: {
7070
+ sql: "s.rootEntityName",
7071
+ parameterType: "String"
7072
+ }
7073
+ };
6988
7074
  const SCORE_FIELDS = {
6989
7075
  scorerId: {
6990
7076
  sql: "s.scorerId",
@@ -7856,11 +7942,11 @@ async function queryThreads(client, plan, timeoutMs) {
7856
7942
  }) : null }
7857
7943
  });
7858
7944
  }
7859
- /** Compile a span-row filter with exactly the same rules as trace span predicates. */
7945
+ /** Compile a direct span-query filter using its dedicated field mapping. */
7860
7946
  function compileSpanQueryPredicate(predicate) {
7861
7947
  const parameters = new ParameterBuilder();
7862
7948
  return {
7863
- sql: compileScalarPredicate(predicate, SPAN_FIELDS, parameters),
7949
+ sql: compileScalarPredicate(predicate, SPAN_QUERY_FIELDS, parameters),
7864
7950
  params: parameters.params
7865
7951
  };
7866
7952
  }
@@ -7874,7 +7960,6 @@ const identityFields = [
7874
7960
  ];
7875
7961
  const identities = identityFields.join(", ");
7876
7962
  const identitySetColumns = "isNull(organizationId), ifNull(organizationId, ''), isNull(resourceId), ifNull(resourceId, ''), traceId, spanId";
7877
- const identitySetKey = `tuple(${identitySetColumns})`;
7878
7963
  const displayFields = [
7879
7964
  "parentSpanId",
7880
7965
  "name",
@@ -7882,6 +7967,24 @@ const displayFields = [
7882
7967
  "entityType",
7883
7968
  "entityId",
7884
7969
  "entityName",
7970
+ "entityVersionId",
7971
+ "parentEntityType",
7972
+ "parentEntityId",
7973
+ "parentEntityName",
7974
+ "parentEntityVersionId",
7975
+ "rootEntityType",
7976
+ "rootEntityId",
7977
+ "rootEntityName",
7978
+ "rootEntityVersionId",
7979
+ "threadId",
7980
+ "runId",
7981
+ "sessionId",
7982
+ "userId",
7983
+ "requestId",
7984
+ "serviceName",
7985
+ "experimentId",
7986
+ "environment",
7987
+ "executionSource",
7885
7988
  "startedAt",
7886
7989
  "endedAt",
7887
7990
  "model",
@@ -7960,15 +8063,11 @@ function compileClickHouseSpanQuery(plan) {
7960
8063
  const expressions = selectionFields.map(fieldExpression);
7961
8064
  const after = afterCursor(plan, parameters);
7962
8065
  return {
7963
- query: `WITH candidate_ids AS (
7964
- SELECT ${identitySetKey} AS identity FROM ${TABLE_SPAN_EVENTS}
7965
- PREWHERE endedAt >= ${from}
7966
- WHERE startedAt >= ${from} AND startedAt < ${to} ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
7967
- ), candidates AS (
8066
+ query: `WITH candidates AS (
7968
8067
  SELECT ${identities}, ${selectionFields.map((field, index) => `${expressions[index]} AS ${field}`).join(", ")}
7969
8068
  FROM ${TABLE_SPAN_EVENTS} e
7970
8069
  PREWHERE e.endedAt >= ${from}
7971
- WHERE ${identitySetKey} IN (SELECT identity FROM candidate_ids) ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
8070
+ WHERE e.startedAt >= ${from} AND e.startedAt < ${to} ${scope.length ? `AND ${scope.join(" AND ")}` : ""}
7972
8071
  ORDER BY ${identities}, e.endedAt DESC
7973
8072
  LIMIT 1 BY ${identities}
7974
8073
  )
@@ -7986,6 +8085,7 @@ function compileClickHouseSpanQuery(plan) {
7986
8085
  }
7987
8086
  };
7988
8087
  }
8088
+ const LEGACY_PAYLOAD_BATCH_ROWS = 32;
7989
8089
  function iso(value) {
7990
8090
  return new Date(value.includes("T") ? value : `${value.replace(" ", "T")}Z`).toISOString();
7991
8091
  }
@@ -8019,34 +8119,25 @@ async function querySpans(client, plan, timeoutMs) {
8019
8119
  });
8020
8120
  const missingKeys = new Set(rowsWithPreviews.filter(needsPreviewPayloads).map(_mastra_core_storage.spanQueryIdentityKey));
8021
8121
  const missing = page.filter((row) => missingKeys.has(_mastra_core_storage.spanQueryIdentityKey(row)));
8022
- const previewPayloads = /* @__PURE__ */ new Map();
8023
- if (missing.length) {
8122
+ const storedByIdentity = new Map(rowsWithPreviews.map((row) => [_mastra_core_storage.spanQueryIdentityKey(row), row]));
8123
+ for (let start = 0; start < missing.length; start += LEGACY_PAYLOAD_BATCH_ROWS) {
8024
8124
  const rows = await run({
8025
8125
  query: `SELECT ${identities}, data.1 AS input, data.2 AS output, data.3 AS error
8026
8126
  FROM (SELECT ${identities}, any(tuple(input, output, error)) AS data
8027
8127
  FROM ${TABLE_SPAN_EVENTS} e WHERE ${payloadWhere} GROUP BY ${identities})`,
8028
- query_params: { page: pageParameter(missing) }
8128
+ query_params: { page: pageParameter(missing.slice(start, start + LEGACY_PAYLOAD_BATCH_ROWS)) }
8029
8129
  });
8030
- for (const row of rows) previewPayloads.set(_mastra_core_storage.spanQueryIdentityKey(row), row);
8130
+ for (const row of rows) {
8131
+ const stored = storedByIdentity.get(_mastra_core_storage.spanQueryIdentityKey(row));
8132
+ if (stored) Object.assign(stored, resolveStoredPreviews(stored, row));
8133
+ }
8031
8134
  }
8032
8135
  const payloads = rowsWithPreviews.map((row) => ({
8033
8136
  ...row,
8034
- ...resolveStoredPreviews(row, previewPayloads.get(_mastra_core_storage.spanQueryIdentityKey(row)))
8137
+ ...resolveStoredPreviews(row)
8035
8138
  }));
8036
- const metricWhere = `${identitySetKey} IN {page:Array(Tuple(UInt8, String, UInt8, String, String, String))}`;
8037
- const metrics = await run({
8038
- query: `SELECT ${identities}, data.1 AS name, data.2 AS estimatedCost,
8039
- data.3 AS costUnit, data.4 AS allocation, data.5 AS costError
8040
- FROM (SELECT ${identities}, metricId, argMax(tuple(name, estimatedCost, costUnit,
8041
- JSONExtractString(costMetadata, 'allocation'), JSONHas(costMetadata, 'error')), timestamp) AS data
8042
- FROM ${TABLE_METRIC_EVENTS} WHERE (${metricWhere}) AND name LIKE 'mastra_model_%'
8043
- GROUP BY ${identities}, metricId)
8044
- LIMIT ${_mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS + 1}`,
8045
- query_params: { page: page.map((row) => new _clickhouse_client.TupleParam(identityValues(row))) }
8046
- });
8047
- if (metrics.length > _mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS) throw new _mastra_core_storage.TraceQueryResourceLimitError();
8048
8139
  const byIdentity = new Map(payloads.map((row) => [_mastra_core_storage.spanQueryIdentityKey(row), row]));
8049
- const result = buildSpanQueryResponse(plan, page.flatMap((identity) => {
8140
+ const hydrated = page.flatMap((identity) => {
8050
8141
  const row = byIdentity.get(_mastra_core_storage.spanQueryIdentityKey(identity));
8051
8142
  if (!row) return [];
8052
8143
  const { inputPreview: _input, outputPreview: _output, errorPreview: _error, ...metadata } = row;
@@ -8055,7 +8146,22 @@ async function querySpans(client, plan, timeoutMs) {
8055
8146
  ...identity,
8056
8147
  durationMs: Number(row.durationMs)
8057
8148
  }];
8058
- }), payloads, metrics);
8149
+ });
8150
+ let metrics = [];
8151
+ if (!_mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY) {
8152
+ metrics = await run({
8153
+ query: `SELECT ${identities}, data.1 AS name, data.2 AS estimatedCost,
8154
+ data.3 AS costUnit, data.4 AS allocation, data.5 AS costError
8155
+ FROM (SELECT ${identities}, metricId, argMax(tuple(name, estimatedCost, costUnit,
8156
+ JSONExtractString(costMetadata, 'allocation'), JSONHas(costMetadata, 'error')), timestamp) AS data
8157
+ FROM ${TABLE_METRIC_EVENTS} WHERE (${`tuple(${identitySetColumns}) IN {page:Array(Tuple(UInt8, String, UInt8, String, String, String))}`}) AND name LIKE 'mastra_model_%'
8158
+ GROUP BY ${identities}, metricId)
8159
+ LIMIT ${_mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS + 1}`,
8160
+ query_params: { page: page.map((row) => new _clickhouse_client.TupleParam(identityValues(row))) }
8161
+ });
8162
+ if (metrics.length > _mastra_core_storage.SPAN_QUERY_MAX_COST_METRICS) throw new _mastra_core_storage.TraceQueryResourceLimitError();
8163
+ }
8164
+ const result = buildSpanQueryResponse(plan, hydrated, payloads, metrics);
8059
8165
  const last = page.at(-1);
8060
8166
  result.page.next = selected.length > plan.limit ? _mastra_core_storage.encodeSpanQueryCursor(plan, {
8061
8167
  organizationId: last.organizationId,
@@ -9214,7 +9320,7 @@ function buildBranchCursor(row) {
9214
9320
  }
9215
9321
  //#endregion
9216
9322
  //#region src/storage/domains/observability/v-next/index.ts
9217
- const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? ["span-query"] : [];
9323
+ const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? ["span-query", "span-query-context-fields"] : [];
9218
9324
  function buildSignalMigrationRequiredMessage(args) {
9219
9325
  const tableList = args.tables.map((table) => ` - ${table.table} (${table.engine})`).join("\n");
9220
9326
  return `