@mastra/clickhouse 1.28.0-alpha.1 → 1.28.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.
@@ -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.28.0-alpha.1"
6
+ version: "1.28.0-alpha.2"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.28.0-alpha.1",
2
+ "version": "1.28.0-alpha.2",
3
3
  "package": "@mastra/clickhouse",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -6938,6 +6938,13 @@ const timingFeatures = [
6938
6938
  ...timeToFirstTokenSupported ? ["trace-query-time-to-first-token"] : [],
6939
6939
  ...timeToFirstTokenSupported && timeToFirstTokenSortSupported ? ["trace-query-time-to-first-token-sort"] : []
6940
6940
  ];
6941
+ /**
6942
+ * Outcome fields follow the same rule: core before them rejects their predicates and strict rows,
6943
+ * so they are only returned and declared when core knows them.
6944
+ */
6945
+ const spanQueryOutcomeFieldsSupported = "outcome" in (_mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY ?? {});
6946
+ const traceQueryOutcomeFieldsSupported = "outcome" in (_mastra_core_storage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});
6947
+ const outcomeFeatures = [...spanQueryOutcomeFieldsSupported ? ["span-query-outcome-fields"] : [], ...traceQueryOutcomeFieldsSupported ? ["trace-query-outcome-fields"] : []];
6941
6948
  /** Order fields holding numbers that can be empty; the rest are timestamps. */
6942
6949
  const NUMERIC_ORDER_FIELDS = /* @__PURE__ */ new Set(["timeToFirstChunkMs", "timeToFirstTokenMs"]);
