@mastra/clickhouse 1.27.0-alpha.1 → 1.27.0

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/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { TupleParam, createClient } from "@clickhouse/client";
2
2
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
3
3
  import * as coreStorage from "@mastra/core/storage";
4
- import { BRANCH_SPAN_TYPES, EntityType, METRIC_DISTINCT_COLUMNS, MastraCompositeStore, MemoryStorage, ObservabilityStorage, SCORERS_SCHEMA, SPAN_SCHEMA, ScoresStorage, TABLE_AGENT_VERSIONS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_HARNESS_SESSIONS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_TRACES, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TraceStatus, WorkflowsStorage, calculatePagination, computeTraceStatus, createStorageErrorId, getDefaultValue, getSqlType, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, normalizePerPage, safelyParseJSON, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
4
+ import { BRANCH_SPAN_TYPES, EntityType, METRIC_DISTINCT_COLUMNS, MastraCompositeStore, MemoryStorage, ObservabilityStorage, SCORERS_SCHEMA, SPAN_SCHEMA, ScoresStorage, TABLE_AGENT_VERSIONS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_HARNESS_SESSIONS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_TRACES, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, TraceStatus, WorkflowsStorage, calculatePagination, computeTraceStatus, createStorageErrorId, getDefaultValue, getSqlType, getStringAttribute, listBranchesArgsSchema, listFeedbackArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listTracesArgsSchema, normalizePerPage, safelyParseJSON, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
5
5
  import { MessageList } from "@mastra/core/agent";
6
6
  import { MastraBase } from "@mastra/core/base";
7
7
  import { parseFieldKey } from "@mastra/core/utils";
@@ -301,7 +301,8 @@ const JSON_FIELDS = [
301
301
  "output",
302
302
  "error",
303
303
  "scope",
304
- "links"
304
+ "links",
305
+ "stopReasonContext"
305
306
  ];
306
307
  const NULLABLE_STRING_FIELDS = ["parentSpanId", "error"];
307
308
  function transformRow(row) {
@@ -2716,6 +2717,17 @@ CREATE TABLE IF NOT EXISTS ${TABLE_SPAN_EVENTS} (
2716
2717
  endedAt DateTime64(3, 'UTC'),
2717
2718
  timeToFirstChunkMs Nullable(Float64),
2718
2719
 
2720
+ -- Native span fields, stored as supplied (NULL when the producer set none)
2721
+ externalParentSpanId Nullable(String),
2722
+ resumedFromSpanId Nullable(String),
2723
+ model LowCardinality(Nullable(String)),
2724
+ provider LowCardinality(Nullable(String)),
2725
+ outcome LowCardinality(Nullable(String)),
2726
+ stopReason LowCardinality(Nullable(String)),
2727
+ stopReasonContext Nullable(String),
2728
+ timeToFirstTokenMs Nullable(Float64),
2729
+ errorCount Nullable(UInt32),
2730
+
2719
2731
  -- Query-relevant flexible fields
2720
2732
  tags Array(LowCardinality(String)) DEFAULT [],
2721
2733
  metadataSearch Map(LowCardinality(String), String) DEFAULT map(),
@@ -2790,6 +2802,17 @@ CREATE TABLE IF NOT EXISTS ${TABLE_TRACE_ROOTS} (
2790
2802
  endedAt DateTime64(3, 'UTC'),
2791
2803
  timeToFirstChunkMs Nullable(Float64),
2792
2804
 
2805
+ -- Native span fields, stored as supplied (NULL when the producer set none)
2806
+ externalParentSpanId Nullable(String),
2807
+ resumedFromSpanId Nullable(String),
2808
+ model LowCardinality(Nullable(String)),
2809
+ provider LowCardinality(Nullable(String)),
2810
+ outcome LowCardinality(Nullable(String)),
2811
+ stopReason LowCardinality(Nullable(String)),
2812
+ stopReasonContext Nullable(String),
2813
+ timeToFirstTokenMs Nullable(Float64),
2814
+ errorCount Nullable(UInt32),
2815
+
2793
2816
  -- Query-relevant flexible fields
2794
2817
  tags Array(LowCardinality(String)) DEFAULT [],
2795
2818
  metadataSearch Map(LowCardinality(String), String) DEFAULT map(),
@@ -2876,6 +2899,17 @@ CREATE TABLE IF NOT EXISTS ${TABLE_TRACE_BRANCHES} (
2876
2899
  endedAt DateTime64(3, 'UTC'),
2877
2900
  timeToFirstChunkMs Nullable(Float64),
2878
2901
 
2902
+ -- Native span fields, stored as supplied (NULL when the producer set none)
2903
+ externalParentSpanId Nullable(String),
2904
+ resumedFromSpanId Nullable(String),
2905
+ model LowCardinality(Nullable(String)),
2906
+ provider LowCardinality(Nullable(String)),
2907
+ outcome LowCardinality(Nullable(String)),
2908
+ stopReason LowCardinality(Nullable(String)),
2909
+ stopReasonContext Nullable(String),
2910
+ timeToFirstTokenMs Nullable(Float64),
2911
+ errorCount Nullable(UInt32),
2912
+
2879
2913
  -- Query-relevant flexible fields
2880
2914
  tags Array(LowCardinality(String)) DEFAULT [],
2881
2915
  metadataSearch Map(LowCardinality(String), String) DEFAULT map(),
@@ -3611,6 +3645,25 @@ function buildAllMvDDL(strategy) {
3611
3645
  }
3612
3646
  /** Discovery-specific refreshable MVs — created separately from core MVs. */
3613
3647
  const DISCOVERY_MV_DDL = [DISCOVERY_VALUES_MV_DDL, DISCOVERY_PAIRS_MV_DDL];
3648
+ /**
3649
+ * Span columns added after the first span tables shipped, with their types.
3650
+ * Present on span events, trace roots and trace branches.
3651
+ */
3652
+ const ADDED_SPAN_COLUMNS = [
3653
+ ["inputPreview", "Nullable(String)"],
3654
+ ["outputPreview", "Nullable(String)"],
3655
+ ["errorPreview", "Nullable(String)"],
3656
+ ["timeToFirstChunkMs", "Nullable(Float64)"],
3657
+ ["externalParentSpanId", "Nullable(String)"],
3658
+ ["resumedFromSpanId", "Nullable(String)"],
3659
+ ["model", "LowCardinality(Nullable(String))"],
3660
+ ["provider", "LowCardinality(Nullable(String))"],
3661
+ ["outcome", "LowCardinality(Nullable(String))"],
3662
+ ["stopReason", "LowCardinality(Nullable(String))"],
3663
+ ["stopReasonContext", "Nullable(String)"],
3664
+ ["timeToFirstTokenMs", "Nullable(Float64)"],
3665
+ ["errorCount", "Nullable(UInt32)"]
3666
+ ];
3614
3667
  const addColumn = (table, name, type) => ({
3615
3668
  kind: "column",
3616
3669
  table,
@@ -3635,14 +3688,11 @@ const LOG_SKIP_INDEX_COLUMNS = [
3635
3688
  "requestId"
3636
3689
  ];
3637
3690
  const ALL_MIGRATIONS = [
3638
- ...[
3639
- "inputPreview",
3640
- "outputPreview",
3641
- "errorPreview"
3642
- ].flatMap((column) => [addColumn(TABLE_TRACE_ROOTS, column, "Nullable(String)"), addColumn(TABLE_TRACE_BRANCHES, column, "Nullable(String)")]),
3643
- addColumn(TABLE_SPAN_EVENTS, "inputPreview", "Nullable(String)"),
3644
- addColumn(TABLE_SPAN_EVENTS, "outputPreview", "Nullable(String)"),
3645
- addColumn(TABLE_SPAN_EVENTS, "errorPreview", "Nullable(String)"),
3691
+ ...ADDED_SPAN_COLUMNS.flatMap(([column, type]) => [
3692
+ addColumn(TABLE_TRACE_ROOTS, column, type),
3693
+ addColumn(TABLE_TRACE_BRANCHES, column, type),
3694
+ addColumn(TABLE_SPAN_EVENTS, column, type)
3695
+ ]),
3646
3696
  addColumn(TABLE_TRACE_BRANCHES, "entityVersionId", "Nullable(String)"),
3647
3697
  addColumn(TABLE_TRACE_BRANCHES, "parentEntityVersionId", "Nullable(String)"),
3648
3698
  addColumn(TABLE_TRACE_BRANCHES, "rootEntityVersionId", "Nullable(String)"),
@@ -3683,10 +3733,7 @@ const ALL_MIGRATIONS = [
3683
3733
  addBloomIndex(TABLE_METRIC_EVENTS, "idx_sessionId", "sessionId"),
3684
3734
  addBloomIndex(TABLE_METRIC_EVENTS, "idx_requestId", "requestId"),
3685
3735
  ...LOG_SKIP_INDEX_COLUMNS.map((column) => addBloomIndex(TABLE_LOG_EVENTS, `idx_${column}`, column)),
3686
- addBloomIndex(TABLE_DELETION_REQUESTS, "idx_predicateValues", "predicateValues"),
3687
- addColumn(TABLE_TRACE_ROOTS, "timeToFirstChunkMs", "Nullable(Float64)"),
3688
- addColumn(TABLE_TRACE_BRANCHES, "timeToFirstChunkMs", "Nullable(Float64)"),
3689
- addColumn(TABLE_SPAN_EVENTS, "timeToFirstChunkMs", "Nullable(Float64)")
3736
+ addBloomIndex(TABLE_DELETION_REQUESTS, "idx_predicateValues", "predicateValues")
3690
3737
  ];
3691
3738
  const ALL_TABLE_NAMES = [
3692
3739
  TABLE_SPAN_EVENTS,
@@ -3937,6 +3984,11 @@ const PROMOTED_KEYS = /* @__PURE__ */ new Set([
3937
3984
  "executionSource",
3938
3985
  "serviceName"
3939
3986
  ]);
3987
+ function nullableNumber$1(value) {
3988
+ if (value == null || value === "") return null;
3989
+ const n = Number(value);
3990
+ return Number.isNaN(n) ? null : n;
3991
+ }
3940
3992
  function nullableString(value) {
3941
3993
  return typeof value === "string" ? value === "" ? null : value : value == null ? null : String(value);
3942
3994
  }
@@ -4018,6 +4070,7 @@ function rowToSpanRecord(row) {
4018
4070
  const startedAt = toDate(row.startedAt);
4019
4071
  const endedAt = row.isEvent ? startedAt : toDateOrNull(row.endedAt);
4020
4072
  const error = parseJson(row.error);
4073
+ const attributes = parseJson(row.attributes);
4021
4074
  return {
4022
4075
  traceId: row.traceId,
4023
4076
  spanId: row.spanId,
@@ -4053,12 +4106,21 @@ function rowToSpanRecord(row) {
4053
4106
  tags: normalizeTags(row.tags),
4054
4107
  metadata: parseJson(row.metadataRaw) ?? void 0,
4055
4108
  scope: parseJson(row.scope) ?? void 0,
4056
- attributes: parseJson(row.attributes) ?? void 0,
4109
+ attributes: attributes ?? void 0,
4057
4110
  links: parseJson(row.links) ?? void 0,
4058
4111
  input: parseJson(row.input) ?? void 0,
4059
4112
  output: parseJson(row.output) ?? void 0,
4060
4113
  error: error ?? void 0,
4061
4114
  requestContext: parseJson(row.requestContext) ?? void 0,
4115
+ externalParentSpanId: nullableString(row.externalParentSpanId),
4116
+ resumedFromSpanId: nullableString(row.resumedFromSpanId),
4117
+ model: nullableString(row.model) ?? getStringAttribute(attributes, "model"),
4118
+ provider: nullableString(row.provider) ?? getStringAttribute(attributes, "provider"),
4119
+ outcome: nullableString(row.outcome),
4120
+ stopReason: nullableString(row.stopReason),
4121
+ stopReasonContext: parseJson(row.stopReasonContext) ?? null,
4122
+ timeToFirstTokenMs: nullableNumber$1(row.timeToFirstTokenMs),
4123
+ errorCount: nullableNumber$1(row.errorCount),
4062
4124
  createdAt: startedAt,
4063
4125
  updatedAt: null
4064
4126
  };
@@ -4132,6 +4194,15 @@ function spanRecordToRow(span) {
4132
4194
  startedAt: toISOString(span.startedAt),
4133
4195
  endedAt: toISOString(endedAt),
4134
4196
  timeToFirstChunkMs: span.timeToFirstChunkMs ?? null,
4197
+ externalParentSpanId: span.externalParentSpanId ?? null,
4198
+ resumedFromSpanId: span.resumedFromSpanId ?? null,
4199
+ model: span.model ?? null,
4200
+ provider: span.provider ?? null,
4201
+ outcome: span.outcome ?? null,
4202
+ stopReason: span.stopReason ?? null,
4203
+ stopReasonContext: jsonEncode(span.stopReasonContext),
4204
+ timeToFirstTokenMs: span.timeToFirstTokenMs ?? null,
4205
+ errorCount: span.errorCount ?? null,
4135
4206
  tags: normalizeTags(span.tags),
4136
4207
  metadataSearch: buildMetadataSearch(metadata),
4137
4208
  metadataRaw: jsonEncode(metadata),
@@ -8566,7 +8637,7 @@ async function queryThreadRows(client, plan, timeoutMs, strategy = "auto") {
8566
8637
  traceId, spanId, startedAt, endedAt) IN {roots:Array(Tuple(UInt8, String, UInt8, String, String, String, DateTime64(3, 'UTC'), DateTime64(3, 'UTC')))}`;
8567
8638
  const stored = [];
8568
8639
  for (const batch of batches([...roots.values()])) stored.push(...await run({
8569
- query: `SELECT organizationId, traceId, spanId, startedAt, endedAt, spanType,
8640
+ query: `SELECT organizationId, traceId, spanId, startedAt, endedAt,
8570
8641
  ${contextFields.join(", ")}, if(spanType = 'agent_run', timeToFirstChunkMs, NULL) AS timeToFirstChunkMs,
8571
8642
  if(isNull(error), 'success', 'error') AS status, ${PREVIEW_COLUMNS.join(", ")}
8572
8643
  FROM ${TABLE_TRACE_ROOTS} WHERE ${rootWhere}
@@ -8586,31 +8657,10 @@ async function queryThreadRows(client, plan, timeoutMs, strategy = "auto") {
8586
8657
  if (row) Object.assign(row, resolveStoredPreviews(row, payload));
8587
8658
  }
8588
8659
  }
8589
- const firstRoots = page.map((row) => representative(row, "first")).filter((root) => byRoot.get(rootKey(root))?.spanType === "agent_run");
8590
- const models = [];
8591
- for (const batch of batches(firstRoots)) models.push(...await run({
8592
- query: `SELECT organizationId, traceId,
8593
- if(JSONType(attributes, 'model') = 'String', JSONExtractString(attributes, 'model'), NULL) AS model,
8594
- if(JSONType(attributes, 'provider') = 'String', JSONExtractString(attributes, 'provider'), NULL) AS provider
8595
- FROM ${TABLE_SPAN_EVENTS} WHERE spanType = 'model_generation' AND
8596
- tuple(isNull(organizationId), ifNull(organizationId, ''), isNull(resourceId), ifNull(resourceId, ''), traceId, parentSpanId)
8597
- IN {agents:Array(Tuple(UInt8, String, UInt8, String, String, String))}
8598
- ORDER BY organizationId, traceId, startedAt, spanId LIMIT 1 BY organizationId, traceId`,
8599
- query_params: { agents: batch.map((root) => new TupleParam([
8600
- root.organizationId === null ? 1 : 0,
8601
- root.organizationId ?? "",
8602
- root.resourceId === null ? 1 : 0,
8603
- root.resourceId ?? "",
8604
- root.traceId,
8605
- root.spanId
8606
- ])) }
8607
- }));
8608
- const byTrace = new Map(models.map((row) => [JSON.stringify([row.organizationId, row.traceId]), row]));
8609
8660
  const threads = page.flatMap((row) => {
8610
8661
  const first = byRoot.get(rootKey(representative(row, "first")));
8611
8662
  const last = byRoot.get(rootKey(representative(row, "last")));
8612
8663
  if (!first || !last) return [];
8613
- const model = byTrace.get(JSON.stringify([row.organizationId, row.firstTraceId]));
8614
8664
  return [coreStorage.threadQueryRowSchema.parse({
8615
8665
  organizationId: row.organizationId,
8616
8666
  threadId: row.threadId,
@@ -8622,8 +8672,6 @@ async function queryThreadRows(client, plan, timeoutMs, strategy = "auto") {
8622
8672
  endedAt: iso(row.endedAt),
8623
8673
  traceCount: Number(row.traceCount),
8624
8674
  timeToFirstChunkMs: first.timeToFirstChunkMs,
8625
- model: model?.model ?? null,
8626
- provider: model?.provider ?? null,
8627
8675
  inputPreview: resolveStoredPreviews(first).inputPreview,
8628
8676
  outputPreview: resolveStoredPreviews(last).outputPreview,
8629
8677
  errorPreview: resolveStoredPreviews(last).errorPreview