@mastra/clickhouse 1.27.0 → 1.28.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/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +43 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +43 -13
- package/dist/index.js.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 +1 -0
- 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 +1 -0
- package/dist/storage/domains/observability/v-next/span-query.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/thread-query.d.ts +1 -0
- package/dist/storage/domains/observability/v-next/thread-query.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts +3 -1
- package/dist/storage/domains/observability/v-next/trace-query.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6906,7 +6906,17 @@ const TRACE_STATUS_SQL = `if(isNotNull(r.error), 'error', 'success')`;
|
|
|
6906
6906
|
const timeToFirstChunkSupported = "timeToFirstChunkMs" in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});
|
|
6907
6907
|
/** Core before the sort rejects `orderBy` on the field, so the sort is only declared when core plans it. */
|
|
6908
6908
|
const timeToFirstChunkSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes("timeToFirstChunkMs") === true;
|
|
6909
|
-
|
|
6909
|
+
/** Same rule for time to first token: returned and sorted only when core knows the field. */
|
|
6910
|
+
const timeToFirstTokenSupported = "timeToFirstTokenMs" in (coreStorage.TRACE_QUERY_FIELD_REGISTRY?.trace ?? {});
|
|
6911
|
+
const timeToFirstTokenSortSupported = coreStorage.TRACE_QUERY_ORDER_FIELDS?.includes("timeToFirstTokenMs") === true;
|
|
6912
|
+
const timingFeatures = [
|
|
6913
|
+
...timeToFirstChunkSupported ? ["trace-query-time-to-first-chunk"] : [],
|
|
6914
|
+
...timeToFirstChunkSupported && timeToFirstChunkSortSupported ? ["trace-query-time-to-first-chunk-sort"] : [],
|
|
6915
|
+
...timeToFirstTokenSupported ? ["trace-query-time-to-first-token"] : [],
|
|
6916
|
+
...timeToFirstTokenSupported && timeToFirstTokenSortSupported ? ["trace-query-time-to-first-token-sort"] : []
|
|
6917
|
+
];
|
|
6918
|
+
/** Order fields holding numbers that can be empty; the rest are timestamps. */
|
|
6919
|
+
const NUMERIC_ORDER_FIELDS = /* @__PURE__ */ new Set(["timeToFirstChunkMs", "timeToFirstTokenMs"]);
|
|
6910
6920
|
function durationMsSql(startedAt, endedAt) {
|
|
6911
6921
|
return `dateDiff('millisecond', ${startedAt}, ${endedAt})`;
|
|
6912
6922
|
}
|
|
@@ -6959,6 +6969,10 @@ const TRACE_FIELDS = {
|
|
|
6959
6969
|
sql: "r.timeToFirstChunkMs",
|
|
6960
6970
|
parameterType: "Float64"
|
|
6961
6971
|
},
|
|
6972
|
+
timeToFirstTokenMs: {
|
|
6973
|
+
sql: "r.timeToFirstTokenMs",
|
|
6974
|
+
parameterType: "Float64"
|
|
6975
|
+
},
|
|
6962
6976
|
entityId: {
|
|
6963
6977
|
sql: "r.entityId",
|
|
6964
6978
|
parameterType: "String"
|
|
@@ -7025,6 +7039,10 @@ const SPAN_FIELDS = {
|
|
|
7025
7039
|
sql: "s.timeToFirstChunkMs",
|
|
7026
7040
|
parameterType: "Float64"
|
|
7027
7041
|
},
|
|
7042
|
+
timeToFirstTokenMs: {
|
|
7043
|
+
sql: "s.timeToFirstTokenMs",
|
|
7044
|
+
parameterType: "Float64"
|
|
7045
|
+
},
|
|
7028
7046
|
status: {
|
|
7029
7047
|
sql: "s.status",
|
|
7030
7048
|
parameterType: "String"
|
|
@@ -7237,6 +7255,7 @@ const TRACE_SELECT = `
|
|
|
7237
7255
|
r.entityType AS entityType,
|
|
7238
7256
|
r.environment AS environment,
|
|
7239
7257
|
r.timeToFirstChunkMs AS timeToFirstChunkMs,
|
|
7258
|
+
r.timeToFirstTokenMs AS timeToFirstTokenMs,
|
|
7240
7259
|
${TRACE_STATUS_SQL} AS status`;
|
|
7241
7260
|
var ParameterBuilder = class {
|
|
7242
7261
|
params = {};
|
|
@@ -7253,7 +7272,7 @@ function fieldDefinition(registry, field) {
|
|
|
7253
7272
|
return definition;
|
|
7254
7273
|
}
|
|
7255
7274
|
function resolveOrderField(field) {
|
|
7256
|
-
if (field === "startedAt" || field === "endedAt" || field
|
|
7275
|
+
if (field === "startedAt" || field === "endedAt" || NUMERIC_ORDER_FIELDS.has(field)) return field;
|
|
7257
7276
|
throw new Error(`Unsupported trusted trace-query field: ${field}`);
|
|
7258
7277
|
}
|
|
7259
7278
|
function isMetadataField(field) {
|
|
@@ -7443,6 +7462,7 @@ function compileClickHouseTraceScope(selection, relationCollections, parameters,
|
|
|
7443
7462
|
endedAt,
|
|
7444
7463
|
${durationMsSql("startedAt", "endedAt")} AS durationMs,
|
|
7445
7464
|
timeToFirstChunkMs,
|
|
7465
|
+
timeToFirstTokenMs,
|
|
7446
7466
|
if(isNotNull(error), 'error', 'success') AS status,
|
|
7447
7467
|
error,
|
|
7448
7468
|
entityType,
|
|
@@ -7558,7 +7578,7 @@ function traceOrder(plan) {
|
|
|
7558
7578
|
function keysetCursorCondition(plan, order, parameters) {
|
|
7559
7579
|
if (plan.paginationMode !== "keyset" || !plan.cursor) return "";
|
|
7560
7580
|
if (plan.cursor.sortValue === null) return `(isNull(sortValue) AND traceId > ${parameters.add(plan.cursor.traceId, "String")})`;
|
|
7561
|
-
const numeric = order.field
|
|
7581
|
+
const numeric = NUMERIC_ORDER_FIELDS.has(order.field);
|
|
7562
7582
|
const comparison = order.direction === "ASC" ? ">" : "<";
|
|
7563
7583
|
const sortValue = parameters.add(plan.cursor.sortValue, numeric ? "Float64" : "DateTime64(3, 'UTC')");
|
|
7564
7584
|
return `(sortValue ${comparison} ${sortValue} OR (sortValue = ${sortValue} AND traceId > ${parameters.add(plan.cursor.traceId, "String")})${numeric ? " OR isNull(sortValue)" : ""})`;
|
|
@@ -7572,7 +7592,7 @@ function compileClickHouseTraceQueryKeys(plan) {
|
|
|
7572
7592
|
if (plan.paginationMode === "delta") throw new Error("Delta trace queries have no keys statement");
|
|
7573
7593
|
const parameters = new ParameterBuilder();
|
|
7574
7594
|
const order = traceOrder(plan);
|
|
7575
|
-
const ctes = compileClickHouseTraceCandidates(plan, "r.traceId AS traceId, r.dedupeKey AS dedupeKey, r.startedAt AS startedAt, r.endedAt AS endedAt, r.timeToFirstChunkMs AS timeToFirstChunkMs", parameters, QUERY_TRACES_SCOPE);
|
|
7595
|
+
const ctes = compileClickHouseTraceCandidates(plan, "r.traceId AS traceId, r.dedupeKey AS dedupeKey, r.startedAt AS startedAt, r.endedAt AS endedAt, r.timeToFirstChunkMs AS timeToFirstChunkMs, r.timeToFirstTokenMs AS timeToFirstTokenMs", parameters, QUERY_TRACES_SCOPE);
|
|
7576
7596
|
const cursor = keysetCursorCondition(plan, order, parameters);
|
|
7577
7597
|
const limit = plan.paginationMode === "page" ? `LIMIT ${parameters.add(plan.perPage, "UInt64")} OFFSET ${parameters.add(plan.page * plan.perPage, "UInt64")}` : `LIMIT ${parameters.add(plan.limit + 1, "UInt64")}`;
|
|
7578
7598
|
return {
|
|
@@ -7973,7 +7993,8 @@ async function queryTraces(client, plan, timeoutMs, strategy = null) {
|
|
|
7973
7993
|
entityType: row.entityType == null ? null : String(row.entityType),
|
|
7974
7994
|
environment: row.environment == null ? null : String(row.environment),
|
|
7975
7995
|
status: row.status,
|
|
7976
|
-
...timeToFirstChunkSupported && { timeToFirstChunkMs: row.timeToFirstChunkMs == null ? null : Number(row.timeToFirstChunkMs) }
|
|
7996
|
+
...timeToFirstChunkSupported && { timeToFirstChunkMs: row.timeToFirstChunkMs == null ? null : Number(row.timeToFirstChunkMs) },
|
|
7997
|
+
...timeToFirstTokenSupported && { timeToFirstTokenMs: row.timeToFirstTokenMs == null ? null : Number(row.timeToFirstTokenMs) }
|
|
7977
7998
|
});
|
|
7978
7999
|
if (plan.paginationMode === "delta") {
|
|
7979
8000
|
const rows = await run(compileClickHouseTraceQuery(plan, deltaHead));
|
|
@@ -7996,7 +8017,7 @@ async function queryTraces(client, plan, timeoutMs, strategy = null) {
|
|
|
7996
8017
|
});
|
|
7997
8018
|
}
|
|
7998
8019
|
const keys = await run(compileClickHouseTraceQueryKeys(plan));
|
|
7999
|
-
const sortValue = (value) => plan.orderBy.field
|
|
8020
|
+
const sortValue = (value) => !NUMERIC_ORDER_FIELDS.has(plan.orderBy.field) ? asIsoTimestamp(value) : value == null ? null : Number(value);
|
|
8000
8021
|
let total = Number(keys[0]?.__total ?? 0);
|
|
8001
8022
|
if (plan.paginationMode === "page" && keys.length === 0 && plan.page > 0) {
|
|
8002
8023
|
const [stats] = await run(compileClickHouseTraceQueryTotal(plan));
|
|
@@ -8099,6 +8120,7 @@ const displayFields = [
|
|
|
8099
8120
|
"provider",
|
|
8100
8121
|
"durationMs",
|
|
8101
8122
|
"timeToFirstChunkMs",
|
|
8123
|
+
"timeToFirstTokenMs",
|
|
8102
8124
|
"status"
|
|
8103
8125
|
];
|
|
8104
8126
|
var Parameters = class {
|
|
@@ -8127,7 +8149,7 @@ function afterCursor$1(plan, parameters) {
|
|
|
8127
8149
|
const equal = [];
|
|
8128
8150
|
if (cursor.sortValue === null) equal.push(`isNull(${field})`);
|
|
8129
8151
|
else {
|
|
8130
|
-
const numeric = plan.orderBy.field === "timeToFirstChunkMs";
|
|
8152
|
+
const numeric = plan.orderBy.field === "timeToFirstChunkMs" || plan.orderBy.field === "timeToFirstTokenMs";
|
|
8131
8153
|
const value = parameters.add(cursor.sortValue, numeric ? "Float64" : "DateTime64(3, 'UTC')");
|
|
8132
8154
|
terms.push(`${field} ${plan.orderBy.direction === "asc" ? ">" : "<"} ${value}`);
|
|
8133
8155
|
if (numeric) terms.push(`isNull(${field})`);
|
|
@@ -8223,6 +8245,7 @@ const TRACE_BRANCHES_SPAN_FIELD_COLUMNS = {
|
|
|
8223
8245
|
"startedAt",
|
|
8224
8246
|
"endedAt",
|
|
8225
8247
|
"timeToFirstChunkMs",
|
|
8248
|
+
"timeToFirstTokenMs",
|
|
8226
8249
|
"threadId",
|
|
8227
8250
|
"runId",
|
|
8228
8251
|
"sessionId",
|
|
@@ -8383,12 +8406,13 @@ async function querySpans(client, plan, timeoutMs) {
|
|
|
8383
8406
|
const hydrated = page.flatMap((identity) => {
|
|
8384
8407
|
const row = byIdentity.get(coreStorage.spanQueryIdentityKey(identity));
|
|
8385
8408
|
if (!row) return [];
|
|
8386
|
-
const { inputPreview: _input, outputPreview: _output, errorPreview: _error, timeToFirstChunkMs, ...metadata } = row;
|
|
8409
|
+
const { inputPreview: _input, outputPreview: _output, errorPreview: _error, timeToFirstChunkMs, timeToFirstTokenMs, ...metadata } = row;
|
|
8387
8410
|
return [{
|
|
8388
8411
|
...metadata,
|
|
8389
8412
|
...identity,
|
|
8390
8413
|
durationMs: Number(row.durationMs),
|
|
8391
|
-
...timeToFirstChunkSupported && { timeToFirstChunkMs: timeToFirstChunkMs == null ? null : Number(timeToFirstChunkMs) }
|
|
8414
|
+
...timeToFirstChunkSupported && { timeToFirstChunkMs: timeToFirstChunkMs == null ? null : Number(timeToFirstChunkMs) },
|
|
8415
|
+
...timeToFirstTokenSupported && { timeToFirstTokenMs: timeToFirstTokenMs == null ? null : Number(timeToFirstTokenMs) }
|
|
8392
8416
|
}];
|
|
8393
8417
|
});
|
|
8394
8418
|
let metrics = [];
|
|
@@ -8511,7 +8535,11 @@ function compileClickHouseThreadRowsQuery(plan, strategy = "full") {
|
|
|
8511
8535
|
const after = afterCursor(plan, parameters);
|
|
8512
8536
|
const qualify = plan.timeRange.mode === "traces" ? "s.inWindow > 0" : `s.${plan.timeRange.field} >= ${from} AND s.${plan.timeRange.field} < ${to}`;
|
|
8513
8537
|
const filtered = predicateFields(plan.where);
|
|
8514
|
-
const firstContext = [
|
|
8538
|
+
const firstContext = [
|
|
8539
|
+
...contextFields,
|
|
8540
|
+
"timeToFirstChunkMs",
|
|
8541
|
+
"timeToFirstTokenMs"
|
|
8542
|
+
].filter((field) => field === "resourceId" || filtered.has(field));
|
|
8515
8543
|
const firstFields = [
|
|
8516
8544
|
"startedAt",
|
|
8517
8545
|
"traceId",
|
|
@@ -8535,7 +8563,7 @@ function compileClickHouseThreadRowsQuery(plan, strategy = "full") {
|
|
|
8535
8563
|
...firstContext,
|
|
8536
8564
|
...filtered.has("status") ? ["status"] : []
|
|
8537
8565
|
];
|
|
8538
|
-
const rootExpression = (field) => field === "timeToFirstChunkMs" ?
|
|
8566
|
+
const rootExpression = (field) => field === "timeToFirstChunkMs" || field === "timeToFirstTokenMs" ? `if(spanType = 'agent_run', ${field}, NULL)` : field === "status" ? "if(isNull(error), 'success', 'error')" : field;
|
|
8539
8567
|
const sortedRoots = `roots AS (
|
|
8540
8568
|
SELECT organizationId, traceId, ${rootDataFields.map((field) => `${rootExpression(field)} AS ${field}`).join(", ")}
|
|
8541
8569
|
FROM ${TABLE_TRACE_ROOTS} ${scope.length || strategy === "candidates" ? `WHERE ${[...scope, ...strategy === "candidates" ? [candidateTracesFilter] : []].join(" AND ")}` : ""}
|
|
@@ -8639,6 +8667,7 @@ async function queryThreadRows(client, plan, timeoutMs, strategy = "auto") {
|
|
|
8639
8667
|
for (const batch of batches([...roots.values()])) stored.push(...await run({
|
|
8640
8668
|
query: `SELECT organizationId, traceId, spanId, startedAt, endedAt,
|
|
8641
8669
|
${contextFields.join(", ")}, if(spanType = 'agent_run', timeToFirstChunkMs, NULL) AS timeToFirstChunkMs,
|
|
8670
|
+
if(spanType = 'agent_run', timeToFirstTokenMs, NULL) AS timeToFirstTokenMs,
|
|
8642
8671
|
if(isNull(error), 'success', 'error') AS status, ${PREVIEW_COLUMNS.join(", ")}
|
|
8643
8672
|
FROM ${TABLE_TRACE_ROOTS} WHERE ${rootWhere}
|
|
8644
8673
|
ORDER BY ${ROOT_VERSION_ORDER} LIMIT 1 BY organizationId, traceId, spanId`,
|
|
@@ -8672,6 +8701,7 @@ async function queryThreadRows(client, plan, timeoutMs, strategy = "auto") {
|
|
|
8672
8701
|
endedAt: iso(row.endedAt),
|
|
8673
8702
|
traceCount: Number(row.traceCount),
|
|
8674
8703
|
timeToFirstChunkMs: first.timeToFirstChunkMs,
|
|
8704
|
+
...timeToFirstTokenSupported && { timeToFirstTokenMs: first.timeToFirstTokenMs },
|
|
8675
8705
|
inputPreview: resolveStoredPreviews(first).inputPreview,
|
|
8676
8706
|
outputPreview: resolveStoredPreviews(last).outputPreview,
|
|
8677
8707
|
errorPreview: resolveStoredPreviews(last).errorPreview
|
|
@@ -10328,7 +10358,7 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
|
|
|
10328
10358
|
"trace-query-tenant-scope",
|
|
10329
10359
|
"feedback",
|
|
10330
10360
|
"trace-query-context-ids",
|
|
10331
|
-
...
|
|
10361
|
+
...timingFeatures,
|
|
10332
10362
|
"trace-query-root-span-fields",
|
|
10333
10363
|
"trace-query-root-entity-id",
|
|
10334
10364
|
"trace-aggregate",
|
|
@@ -10353,7 +10383,7 @@ var ObservabilityStorageClickhouseVNext = class extends ObservabilityStorage {
|
|
|
10353
10383
|
"trace-query-tenant-scope",
|
|
10354
10384
|
"feedback",
|
|
10355
10385
|
"trace-query-context-ids",
|
|
10356
|
-
...
|
|
10386
|
+
...timingFeatures,
|
|
10357
10387
|
"trace-query-root-span-fields",
|
|
10358
10388
|
"trace-query-root-entity-id",
|
|
10359
10389
|
"trace-aggregate",
|