@mastra/clickhouse 1.16.1-alpha.0 → 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/README.md +7 -119
- 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/README.md
CHANGED
|
@@ -8,13 +8,6 @@ Clickhouse implementation for Mastra, providing efficient storage capabilities w
|
|
|
8
8
|
npm install @mastra/clickhouse
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
## Prerequisites
|
|
12
|
-
|
|
13
|
-
- Clickhouse server (version 23.3 or higher required for delete operations; earlier versions may work for read/write operations)
|
|
14
|
-
- Lightweight `DELETE FROM` requires ClickHouse 22.8+ with `allow_experimental_lightweight_delete = 1` (for 22.8–23.2), or 23.3+ where it is generally available.
|
|
15
|
-
- The `deleteTask`, `deleteTasks`, and `deleteMessages` methods use `DELETE FROM` — ensure your server supports lightweight delete before using those operations.
|
|
16
|
-
- Node.js 22.13.0 or later
|
|
17
|
-
|
|
18
11
|
## Usage
|
|
19
12
|
|
|
20
13
|
```typescript
|
|
@@ -59,120 +52,15 @@ const { messages } = await store.listMessages({ threadId: 'thread-123' });
|
|
|
59
52
|
await store.close();
|
|
60
53
|
```
|
|
61
54
|
|
|
62
|
-
##
|
|
63
|
-
|
|
64
|
-
The Clickhouse store can be initialized with the following configuration:
|
|
65
|
-
|
|
66
|
-
```typescript
|
|
67
|
-
type ClickhouseConfig = {
|
|
68
|
-
url: string; // Clickhouse HTTP interface URL
|
|
69
|
-
username: string; // Database username
|
|
70
|
-
password: string; // Database password
|
|
71
|
-
replication?: {
|
|
72
|
-
cluster?: string; // Adds ON CLUSTER to Mastra-owned DDL when set
|
|
73
|
-
zookeeperPath?: string; // Defaults to '/clickhouse/tables/{shard}/{database}/{table}'
|
|
74
|
-
replicaName?: string; // Defaults to '{replica}'
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### Replicated ClickHouse clusters
|
|
80
|
-
|
|
81
|
-
Set `replication` when Mastra writes to a multi-replica ClickHouse cluster through a load balancer. Mastra will create its tables with replicated MergeTree engines and add `ON CLUSTER` to Mastra-owned DDL when `cluster` is provided.
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
const store = new ClickhouseStore({
|
|
85
|
-
url: 'http://clickhouse-lb:8123',
|
|
86
|
-
username: 'default',
|
|
87
|
-
password: 'password',
|
|
88
|
-
replication: {
|
|
89
|
-
cluster: 'company_cluster',
|
|
90
|
-
},
|
|
91
|
-
});
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
The default `zookeeperPath` is `/clickhouse/tables/{shard}/{database}/{table}`. If your cluster's existing tables use a different layout (for example `/clickhouse/tables/{shard}/{table}` without the `{database}` segment), set `zookeeperPath` explicitly to match. Mastra does not infer your cluster's convention from Keeper.
|
|
95
|
-
|
|
96
|
-
Manual maintenance such as `optimizeTable()` and `materializeTtl()` runs on every replica when `cluster` is set. These operations can be expensive on a large cluster. Prefer running them outside peak hours.
|
|
97
|
-
|
|
98
|
-
If Mastra finds an existing local `MergeTree` or `ReplacingMergeTree` table while replication is enabled, initialization fails instead of silently mixing local and replicated tables. Migrate existing local tables manually before enabling this option.
|
|
99
|
-
|
|
100
|
-
## Features
|
|
101
|
-
|
|
102
|
-
### Storage Features
|
|
103
|
-
|
|
104
|
-
- Thread and message storage with JSON support
|
|
105
|
-
- Efficient batch operations
|
|
106
|
-
- Rich metadata support
|
|
107
|
-
- Timestamp tracking
|
|
108
|
-
- Workflow snapshot persistence
|
|
109
|
-
- Optimized for high-volume data ingestion
|
|
110
|
-
- Uses Clickhouse's MergeTree and ReplacingMergeTree engines for optimal performance
|
|
111
|
-
|
|
112
|
-
### Table Engines
|
|
113
|
-
|
|
114
|
-
The store uses different table engines for different types of data:
|
|
115
|
-
|
|
116
|
-
- `MergeTree()`: Used for messages, traces, and evals
|
|
117
|
-
- `ReplacingMergeTree()`: Used for threads and workflow snapshots
|
|
118
|
-
- `ReplicatedMergeTree(...)` / `ReplicatedReplacingMergeTree(...)`: Used instead when `replication` is enabled
|
|
119
|
-
|
|
120
|
-
## Storage Methods
|
|
121
|
-
|
|
122
|
-
### Thread Operations
|
|
123
|
-
|
|
124
|
-
- `saveThread({ thread })`: Create or update a thread
|
|
125
|
-
- `getThreadById({ threadId })`: Get a thread by ID
|
|
126
|
-
- `listThreadsByResourceId({ resourceId, offset, limit, orderBy? })`: List paginated threads for a resource
|
|
127
|
-
- `updateThread({ id, title, metadata })`: Update thread title and metadata
|
|
128
|
-
- `deleteThread({ threadId })`: Delete a thread and its messages
|
|
129
|
-
|
|
130
|
-
### Message Operations
|
|
131
|
-
|
|
132
|
-
- `saveMessages({ messages })`: Save multiple messages
|
|
133
|
-
- `listMessages({ threadId, perPage?, page? })`: Get messages for a thread with pagination
|
|
134
|
-
- `updateMessages({ messages })`: Update existing messages
|
|
135
|
-
|
|
136
|
-
### Resource Operations
|
|
137
|
-
|
|
138
|
-
- `getResourceById({ resourceId })`: Get a resource by ID
|
|
139
|
-
- `saveResource({ resource })`: Create or save a resource
|
|
140
|
-
- `updateResource({ resourceId, workingMemory })`: Update resource working memory
|
|
141
|
-
|
|
142
|
-
### Workflow Operations
|
|
143
|
-
|
|
144
|
-
- `persistWorkflowSnapshot({ workflowName, runId, snapshot })`: Save workflow state
|
|
145
|
-
- `loadWorkflowSnapshot({ workflowName, runId })`: Load workflow state
|
|
146
|
-
- `listWorkflowRuns({ workflowName, pagination })`: List workflow runs with pagination
|
|
147
|
-
- `getWorkflowRunById({ workflowName, runId })`: Get a specific workflow run
|
|
148
|
-
|
|
149
|
-
### Evaluation/Scoring Operations
|
|
150
|
-
|
|
151
|
-
- `getScoreById({ id })`: Get a score by ID
|
|
152
|
-
- `saveScore(score)`: Save an evaluation score
|
|
153
|
-
- `listScoresByScorerId({ scorerId, pagination })`: List scores by scorer with pagination
|
|
154
|
-
- `listScoresByRunId({ runId, pagination })`: List scores by run with pagination
|
|
155
|
-
- `listScoresByEntityId({ entityId, entityType, pagination })`: List scores by entity with pagination
|
|
156
|
-
- `listScoresBySpan({ traceId, spanId, pagination })`: List scores by span with pagination
|
|
157
|
-
|
|
158
|
-
### Operations Not Currently Supported
|
|
159
|
-
|
|
160
|
-
- AI Observability (traces/spans): Not currently supported
|
|
55
|
+
## Documentation
|
|
161
56
|
|
|
162
|
-
|
|
57
|
+
- [ClickHouse integration guide](https://mastra.ai/integrations/databases/clickhouse)
|
|
58
|
+
- [Storage reference](https://mastra.ai/reference/storage/overview)
|
|
163
59
|
|
|
164
|
-
|
|
60
|
+
## Changelog
|
|
165
61
|
|
|
166
|
-
-
|
|
167
|
-
- `timestamp`: DateTime64(3)
|
|
168
|
-
- `uuid`: String
|
|
169
|
-
- `jsonb`: String (JSON serialized)
|
|
170
|
-
- `integer`: Int64
|
|
171
|
-
- `bigint`: Int64
|
|
172
|
-
- `float`: Float64
|
|
173
|
-
- `boolean`: Bool
|
|
62
|
+
See the [package changelog](https://github.com/mastra-ai/mastra/blob/main/stores/clickhouse/CHANGELOG.md) for version history and release notes.
|
|
174
63
|
|
|
175
|
-
##
|
|
64
|
+
## Support
|
|
176
65
|
|
|
177
|
-
|
|
178
|
-
- [Clickhouse Node.js Client](https://github.com/clickhouse/clickhouse-js)
|
|
66
|
+
We have an [open community Discord](https://discord.gg/mastra-ai). Come and say hello and let us know if you have any questions or need any help getting things running.
|
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);
|