6943
6950
  function durationMsSql(startedAt, endedAt) {
@@ -7024,6 +7031,14 @@ const TRACE_FIELDS = {
7024
7031
  sql: TRACE_STATUS_SQL,
7025
7032
  parameterType: "String"
7026
7033
  },
7034
+ outcome: {
7035
+ sql: "r.outcome",
7036
+ parameterType: "String"
7037
+ },
7038
+ stopReason: {
7039
+ sql: "r.stopReason",
7040
+ parameterType: "String"
7041
+ },
7027
7042
  tags: {
7028
7043
  sql: "r.tags",
7029
7044
  parameterType: "String"
@@ -7070,6 +7085,14 @@ const SPAN_FIELDS = {
7070
7085
  sql: "s.status",
7071
7086
  parameterType: "String"
7072
7087
  },
7088
+ outcome: {
7089
+ sql: "s.outcome",
7090
+ parameterType: "String"
7091
+ },
7092
+ stopReason: {
7093
+ sql: "s.stopReason",
7094
+ parameterType: "String"
7095
+ },
7073
7096
  error: {
7074
7097
  sql: "s.error",
7075
7098
  parameterType: "String"
@@ -7279,6 +7302,9 @@ const TRACE_SELECT = `
7279
7302
  r.environment AS environment,
7280
7303
  r.timeToFirstChunkMs AS timeToFirstChunkMs,
7281
7304
  r.timeToFirstTokenMs AS timeToFirstTokenMs,
7305
+ r.outcome AS outcome,
7306
+ r.stopReason AS stopReason,
7307
+ r.stopReasonContext AS stopReasonContext,
7282
7308
  ${TRACE_STATUS_SQL} AS status`;
7283
7309
  var ParameterBuilder = class {
7284
7310
  params = {};
@@ -7479,14 +7505,16 @@ function compileClickHouseTraceScope(selection, relationCollections, parameters,
7479
7505
  traceId,
7480
7506
  name,
7481
7507
  spanType,
7482
- if(JSONType(attributes, 'model') = 'String', JSONExtractString(attributes, 'model'), NULL) AS model,
7483
- if(JSONType(attributes, 'provider') = 'String', JSONExtractString(attributes, 'provider'), NULL) AS provider,
7508
+ coalesce(model, if(JSONType(attributes, 'model') = 'String', JSONExtractString(attributes, 'model'), NULL)) AS model,
7509
+ coalesce(provider, if(JSONType(attributes, 'provider') = 'String', JSONExtractString(attributes, 'provider'), NULL)) AS provider,
7484
7510
  startedAt,
7485
7511
  endedAt,
7486
7512
  ${durationMsSql("startedAt", "endedAt")} AS durationMs,
7487
7513
  timeToFirstChunkMs,
7488
7514
  timeToFirstTokenMs,
7489
7515
  if(isNotNull(error), 'error', 'success') AS status,
7516
+ outcome,
7517
+ stopReason,
7490
7518
  error,
7491
7519
  entityType,
7492
7520
  entityId,
@@ -7590,7 +7618,7 @@ const QUERY_TRACES_SCOPE = {
7590
7618
  oneRootPerTrace: true,
7591
7619
  spanExistence: true
7592
7620
  };
7593
- const TRACE_LIST_SELECT = TRACE_SELECT.split("\n").filter((line) => !/ AS (metadata|inputPreview|outputPreview|errorPreview),$/.test(line)).join("\n");
7621
+ const TRACE_LIST_SELECT = TRACE_SELECT.split("\n").filter((line) => !/ AS (metadata|inputPreview|outputPreview|errorPreview|stopReasonContext),$/.test(line)).join("\n");
7594
7622
  function traceOrder(plan) {
7595
7623
  return {
7596
7624
  field: resolveOrderField(plan.orderBy.field),
@@ -7750,7 +7778,7 @@ function compileClickHouseTraceRootPayloads(keys, scope, columns = "payload") {
7750
7778
  const tenant = (value) => `${parameters.add(value ?? "", "String")}, ${value === null ? 1 : 0}`;
7751
7779
  const tuples = keys.map((key) => `(${parameters.add(key.startedAt, "DateTime64(3, 'UTC')")}, ${parameters.add(key.traceId, "String")}, ${parameters.add(key.dedupeKey, "String")}, ${parameters.add(key.endedAt, "DateTime64(3, 'UTC')")}, ${tenant(key.organizationId)}, ${tenant(key.resourceId)})`);
7752
7780
  return {
7753
- query: `SELECT traceId, spanId AS rootSpanId, dedupeKey, organizationId, resourceId, ${columns === "payload" ? `metadataRaw AS metadata, ${PREVIEW_COLUMNS.join(", ")}` : "input, output, error"}
7781
+ query: `SELECT traceId, spanId AS rootSpanId, dedupeKey, organizationId, resourceId, ${columns === "payload" ? `metadataRaw AS metadata, stopReasonContext, ${PREVIEW_COLUMNS.join(", ")}` : "input, output, error"}
7754
7782
  FROM ${TABLE_TRACE_ROOTS}
7755
7783
  WHERE (startedAt, traceId, dedupeKey, endedAt, ifNull(organizationId, ''), isNull(organizationId), ifNull(resourceId, ''), isNull(resourceId)) IN (${tuples.join(", ")})${compileTenantScope(scope, parameters)}
7756
7784
  ORDER BY ${ROOT_VERSION_ORDER}
@@ -8017,7 +8045,12 @@ async function queryTraces(client, plan, timeoutMs, strategy = null) {
8017
8045
  environment: row.environment == null ? null : String(row.environment),
8018
8046
  status: row.status,
8019
8047
  ...timeToFirstChunkSupported && { timeToFirstChunkMs: row.timeToFirstChunkMs == null ? null : Number(row.timeToFirstChunkMs) },
8020
- ...timeToFirstTokenSupported && { timeToFirstTokenMs: row.timeToFirstTokenMs == null ? null : Number(row.timeToFirstTokenMs) }
8048
+ ...timeToFirstTokenSupported && { timeToFirstTokenMs: row.timeToFirstTokenMs == null ? null : Number(row.timeToFirstTokenMs) },
8049
+ ...traceQueryOutcomeFieldsSupported && {
8050
+ outcome: row.outcome == null ? null : String(row.outcome),
8051
+ stopReason: row.stopReason == null ? null : String(row.stopReason),
8052
+ stopReasonContext: parseJson(row.stopReasonContext) ?? null
8053
+ }
8021
8054
  });
8022
8055
  if (plan.paginationMode === "delta") {
8023
8056
  const rows = await run(compileClickHouseTraceQuery(plan, deltaHead));
@@ -8144,7 +8177,10 @@ const displayFields = [
8144
8177
  "durationMs",
8145
8178
  "timeToFirstChunkMs",
8146
8179
  "timeToFirstTokenMs",
8147
- "status"
8180
+ "status",
8181
+ "outcome",
8182
+ "stopReason",
8183
+ "stopReasonContext"
8148
8184
  ];
8149
8185
  var Parameters = class {
8150
8186
  values = {};
@@ -8196,13 +8232,18 @@ function predicateFields$1(predicate, fields = /* @__PURE__ */ new Set()) {
8196
8232
  else fields.add(predicate.field);
8197
8233
  return fields;
8198
8234
  }
8235
+ /** Selection and filter expressions read only columns; `model`/`provider` read their dedicated columns. */
8199
8236
  function fieldExpression(field) {
8200
- if (field === "model" || field === "provider") return `if(JSONType(e.attributes, '${field}') = 'String', JSONExtractString(e.attributes, '${field}'), NULL)`;
8201
8237
  if (field === "durationMs") return "dateDiff('millisecond', e.startedAt, e.endedAt)";
8202
8238
  if (field === "status") return "if(isNull(e.error), 'success', 'error')";
8203
8239
  if (field === "error") return "if(isNull(e.error), NULL, 'error')";
8204
8240
  return `e.${field}`;
8205
8241
  }
8242
+ /** Returned values fall back to span attributes for rows written before the dedicated columns existed. */
8243
+ function displayExpression(field) {
8244
+ if (field === "model" || field === "provider") return `coalesce(e.${field}, if(JSONType(e.attributes, '${field}') = 'String', JSONExtractString(e.attributes, '${field}'), NULL))`;
8245
+ return fieldExpression(field);
8246
+ }
8206
8247
  function compileClickHouseSpanQuery(plan) {
8207
8248
  const parameters = new Parameters();
8208
8249
  const from = parameters.add(plan.timeRange.from, "DateTime64(3, 'UTC')");
@@ -8289,7 +8330,11 @@ const TRACE_BRANCHES_SPAN_FIELD_COLUMNS = {
8289
8330
  "rootEntityType",
8290
8331
  "rootEntityId",
8291
8332
  "rootEntityName",
8292
- "rootEntityVersionId"
8333
+ "rootEntityVersionId",
8334
+ "model",
8335
+ "provider",
8336
+ "outcome",
8337
+ "stopReason"
8293
8338
  ].map((field) => [field, sameColumn(field)])),
8294
8339
  status: ["error"],
8295
8340
  error: ["error"],
@@ -8402,7 +8447,7 @@ async function querySpans(client, plan, timeoutMs) {
8402
8447
  const pageParameter = (rows) => rows.map((row) => new _clickhouse_client.TupleParam([...identityValues(row), row.endedAt.replace("T", " ").replace(/Z$/, "")]));
8403
8448
  const rowsWithPreviews = await run({
8404
8449
  query: `SELECT ${identities}, ${[...displayFields, ...PREVIEW_COLUMNS].map((field, index) => `data.${index + 1} AS ${field}`).join(", ")}
8405
- FROM (SELECT ${identities}, any(tuple(${[...displayFields.map(fieldExpression), ...PREVIEW_COLUMNS].join(", ")})) AS data
8450
+ FROM (SELECT ${identities}, any(tuple(${[...displayFields.map(displayExpression), ...PREVIEW_COLUMNS].join(", ")})) AS data
8406
8451
  FROM ${TABLE_SPAN_EVENTS} e WHERE ${payloadWhere} GROUP BY ${identities})`,
8407
8452
  query_params: { page: pageParameter(page) }
8408
8453
  });
@@ -8429,13 +8474,18 @@ async function querySpans(client, plan, timeoutMs) {
8429
8474
  const hydrated = page.flatMap((identity) => {
8430
8475
  const row = byIdentity.get(_mastra_core_storage.spanQueryIdentityKey(identity));
8431
8476
  if (!row) return [];
8432
- const { inputPreview: _input, outputPreview: _output, errorPreview: _error, timeToFirstChunkMs, timeToFirstTokenMs, ...metadata } = row;
8477
+ const { inputPreview: _input, outputPreview: _output, errorPreview: _error, timeToFirstChunkMs, timeToFirstTokenMs, outcome, stopReason, stopReasonContext, ...metadata } = row;
8433
8478
  return [{
8434
8479
  ...metadata,
8435
8480
  ...identity,
8436
8481
  durationMs: Number(row.durationMs),
8437
8482
  ...timeToFirstChunkSupported && { timeToFirstChunkMs: timeToFirstChunkMs == null ? null : Number(timeToFirstChunkMs) },
8438
- ...timeToFirstTokenSupported && { timeToFirstTokenMs: timeToFirstTokenMs == null ? null : Number(timeToFirstTokenMs) }
8483
+ ...timeToFirstTokenSupported && { timeToFirstTokenMs: timeToFirstTokenMs == null ? null : Number(timeToFirstTokenMs) },
8484
+ ...spanQueryOutcomeFieldsSupported && {
8485
+ outcome: outcome ?? null,
8486
+ stopReason: stopReason ?? null,
8487
+ stopReasonContext: parseJson(stopReasonContext) ?? null
8488
+ }
8439
8489
  }];
8440
8490
  });
8441
8491
  let metrics = [];
@@ -8750,6 +8800,8 @@ const DIMENSION_SQL = {
8750
8800
  entityId: "r.entityId",
8751
8801
  environment: "r.environment",
8752
8802
  status: TRACE_STATUS_SQL,
8803
+ outcome: "r.outcome",
8804
+ stopReason: "r.stopReason",
8753
8805
  serviceName: "r.serviceName",
8754
8806
  executionSource: "r.executionSource",
8755
8807
  threadId: "r.threadId",
@@ -8772,6 +8824,8 @@ const SPAN_DIMENSION_SQL = Object.fromEntries([
8772
8824
  "rootEntityName",
8773
8825
  "environment",
8774
8826
  "status",
8827
+ "outcome",
8828
+ "stopReason",
8775
8829
  "serviceName",
8776
8830
  "executionSource",
8777
8831
  "threadId",
@@ -8779,7 +8833,9 @@ const SPAN_DIMENSION_SQL = Object.fromEntries([
8779
8833
  "userId",
8780
8834
  "sessionId",
8781
8835
  "organizationId",
8782
- "experimentId"
8836
+ "experimentId",
8837
+ "model",
8838
+ "provider"
8783
8839
  ].map((field) => [field, `r.${field}`]));
8784
8840
  const PERCENTILES = {
8785
8841
  "duration.p50": .5,
@@ -9941,8 +9997,12 @@ function buildBranchCursor(row) {
9941
9997
  return row.cursorId ?? "0";
9942
9998
  }
9943
9999
  // src/storage/domains/observability/v-next/index.ts
9944
- const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? ["span-query", "span-query-context-fields"] : [];
9945
- const spanAggregateFeatures = typeof _mastra_core_storage.planSpanAggregate === "function" ? ["span-aggregate"] : [];
10000
+ const spanQueryFeatures = typeof _mastra_core_storage.planSpanQuery === "function" ? [
10001
+ "span-query",
10002
+ "span-query-context-fields",
10003
+ ..."model" in (_mastra_core_storage.SPAN_QUERY_FIELD_REGISTRY ?? {}) ? ["span-query-model-fields"] : []
10004
+ ] : [];
10005
+ const spanAggregateFeatures = typeof _mastra_core_storage.planSpanAggregate === "function" ? ["span-aggregate", ..."model" in (_mastra_core_storage.SPAN_AGGREGATE_DIMENSION_REGISTRY ?? {}) ? ["span-aggregate-model-dimensions"] : []] : [];
9946
10006
  const threadQueryFeatures = typeof _mastra_core_storage.planThreadRowsQuery === "function" ? ["thread-query-rows"] : [];
9947
10007
  function buildSignalMigrationRequiredMessage(args) {
9948
10008
  const tableList = args.tables.map((table) => ` - ${table.table} (${table.engine})`).join("\n");
@@ -10382,6 +10442,7 @@ var ObservabilityStorageClickhouseVNext = class extends _mastra_core_storage.Obs
10382
10442
  "feedback",
10383
10443
  "trace-query-context-ids",
10384
10444
  ...timingFeatures,
10445
+ ...outcomeFeatures,
10385
10446
  "trace-query-root-span-fields",
10386
10447
  "trace-query-root-entity-id",
10387
10448
  "trace-aggregate",
@@ -10407,6 +10468,7 @@ var ObservabilityStorageClickhouseVNext = class extends _mastra_core_storage.Obs
10407
10468
  "feedback",
10408
10469
  "trace-query-context-ids",
10409
10470
  ...timingFeatures,
10471
+ ...outcomeFeatures,
10410
10472
  "trace-query-root-span-fields",
10411
10473
  "trace-query-root-entity-id",
10412
10474
  "trace-aggregate",