@mastra/clickhouse 1.6.0 → 1.7.0-alpha.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/CHANGELOG.md +53 -0
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +390 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +391 -13
- package/dist/index.js.map +1 -1
- package/dist/storage/db/utils.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts +21 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +4 -1
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/metrics.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/scores.d.ts +2 -1
- package/dist/storage/domains/observability/v-next/scores.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/tracing.d.ts +28 -3
- package/dist/storage/domains/observability/v-next/tracing.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClient } from '@clickhouse/client';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import { TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SKILLS, TABLE_WORKSPACE_VERSIONS, TABLE_WORKSPACES, TABLE_MCP_SERVER_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_CLIENTS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SCORER_DEFINITIONS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_PROMPT_BLOCKS, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, TABLE_DATASET_VERSIONS, TABLE_DATASET_ITEMS, TABLE_DATASETS, TABLE_AGENT_VERSIONS, TABLE_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, BackgroundTasksStorage, TABLE_SCHEMAS, TABLE_BACKGROUND_TASKS, MemoryStorage, createStorageErrorId, normalizePerPage, calculatePagination, ObservabilityStorage, SPAN_SCHEMA, listTracesArgsSchema, toTraceSpans, ScoresStorage, transformScoreRow, SCORERS_SCHEMA, WorkflowsStorage, MastraCompositeStore, getSqlType, getDefaultValue, safelyParseJSON, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listFeedbackArgsSchema, EntityType, TraceStatus } from '@mastra/core/storage';
|
|
3
|
+
import { BRANCH_SPAN_TYPES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEDULES, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SKILLS, TABLE_WORKSPACE_VERSIONS, TABLE_WORKSPACES, TABLE_MCP_SERVER_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_CLIENTS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SCORER_DEFINITIONS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_PROMPT_BLOCKS, TABLE_EXPERIMENT_RESULTS, TABLE_EXPERIMENTS, TABLE_DATASET_VERSIONS, TABLE_DATASET_ITEMS, TABLE_DATASETS, TABLE_AGENT_VERSIONS, TABLE_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, BackgroundTasksStorage, TABLE_SCHEMAS, TABLE_BACKGROUND_TASKS, MemoryStorage, createStorageErrorId, normalizePerPage, calculatePagination, ObservabilityStorage, SPAN_SCHEMA, listTracesArgsSchema, toTraceSpans, ScoresStorage, transformScoreRow, SCORERS_SCHEMA, WorkflowsStorage, MastraCompositeStore, getSqlType, getDefaultValue, safelyParseJSON, listBranchesArgsSchema, listLogsArgsSchema, listMetricsArgsSchema, listScoresArgsSchema, listFeedbackArgsSchema, EntityType, TraceStatus, METRIC_DISTINCT_COLUMNS } from '@mastra/core/storage';
|
|
4
4
|
import { MastraBase } from '@mastra/core/base';
|
|
5
5
|
import { MessageList } from '@mastra/core/agent';
|
|
6
6
|
import { parseFieldKey } from '@mastra/core/utils';
|
|
@@ -39,6 +39,8 @@ var TABLE_ENGINES = {
|
|
|
39
39
|
[TABLE_SKILL_VERSIONS]: `MergeTree()`,
|
|
40
40
|
[TABLE_SKILL_BLOBS]: `ReplacingMergeTree()`,
|
|
41
41
|
mastra_background_tasks: `ReplacingMergeTree()`,
|
|
42
|
+
[TABLE_SCHEDULES]: `ReplacingMergeTree()`,
|
|
43
|
+
[TABLE_SCHEDULE_TRIGGERS]: `MergeTree()`,
|
|
42
44
|
mastra_channel_installations: `ReplacingMergeTree()`,
|
|
43
45
|
mastra_channel_config: `ReplacingMergeTree()`
|
|
44
46
|
};
|
|
@@ -2830,6 +2832,7 @@ time for large tables. Please ensure you have a backup before proceeding.
|
|
|
2830
2832
|
// src/storage/domains/observability/v-next/ddl.ts
|
|
2831
2833
|
var TABLE_SPAN_EVENTS = "mastra_span_events";
|
|
2832
2834
|
var TABLE_TRACE_ROOTS = "mastra_trace_roots";
|
|
2835
|
+
var TABLE_TRACE_BRANCHES = "mastra_trace_branches";
|
|
2833
2836
|
var TABLE_METRIC_EVENTS = "mastra_metric_events";
|
|
2834
2837
|
var TABLE_LOG_EVENTS = "mastra_log_events";
|
|
2835
2838
|
var TABLE_SCORE_EVENTS = "mastra_score_events";
|
|
@@ -2837,8 +2840,18 @@ var TABLE_FEEDBACK_EVENTS = "mastra_feedback_events";
|
|
|
2837
2840
|
var TABLE_DISCOVERY_VALUES = "mastra_discovery_values";
|
|
2838
2841
|
var TABLE_DISCOVERY_PAIRS = "mastra_discovery_pairs";
|
|
2839
2842
|
var MV_TRACE_ROOTS = "mastra_mv_trace_roots";
|
|
2843
|
+
var MV_TRACE_BRANCHES = "mastra_mv_trace_branches";
|
|
2840
2844
|
var MV_DISCOVERY_VALUES = "mastra_mv_discovery_values";
|
|
2841
2845
|
var MV_DISCOVERY_PAIRS = "mastra_mv_discovery_pairs";
|
|
2846
|
+
var BRANCH_SPAN_TYPE_VALUES = [
|
|
2847
|
+
"agent_run",
|
|
2848
|
+
"workflow_run",
|
|
2849
|
+
"processor_run",
|
|
2850
|
+
"scorer_run",
|
|
2851
|
+
"rag_ingestion",
|
|
2852
|
+
"tool_call",
|
|
2853
|
+
"mcp_tool_call"
|
|
2854
|
+
];
|
|
2842
2855
|
var SPAN_EVENTS_DDL = `
|
|
2843
2856
|
CREATE TABLE IF NOT EXISTS ${TABLE_SPAN_EVENTS} (
|
|
2844
2857
|
-- Identity
|
|
@@ -2979,6 +2992,80 @@ SELECT *
|
|
|
2979
2992
|
FROM ${TABLE_SPAN_EVENTS}
|
|
2980
2993
|
WHERE parentSpanId IS NULL
|
|
2981
2994
|
`;
|
|
2995
|
+
var TRACE_BRANCHES_DDL = `
|
|
2996
|
+
CREATE TABLE IF NOT EXISTS ${TABLE_TRACE_BRANCHES} (
|
|
2997
|
+
-- Identity
|
|
2998
|
+
dedupeKey String,
|
|
2999
|
+
|
|
3000
|
+
-- IDs
|
|
3001
|
+
traceId String,
|
|
3002
|
+
spanId String,
|
|
3003
|
+
parentSpanId Nullable(String),
|
|
3004
|
+
experimentId Nullable(String),
|
|
3005
|
+
|
|
3006
|
+
-- Entity
|
|
3007
|
+
entityType LowCardinality(Nullable(String)),
|
|
3008
|
+
entityId Nullable(String),
|
|
3009
|
+
entityName Nullable(String),
|
|
3010
|
+
entityVersionId Nullable(String),
|
|
3011
|
+
|
|
3012
|
+
-- Parent entity
|
|
3013
|
+
parentEntityVersionId Nullable(String),
|
|
3014
|
+
parentEntityType LowCardinality(Nullable(String)),
|
|
3015
|
+
parentEntityId Nullable(String),
|
|
3016
|
+
parentEntityName Nullable(String),
|
|
3017
|
+
|
|
3018
|
+
-- Root entity
|
|
3019
|
+
rootEntityVersionId Nullable(String),
|
|
3020
|
+
rootEntityType LowCardinality(Nullable(String)),
|
|
3021
|
+
rootEntityId Nullable(String),
|
|
3022
|
+
rootEntityName Nullable(String),
|
|
3023
|
+
|
|
3024
|
+
-- Context
|
|
3025
|
+
userId Nullable(String),
|
|
3026
|
+
organizationId Nullable(String),
|
|
3027
|
+
resourceId Nullable(String),
|
|
3028
|
+
runId Nullable(String),
|
|
3029
|
+
sessionId Nullable(String),
|
|
3030
|
+
threadId Nullable(String),
|
|
3031
|
+
requestId Nullable(String),
|
|
3032
|
+
environment LowCardinality(Nullable(String)),
|
|
3033
|
+
executionSource LowCardinality(Nullable(String)),
|
|
3034
|
+
serviceName LowCardinality(Nullable(String)),
|
|
3035
|
+
|
|
3036
|
+
-- Span scalars
|
|
3037
|
+
name String,
|
|
3038
|
+
spanType LowCardinality(String),
|
|
3039
|
+
isEvent Bool DEFAULT false,
|
|
3040
|
+
startedAt DateTime64(3, 'UTC'),
|
|
3041
|
+
endedAt DateTime64(3, 'UTC'),
|
|
3042
|
+
|
|
3043
|
+
-- Query-relevant flexible fields
|
|
3044
|
+
tags Array(LowCardinality(String)) DEFAULT [],
|
|
3045
|
+
metadataSearch Map(LowCardinality(String), String) DEFAULT map(),
|
|
3046
|
+
|
|
3047
|
+
-- Information-only JSON payloads
|
|
3048
|
+
attributes Nullable(String),
|
|
3049
|
+
scope Nullable(String),
|
|
3050
|
+
links Nullable(String),
|
|
3051
|
+
input Nullable(String),
|
|
3052
|
+
output Nullable(String),
|
|
3053
|
+
error Nullable(String),
|
|
3054
|
+
metadataRaw Nullable(String),
|
|
3055
|
+
requestContext Nullable(String)
|
|
3056
|
+
)
|
|
3057
|
+
ENGINE = ReplacingMergeTree
|
|
3058
|
+
PARTITION BY toDate(endedAt)
|
|
3059
|
+
ORDER BY (spanType, startedAt, traceId, dedupeKey)
|
|
3060
|
+
`;
|
|
3061
|
+
var TRACE_BRANCHES_MV_DDL = `
|
|
3062
|
+
CREATE MATERIALIZED VIEW IF NOT EXISTS ${MV_TRACE_BRANCHES}
|
|
3063
|
+
TO ${TABLE_TRACE_BRANCHES}
|
|
3064
|
+
AS
|
|
3065
|
+
SELECT *
|
|
3066
|
+
FROM ${TABLE_SPAN_EVENTS}
|
|
3067
|
+
WHERE spanType IN (${BRANCH_SPAN_TYPE_VALUES.map((v) => `'${v}'`).join(", ")})
|
|
3068
|
+
`;
|
|
2982
3069
|
var METRIC_EVENTS_DDL = `
|
|
2983
3070
|
CREATE TABLE IF NOT EXISTS ${TABLE_METRIC_EVENTS} (
|
|
2984
3071
|
-- Timestamp
|
|
@@ -3031,7 +3118,22 @@ CREATE TABLE IF NOT EXISTS ${TABLE_METRIC_EVENTS} (
|
|
|
3031
3118
|
-- Information-only JSON payloads
|
|
3032
3119
|
costMetadata Nullable(String),
|
|
3033
3120
|
metadata Nullable(String),
|
|
3034
|
-
scope Nullable(String)
|
|
3121
|
+
scope Nullable(String),
|
|
3122
|
+
|
|
3123
|
+
-- Bloom-filter skip indexes for high-cardinality ID drilldowns.
|
|
3124
|
+
-- Equality and IN filters on these columns can skip granule chunks that
|
|
3125
|
+
-- definitely do not contain the value. GRANULARITY 2 = 16K-row chunks.
|
|
3126
|
+
-- ID columns are out-of-sort-key, so without these every drilldown scans
|
|
3127
|
+
-- every row in the time range.
|
|
3128
|
+
INDEX idx_traceId traceId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3129
|
+
INDEX idx_threadId threadId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3130
|
+
INDEX idx_resourceId resourceId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3131
|
+
INDEX idx_userId userId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3132
|
+
INDEX idx_organizationId organizationId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3133
|
+
INDEX idx_experimentId experimentId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3134
|
+
INDEX idx_runId runId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3135
|
+
INDEX idx_sessionId sessionId TYPE bloom_filter(0.01) GRANULARITY 2,
|
|
3136
|
+
INDEX idx_requestId requestId TYPE bloom_filter(0.01) GRANULARITY 2
|
|
3035
3137
|
)
|
|
3036
3138
|
ENGINE = ReplacingMergeTree
|
|
3037
3139
|
PARTITION BY toDate(timestamp)
|
|
@@ -3286,6 +3388,7 @@ SELECT DISTINCT kind, key1, key2, value FROM (
|
|
|
3286
3388
|
var ALL_TABLE_DDL = [
|
|
3287
3389
|
SPAN_EVENTS_DDL,
|
|
3288
3390
|
TRACE_ROOTS_DDL,
|
|
3391
|
+
TRACE_BRANCHES_DDL,
|
|
3289
3392
|
METRIC_EVENTS_DDL,
|
|
3290
3393
|
LOG_EVENTS_DDL,
|
|
3291
3394
|
SCORE_EVENTS_DDL,
|
|
@@ -3293,7 +3396,7 @@ var ALL_TABLE_DDL = [
|
|
|
3293
3396
|
DISCOVERY_VALUES_DDL,
|
|
3294
3397
|
DISCOVERY_PAIRS_DDL
|
|
3295
3398
|
];
|
|
3296
|
-
var ALL_MV_DDL = [TRACE_ROOTS_MV_DDL];
|
|
3399
|
+
var ALL_MV_DDL = [TRACE_ROOTS_MV_DDL, TRACE_BRANCHES_MV_DDL];
|
|
3297
3400
|
var DISCOVERY_MV_DDL = [DISCOVERY_VALUES_MV_DDL, DISCOVERY_PAIRS_MV_DDL];
|
|
3298
3401
|
var ALL_MIGRATIONS = [
|
|
3299
3402
|
// Span events
|
|
@@ -3319,11 +3422,25 @@ var ALL_MIGRATIONS = [
|
|
|
3319
3422
|
// Feedback
|
|
3320
3423
|
`ALTER TABLE ${TABLE_FEEDBACK_EVENTS} ADD COLUMN IF NOT EXISTS entityVersionId Nullable(String)`,
|
|
3321
3424
|
`ALTER TABLE ${TABLE_FEEDBACK_EVENTS} ADD COLUMN IF NOT EXISTS parentEntityVersionId Nullable(String)`,
|
|
3322
|
-
`ALTER TABLE ${TABLE_FEEDBACK_EVENTS} ADD COLUMN IF NOT EXISTS rootEntityVersionId Nullable(String)
|
|
3425
|
+
`ALTER TABLE ${TABLE_FEEDBACK_EVENTS} ADD COLUMN IF NOT EXISTS rootEntityVersionId Nullable(String)`,
|
|
3426
|
+
// Metric skip indexes — additive, instant DDL. Existing parts keep no index
|
|
3427
|
+
// until merged or `MATERIALIZE INDEX` is run; new parts are bloom-filtered
|
|
3428
|
+
// immediately. With normal retention turning over the table, the index
|
|
3429
|
+
// converges to full coverage without an explicit backfill.
|
|
3430
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_traceId traceId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3431
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_threadId threadId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3432
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_resourceId resourceId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3433
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_userId userId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3434
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_organizationId organizationId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3435
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_experimentId experimentId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3436
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_runId runId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3437
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_sessionId sessionId TYPE bloom_filter(0.01) GRANULARITY 2`,
|
|
3438
|
+
`ALTER TABLE ${TABLE_METRIC_EVENTS} ADD INDEX IF NOT EXISTS idx_requestId requestId TYPE bloom_filter(0.01) GRANULARITY 2`
|
|
3323
3439
|
];
|
|
3324
3440
|
var ALL_TABLE_NAMES = [
|
|
3325
3441
|
TABLE_SPAN_EVENTS,
|
|
3326
3442
|
TABLE_TRACE_ROOTS,
|
|
3443
|
+
TABLE_TRACE_BRANCHES,
|
|
3327
3444
|
TABLE_METRIC_EVENTS,
|
|
3328
3445
|
TABLE_LOG_EVENTS,
|
|
3329
3446
|
TABLE_SCORE_EVENTS,
|
|
@@ -3334,13 +3451,14 @@ var ALL_TABLE_NAMES = [
|
|
|
3334
3451
|
var SIGNAL_TTL_COLUMNS = {
|
|
3335
3452
|
[TABLE_SPAN_EVENTS]: "endedAt",
|
|
3336
3453
|
[TABLE_TRACE_ROOTS]: "endedAt",
|
|
3454
|
+
[TABLE_TRACE_BRANCHES]: "endedAt",
|
|
3337
3455
|
[TABLE_METRIC_EVENTS]: "timestamp",
|
|
3338
3456
|
[TABLE_LOG_EVENTS]: "timestamp",
|
|
3339
3457
|
[TABLE_SCORE_EVENTS]: "timestamp",
|
|
3340
3458
|
[TABLE_FEEDBACK_EVENTS]: "timestamp"
|
|
3341
3459
|
};
|
|
3342
3460
|
var SIGNAL_TO_TABLES = {
|
|
3343
|
-
tracing: [TABLE_SPAN_EVENTS, TABLE_TRACE_ROOTS],
|
|
3461
|
+
tracing: [TABLE_SPAN_EVENTS, TABLE_TRACE_ROOTS, TABLE_TRACE_BRANCHES],
|
|
3344
3462
|
logs: [TABLE_LOG_EVENTS],
|
|
3345
3463
|
metrics: [TABLE_METRIC_EVENTS],
|
|
3346
3464
|
scores: [TABLE_SCORE_EVENTS],
|
|
@@ -4559,7 +4677,16 @@ var METRIC_TYPED_COLUMNS = /* @__PURE__ */ new Set([
|
|
|
4559
4677
|
"costUnit"
|
|
4560
4678
|
]);
|
|
4561
4679
|
var GROUP_BY_EXCLUDED2 = /* @__PURE__ */ new Set(["metadata", "scope", "costMetadata", "tags"]);
|
|
4562
|
-
function
|
|
4680
|
+
function resolveDistinctColumnSql(distinctColumn) {
|
|
4681
|
+
if (!distinctColumn) {
|
|
4682
|
+
throw new Error(`count_distinct aggregation requires a 'distinctColumn' argument`);
|
|
4683
|
+
}
|
|
4684
|
+
if (!METRIC_DISTINCT_COLUMNS.includes(distinctColumn)) {
|
|
4685
|
+
throw new Error(`Invalid distinctColumn: ${distinctColumn}`);
|
|
4686
|
+
}
|
|
4687
|
+
return parseFieldKey(distinctColumn);
|
|
4688
|
+
}
|
|
4689
|
+
function getAggregationSql2(aggregation, measure = "value", distinctColumn) {
|
|
4563
4690
|
switch (aggregation) {
|
|
4564
4691
|
case "sum":
|
|
4565
4692
|
return `sum(${measure})`;
|
|
@@ -4571,6 +4698,9 @@ function getAggregationSql2(aggregation, measure = "value") {
|
|
|
4571
4698
|
return `max(${measure})`;
|
|
4572
4699
|
case "count":
|
|
4573
4700
|
return `toFloat64(count(${measure}))`;
|
|
4701
|
+
case "count_distinct": {
|
|
4702
|
+
return `toFloat64(uniq(${resolveDistinctColumnSql(distinctColumn)}))`;
|
|
4703
|
+
}
|
|
4574
4704
|
case "last":
|
|
4575
4705
|
return `argMax(${measure}, timestamp)`;
|
|
4576
4706
|
default:
|
|
@@ -4709,7 +4839,7 @@ async function listMetrics(client, args) {
|
|
|
4709
4839
|
};
|
|
4710
4840
|
}
|
|
4711
4841
|
async function getMetricAggregate(client, args) {
|
|
4712
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
4842
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
4713
4843
|
const nameFilter = buildMetricNameFilter(args.name);
|
|
4714
4844
|
const signalFilter = buildMetricsFilterConditions(args.filters);
|
|
4715
4845
|
const combined = mergeFilters2(nameFilter, signalFilter);
|
|
@@ -4781,7 +4911,7 @@ async function getMetricAggregate(client, args) {
|
|
|
4781
4911
|
return { value, estimatedCost: costSummary.estimatedCost, costUnit: costSummary.costUnit };
|
|
4782
4912
|
}
|
|
4783
4913
|
async function getMetricBreakdown(client, args) {
|
|
4784
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
4914
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
4785
4915
|
const nameFilter = buildMetricNameFilter(args.name);
|
|
4786
4916
|
const signalFilter = buildMetricsFilterConditions(args.filters);
|
|
4787
4917
|
const combined = mergeFilters2(nameFilter, signalFilter);
|
|
@@ -4792,14 +4922,22 @@ async function getMetricBreakdown(client, args) {
|
|
|
4792
4922
|
const groupByCols = resolvedGroupBy.map((e) => e.groupSql).join(", ");
|
|
4793
4923
|
const allConditions = [...combined.conditions, ...labelExclusions];
|
|
4794
4924
|
const fullWhereClause = allConditions.length ? `WHERE ${allConditions.join(" AND ")}` : "";
|
|
4925
|
+
const orderDirection = args.orderDirection === "ASC" ? "ASC" : "DESC";
|
|
4926
|
+
const limitClause = typeof args.limit === "number" ? `LIMIT {breakdown_limit:UInt32}` : "";
|
|
4927
|
+
const extraParams = typeof args.limit === "number" ? { breakdown_limit: args.limit } : {};
|
|
4795
4928
|
const sql = `
|
|
4796
4929
|
SELECT ${selectGroupBy}, ${aggSql} AS value, ${getCostSummarySelect()}
|
|
4797
4930
|
FROM ${TABLE_METRIC_EVENTS}
|
|
4798
4931
|
${fullWhereClause}
|
|
4799
4932
|
GROUP BY ${groupByCols}
|
|
4800
|
-
ORDER BY value
|
|
4933
|
+
ORDER BY value ${orderDirection}
|
|
4934
|
+
${limitClause}
|
|
4801
4935
|
`;
|
|
4802
|
-
const rows = await queryJson3(client, sql, {
|
|
4936
|
+
const rows = await queryJson3(client, sql, {
|
|
4937
|
+
...combined.params,
|
|
4938
|
+
...labelParams,
|
|
4939
|
+
...extraParams
|
|
4940
|
+
});
|
|
4803
4941
|
const groups = rows.map((row) => {
|
|
4804
4942
|
const dimensions = {};
|
|
4805
4943
|
for (const entry of resolvedGroupBy) {
|
|
@@ -4817,7 +4955,7 @@ async function getMetricBreakdown(client, args) {
|
|
|
4817
4955
|
return { groups };
|
|
4818
4956
|
}
|
|
4819
4957
|
async function getMetricTimeSeries(client, args) {
|
|
4820
|
-
const aggSql = getAggregationSql2(args.aggregation);
|
|
4958
|
+
const aggSql = getAggregationSql2(args.aggregation, "value", args.distinctColumn);
|
|
4821
4959
|
const intervalSql = getIntervalSql2(args.interval);
|
|
4822
4960
|
const nameFilter = buildMetricNameFilter(args.name);
|
|
4823
4961
|
const signalFilter = buildMetricsFilterConditions(args.filters);
|
|
@@ -5215,6 +5353,14 @@ async function listScores(client, args) {
|
|
|
5215
5353
|
scores: rows.map(rowToScoreRecord)
|
|
5216
5354
|
};
|
|
5217
5355
|
}
|
|
5356
|
+
async function getScoreById(client, scoreId) {
|
|
5357
|
+
const rows = await queryJson4(
|
|
5358
|
+
client,
|
|
5359
|
+
`SELECT * FROM ${TABLE_SCORE_EVENTS} WHERE scoreId = {scoreId:String} LIMIT 1`,
|
|
5360
|
+
{ scoreId }
|
|
5361
|
+
);
|
|
5362
|
+
return rows[0] ? rowToScoreRecord(rows[0]) : null;
|
|
5363
|
+
}
|
|
5218
5364
|
async function getScoreAggregate(client, args) {
|
|
5219
5365
|
const aggSql = getAggregationSql3(args.aggregation);
|
|
5220
5366
|
const identity = buildScoreIdentityFilter(args);
|
|
@@ -5470,8 +5616,7 @@ async function listTraces(client, args) {
|
|
|
5470
5616
|
spans: toTraceSpans(spans)
|
|
5471
5617
|
};
|
|
5472
5618
|
}
|
|
5473
|
-
|
|
5474
|
-
// src/storage/domains/observability/v-next/tracing.ts
|
|
5619
|
+
var BRANCH_SPAN_TYPE_SQL_LIST = BRANCH_SPAN_TYPES.map((t) => `'${t}'`).join(", ");
|
|
5475
5620
|
async function createSpan(client, args) {
|
|
5476
5621
|
const row = spanRecordToRow(args.span);
|
|
5477
5622
|
await client.insert({
|
|
@@ -5491,6 +5636,29 @@ async function batchCreateSpans(client, args) {
|
|
|
5491
5636
|
clickhouse_settings: CH_INSERT_SETTINGS
|
|
5492
5637
|
});
|
|
5493
5638
|
}
|
|
5639
|
+
async function getSpans(client, args) {
|
|
5640
|
+
if (args.spanIds.length === 0) {
|
|
5641
|
+
return { traceId: args.traceId, spans: [] };
|
|
5642
|
+
}
|
|
5643
|
+
const result = await client.query({
|
|
5644
|
+
query: `
|
|
5645
|
+
SELECT * FROM (
|
|
5646
|
+
SELECT *
|
|
5647
|
+
FROM ${TABLE_SPAN_EVENTS}
|
|
5648
|
+
WHERE traceId = {traceId:String}
|
|
5649
|
+
AND spanId IN {spanIds:Array(String)}
|
|
5650
|
+
ORDER BY dedupeKey, endedAt DESC
|
|
5651
|
+
LIMIT 1 BY dedupeKey
|
|
5652
|
+
)
|
|
5653
|
+
`,
|
|
5654
|
+
query_params: { traceId: args.traceId, spanIds: args.spanIds },
|
|
5655
|
+
format: "JSONEachRow",
|
|
5656
|
+
clickhouse_settings: CH_SETTINGS
|
|
5657
|
+
});
|
|
5658
|
+
const rows = await result.json();
|
|
5659
|
+
const spans = rows.map(rowToSpanRecord);
|
|
5660
|
+
return { traceId: args.traceId, spans };
|
|
5661
|
+
}
|
|
5494
5662
|
async function getSpan(client, args) {
|
|
5495
5663
|
const result = await client.query({
|
|
5496
5664
|
query: `
|
|
@@ -5579,6 +5747,169 @@ async function batchDeleteTraces(client, args) {
|
|
|
5579
5747
|
})
|
|
5580
5748
|
]);
|
|
5581
5749
|
}
|
|
5750
|
+
async function listBranches(client, args) {
|
|
5751
|
+
const { filters, pagination, orderBy } = listBranchesArgsSchema.parse(args);
|
|
5752
|
+
const page = pagination?.page ?? 0;
|
|
5753
|
+
const perPage = pagination?.perPage ?? 10;
|
|
5754
|
+
const conditions = [];
|
|
5755
|
+
const params = {};
|
|
5756
|
+
if (filters?.spanType) {
|
|
5757
|
+
conditions.push(`spanType = {spanType:String}`);
|
|
5758
|
+
params.spanType = filters.spanType;
|
|
5759
|
+
} else {
|
|
5760
|
+
conditions.push(`spanType IN (${BRANCH_SPAN_TYPE_SQL_LIST})`);
|
|
5761
|
+
}
|
|
5762
|
+
if (filters?.startedAt?.start) {
|
|
5763
|
+
const op = filters.startedAt.startExclusive ? ">" : ">=";
|
|
5764
|
+
conditions.push(`startedAt ${op} {startedAtStart:DateTime64(3)}`);
|
|
5765
|
+
params.startedAtStart = filters.startedAt.start.getTime();
|
|
5766
|
+
}
|
|
5767
|
+
if (filters?.startedAt?.end) {
|
|
5768
|
+
const op = filters.startedAt.endExclusive ? "<" : "<=";
|
|
5769
|
+
conditions.push(`startedAt ${op} {startedAtEnd:DateTime64(3)}`);
|
|
5770
|
+
params.startedAtEnd = filters.startedAt.end.getTime();
|
|
5771
|
+
}
|
|
5772
|
+
if (filters?.endedAt?.start) {
|
|
5773
|
+
const op = filters.endedAt.startExclusive ? ">" : ">=";
|
|
5774
|
+
conditions.push(`endedAt ${op} {endedAtStart:DateTime64(3)}`);
|
|
5775
|
+
params.endedAtStart = filters.endedAt.start.getTime();
|
|
5776
|
+
}
|
|
5777
|
+
if (filters?.endedAt?.end) {
|
|
5778
|
+
const op = filters.endedAt.endExclusive ? "<" : "<=";
|
|
5779
|
+
conditions.push(`endedAt ${op} {endedAtEnd:DateTime64(3)}`);
|
|
5780
|
+
params.endedAtEnd = filters.endedAt.end.getTime();
|
|
5781
|
+
}
|
|
5782
|
+
const eq = [
|
|
5783
|
+
{ col: "traceId", value: filters?.traceId, param: "traceId" },
|
|
5784
|
+
{ col: "entityType", value: filters?.entityType, param: "entityType" },
|
|
5785
|
+
{ col: "entityId", value: filters?.entityId, param: "entityId" },
|
|
5786
|
+
{ col: "entityName", value: filters?.entityName, param: "entityName" },
|
|
5787
|
+
{ col: "entityVersionId", value: filters?.entityVersionId, param: "entityVersionId" },
|
|
5788
|
+
{ col: "parentEntityVersionId", value: filters?.parentEntityVersionId, param: "parentEntityVersionId" },
|
|
5789
|
+
{ col: "parentEntityType", value: filters?.parentEntityType, param: "parentEntityType" },
|
|
5790
|
+
{ col: "parentEntityId", value: filters?.parentEntityId, param: "parentEntityId" },
|
|
5791
|
+
{ col: "parentEntityName", value: filters?.parentEntityName, param: "parentEntityName" },
|
|
5792
|
+
{ col: "rootEntityVersionId", value: filters?.rootEntityVersionId, param: "rootEntityVersionId" },
|
|
5793
|
+
{ col: "rootEntityType", value: filters?.rootEntityType, param: "rootEntityType" },
|
|
5794
|
+
{ col: "rootEntityId", value: filters?.rootEntityId, param: "rootEntityId" },
|
|
5795
|
+
{ col: "rootEntityName", value: filters?.rootEntityName, param: "rootEntityName" },
|
|
5796
|
+
{ col: "experimentId", value: filters?.experimentId, param: "experimentId" },
|
|
5797
|
+
{ col: "userId", value: filters?.userId, param: "userId" },
|
|
5798
|
+
{ col: "organizationId", value: filters?.organizationId, param: "organizationId" },
|
|
5799
|
+
{ col: "resourceId", value: filters?.resourceId, param: "resourceId" },
|
|
5800
|
+
{ col: "runId", value: filters?.runId, param: "runId" },
|
|
5801
|
+
{ col: "sessionId", value: filters?.sessionId, param: "sessionId" },
|
|
5802
|
+
{ col: "threadId", value: filters?.threadId, param: "threadId" },
|
|
5803
|
+
{ col: "requestId", value: filters?.requestId, param: "requestId" },
|
|
5804
|
+
{ col: "environment", value: filters?.environment, param: "environment" },
|
|
5805
|
+
{ col: "executionSource", value: filters?.source, param: "source" },
|
|
5806
|
+
{ col: "serviceName", value: filters?.serviceName, param: "serviceName" }
|
|
5807
|
+
];
|
|
5808
|
+
for (const { col, value, param } of eq) {
|
|
5809
|
+
if (value == null) continue;
|
|
5810
|
+
conditions.push(`${col} = {${param}:String}`);
|
|
5811
|
+
params[param] = value;
|
|
5812
|
+
}
|
|
5813
|
+
if (filters?.tags && filters.tags.length > 0) {
|
|
5814
|
+
for (let i = 0; i < filters.tags.length; i++) {
|
|
5815
|
+
const tag = filters.tags[i];
|
|
5816
|
+
if (typeof tag !== "string" || tag.trim() === "") continue;
|
|
5817
|
+
const param = `tag_${i}`;
|
|
5818
|
+
conditions.push(`has(tags, {${param}:String})`);
|
|
5819
|
+
params[param] = tag;
|
|
5820
|
+
}
|
|
5821
|
+
}
|
|
5822
|
+
if (filters?.metadata != null && typeof filters.metadata === "object") {
|
|
5823
|
+
let i = 0;
|
|
5824
|
+
for (const [key, value] of Object.entries(filters.metadata)) {
|
|
5825
|
+
if (typeof value !== "string") continue;
|
|
5826
|
+
const keyParam = `meta_k_${i}`;
|
|
5827
|
+
const valParam = `meta_v_${i}`;
|
|
5828
|
+
conditions.push(`metadataSearch[{${keyParam}:String}] = {${valParam}:String}`);
|
|
5829
|
+
params[keyParam] = key;
|
|
5830
|
+
params[valParam] = value;
|
|
5831
|
+
i++;
|
|
5832
|
+
}
|
|
5833
|
+
}
|
|
5834
|
+
if (filters?.scope != null && typeof filters.scope === "object") {
|
|
5835
|
+
let i = 0;
|
|
5836
|
+
for (const [key, value] of Object.entries(filters.scope)) {
|
|
5837
|
+
if (value === void 0) continue;
|
|
5838
|
+
const normalized = typeof value === "string" ? value : JSON.stringify(value);
|
|
5839
|
+
if (normalized == null) continue;
|
|
5840
|
+
const keyParam = `scope_k_${i}`;
|
|
5841
|
+
const valParam = `scope_v_${i}`;
|
|
5842
|
+
conditions.push(`JSONExtractString(scope, {${keyParam}:String}) = {${valParam}:String}`);
|
|
5843
|
+
params[keyParam] = key;
|
|
5844
|
+
params[valParam] = normalized;
|
|
5845
|
+
i++;
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
if (filters?.status === TraceStatus.ERROR) {
|
|
5849
|
+
conditions.push(`error IS NOT NULL`);
|
|
5850
|
+
} else if (filters?.status === TraceStatus.SUCCESS) {
|
|
5851
|
+
conditions.push(`error IS NULL`);
|
|
5852
|
+
} else if (filters?.status === TraceStatus.RUNNING) {
|
|
5853
|
+
conditions.push("1 = 0");
|
|
5854
|
+
}
|
|
5855
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
5856
|
+
const sortField = orderBy?.field === "endedAt" ? "endedAt" : "startedAt";
|
|
5857
|
+
const sortDirection = orderBy?.direction === "ASC" ? "ASC" : "DESC";
|
|
5858
|
+
const countResult = await client.query({
|
|
5859
|
+
query: `
|
|
5860
|
+
SELECT count() as cnt FROM (
|
|
5861
|
+
SELECT dedupeKey
|
|
5862
|
+
FROM ${TABLE_TRACE_BRANCHES}
|
|
5863
|
+
${whereClause}
|
|
5864
|
+
ORDER BY dedupeKey
|
|
5865
|
+
LIMIT 1 BY dedupeKey
|
|
5866
|
+
)
|
|
5867
|
+
`,
|
|
5868
|
+
query_params: params,
|
|
5869
|
+
format: "JSONEachRow",
|
|
5870
|
+
clickhouse_settings: CH_SETTINGS
|
|
5871
|
+
});
|
|
5872
|
+
const countRows = await countResult.json();
|
|
5873
|
+
const total = Number(countRows[0]?.cnt ?? 0);
|
|
5874
|
+
if (total === 0) {
|
|
5875
|
+
return {
|
|
5876
|
+
pagination: { total: 0, page, perPage, hasMore: false },
|
|
5877
|
+
branches: []
|
|
5878
|
+
};
|
|
5879
|
+
}
|
|
5880
|
+
const dataResult = await client.query({
|
|
5881
|
+
query: `
|
|
5882
|
+
SELECT * FROM (
|
|
5883
|
+
SELECT *
|
|
5884
|
+
FROM ${TABLE_TRACE_BRANCHES}
|
|
5885
|
+
${whereClause}
|
|
5886
|
+
ORDER BY dedupeKey
|
|
5887
|
+
LIMIT 1 BY dedupeKey
|
|
5888
|
+
)
|
|
5889
|
+
ORDER BY ${sortField} ${sortDirection}, dedupeKey ASC
|
|
5890
|
+
LIMIT {limit:UInt32}
|
|
5891
|
+
OFFSET {offset:UInt32}
|
|
5892
|
+
`,
|
|
5893
|
+
query_params: {
|
|
5894
|
+
...params,
|
|
5895
|
+
limit: perPage,
|
|
5896
|
+
offset: page * perPage
|
|
5897
|
+
},
|
|
5898
|
+
format: "JSONEachRow",
|
|
5899
|
+
clickhouse_settings: CH_SETTINGS
|
|
5900
|
+
});
|
|
5901
|
+
const rows = await dataResult.json();
|
|
5902
|
+
const spans = rows.map(rowToSpanRecord);
|
|
5903
|
+
return {
|
|
5904
|
+
pagination: {
|
|
5905
|
+
total,
|
|
5906
|
+
page,
|
|
5907
|
+
perPage,
|
|
5908
|
+
hasMore: (page + 1) * perPage < total
|
|
5909
|
+
},
|
|
5910
|
+
branches: toTraceSpans(spans)
|
|
5911
|
+
};
|
|
5912
|
+
}
|
|
5582
5913
|
|
|
5583
5914
|
// src/storage/domains/observability/v-next/index.ts
|
|
5584
5915
|
function buildSignalMigrationRequiredMessage(args) {
|
|
@@ -5757,6 +6088,22 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
|
|
|
5757
6088
|
);
|
|
5758
6089
|
}
|
|
5759
6090
|
}
|
|
6091
|
+
async getSpans(args) {
|
|
6092
|
+
try {
|
|
6093
|
+
return await getSpans(this.#client, args);
|
|
6094
|
+
} catch (error) {
|
|
6095
|
+
if (error instanceof MastraError) throw error;
|
|
6096
|
+
throw new MastraError(
|
|
6097
|
+
{
|
|
6098
|
+
id: createStorageErrorId("CLICKHOUSE", "GET_SPANS", "FAILED"),
|
|
6099
|
+
domain: ErrorDomain.STORAGE,
|
|
6100
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
6101
|
+
details: { traceId: args.traceId, count: args.spanIds.length }
|
|
6102
|
+
},
|
|
6103
|
+
error
|
|
6104
|
+
);
|
|
6105
|
+
}
|
|
6106
|
+
}
|
|
5760
6107
|
async getRootSpan(args) {
|
|
5761
6108
|
try {
|
|
5762
6109
|
return await getRootSpan(this.#client, args);
|
|
@@ -5820,6 +6167,21 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
|
|
|
5820
6167
|
);
|
|
5821
6168
|
}
|
|
5822
6169
|
}
|
|
6170
|
+
async listBranches(args) {
|
|
6171
|
+
try {
|
|
6172
|
+
return await listBranches(this.#client, args);
|
|
6173
|
+
} catch (error) {
|
|
6174
|
+
if (error instanceof MastraError) throw error;
|
|
6175
|
+
throw new MastraError(
|
|
6176
|
+
{
|
|
6177
|
+
id: createStorageErrorId("CLICKHOUSE", "LIST_BRANCHES", "FAILED"),
|
|
6178
|
+
domain: ErrorDomain.STORAGE,
|
|
6179
|
+
category: ErrorCategory.THIRD_PARTY
|
|
6180
|
+
},
|
|
6181
|
+
error
|
|
6182
|
+
);
|
|
6183
|
+
}
|
|
6184
|
+
}
|
|
5823
6185
|
async batchCreateLogs(args) {
|
|
5824
6186
|
try {
|
|
5825
6187
|
await batchCreateLogs(this.#client, args);
|
|
@@ -5928,6 +6290,22 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
|
|
|
5928
6290
|
);
|
|
5929
6291
|
}
|
|
5930
6292
|
}
|
|
6293
|
+
async getScoreById(scoreId) {
|
|
6294
|
+
try {
|
|
6295
|
+
return await getScoreById(this.#client, scoreId);
|
|
6296
|
+
} catch (error) {
|
|
6297
|
+
if (error instanceof MastraError) throw error;
|
|
6298
|
+
throw new MastraError(
|
|
6299
|
+
{
|
|
6300
|
+
id: createStorageErrorId("CLICKHOUSE", "GET_SCORE_BY_ID", "FAILED"),
|
|
6301
|
+
domain: ErrorDomain.STORAGE,
|
|
6302
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
6303
|
+
details: { scoreId }
|
|
6304
|
+
},
|
|
6305
|
+
error
|
|
6306
|
+
);
|
|
6307
|
+
}
|
|
6308
|
+
}
|
|
5931
6309
|
async createFeedback(args) {
|
|
5932
6310
|
try {
|
|
5933
6311
|
await createFeedback(this.#client, args);
|