@mastra/clickhouse 1.16.1-alpha.1 → 1.16.1-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.
- package/dist/docs/SKILL.md +1 -1
- package/dist/docs/assets/SOURCE_MAP.json +1 -1
- package/dist/index.cjs +77 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +77 -10
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts +1 -1
- package/dist/storage/domains/observability/v-next/ddl.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/feedback.d.ts +2 -1
- package/dist/storage/domains/observability/v-next/feedback.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/filters.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/helpers.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/index.d.ts +2 -1
- package/dist/storage/domains/observability/v-next/index.d.ts.map +1 -1
- package/dist/storage/domains/observability/v-next/review-status.d.ts +5 -0
- package/dist/storage/domains/observability/v-next/review-status.d.ts.map +1 -0
- package/package.json +3 -3
package/dist/docs/SKILL.md
CHANGED
|
@@ -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.16.1-alpha.
|
|
6
|
+
version: "1.16.1-alpha.2"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
## When to use
|
package/dist/index.cjs
CHANGED
|
@@ -3173,6 +3173,9 @@ CREATE TABLE IF NOT EXISTS ${TABLE_FEEDBACK_EVENTS} (
|
|
|
3173
3173
|
feedbackUserId Nullable(String),
|
|
3174
3174
|
sourceId Nullable(String),
|
|
3175
3175
|
|
|
3176
|
+
-- Review workflow
|
|
3177
|
+
reviewStatus LowCardinality(String) DEFAULT 'needs-review',
|
|
3178
|
+
|
|
3176
3179
|
-- Feedback identity
|
|
3177
3180
|
feedbackSource LowCardinality(String),
|
|
3178
3181
|
feedbackType LowCardinality(String),
|
|
@@ -3406,6 +3409,7 @@ const ALL_MIGRATIONS = [
|
|
|
3406
3409
|
addColumn(TABLE_SCORE_EVENTS, "parentEntityVersionId", "Nullable(String)"),
|
|
3407
3410
|
addColumn(TABLE_SCORE_EVENTS, "rootEntityVersionId", "Nullable(String)"),
|
|
3408
3411
|
addColumn(TABLE_FEEDBACK_EVENTS, "entityVersionId", "Nullable(String)"),
|
|
3412
|
+
addColumn(TABLE_FEEDBACK_EVENTS, "reviewStatus", "LowCardinality(String) DEFAULT 'needs-review'"),
|
|
3409
3413
|
addColumn(TABLE_FEEDBACK_EVENTS, "parentEntityVersionId", "Nullable(String)"),
|
|
3410
3414
|
addColumn(TABLE_FEEDBACK_EVENTS, "rootEntityVersionId", "Nullable(String)"),
|
|
3411
3415
|
addBloomIndex(TABLE_METRIC_EVENTS, "idx_traceId", "traceId"),
|
|
@@ -3498,6 +3502,31 @@ function parseTtlExpression(expr) {
|
|
|
3498
3502
|
};
|
|
3499
3503
|
}
|
|
3500
3504
|
//#endregion
|
|
3505
|
+
//#region src/storage/domains/observability/v-next/review-status.ts
|
|
3506
|
+
const FEEDBACK_REVIEW_STATUSES = ["needs-review", "reviewed"];
|
|
3507
|
+
function isFeedbackReviewStatus(value) {
|
|
3508
|
+
return FEEDBACK_REVIEW_STATUSES.some((status) => status === value);
|
|
3509
|
+
}
|
|
3510
|
+
/** Normalize a stored value to a review status, defaulting legacy/unknown values to `needs-review`. */
|
|
3511
|
+
function coerceFeedbackReviewStatus(value) {
|
|
3512
|
+
return isFeedbackReviewStatus(value) ? value : "needs-review";
|
|
3513
|
+
}
|
|
3514
|
+
function parseUpdateFeedbackReviewStatusArgs(args) {
|
|
3515
|
+
const invalid = (text) => new _mastra_core_error.MastraError({
|
|
3516
|
+
id: "OBSERVABILITY_UPDATE_FEEDBACK_REVIEW_STATUS_INVALID_ARGS",
|
|
3517
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
3518
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
3519
|
+
text
|
|
3520
|
+
});
|
|
3521
|
+
if (typeof args !== "object" || args === null) throw invalid("args must be an object");
|
|
3522
|
+
if (typeof args.feedbackId !== "string" || args.feedbackId.length === 0) throw invalid("feedbackId is required");
|
|
3523
|
+
if (!isFeedbackReviewStatus(args.reviewStatus)) throw invalid(`reviewStatus must be one of: ${FEEDBACK_REVIEW_STATUSES.join(", ")}`);
|
|
3524
|
+
return {
|
|
3525
|
+
feedbackId: args.feedbackId,
|
|
3526
|
+
reviewStatus: args.reviewStatus
|
|
3527
|
+
};
|
|
3528
|
+
}
|
|
3529
|
+
//#endregion
|
|
3501
3530
|
//#region src/storage/domains/observability/v-next/helpers.ts
|
|
3502
3531
|
const CH_SETTINGS = {
|
|
3503
3532
|
date_time_input_format: "best_effort",
|
|
@@ -4004,6 +4033,7 @@ function rowToFeedbackRecord(row) {
|
|
|
4004
4033
|
serviceName: nullableString(row.serviceName),
|
|
4005
4034
|
feedbackUserId,
|
|
4006
4035
|
sourceId: nullableString(row.sourceId),
|
|
4036
|
+
reviewStatus: coerceFeedbackReviewStatus(row.reviewStatus),
|
|
4007
4037
|
feedbackSource,
|
|
4008
4038
|
feedbackType: row.feedbackType,
|
|
4009
4039
|
value: hasNumber ? Number(row.valueNumber) : nullableString(row.valueString) ?? "",
|
|
@@ -4047,6 +4077,7 @@ function feedbackRecordToRow(feedback) {
|
|
|
4047
4077
|
serviceName: feedback.serviceName ?? null,
|
|
4048
4078
|
feedbackUserId,
|
|
4049
4079
|
sourceId: feedback.sourceId ?? null,
|
|
4080
|
+
reviewStatus: feedback.reviewStatus ?? "needs-review",
|
|
4050
4081
|
feedbackSource,
|
|
4051
4082
|
feedbackType: feedback.feedbackType,
|
|
4052
4083
|
valueString: typeof feedback.value === "string" ? feedback.value : null,
|
|
@@ -4344,6 +4375,7 @@ function buildFeedbackFilterConditions(filters, tableAlias) {
|
|
|
4344
4375
|
const fbActor = filters.feedbackUserId ?? filters.userId;
|
|
4345
4376
|
addEq(col("feedbackUserId"), fbActor, "feedbackUserId", "String", out);
|
|
4346
4377
|
addEq(col("feedbackSource"), filters.feedbackSource, "feedbackSource", "String", out);
|
|
4378
|
+
addEq(col("reviewStatus"), filters.reviewStatus, "reviewStatus", "String", out);
|
|
4347
4379
|
if (typeof filters.feedbackType === "string") addEq(col("feedbackType"), filters.feedbackType, "feedbackType", "String", out);
|
|
4348
4380
|
else if (Array.isArray(filters.feedbackType)) addIn(col("feedbackType"), filters.feedbackType, "feedbackTypes", out);
|
|
4349
4381
|
return out;
|
|
@@ -4521,6 +4553,28 @@ async function batchCreateFeedback(client, args) {
|
|
|
4521
4553
|
clickhouse_settings: CH_INSERT_SETTINGS
|
|
4522
4554
|
});
|
|
4523
4555
|
}
|
|
4556
|
+
async function updateFeedbackReviewStatus(client, args) {
|
|
4557
|
+
const { feedbackId, reviewStatus } = parseUpdateFeedbackReviewStatusArgs(args);
|
|
4558
|
+
const existing = await queryJson$2(client, `SELECT * FROM ${TABLE_FEEDBACK_EVENTS} FINAL WHERE feedbackId = {feedbackId:String} LIMIT 1`, { feedbackId });
|
|
4559
|
+
if (!existing[0]) throw new _mastra_core_error.MastraError({
|
|
4560
|
+
id: "OBSERVABILITY_UPDATE_FEEDBACK_REVIEW_STATUS_NOT_FOUND",
|
|
4561
|
+
domain: _mastra_core_error.ErrorDomain.MASTRA_OBSERVABILITY,
|
|
4562
|
+
category: _mastra_core_error.ErrorCategory.USER,
|
|
4563
|
+
text: "Feedback record not found",
|
|
4564
|
+
details: { feedbackId }
|
|
4565
|
+
});
|
|
4566
|
+
const updated = rowToFeedbackRecord({
|
|
4567
|
+
...existing[0],
|
|
4568
|
+
reviewStatus
|
|
4569
|
+
});
|
|
4570
|
+
await client.insert({
|
|
4571
|
+
table: TABLE_FEEDBACK_EVENTS,
|
|
4572
|
+
values: [feedbackRecordToRow(updated)],
|
|
4573
|
+
format: "JSONEachRow",
|
|
4574
|
+
clickhouse_settings: CH_INSERT_SETTINGS
|
|
4575
|
+
});
|
|
4576
|
+
return updated;
|
|
4577
|
+
}
|
|
4524
4578
|
async function listFeedback(client, args, strategy) {
|
|
4525
4579
|
const parsed = _mastra_core_storage.listFeedbackArgsSchema.parse(args);
|
|
4526
4580
|
const deltaCursorEnabled = deltaPollingSupported(strategy);
|
|
@@ -4552,8 +4606,8 @@ async function listFeedback(client, args, strategy) {
|
|
|
4552
4606
|
};
|
|
4553
4607
|
}
|
|
4554
4608
|
const currentDeltaCursor = deltaCursorEnabled ? await getDeltaCursor$5(client, whereClause, filter.params) : void 0;
|
|
4555
|
-
const countResult = await queryJson$2(client, `SELECT count() AS total FROM ${TABLE_FEEDBACK_EVENTS} AS f ${whereClause}`, filter.params);
|
|
4556
|
-
const rows = await queryJson$2(client, `SELECT * FROM ${TABLE_FEEDBACK_EVENTS} AS f ${whereClause} ORDER BY ${orderBy} LIMIT {limit:UInt32} OFFSET {offset:UInt32}`, {
|
|
4609
|
+
const countResult = await queryJson$2(client, `SELECT count() AS total FROM ${TABLE_FEEDBACK_EVENTS} AS f FINAL ${whereClause}`, filter.params);
|
|
4610
|
+
const rows = await queryJson$2(client, `SELECT * FROM ${TABLE_FEEDBACK_EVENTS} AS f FINAL ${whereClause} ORDER BY ${orderBy} LIMIT {limit:UInt32} OFFSET {offset:UInt32}`, {
|
|
4557
4611
|
...filter.params,
|
|
4558
4612
|
limit: pagination.limit,
|
|
4559
4613
|
offset: pagination.offset
|
|
@@ -4579,7 +4633,7 @@ async function queryFeedbackAfterCursor(client, whereClause, params, limit, curs
|
|
|
4579
4633
|
f.feedbackId AS feedbackId,
|
|
4580
4634
|
toString(d.cursorId) AS cursorId
|
|
4581
4635
|
FROM ${TABLE_FEEDBACK_EVENTS_DELTA} d
|
|
4582
|
-
INNER JOIN ${TABLE_FEEDBACK_EVENTS} f
|
|
4636
|
+
INNER JOIN ${TABLE_FEEDBACK_EVENTS} f FINAL
|
|
4583
4637
|
ON ((f.traceId = d.traceId) OR (f.traceId IS NULL AND d.traceId IS NULL))
|
|
4584
4638
|
AND f.timestamp = d.timestamp
|
|
4585
4639
|
AND f.feedbackId = d.feedbackId
|
|
@@ -4596,7 +4650,7 @@ async function getDeltaCursor$5(client, whereClause, params) {
|
|
|
4596
4650
|
const cursorId = (await queryJson$2(client, `
|
|
4597
4651
|
SELECT toString(max(d.cursorId)) AS cursorId
|
|
4598
4652
|
FROM mastra_feedback_events_delta d
|
|
4599
|
-
INNER JOIN mastra_feedback_events f
|
|
4653
|
+
INNER JOIN mastra_feedback_events f FINAL
|
|
4600
4654
|
ON ((f.traceId = d.traceId) OR (f.traceId IS NULL AND d.traceId IS NULL))
|
|
4601
4655
|
AND f.timestamp = d.timestamp
|
|
4602
4656
|
AND f.feedbackId = d.feedbackId
|
|
@@ -4615,7 +4669,7 @@ async function getFeedbackAggregate(client, args) {
|
|
|
4615
4669
|
const aggSql = getAggregationSql$2(args.aggregation);
|
|
4616
4670
|
const identity = buildFeedbackIdentityFilter(args);
|
|
4617
4671
|
const combined = mergeFilters$2(identity, buildFeedbackFilterConditions(args.filters));
|
|
4618
|
-
const result = await queryJson$2(client, `SELECT ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} ${toWhereClause$2(combined)}`, combined.params);
|
|
4672
|
+
const result = await queryJson$2(client, `SELECT ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} FINAL ${toWhereClause$2(combined)}`, combined.params);
|
|
4619
4673
|
const value = result[0]?.value == null ? null : Number(result[0]?.value);
|
|
4620
4674
|
if (args.comparePeriod && args.filters?.timestamp) {
|
|
4621
4675
|
const ts = args.filters.timestamp;
|
|
@@ -4649,7 +4703,7 @@ async function getFeedbackAggregate(client, args) {
|
|
|
4649
4703
|
endExclusive: ts.endExclusive
|
|
4650
4704
|
}
|
|
4651
4705
|
}));
|
|
4652
|
-
const prevResult = await queryJson$2(client, `SELECT ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} ${toWhereClause$2(prevCombined)}`, prevCombined.params);
|
|
4706
|
+
const prevResult = await queryJson$2(client, `SELECT ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} FINAL ${toWhereClause$2(prevCombined)}`, prevCombined.params);
|
|
4653
4707
|
const previousValue = prevResult[0]?.value == null ? null : Number(prevResult[0]?.value);
|
|
4654
4708
|
let changePercent = null;
|
|
4655
4709
|
if (previousValue !== null && previousValue !== 0 && value !== null) changePercent = (value - previousValue) / Math.abs(previousValue) * 100;
|
|
@@ -4667,7 +4721,7 @@ async function getFeedbackBreakdown(client, args) {
|
|
|
4667
4721
|
const combined = mergeFilters$2(buildFeedbackIdentityFilter(args), buildFeedbackFilterConditions(args.filters));
|
|
4668
4722
|
const whereClause = toWhereClause$2(combined);
|
|
4669
4723
|
const resolved = resolveFeedbackGroupBy(args.groupBy);
|
|
4670
|
-
return { groups: (await queryJson$2(client, `SELECT ${resolved.map((e) => e.selectSql).join(", ")}, ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} ${whereClause} GROUP BY ${resolved.map((e) => e.groupSql).join(", ")} ORDER BY value DESC`, combined.params)).map((row) => ({
|
|
4724
|
+
return { groups: (await queryJson$2(client, `SELECT ${resolved.map((e) => e.selectSql).join(", ")}, ${aggSql} AS value FROM ${TABLE_FEEDBACK_EVENTS} FINAL ${whereClause} GROUP BY ${resolved.map((e) => e.groupSql).join(", ")} ORDER BY value DESC`, combined.params)).map((row) => ({
|
|
4671
4725
|
dimensions: Object.fromEntries(resolved.map((entry, index) => {
|
|
4672
4726
|
const v = row[`group_by_${index}`];
|
|
4673
4727
|
return [entry.key, v == null ? null : String(v)];
|
|
@@ -4686,7 +4740,7 @@ async function getFeedbackTimeSeries(client, args) {
|
|
|
4686
4740
|
SELECT toStartOfInterval(timestamp, ${intervalSql}) AS bucket,
|
|
4687
4741
|
${resolved.map((e) => e.selectSql).join(", ")},
|
|
4688
4742
|
${aggSql} AS value
|
|
4689
|
-
FROM ${TABLE_FEEDBACK_EVENTS} ${whereClause}
|
|
4743
|
+
FROM ${TABLE_FEEDBACK_EVENTS} FINAL ${whereClause}
|
|
4690
4744
|
GROUP BY bucket, ${resolved.map((e) => e.groupSql).join(", ")}
|
|
4691
4745
|
ORDER BY bucket
|
|
4692
4746
|
`, combined.params);
|
|
@@ -4708,7 +4762,7 @@ async function getFeedbackTimeSeries(client, args) {
|
|
|
4708
4762
|
const rows = await queryJson$2(client, `
|
|
4709
4763
|
SELECT toStartOfInterval(timestamp, ${intervalSql}) AS bucket,
|
|
4710
4764
|
${aggSql} AS value
|
|
4711
|
-
FROM ${TABLE_FEEDBACK_EVENTS} ${whereClause}
|
|
4765
|
+
FROM ${TABLE_FEEDBACK_EVENTS} FINAL ${whereClause}
|
|
4712
4766
|
GROUP BY bucket
|
|
4713
4767
|
ORDER BY bucket
|
|
4714
4768
|
`, combined.params);
|
|
@@ -4731,7 +4785,7 @@ async function getFeedbackPercentiles(client, args) {
|
|
|
4731
4785
|
const rows = await queryJson$2(client, `
|
|
4732
4786
|
SELECT toStartOfInterval(timestamp, ${intervalSql}) AS bucket,
|
|
4733
4787
|
quantile(${p})(valueNumber) AS pvalue
|
|
4734
|
-
FROM ${TABLE_FEEDBACK_EVENTS}
|
|
4788
|
+
FROM ${TABLE_FEEDBACK_EVENTS} FINAL
|
|
4735
4789
|
${whereClause}
|
|
4736
4790
|
GROUP BY bucket
|
|
4737
4791
|
ORDER BY bucket
|
|
@@ -7359,6 +7413,19 @@ var ObservabilityStorageClickhouseVNext = class extends _mastra_core_storage.Obs
|
|
|
7359
7413
|
}, error);
|
|
7360
7414
|
}
|
|
7361
7415
|
}
|
|
7416
|
+
async updateFeedbackReviewStatus(args) {
|
|
7417
|
+
try {
|
|
7418
|
+
return await updateFeedbackReviewStatus(this.#client, args);
|
|
7419
|
+
} catch (error) {
|
|
7420
|
+
if (error instanceof _mastra_core_error.MastraError) throw error;
|
|
7421
|
+
throw new _mastra_core_error.MastraError({
|
|
7422
|
+
id: (0, _mastra_core_storage.createStorageErrorId)("CLICKHOUSE", "UPDATE_FEEDBACK_REVIEW_STATUS", "FAILED"),
|
|
7423
|
+
domain: _mastra_core_error.ErrorDomain.STORAGE,
|
|
7424
|
+
category: _mastra_core_error.ErrorCategory.THIRD_PARTY,
|
|
7425
|
+
details: { feedbackId: args.feedbackId }
|
|
7426
|
+
}, error);
|
|
7427
|
+
}
|
|
7428
|
+
}
|
|
7362
7429
|
async listFeedback(args) {
|
|
7363
7430
|
try {
|
|
7364
7431
|
return await listFeedback(this.#client, args, this.#deltaCursorStrategy);
|