@mastra/clickhouse 0.0.0-trigger-playground-ui-package-20250506151043 → 0.0.0-unified-sidebar-20251010130811
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 +946 -2
- package/LICENSE.md +12 -4
- package/dist/index.cjs +2471 -439
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2455 -423
- package/dist/index.js.map +1 -0
- package/dist/storage/domains/legacy-evals/index.d.ts +21 -0
- package/dist/storage/domains/legacy-evals/index.d.ts.map +1 -0
- package/dist/storage/domains/memory/index.d.ts +87 -0
- package/dist/storage/domains/memory/index.d.ts.map +1 -0
- package/dist/storage/domains/operations/index.d.ts +42 -0
- package/dist/storage/domains/operations/index.d.ts.map +1 -0
- package/dist/storage/domains/scores/index.d.ts +54 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -0
- package/dist/storage/domains/traces/index.d.ts +21 -0
- package/dist/storage/domains/traces/index.d.ts.map +1 -0
- package/dist/storage/domains/utils.d.ts +28 -0
- package/dist/storage/domains/utils.d.ts.map +1 -0
- package/dist/storage/domains/workflows/index.d.ts +55 -0
- package/dist/storage/domains/workflows/index.d.ts.map +1 -0
- package/dist/storage/index.d.ts +245 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/package.json +32 -14
- package/dist/_tsup-dts-rollup.d.cts +0 -138
- package/dist/_tsup-dts-rollup.d.ts +0 -138
- package/dist/index.d.cts +0 -4
- package/docker-compose.yaml +0 -15
- package/eslint.config.js +0 -6
- package/src/index.ts +0 -1
- package/src/storage/index.test.ts +0 -856
- package/src/storage/index.ts +0 -1058
- package/tsconfig.json +0 -5
- package/vitest.config.ts +0 -12
package/dist/index.cjs
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var client = require('@clickhouse/client');
|
|
4
|
+
var error = require('@mastra/core/error');
|
|
4
5
|
var storage = require('@mastra/core/storage');
|
|
6
|
+
var agent = require('@mastra/core/agent');
|
|
7
|
+
var scores = require('@mastra/core/scores');
|
|
5
8
|
|
|
6
9
|
// src/storage/index.ts
|
|
7
|
-
function safelyParseJSON(jsonString) {
|
|
8
|
-
try {
|
|
9
|
-
return JSON.parse(jsonString);
|
|
10
|
-
} catch {
|
|
11
|
-
return {};
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
10
|
var TABLE_ENGINES = {
|
|
15
11
|
[storage.TABLE_MESSAGES]: `MergeTree()`,
|
|
16
12
|
[storage.TABLE_WORKFLOW_SNAPSHOT]: `ReplacingMergeTree()`,
|
|
17
13
|
[storage.TABLE_TRACES]: `MergeTree()`,
|
|
18
14
|
[storage.TABLE_THREADS]: `ReplacingMergeTree()`,
|
|
19
|
-
[storage.TABLE_EVALS]: `MergeTree()
|
|
15
|
+
[storage.TABLE_EVALS]: `MergeTree()`,
|
|
16
|
+
[storage.TABLE_SCORERS]: `MergeTree()`,
|
|
17
|
+
[storage.TABLE_RESOURCES]: `ReplacingMergeTree()`,
|
|
18
|
+
// TODO: verify this is the correct engine for ai spans when implementing clickhouse storage
|
|
19
|
+
[storage.TABLE_AI_SPANS]: `ReplacingMergeTree()`
|
|
20
20
|
};
|
|
21
21
|
var COLUMN_TYPES = {
|
|
22
22
|
text: "String",
|
|
@@ -24,11 +24,10 @@ var COLUMN_TYPES = {
|
|
|
24
24
|
uuid: "String",
|
|
25
25
|
jsonb: "String",
|
|
26
26
|
integer: "Int64",
|
|
27
|
-
|
|
27
|
+
float: "Float64",
|
|
28
|
+
bigint: "Int64",
|
|
29
|
+
boolean: "Bool"
|
|
28
30
|
};
|
|
29
|
-
function transformRows(rows) {
|
|
30
|
-
return rows.map((row) => transformRow(row));
|
|
31
|
-
}
|
|
32
31
|
function transformRow(row) {
|
|
33
32
|
if (!row) {
|
|
34
33
|
return row;
|
|
@@ -39,33 +38,63 @@ function transformRow(row) {
|
|
|
39
38
|
if (row.updatedAt) {
|
|
40
39
|
row.updatedAt = new Date(row.updatedAt);
|
|
41
40
|
}
|
|
41
|
+
if (row.content && typeof row.content === "string") {
|
|
42
|
+
row.content = storage.safelyParseJSON(row.content);
|
|
43
|
+
}
|
|
42
44
|
return row;
|
|
43
45
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
// This is crucial
|
|
57
|
-
use_client_time_zone: 1,
|
|
58
|
-
output_format_json_quote_64bit_integers: 0
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
this.ttl = config.ttl;
|
|
46
|
+
function transformRows(rows) {
|
|
47
|
+
return rows.map((row) => transformRow(row));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/storage/domains/legacy-evals/index.ts
|
|
51
|
+
var LegacyEvalsStorageClickhouse = class extends storage.LegacyEvalsStorage {
|
|
52
|
+
client;
|
|
53
|
+
operations;
|
|
54
|
+
constructor({ client, operations }) {
|
|
55
|
+
super();
|
|
56
|
+
this.client = client;
|
|
57
|
+
this.operations = operations;
|
|
62
58
|
}
|
|
63
59
|
transformEvalRow(row) {
|
|
64
60
|
row = transformRow(row);
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
let resultValue;
|
|
62
|
+
try {
|
|
63
|
+
if (row.result && typeof row.result === "string" && row.result.trim() !== "") {
|
|
64
|
+
resultValue = JSON.parse(row.result);
|
|
65
|
+
} else if (typeof row.result === "object" && row.result !== null) {
|
|
66
|
+
resultValue = row.result;
|
|
67
|
+
} else if (row.result === null || row.result === void 0 || row.result === "") {
|
|
68
|
+
resultValue = { score: 0 };
|
|
69
|
+
} else {
|
|
70
|
+
throw new Error(`Invalid or empty result field: ${JSON.stringify(row.result)}`);
|
|
71
|
+
}
|
|
72
|
+
} catch (error$1) {
|
|
73
|
+
console.error("Error parsing result field:", row.result, error$1);
|
|
74
|
+
throw new error.MastraError({
|
|
75
|
+
id: "CLICKHOUSE_STORAGE_INVALID_RESULT_FORMAT",
|
|
76
|
+
text: `Invalid result format: ${JSON.stringify(row.result)}`,
|
|
77
|
+
domain: error.ErrorDomain.STORAGE,
|
|
78
|
+
category: error.ErrorCategory.USER
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
let testInfoValue;
|
|
82
|
+
try {
|
|
83
|
+
if (row.test_info && typeof row.test_info === "string" && row.test_info.trim() !== "" && row.test_info !== "null") {
|
|
84
|
+
testInfoValue = JSON.parse(row.test_info);
|
|
85
|
+
} else if (typeof row.test_info === "object" && row.test_info !== null) {
|
|
86
|
+
testInfoValue = row.test_info;
|
|
87
|
+
}
|
|
88
|
+
} catch {
|
|
89
|
+
testInfoValue = void 0;
|
|
90
|
+
}
|
|
67
91
|
if (!resultValue || typeof resultValue !== "object" || !("score" in resultValue)) {
|
|
68
|
-
throw new
|
|
92
|
+
throw new error.MastraError({
|
|
93
|
+
id: "CLICKHOUSE_STORAGE_INVALID_METRIC_FORMAT",
|
|
94
|
+
text: `Invalid MetricResult format: ${JSON.stringify(resultValue)}`,
|
|
95
|
+
domain: error.ErrorDomain.STORAGE,
|
|
96
|
+
category: error.ErrorCategory.USER
|
|
97
|
+
});
|
|
69
98
|
}
|
|
70
99
|
return {
|
|
71
100
|
input: row.input,
|
|
@@ -82,9 +111,9 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
82
111
|
}
|
|
83
112
|
async getEvalsByAgentName(agentName, type) {
|
|
84
113
|
try {
|
|
85
|
-
const baseQuery = `SELECT *, toDateTime64(
|
|
86
|
-
const typeCondition = type === "test" ? " AND test_info IS NOT NULL AND JSONExtractString(test_info, 'testPath') IS NOT NULL" : type === "live" ? " AND (test_info IS NULL OR JSONExtractString(test_info, 'testPath') IS NULL)" : "";
|
|
87
|
-
const result = await this.
|
|
114
|
+
const baseQuery = `SELECT *, toDateTime64(created_at, 3) as createdAt FROM ${storage.TABLE_EVALS} WHERE agent_name = {var_agent_name:String}`;
|
|
115
|
+
const typeCondition = type === "test" ? " AND test_info IS NOT NULL AND test_info != 'null' AND JSONExtractString(test_info, 'testPath') IS NOT NULL AND JSONExtractString(test_info, 'testPath') != ''" : type === "live" ? " AND (test_info IS NULL OR test_info = 'null' OR JSONExtractString(test_info, 'testPath') IS NULL OR JSONExtractString(test_info, 'testPath') = '')" : "";
|
|
116
|
+
const result = await this.client.query({
|
|
88
117
|
query: `${baseQuery}${typeCondition} ORDER BY createdAt DESC`,
|
|
89
118
|
query_params: { var_agent_name: agentName },
|
|
90
119
|
clickhouse_settings: {
|
|
@@ -99,126 +128,1358 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
99
128
|
}
|
|
100
129
|
const rows = await result.json();
|
|
101
130
|
return rows.data.map((row) => this.transformEvalRow(row));
|
|
102
|
-
} catch (error) {
|
|
103
|
-
if (error
|
|
131
|
+
} catch (error$1) {
|
|
132
|
+
if (error$1?.message?.includes("no such table") || error$1?.message?.includes("does not exist")) {
|
|
104
133
|
return [];
|
|
105
134
|
}
|
|
106
|
-
|
|
107
|
-
|
|
135
|
+
throw new error.MastraError(
|
|
136
|
+
{
|
|
137
|
+
id: "CLICKHOUSE_STORAGE_GET_EVALS_BY_AGENT_FAILED",
|
|
138
|
+
domain: error.ErrorDomain.STORAGE,
|
|
139
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
140
|
+
details: { agentName, type: type ?? null }
|
|
141
|
+
},
|
|
142
|
+
error$1
|
|
143
|
+
);
|
|
108
144
|
}
|
|
109
145
|
}
|
|
110
|
-
async
|
|
146
|
+
async getEvals(options = {}) {
|
|
147
|
+
const { agentName, type, page = 0, perPage = 100, dateRange } = options;
|
|
148
|
+
const fromDate = dateRange?.start;
|
|
149
|
+
const toDate = dateRange?.end;
|
|
150
|
+
const conditions = [];
|
|
151
|
+
if (agentName) {
|
|
152
|
+
conditions.push(`agent_name = {var_agent_name:String}`);
|
|
153
|
+
}
|
|
154
|
+
if (type === "test") {
|
|
155
|
+
conditions.push(
|
|
156
|
+
`(test_info IS NOT NULL AND test_info != 'null' AND JSONExtractString(test_info, 'testPath') IS NOT NULL AND JSONExtractString(test_info, 'testPath') != '')`
|
|
157
|
+
);
|
|
158
|
+
} else if (type === "live") {
|
|
159
|
+
conditions.push(
|
|
160
|
+
`(test_info IS NULL OR test_info = 'null' OR JSONExtractString(test_info, 'testPath') IS NULL OR JSONExtractString(test_info, 'testPath') = '')`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if (fromDate) {
|
|
164
|
+
conditions.push(`created_at >= parseDateTime64BestEffort({var_from_date:String})`);
|
|
165
|
+
fromDate.toISOString();
|
|
166
|
+
}
|
|
167
|
+
if (toDate) {
|
|
168
|
+
conditions.push(`created_at <= parseDateTime64BestEffort({var_to_date:String})`);
|
|
169
|
+
toDate.toISOString();
|
|
170
|
+
}
|
|
171
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
111
172
|
try {
|
|
112
|
-
await this.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
...
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
173
|
+
const countResult = await this.client.query({
|
|
174
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_EVALS} ${whereClause}`,
|
|
175
|
+
query_params: {
|
|
176
|
+
...agentName ? { var_agent_name: agentName } : {},
|
|
177
|
+
...fromDate ? { var_from_date: fromDate.toISOString() } : {},
|
|
178
|
+
...toDate ? { var_to_date: toDate.toISOString() } : {}
|
|
179
|
+
},
|
|
180
|
+
clickhouse_settings: {
|
|
181
|
+
date_time_input_format: "best_effort",
|
|
182
|
+
date_time_output_format: "iso",
|
|
183
|
+
use_client_time_zone: 1,
|
|
184
|
+
output_format_json_quote_64bit_integers: 0
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
const countData = await countResult.json();
|
|
188
|
+
const total = Number(countData.data?.[0]?.count ?? 0);
|
|
189
|
+
const currentOffset = page * perPage;
|
|
190
|
+
const hasMore = currentOffset + perPage < total;
|
|
191
|
+
if (total === 0) {
|
|
192
|
+
return {
|
|
193
|
+
evals: [],
|
|
194
|
+
total: 0,
|
|
195
|
+
page,
|
|
196
|
+
perPage,
|
|
197
|
+
hasMore: false
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const dataResult = await this.client.query({
|
|
201
|
+
query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${storage.TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT {var_limit:UInt32} OFFSET {var_offset:UInt32}`,
|
|
202
|
+
query_params: {
|
|
203
|
+
...agentName ? { var_agent_name: agentName } : {},
|
|
204
|
+
...fromDate ? { var_from_date: fromDate.toISOString() } : {},
|
|
205
|
+
...toDate ? { var_to_date: toDate.toISOString() } : {},
|
|
206
|
+
var_limit: perPage || 100,
|
|
207
|
+
var_offset: currentOffset || 0
|
|
208
|
+
},
|
|
123
209
|
clickhouse_settings: {
|
|
124
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
125
210
|
date_time_input_format: "best_effort",
|
|
211
|
+
date_time_output_format: "iso",
|
|
126
212
|
use_client_time_zone: 1,
|
|
127
213
|
output_format_json_quote_64bit_integers: 0
|
|
128
214
|
}
|
|
129
215
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
216
|
+
const rows = await dataResult.json();
|
|
217
|
+
return {
|
|
218
|
+
evals: rows.data.map((row) => this.transformEvalRow(row)),
|
|
219
|
+
total,
|
|
220
|
+
page,
|
|
221
|
+
perPage,
|
|
222
|
+
hasMore
|
|
223
|
+
};
|
|
224
|
+
} catch (error$1) {
|
|
225
|
+
if (error$1?.message?.includes("no such table") || error$1?.message?.includes("does not exist")) {
|
|
226
|
+
return {
|
|
227
|
+
evals: [],
|
|
228
|
+
total: 0,
|
|
229
|
+
page,
|
|
230
|
+
perPage,
|
|
231
|
+
hasMore: false
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
throw new error.MastraError(
|
|
235
|
+
{
|
|
236
|
+
id: "CLICKHOUSE_STORAGE_GET_EVALS_FAILED",
|
|
237
|
+
domain: error.ErrorDomain.STORAGE,
|
|
238
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
239
|
+
details: { agentName: agentName ?? "all", type: type ?? "all" }
|
|
240
|
+
},
|
|
241
|
+
error$1
|
|
242
|
+
);
|
|
133
243
|
}
|
|
134
244
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
245
|
+
};
|
|
246
|
+
var MemoryStorageClickhouse = class extends storage.MemoryStorage {
|
|
247
|
+
client;
|
|
248
|
+
operations;
|
|
249
|
+
constructor({ client, operations }) {
|
|
250
|
+
super();
|
|
251
|
+
this.client = client;
|
|
252
|
+
this.operations = operations;
|
|
253
|
+
}
|
|
254
|
+
async getMessages({
|
|
255
|
+
threadId,
|
|
256
|
+
resourceId,
|
|
257
|
+
selectBy,
|
|
258
|
+
format
|
|
144
259
|
}) {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
260
|
+
try {
|
|
261
|
+
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
262
|
+
const messages = [];
|
|
263
|
+
const limit = storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
|
|
264
|
+
const include = selectBy?.include || [];
|
|
265
|
+
if (include.length) {
|
|
266
|
+
const unionQueries = [];
|
|
267
|
+
const params = [];
|
|
268
|
+
let paramIdx = 1;
|
|
269
|
+
for (const inc of include) {
|
|
270
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
271
|
+
const searchId = inc.threadId || threadId;
|
|
272
|
+
unionQueries.push(`
|
|
273
|
+
SELECT * FROM (
|
|
274
|
+
WITH numbered_messages AS (
|
|
275
|
+
SELECT
|
|
276
|
+
id, content, role, type, "createdAt", thread_id, "resourceId",
|
|
277
|
+
ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
|
|
278
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
279
|
+
WHERE thread_id = {var_thread_id_${paramIdx}:String}
|
|
280
|
+
),
|
|
281
|
+
target_positions AS (
|
|
282
|
+
SELECT row_num as target_pos
|
|
283
|
+
FROM numbered_messages
|
|
284
|
+
WHERE id = {var_include_id_${paramIdx}:String}
|
|
285
|
+
)
|
|
286
|
+
SELECT DISTINCT m.id, m.content, m.role, m.type, m."createdAt", m.thread_id AS "threadId"
|
|
287
|
+
FROM numbered_messages m
|
|
288
|
+
CROSS JOIN target_positions t
|
|
289
|
+
WHERE m.row_num BETWEEN (t.target_pos - {var_withPreviousMessages_${paramIdx}:Int64}) AND (t.target_pos + {var_withNextMessages_${paramIdx}:Int64})
|
|
290
|
+
) AS query_${paramIdx}
|
|
291
|
+
`);
|
|
292
|
+
params.push(
|
|
293
|
+
{ [`var_thread_id_${paramIdx}`]: searchId },
|
|
294
|
+
{ [`var_include_id_${paramIdx}`]: id },
|
|
295
|
+
{ [`var_withPreviousMessages_${paramIdx}`]: withPreviousMessages },
|
|
296
|
+
{ [`var_withNextMessages_${paramIdx}`]: withNextMessages }
|
|
297
|
+
);
|
|
298
|
+
paramIdx++;
|
|
299
|
+
}
|
|
300
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" DESC';
|
|
301
|
+
const mergedParams = params.reduce((acc, paramObj) => ({ ...acc, ...paramObj }), {});
|
|
302
|
+
const includeResult = await this.client.query({
|
|
303
|
+
query: finalQuery,
|
|
304
|
+
query_params: mergedParams,
|
|
305
|
+
clickhouse_settings: {
|
|
306
|
+
date_time_input_format: "best_effort",
|
|
307
|
+
date_time_output_format: "iso",
|
|
308
|
+
use_client_time_zone: 1,
|
|
309
|
+
output_format_json_quote_64bit_integers: 0
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
const rows2 = await includeResult.json();
|
|
313
|
+
const includedMessages = transformRows(rows2.data);
|
|
314
|
+
const seen = /* @__PURE__ */ new Set();
|
|
315
|
+
const dedupedMessages = includedMessages.filter((message) => {
|
|
316
|
+
if (seen.has(message.id)) return false;
|
|
317
|
+
seen.add(message.id);
|
|
318
|
+
return true;
|
|
319
|
+
});
|
|
320
|
+
messages.push(...dedupedMessages);
|
|
321
|
+
}
|
|
322
|
+
const result = await this.client.query({
|
|
323
|
+
query: `
|
|
324
|
+
SELECT
|
|
325
|
+
id,
|
|
326
|
+
content,
|
|
327
|
+
role,
|
|
328
|
+
type,
|
|
329
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
330
|
+
thread_id AS "threadId"
|
|
331
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
332
|
+
WHERE thread_id = {threadId:String}
|
|
333
|
+
AND id NOT IN ({exclude:Array(String)})
|
|
334
|
+
ORDER BY "createdAt" DESC
|
|
335
|
+
LIMIT {limit:Int64}
|
|
336
|
+
`,
|
|
337
|
+
query_params: {
|
|
338
|
+
threadId,
|
|
339
|
+
exclude: messages.map((m) => m.id),
|
|
340
|
+
limit
|
|
341
|
+
},
|
|
342
|
+
clickhouse_settings: {
|
|
343
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
344
|
+
date_time_input_format: "best_effort",
|
|
345
|
+
date_time_output_format: "iso",
|
|
346
|
+
use_client_time_zone: 1,
|
|
347
|
+
output_format_json_quote_64bit_integers: 0
|
|
348
|
+
}
|
|
161
349
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
350
|
+
const rows = await result.json();
|
|
351
|
+
messages.push(...transformRows(rows.data));
|
|
352
|
+
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
353
|
+
messages.forEach((message) => {
|
|
354
|
+
if (typeof message.content === "string") {
|
|
355
|
+
try {
|
|
356
|
+
message.content = JSON.parse(message.content);
|
|
357
|
+
} catch {
|
|
358
|
+
}
|
|
359
|
+
}
|
|
169
360
|
});
|
|
361
|
+
const list = new agent.MessageList({ threadId, resourceId }).add(messages, "memory");
|
|
362
|
+
if (format === `v2`) return list.get.all.v2();
|
|
363
|
+
return list.get.all.v1();
|
|
364
|
+
} catch (error$1) {
|
|
365
|
+
throw new error.MastraError(
|
|
366
|
+
{
|
|
367
|
+
id: "CLICKHOUSE_STORAGE_GET_MESSAGES_FAILED",
|
|
368
|
+
domain: error.ErrorDomain.STORAGE,
|
|
369
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
370
|
+
details: { threadId, resourceId: resourceId ?? "" }
|
|
371
|
+
},
|
|
372
|
+
error$1
|
|
373
|
+
);
|
|
170
374
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
375
|
+
}
|
|
376
|
+
async getMessagesById({
|
|
377
|
+
messageIds,
|
|
378
|
+
format
|
|
379
|
+
}) {
|
|
380
|
+
if (messageIds.length === 0) return [];
|
|
381
|
+
try {
|
|
382
|
+
const result = await this.client.query({
|
|
383
|
+
query: `
|
|
384
|
+
SELECT
|
|
385
|
+
id,
|
|
386
|
+
content,
|
|
387
|
+
role,
|
|
388
|
+
type,
|
|
389
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
390
|
+
thread_id AS "threadId",
|
|
391
|
+
"resourceId"
|
|
392
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
393
|
+
WHERE id IN {messageIds:Array(String)}
|
|
394
|
+
ORDER BY "createdAt" DESC
|
|
395
|
+
`,
|
|
396
|
+
query_params: {
|
|
397
|
+
messageIds
|
|
398
|
+
},
|
|
399
|
+
clickhouse_settings: {
|
|
400
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
401
|
+
date_time_input_format: "best_effort",
|
|
402
|
+
date_time_output_format: "iso",
|
|
403
|
+
use_client_time_zone: 1,
|
|
404
|
+
output_format_json_quote_64bit_integers: 0
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
const rows = await result.json();
|
|
408
|
+
const messages = transformRows(rows.data);
|
|
409
|
+
messages.forEach((message) => {
|
|
410
|
+
if (typeof message.content === "string") {
|
|
411
|
+
try {
|
|
412
|
+
message.content = JSON.parse(message.content);
|
|
413
|
+
} catch {
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
const list = new agent.MessageList().add(messages, "memory");
|
|
418
|
+
if (format === `v1`) return list.get.all.v1();
|
|
419
|
+
return list.get.all.v2();
|
|
420
|
+
} catch (error$1) {
|
|
421
|
+
throw new error.MastraError(
|
|
422
|
+
{
|
|
423
|
+
id: "CLICKHOUSE_STORAGE_GET_MESSAGES_BY_ID_FAILED",
|
|
424
|
+
domain: error.ErrorDomain.STORAGE,
|
|
425
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
426
|
+
details: { messageIds: JSON.stringify(messageIds) }
|
|
427
|
+
},
|
|
428
|
+
error$1
|
|
429
|
+
);
|
|
178
430
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
431
|
+
}
|
|
432
|
+
async saveMessages(args) {
|
|
433
|
+
const { messages, format = "v1" } = args;
|
|
434
|
+
if (messages.length === 0) return messages;
|
|
435
|
+
for (const message of messages) {
|
|
436
|
+
const resourceId = message.resourceId;
|
|
437
|
+
if (!resourceId) {
|
|
438
|
+
throw new Error("Resource ID is required");
|
|
439
|
+
}
|
|
440
|
+
if (!message.threadId) {
|
|
441
|
+
throw new Error("Thread ID is required");
|
|
442
|
+
}
|
|
443
|
+
const thread = await this.getThreadById({ threadId: message.threadId });
|
|
444
|
+
if (!thread) {
|
|
445
|
+
throw new Error(`Thread ${message.threadId} not found`);
|
|
189
446
|
}
|
|
190
|
-
});
|
|
191
|
-
if (!result) {
|
|
192
|
-
return [];
|
|
193
447
|
}
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
448
|
+
const threadIdSet = /* @__PURE__ */ new Map();
|
|
449
|
+
await Promise.all(
|
|
450
|
+
messages.map(async (m) => {
|
|
451
|
+
const resourceId = m.resourceId;
|
|
452
|
+
if (!resourceId) {
|
|
453
|
+
throw new Error("Resource ID is required");
|
|
454
|
+
}
|
|
455
|
+
if (!m.threadId) {
|
|
456
|
+
throw new Error("Thread ID is required");
|
|
457
|
+
}
|
|
458
|
+
const thread = await this.getThreadById({ threadId: m.threadId });
|
|
459
|
+
if (!thread) {
|
|
460
|
+
throw new Error(`Thread ${m.threadId} not found`);
|
|
461
|
+
}
|
|
462
|
+
threadIdSet.set(m.threadId, thread);
|
|
463
|
+
})
|
|
464
|
+
);
|
|
465
|
+
try {
|
|
466
|
+
const existingResult = await this.client.query({
|
|
467
|
+
query: `SELECT id, thread_id FROM ${storage.TABLE_MESSAGES} WHERE id IN ({ids:Array(String)})`,
|
|
468
|
+
query_params: {
|
|
469
|
+
ids: messages.map((m) => m.id)
|
|
470
|
+
},
|
|
471
|
+
clickhouse_settings: {
|
|
472
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
473
|
+
date_time_input_format: "best_effort",
|
|
474
|
+
date_time_output_format: "iso",
|
|
475
|
+
use_client_time_zone: 1,
|
|
476
|
+
output_format_json_quote_64bit_integers: 0
|
|
477
|
+
},
|
|
478
|
+
format: "JSONEachRow"
|
|
479
|
+
});
|
|
480
|
+
const existingRows = await existingResult.json();
|
|
481
|
+
const existingSet = new Set(existingRows.map((row) => `${row.id}::${row.thread_id}`));
|
|
482
|
+
const toInsert = messages.filter((m) => !existingSet.has(`${m.id}::${m.threadId}`));
|
|
483
|
+
const toUpdate = messages.filter((m) => existingSet.has(`${m.id}::${m.threadId}`));
|
|
484
|
+
const toMove = messages.filter((m) => {
|
|
485
|
+
const existingRow = existingRows.find((row) => row.id === m.id);
|
|
486
|
+
return existingRow && existingRow.thread_id !== m.threadId;
|
|
487
|
+
});
|
|
488
|
+
const deletePromises = toMove.map((message) => {
|
|
489
|
+
const existingRow = existingRows.find((row) => row.id === message.id);
|
|
490
|
+
if (!existingRow) return Promise.resolve();
|
|
491
|
+
return this.client.command({
|
|
492
|
+
query: `DELETE FROM ${storage.TABLE_MESSAGES} WHERE id = {var_id:String} AND thread_id = {var_old_thread_id:String}`,
|
|
493
|
+
query_params: {
|
|
494
|
+
var_id: message.id,
|
|
495
|
+
var_old_thread_id: existingRow.thread_id
|
|
496
|
+
},
|
|
497
|
+
clickhouse_settings: {
|
|
498
|
+
date_time_input_format: "best_effort",
|
|
499
|
+
use_client_time_zone: 1,
|
|
500
|
+
output_format_json_quote_64bit_integers: 0
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
const updatePromises = toUpdate.map(
|
|
505
|
+
(message) => this.client.command({
|
|
506
|
+
query: `
|
|
507
|
+
ALTER TABLE ${storage.TABLE_MESSAGES}
|
|
508
|
+
UPDATE content = {var_content:String}, role = {var_role:String}, type = {var_type:String}, resourceId = {var_resourceId:String}
|
|
509
|
+
WHERE id = {var_id:String} AND thread_id = {var_thread_id:String}
|
|
510
|
+
`,
|
|
511
|
+
query_params: {
|
|
512
|
+
var_content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
513
|
+
var_role: message.role,
|
|
514
|
+
var_type: message.type || "v2",
|
|
515
|
+
var_resourceId: message.resourceId,
|
|
516
|
+
var_id: message.id,
|
|
517
|
+
var_thread_id: message.threadId
|
|
518
|
+
},
|
|
519
|
+
clickhouse_settings: {
|
|
520
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
521
|
+
date_time_input_format: "best_effort",
|
|
522
|
+
use_client_time_zone: 1,
|
|
523
|
+
output_format_json_quote_64bit_integers: 0
|
|
524
|
+
}
|
|
525
|
+
})
|
|
526
|
+
);
|
|
527
|
+
await Promise.all([
|
|
528
|
+
// Insert new messages (including moved messages)
|
|
529
|
+
this.client.insert({
|
|
530
|
+
table: storage.TABLE_MESSAGES,
|
|
531
|
+
format: "JSONEachRow",
|
|
532
|
+
values: toInsert.map((message) => ({
|
|
533
|
+
id: message.id,
|
|
534
|
+
thread_id: message.threadId,
|
|
535
|
+
resourceId: message.resourceId,
|
|
536
|
+
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
537
|
+
createdAt: message.createdAt.toISOString(),
|
|
538
|
+
role: message.role,
|
|
539
|
+
type: message.type || "v2"
|
|
540
|
+
})),
|
|
541
|
+
clickhouse_settings: {
|
|
542
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
543
|
+
date_time_input_format: "best_effort",
|
|
544
|
+
use_client_time_zone: 1,
|
|
545
|
+
output_format_json_quote_64bit_integers: 0
|
|
546
|
+
}
|
|
547
|
+
}),
|
|
548
|
+
...updatePromises,
|
|
549
|
+
...deletePromises,
|
|
550
|
+
// Update thread's updatedAt timestamp
|
|
551
|
+
this.client.insert({
|
|
552
|
+
table: storage.TABLE_THREADS,
|
|
553
|
+
format: "JSONEachRow",
|
|
554
|
+
values: Array.from(threadIdSet.values()).map((thread) => ({
|
|
555
|
+
id: thread.id,
|
|
556
|
+
resourceId: thread.resourceId,
|
|
557
|
+
title: thread.title,
|
|
558
|
+
metadata: thread.metadata,
|
|
559
|
+
createdAt: thread.createdAt,
|
|
560
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
561
|
+
})),
|
|
562
|
+
clickhouse_settings: {
|
|
563
|
+
date_time_input_format: "best_effort",
|
|
564
|
+
use_client_time_zone: 1,
|
|
565
|
+
output_format_json_quote_64bit_integers: 0
|
|
566
|
+
}
|
|
567
|
+
})
|
|
568
|
+
]);
|
|
569
|
+
const list = new agent.MessageList().add(messages, "memory");
|
|
570
|
+
if (format === `v2`) return list.get.all.v2();
|
|
571
|
+
return list.get.all.v1();
|
|
572
|
+
} catch (error$1) {
|
|
573
|
+
throw new error.MastraError(
|
|
574
|
+
{
|
|
575
|
+
id: "CLICKHOUSE_STORAGE_SAVE_MESSAGES_FAILED",
|
|
576
|
+
domain: error.ErrorDomain.STORAGE,
|
|
577
|
+
category: error.ErrorCategory.THIRD_PARTY
|
|
578
|
+
},
|
|
579
|
+
error$1
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
async getThreadById({ threadId }) {
|
|
584
|
+
try {
|
|
585
|
+
const result = await this.client.query({
|
|
586
|
+
query: `SELECT
|
|
587
|
+
id,
|
|
588
|
+
"resourceId",
|
|
589
|
+
title,
|
|
590
|
+
metadata,
|
|
591
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
592
|
+
toDateTime64(updatedAt, 3) as updatedAt
|
|
593
|
+
FROM "${storage.TABLE_THREADS}"
|
|
594
|
+
FINAL
|
|
595
|
+
WHERE id = {var_id:String}`,
|
|
596
|
+
query_params: { var_id: threadId },
|
|
597
|
+
clickhouse_settings: {
|
|
598
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
599
|
+
date_time_input_format: "best_effort",
|
|
600
|
+
date_time_output_format: "iso",
|
|
601
|
+
use_client_time_zone: 1,
|
|
602
|
+
output_format_json_quote_64bit_integers: 0
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
const rows = await result.json();
|
|
606
|
+
const thread = transformRow(rows.data[0]);
|
|
607
|
+
if (!thread) {
|
|
608
|
+
return null;
|
|
609
|
+
}
|
|
610
|
+
return {
|
|
611
|
+
...thread,
|
|
612
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
613
|
+
createdAt: thread.createdAt,
|
|
614
|
+
updatedAt: thread.updatedAt
|
|
615
|
+
};
|
|
616
|
+
} catch (error$1) {
|
|
617
|
+
throw new error.MastraError(
|
|
618
|
+
{
|
|
619
|
+
id: "CLICKHOUSE_STORAGE_GET_THREAD_BY_ID_FAILED",
|
|
620
|
+
domain: error.ErrorDomain.STORAGE,
|
|
621
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
622
|
+
details: { threadId }
|
|
623
|
+
},
|
|
624
|
+
error$1
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
async getThreadsByResourceId({ resourceId }) {
|
|
629
|
+
try {
|
|
630
|
+
const result = await this.client.query({
|
|
631
|
+
query: `SELECT
|
|
632
|
+
id,
|
|
633
|
+
"resourceId",
|
|
634
|
+
title,
|
|
635
|
+
metadata,
|
|
636
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
637
|
+
toDateTime64(updatedAt, 3) as updatedAt
|
|
638
|
+
FROM "${storage.TABLE_THREADS}"
|
|
639
|
+
WHERE "resourceId" = {var_resourceId:String}`,
|
|
640
|
+
query_params: { var_resourceId: resourceId },
|
|
641
|
+
clickhouse_settings: {
|
|
642
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
643
|
+
date_time_input_format: "best_effort",
|
|
644
|
+
date_time_output_format: "iso",
|
|
645
|
+
use_client_time_zone: 1,
|
|
646
|
+
output_format_json_quote_64bit_integers: 0
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
const rows = await result.json();
|
|
650
|
+
const threads = transformRows(rows.data);
|
|
651
|
+
return threads.map((thread) => ({
|
|
652
|
+
...thread,
|
|
653
|
+
metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
|
|
654
|
+
createdAt: thread.createdAt,
|
|
655
|
+
updatedAt: thread.updatedAt
|
|
656
|
+
}));
|
|
657
|
+
} catch (error$1) {
|
|
658
|
+
throw new error.MastraError(
|
|
659
|
+
{
|
|
660
|
+
id: "CLICKHOUSE_STORAGE_GET_THREADS_BY_RESOURCE_ID_FAILED",
|
|
661
|
+
domain: error.ErrorDomain.STORAGE,
|
|
662
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
663
|
+
details: { resourceId }
|
|
664
|
+
},
|
|
665
|
+
error$1
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
async saveThread({ thread }) {
|
|
670
|
+
try {
|
|
671
|
+
await this.client.insert({
|
|
672
|
+
table: storage.TABLE_THREADS,
|
|
673
|
+
values: [
|
|
674
|
+
{
|
|
675
|
+
...thread,
|
|
676
|
+
createdAt: thread.createdAt.toISOString(),
|
|
677
|
+
updatedAt: thread.updatedAt.toISOString()
|
|
678
|
+
}
|
|
679
|
+
],
|
|
680
|
+
format: "JSONEachRow",
|
|
681
|
+
clickhouse_settings: {
|
|
682
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
683
|
+
date_time_input_format: "best_effort",
|
|
684
|
+
use_client_time_zone: 1,
|
|
685
|
+
output_format_json_quote_64bit_integers: 0
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
return thread;
|
|
689
|
+
} catch (error$1) {
|
|
690
|
+
throw new error.MastraError(
|
|
691
|
+
{
|
|
692
|
+
id: "CLICKHOUSE_STORAGE_SAVE_THREAD_FAILED",
|
|
693
|
+
domain: error.ErrorDomain.STORAGE,
|
|
694
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
695
|
+
details: { threadId: thread.id }
|
|
696
|
+
},
|
|
697
|
+
error$1
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
async updateThread({
|
|
702
|
+
id,
|
|
703
|
+
title,
|
|
704
|
+
metadata
|
|
705
|
+
}) {
|
|
706
|
+
try {
|
|
707
|
+
const existingThread = await this.getThreadById({ threadId: id });
|
|
708
|
+
if (!existingThread) {
|
|
709
|
+
throw new Error(`Thread ${id} not found`);
|
|
710
|
+
}
|
|
711
|
+
const mergedMetadata = {
|
|
712
|
+
...existingThread.metadata,
|
|
713
|
+
...metadata
|
|
714
|
+
};
|
|
715
|
+
const updatedThread = {
|
|
716
|
+
...existingThread,
|
|
717
|
+
title,
|
|
718
|
+
metadata: mergedMetadata,
|
|
719
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
720
|
+
};
|
|
721
|
+
await this.client.insert({
|
|
722
|
+
table: storage.TABLE_THREADS,
|
|
723
|
+
format: "JSONEachRow",
|
|
724
|
+
values: [
|
|
725
|
+
{
|
|
726
|
+
id: updatedThread.id,
|
|
727
|
+
resourceId: updatedThread.resourceId,
|
|
728
|
+
title: updatedThread.title,
|
|
729
|
+
metadata: updatedThread.metadata,
|
|
730
|
+
createdAt: updatedThread.createdAt,
|
|
731
|
+
updatedAt: updatedThread.updatedAt.toISOString()
|
|
732
|
+
}
|
|
733
|
+
],
|
|
734
|
+
clickhouse_settings: {
|
|
735
|
+
date_time_input_format: "best_effort",
|
|
736
|
+
use_client_time_zone: 1,
|
|
737
|
+
output_format_json_quote_64bit_integers: 0
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
return updatedThread;
|
|
741
|
+
} catch (error$1) {
|
|
742
|
+
throw new error.MastraError(
|
|
743
|
+
{
|
|
744
|
+
id: "CLICKHOUSE_STORAGE_UPDATE_THREAD_FAILED",
|
|
745
|
+
domain: error.ErrorDomain.STORAGE,
|
|
746
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
747
|
+
details: { threadId: id, title }
|
|
748
|
+
},
|
|
749
|
+
error$1
|
|
750
|
+
);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
async deleteThread({ threadId }) {
|
|
754
|
+
try {
|
|
755
|
+
await this.client.command({
|
|
756
|
+
query: `DELETE FROM "${storage.TABLE_MESSAGES}" WHERE thread_id = {var_thread_id:String};`,
|
|
757
|
+
query_params: { var_thread_id: threadId },
|
|
758
|
+
clickhouse_settings: {
|
|
759
|
+
output_format_json_quote_64bit_integers: 0
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
await this.client.command({
|
|
763
|
+
query: `DELETE FROM "${storage.TABLE_THREADS}" WHERE id = {var_id:String};`,
|
|
764
|
+
query_params: { var_id: threadId },
|
|
765
|
+
clickhouse_settings: {
|
|
766
|
+
output_format_json_quote_64bit_integers: 0
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
} catch (error$1) {
|
|
770
|
+
throw new error.MastraError(
|
|
771
|
+
{
|
|
772
|
+
id: "CLICKHOUSE_STORAGE_DELETE_THREAD_FAILED",
|
|
773
|
+
domain: error.ErrorDomain.STORAGE,
|
|
774
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
775
|
+
details: { threadId }
|
|
776
|
+
},
|
|
777
|
+
error$1
|
|
778
|
+
);
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
782
|
+
const { resourceId, page = 0, perPage = 100 } = args;
|
|
783
|
+
try {
|
|
784
|
+
const currentOffset = page * perPage;
|
|
785
|
+
const countResult = await this.client.query({
|
|
786
|
+
query: `SELECT count() as total FROM ${storage.TABLE_THREADS} WHERE resourceId = {resourceId:String}`,
|
|
787
|
+
query_params: { resourceId },
|
|
788
|
+
clickhouse_settings: {
|
|
789
|
+
date_time_input_format: "best_effort",
|
|
790
|
+
date_time_output_format: "iso",
|
|
791
|
+
use_client_time_zone: 1,
|
|
792
|
+
output_format_json_quote_64bit_integers: 0
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
const countData = await countResult.json();
|
|
796
|
+
const total = countData.data[0].total;
|
|
797
|
+
if (total === 0) {
|
|
798
|
+
return {
|
|
799
|
+
threads: [],
|
|
800
|
+
total: 0,
|
|
801
|
+
page,
|
|
802
|
+
perPage,
|
|
803
|
+
hasMore: false
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
const dataResult = await this.client.query({
|
|
807
|
+
query: `
|
|
808
|
+
SELECT
|
|
809
|
+
id,
|
|
810
|
+
resourceId,
|
|
811
|
+
title,
|
|
812
|
+
metadata,
|
|
813
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
814
|
+
toDateTime64(updatedAt, 3) as updatedAt
|
|
815
|
+
FROM ${storage.TABLE_THREADS}
|
|
816
|
+
WHERE resourceId = {resourceId:String}
|
|
817
|
+
ORDER BY createdAt DESC
|
|
818
|
+
LIMIT {limit:Int64} OFFSET {offset:Int64}
|
|
819
|
+
`,
|
|
820
|
+
query_params: {
|
|
821
|
+
resourceId,
|
|
822
|
+
limit: perPage,
|
|
823
|
+
offset: currentOffset
|
|
824
|
+
},
|
|
825
|
+
clickhouse_settings: {
|
|
826
|
+
date_time_input_format: "best_effort",
|
|
827
|
+
date_time_output_format: "iso",
|
|
828
|
+
use_client_time_zone: 1,
|
|
829
|
+
output_format_json_quote_64bit_integers: 0
|
|
830
|
+
}
|
|
831
|
+
});
|
|
832
|
+
const rows = await dataResult.json();
|
|
833
|
+
const threads = transformRows(rows.data);
|
|
834
|
+
return {
|
|
835
|
+
threads,
|
|
836
|
+
total,
|
|
837
|
+
page,
|
|
838
|
+
perPage,
|
|
839
|
+
hasMore: currentOffset + threads.length < total
|
|
840
|
+
};
|
|
841
|
+
} catch (error$1) {
|
|
842
|
+
throw new error.MastraError(
|
|
843
|
+
{
|
|
844
|
+
id: "CLICKHOUSE_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
|
|
845
|
+
domain: error.ErrorDomain.STORAGE,
|
|
846
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
847
|
+
details: { resourceId, page }
|
|
848
|
+
},
|
|
849
|
+
error$1
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
async getMessagesPaginated(args) {
|
|
854
|
+
const { threadId, resourceId, selectBy, format = "v1" } = args;
|
|
855
|
+
const page = selectBy?.pagination?.page || 0;
|
|
856
|
+
const perPageInput = selectBy?.pagination?.perPage;
|
|
857
|
+
const perPage = perPageInput !== void 0 ? perPageInput : storage.resolveMessageLimit({ last: selectBy?.last, defaultLimit: 20 });
|
|
858
|
+
try {
|
|
859
|
+
if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
|
|
860
|
+
const offset = page * perPage;
|
|
861
|
+
const dateRange = selectBy?.pagination?.dateRange;
|
|
862
|
+
const fromDate = dateRange?.start;
|
|
863
|
+
const toDate = dateRange?.end;
|
|
864
|
+
const messages = [];
|
|
865
|
+
if (selectBy?.include?.length) {
|
|
866
|
+
const include = selectBy.include;
|
|
867
|
+
const unionQueries = [];
|
|
868
|
+
const params = [];
|
|
869
|
+
let paramIdx = 1;
|
|
870
|
+
for (const inc of include) {
|
|
871
|
+
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
872
|
+
const searchId = inc.threadId || threadId;
|
|
873
|
+
unionQueries.push(`
|
|
874
|
+
SELECT * FROM (
|
|
875
|
+
WITH numbered_messages AS (
|
|
876
|
+
SELECT
|
|
877
|
+
id, content, role, type, "createdAt", thread_id, "resourceId",
|
|
878
|
+
ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
|
|
879
|
+
FROM "${storage.TABLE_MESSAGES}"
|
|
880
|
+
WHERE thread_id = {var_thread_id_${paramIdx}:String}
|
|
881
|
+
),
|
|
882
|
+
target_positions AS (
|
|
883
|
+
SELECT row_num as target_pos
|
|
884
|
+
FROM numbered_messages
|
|
885
|
+
WHERE id = {var_include_id_${paramIdx}:String}
|
|
886
|
+
)
|
|
887
|
+
SELECT DISTINCT m.id, m.content, m.role, m.type, m."createdAt", m.thread_id AS "threadId"
|
|
888
|
+
FROM numbered_messages m
|
|
889
|
+
CROSS JOIN target_positions t
|
|
890
|
+
WHERE m.row_num BETWEEN (t.target_pos - {var_withPreviousMessages_${paramIdx}:Int64}) AND (t.target_pos + {var_withNextMessages_${paramIdx}:Int64})
|
|
891
|
+
) AS query_${paramIdx}
|
|
892
|
+
`);
|
|
893
|
+
params.push(
|
|
894
|
+
{ [`var_thread_id_${paramIdx}`]: searchId },
|
|
895
|
+
{ [`var_include_id_${paramIdx}`]: id },
|
|
896
|
+
{ [`var_withPreviousMessages_${paramIdx}`]: withPreviousMessages },
|
|
897
|
+
{ [`var_withNextMessages_${paramIdx}`]: withNextMessages }
|
|
898
|
+
);
|
|
899
|
+
paramIdx++;
|
|
900
|
+
}
|
|
901
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" DESC';
|
|
902
|
+
const mergedParams = params.reduce((acc, paramObj) => ({ ...acc, ...paramObj }), {});
|
|
903
|
+
const includeResult = await this.client.query({
|
|
904
|
+
query: finalQuery,
|
|
905
|
+
query_params: mergedParams,
|
|
906
|
+
clickhouse_settings: {
|
|
907
|
+
date_time_input_format: "best_effort",
|
|
908
|
+
date_time_output_format: "iso",
|
|
909
|
+
use_client_time_zone: 1,
|
|
910
|
+
output_format_json_quote_64bit_integers: 0
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
const rows2 = await includeResult.json();
|
|
914
|
+
const includedMessages = transformRows(rows2.data);
|
|
915
|
+
const seen = /* @__PURE__ */ new Set();
|
|
916
|
+
const dedupedMessages = includedMessages.filter((message) => {
|
|
917
|
+
if (seen.has(message.id)) return false;
|
|
918
|
+
seen.add(message.id);
|
|
919
|
+
return true;
|
|
920
|
+
});
|
|
921
|
+
messages.push(...dedupedMessages);
|
|
922
|
+
}
|
|
923
|
+
let countQuery = `SELECT count() as total FROM ${storage.TABLE_MESSAGES} WHERE thread_id = {threadId:String}`;
|
|
924
|
+
const countParams = { threadId };
|
|
925
|
+
if (fromDate) {
|
|
926
|
+
countQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
|
|
927
|
+
countParams.fromDate = fromDate.toISOString();
|
|
928
|
+
}
|
|
929
|
+
if (toDate) {
|
|
930
|
+
countQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
|
|
931
|
+
countParams.toDate = toDate.toISOString();
|
|
932
|
+
}
|
|
933
|
+
const countResult = await this.client.query({
|
|
934
|
+
query: countQuery,
|
|
935
|
+
query_params: countParams,
|
|
936
|
+
clickhouse_settings: {
|
|
937
|
+
date_time_input_format: "best_effort",
|
|
938
|
+
date_time_output_format: "iso",
|
|
939
|
+
use_client_time_zone: 1,
|
|
940
|
+
output_format_json_quote_64bit_integers: 0
|
|
941
|
+
}
|
|
942
|
+
});
|
|
943
|
+
const countData = await countResult.json();
|
|
944
|
+
const total = countData.data[0].total;
|
|
945
|
+
if (total === 0 && messages.length === 0) {
|
|
946
|
+
return {
|
|
947
|
+
messages: [],
|
|
948
|
+
total: 0,
|
|
949
|
+
page,
|
|
950
|
+
perPage,
|
|
951
|
+
hasMore: false
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
const excludeIds = messages.map((m) => m.id);
|
|
955
|
+
let dataQuery = `
|
|
956
|
+
SELECT
|
|
957
|
+
id,
|
|
958
|
+
content,
|
|
959
|
+
role,
|
|
960
|
+
type,
|
|
961
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
962
|
+
thread_id AS "threadId",
|
|
963
|
+
resourceId
|
|
964
|
+
FROM ${storage.TABLE_MESSAGES}
|
|
965
|
+
WHERE thread_id = {threadId:String}
|
|
966
|
+
`;
|
|
967
|
+
const dataParams = { threadId };
|
|
968
|
+
if (fromDate) {
|
|
969
|
+
dataQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
|
|
970
|
+
dataParams.fromDate = fromDate.toISOString();
|
|
971
|
+
}
|
|
972
|
+
if (toDate) {
|
|
973
|
+
dataQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
|
|
974
|
+
dataParams.toDate = toDate.toISOString();
|
|
975
|
+
}
|
|
976
|
+
if (excludeIds.length > 0) {
|
|
977
|
+
dataQuery += ` AND id NOT IN ({excludeIds:Array(String)})`;
|
|
978
|
+
dataParams.excludeIds = excludeIds;
|
|
979
|
+
}
|
|
980
|
+
if (selectBy?.last) {
|
|
981
|
+
dataQuery += `
|
|
982
|
+
ORDER BY createdAt DESC
|
|
983
|
+
LIMIT {limit:Int64}
|
|
984
|
+
`;
|
|
985
|
+
dataParams.limit = perPage;
|
|
986
|
+
} else {
|
|
987
|
+
dataQuery += `
|
|
988
|
+
ORDER BY createdAt ASC
|
|
989
|
+
LIMIT {limit:Int64} OFFSET {offset:Int64}
|
|
990
|
+
`;
|
|
991
|
+
dataParams.limit = perPage;
|
|
992
|
+
dataParams.offset = offset;
|
|
993
|
+
}
|
|
994
|
+
const result = await this.client.query({
|
|
995
|
+
query: dataQuery,
|
|
996
|
+
query_params: dataParams,
|
|
997
|
+
clickhouse_settings: {
|
|
998
|
+
date_time_input_format: "best_effort",
|
|
999
|
+
date_time_output_format: "iso",
|
|
1000
|
+
use_client_time_zone: 1,
|
|
1001
|
+
output_format_json_quote_64bit_integers: 0
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
const rows = await result.json();
|
|
1005
|
+
const paginatedMessages = transformRows(rows.data);
|
|
1006
|
+
messages.push(...paginatedMessages);
|
|
1007
|
+
if (selectBy?.last) {
|
|
1008
|
+
messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
|
|
1009
|
+
}
|
|
1010
|
+
return {
|
|
1011
|
+
messages: format === "v2" ? messages : messages,
|
|
1012
|
+
total,
|
|
1013
|
+
page,
|
|
1014
|
+
perPage,
|
|
1015
|
+
hasMore: offset + perPage < total
|
|
1016
|
+
};
|
|
1017
|
+
} catch (error$1) {
|
|
1018
|
+
const mastraError = new error.MastraError(
|
|
1019
|
+
{
|
|
1020
|
+
id: "CLICKHOUSE_STORAGE_GET_MESSAGES_PAGINATED_FAILED",
|
|
1021
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1022
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1023
|
+
details: {
|
|
1024
|
+
threadId,
|
|
1025
|
+
resourceId: resourceId ?? ""
|
|
1026
|
+
}
|
|
1027
|
+
},
|
|
1028
|
+
error$1
|
|
1029
|
+
);
|
|
1030
|
+
this.logger?.trackException?.(mastraError);
|
|
1031
|
+
this.logger?.error?.(mastraError.toString());
|
|
1032
|
+
return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
async updateMessages(args) {
|
|
1036
|
+
const { messages } = args;
|
|
1037
|
+
if (messages.length === 0) {
|
|
1038
|
+
return [];
|
|
1039
|
+
}
|
|
1040
|
+
try {
|
|
1041
|
+
const messageIds = messages.map((m) => m.id);
|
|
1042
|
+
const existingResult = await this.client.query({
|
|
1043
|
+
query: `SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId" FROM ${storage.TABLE_MESSAGES} WHERE id IN (${messageIds.map((_, i) => `{id_${i}:String}`).join(",")})`,
|
|
1044
|
+
query_params: messageIds.reduce((acc, m, i) => ({ ...acc, [`id_${i}`]: m }), {}),
|
|
1045
|
+
clickhouse_settings: {
|
|
1046
|
+
date_time_input_format: "best_effort",
|
|
1047
|
+
date_time_output_format: "iso",
|
|
1048
|
+
use_client_time_zone: 1,
|
|
1049
|
+
output_format_json_quote_64bit_integers: 0
|
|
1050
|
+
}
|
|
1051
|
+
});
|
|
1052
|
+
const existingRows = await existingResult.json();
|
|
1053
|
+
const existingMessages = transformRows(existingRows.data);
|
|
1054
|
+
if (existingMessages.length === 0) {
|
|
1055
|
+
return [];
|
|
1056
|
+
}
|
|
1057
|
+
const parsedExistingMessages = existingMessages.map((msg) => {
|
|
1058
|
+
if (typeof msg.content === "string") {
|
|
1059
|
+
try {
|
|
1060
|
+
msg.content = JSON.parse(msg.content);
|
|
1061
|
+
} catch {
|
|
1062
|
+
}
|
|
1063
|
+
}
|
|
1064
|
+
return msg;
|
|
1065
|
+
});
|
|
1066
|
+
const threadIdsToUpdate = /* @__PURE__ */ new Set();
|
|
1067
|
+
const updatePromises = [];
|
|
1068
|
+
for (const existingMessage of parsedExistingMessages) {
|
|
1069
|
+
const updatePayload = messages.find((m) => m.id === existingMessage.id);
|
|
1070
|
+
if (!updatePayload) continue;
|
|
1071
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1072
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
1073
|
+
threadIdsToUpdate.add(existingMessage.threadId);
|
|
1074
|
+
if (updatePayload.threadId && updatePayload.threadId !== existingMessage.threadId) {
|
|
1075
|
+
threadIdsToUpdate.add(updatePayload.threadId);
|
|
1076
|
+
}
|
|
1077
|
+
const setClauses = [];
|
|
1078
|
+
const values = {};
|
|
1079
|
+
let paramIdx = 1;
|
|
1080
|
+
let newContent = null;
|
|
1081
|
+
const updatableFields = { ...fieldsToUpdate };
|
|
1082
|
+
if (updatableFields.content) {
|
|
1083
|
+
const existingContent = existingMessage.content || {};
|
|
1084
|
+
const existingMetadata = existingContent.metadata || {};
|
|
1085
|
+
const updateMetadata = updatableFields.content.metadata || {};
|
|
1086
|
+
newContent = {
|
|
1087
|
+
...existingContent,
|
|
1088
|
+
...updatableFields.content,
|
|
1089
|
+
// Deep merge metadata
|
|
1090
|
+
metadata: {
|
|
1091
|
+
...existingMetadata,
|
|
1092
|
+
...updateMetadata
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
setClauses.push(`content = {var_content_${paramIdx}:String}`);
|
|
1096
|
+
values[`var_content_${paramIdx}`] = JSON.stringify(newContent);
|
|
1097
|
+
paramIdx++;
|
|
1098
|
+
delete updatableFields.content;
|
|
1099
|
+
}
|
|
1100
|
+
for (const key in updatableFields) {
|
|
1101
|
+
if (Object.prototype.hasOwnProperty.call(updatableFields, key)) {
|
|
1102
|
+
const dbColumn = key === "threadId" ? "thread_id" : key;
|
|
1103
|
+
setClauses.push(`"${dbColumn}" = {var_${key}_${paramIdx}:String}`);
|
|
1104
|
+
values[`var_${key}_${paramIdx}`] = updatableFields[key];
|
|
1105
|
+
paramIdx++;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
if (setClauses.length > 0) {
|
|
1109
|
+
values[`var_id_${paramIdx}`] = id;
|
|
1110
|
+
const updateQuery = `
|
|
1111
|
+
ALTER TABLE ${storage.TABLE_MESSAGES}
|
|
1112
|
+
UPDATE ${setClauses.join(", ")}
|
|
1113
|
+
WHERE id = {var_id_${paramIdx}:String}
|
|
1114
|
+
`;
|
|
1115
|
+
console.info("Updating message:", id, "with query:", updateQuery, "values:", values);
|
|
1116
|
+
updatePromises.push(
|
|
1117
|
+
this.client.command({
|
|
1118
|
+
query: updateQuery,
|
|
1119
|
+
query_params: values,
|
|
1120
|
+
clickhouse_settings: {
|
|
1121
|
+
date_time_input_format: "best_effort",
|
|
1122
|
+
use_client_time_zone: 1,
|
|
1123
|
+
output_format_json_quote_64bit_integers: 0
|
|
1124
|
+
}
|
|
1125
|
+
})
|
|
1126
|
+
);
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
1129
|
+
if (updatePromises.length > 0) {
|
|
1130
|
+
await Promise.all(updatePromises);
|
|
1131
|
+
}
|
|
1132
|
+
await this.client.command({
|
|
1133
|
+
query: `OPTIMIZE TABLE ${storage.TABLE_MESSAGES} FINAL`,
|
|
1134
|
+
clickhouse_settings: {
|
|
1135
|
+
date_time_input_format: "best_effort",
|
|
1136
|
+
use_client_time_zone: 1,
|
|
1137
|
+
output_format_json_quote_64bit_integers: 0
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
for (const existingMessage of parsedExistingMessages) {
|
|
1141
|
+
const updatePayload = messages.find((m) => m.id === existingMessage.id);
|
|
1142
|
+
if (!updatePayload) continue;
|
|
1143
|
+
const { id, ...fieldsToUpdate } = updatePayload;
|
|
1144
|
+
if (Object.keys(fieldsToUpdate).length === 0) continue;
|
|
1145
|
+
const verifyResult = await this.client.query({
|
|
1146
|
+
query: `SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId" FROM ${storage.TABLE_MESSAGES} WHERE id = {messageId:String}`,
|
|
1147
|
+
query_params: { messageId: id },
|
|
1148
|
+
clickhouse_settings: {
|
|
1149
|
+
date_time_input_format: "best_effort",
|
|
1150
|
+
date_time_output_format: "iso",
|
|
1151
|
+
use_client_time_zone: 1,
|
|
1152
|
+
output_format_json_quote_64bit_integers: 0
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
const verifyRows = await verifyResult.json();
|
|
1156
|
+
if (verifyRows.data.length > 0) {
|
|
1157
|
+
const updatedMessage = transformRows(verifyRows.data)[0];
|
|
1158
|
+
if (updatedMessage) {
|
|
1159
|
+
let needsRetry = false;
|
|
1160
|
+
for (const [key, value] of Object.entries(fieldsToUpdate)) {
|
|
1161
|
+
if (key === "content") {
|
|
1162
|
+
const expectedContent = typeof value === "string" ? value : JSON.stringify(value);
|
|
1163
|
+
const actualContent = typeof updatedMessage.content === "string" ? updatedMessage.content : JSON.stringify(updatedMessage.content);
|
|
1164
|
+
if (actualContent !== expectedContent) {
|
|
1165
|
+
needsRetry = true;
|
|
1166
|
+
break;
|
|
1167
|
+
}
|
|
1168
|
+
} else if (updatedMessage[key] !== value) {
|
|
1169
|
+
needsRetry = true;
|
|
1170
|
+
break;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (needsRetry) {
|
|
1174
|
+
console.info("Update not applied correctly, retrying with DELETE + INSERT for message:", id);
|
|
1175
|
+
await this.client.command({
|
|
1176
|
+
query: `DELETE FROM ${storage.TABLE_MESSAGES} WHERE id = {messageId:String}`,
|
|
1177
|
+
query_params: { messageId: id },
|
|
1178
|
+
clickhouse_settings: {
|
|
1179
|
+
date_time_input_format: "best_effort",
|
|
1180
|
+
use_client_time_zone: 1,
|
|
1181
|
+
output_format_json_quote_64bit_integers: 0
|
|
1182
|
+
}
|
|
1183
|
+
});
|
|
1184
|
+
let updatedContent = existingMessage.content || {};
|
|
1185
|
+
if (fieldsToUpdate.content) {
|
|
1186
|
+
const existingContent = existingMessage.content || {};
|
|
1187
|
+
const existingMetadata = existingContent.metadata || {};
|
|
1188
|
+
const updateMetadata = fieldsToUpdate.content.metadata || {};
|
|
1189
|
+
updatedContent = {
|
|
1190
|
+
...existingContent,
|
|
1191
|
+
...fieldsToUpdate.content,
|
|
1192
|
+
metadata: {
|
|
1193
|
+
...existingMetadata,
|
|
1194
|
+
...updateMetadata
|
|
1195
|
+
}
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
const updatedMessageData = {
|
|
1199
|
+
...existingMessage,
|
|
1200
|
+
...fieldsToUpdate,
|
|
1201
|
+
content: updatedContent
|
|
1202
|
+
};
|
|
1203
|
+
await this.client.insert({
|
|
1204
|
+
table: storage.TABLE_MESSAGES,
|
|
1205
|
+
format: "JSONEachRow",
|
|
1206
|
+
values: [
|
|
1207
|
+
{
|
|
1208
|
+
id: updatedMessageData.id,
|
|
1209
|
+
thread_id: updatedMessageData.threadId,
|
|
1210
|
+
resourceId: updatedMessageData.resourceId,
|
|
1211
|
+
content: typeof updatedMessageData.content === "string" ? updatedMessageData.content : JSON.stringify(updatedMessageData.content),
|
|
1212
|
+
createdAt: updatedMessageData.createdAt.toISOString(),
|
|
1213
|
+
role: updatedMessageData.role,
|
|
1214
|
+
type: updatedMessageData.type || "v2"
|
|
1215
|
+
}
|
|
1216
|
+
],
|
|
1217
|
+
clickhouse_settings: {
|
|
1218
|
+
date_time_input_format: "best_effort",
|
|
1219
|
+
use_client_time_zone: 1,
|
|
1220
|
+
output_format_json_quote_64bit_integers: 0
|
|
1221
|
+
}
|
|
1222
|
+
});
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
}
|
|
1227
|
+
if (threadIdsToUpdate.size > 0) {
|
|
1228
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
1229
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace("Z", "");
|
|
1230
|
+
const threadUpdatePromises = Array.from(threadIdsToUpdate).map(async (threadId) => {
|
|
1231
|
+
const threadResult = await this.client.query({
|
|
1232
|
+
query: `SELECT id, resourceId, title, metadata, createdAt FROM ${storage.TABLE_THREADS} WHERE id = {threadId:String}`,
|
|
1233
|
+
query_params: { threadId },
|
|
1234
|
+
clickhouse_settings: {
|
|
1235
|
+
date_time_input_format: "best_effort",
|
|
1236
|
+
date_time_output_format: "iso",
|
|
1237
|
+
use_client_time_zone: 1,
|
|
1238
|
+
output_format_json_quote_64bit_integers: 0
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
const threadRows = await threadResult.json();
|
|
1242
|
+
if (threadRows.data.length > 0) {
|
|
1243
|
+
const existingThread = threadRows.data[0];
|
|
1244
|
+
await this.client.command({
|
|
1245
|
+
query: `DELETE FROM ${storage.TABLE_THREADS} WHERE id = {threadId:String}`,
|
|
1246
|
+
query_params: { threadId },
|
|
1247
|
+
clickhouse_settings: {
|
|
1248
|
+
date_time_input_format: "best_effort",
|
|
1249
|
+
use_client_time_zone: 1,
|
|
1250
|
+
output_format_json_quote_64bit_integers: 0
|
|
1251
|
+
}
|
|
1252
|
+
});
|
|
1253
|
+
await this.client.insert({
|
|
1254
|
+
table: storage.TABLE_THREADS,
|
|
1255
|
+
format: "JSONEachRow",
|
|
1256
|
+
values: [
|
|
1257
|
+
{
|
|
1258
|
+
id: existingThread.id,
|
|
1259
|
+
resourceId: existingThread.resourceId,
|
|
1260
|
+
title: existingThread.title,
|
|
1261
|
+
metadata: existingThread.metadata,
|
|
1262
|
+
createdAt: existingThread.createdAt,
|
|
1263
|
+
updatedAt: now
|
|
1264
|
+
}
|
|
1265
|
+
],
|
|
1266
|
+
clickhouse_settings: {
|
|
1267
|
+
date_time_input_format: "best_effort",
|
|
1268
|
+
use_client_time_zone: 1,
|
|
1269
|
+
output_format_json_quote_64bit_integers: 0
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
await Promise.all(threadUpdatePromises);
|
|
1275
|
+
}
|
|
1276
|
+
const updatedMessages = [];
|
|
1277
|
+
for (const messageId of messageIds) {
|
|
1278
|
+
const updatedResult = await this.client.query({
|
|
1279
|
+
query: `SELECT id, content, role, type, "createdAt", thread_id AS "threadId", "resourceId" FROM ${storage.TABLE_MESSAGES} WHERE id = {messageId:String}`,
|
|
1280
|
+
query_params: { messageId },
|
|
1281
|
+
clickhouse_settings: {
|
|
1282
|
+
date_time_input_format: "best_effort",
|
|
1283
|
+
date_time_output_format: "iso",
|
|
1284
|
+
use_client_time_zone: 1,
|
|
1285
|
+
output_format_json_quote_64bit_integers: 0
|
|
1286
|
+
}
|
|
1287
|
+
});
|
|
1288
|
+
const updatedRows = await updatedResult.json();
|
|
1289
|
+
if (updatedRows.data.length > 0) {
|
|
1290
|
+
const message = transformRows(updatedRows.data)[0];
|
|
1291
|
+
if (message) {
|
|
1292
|
+
updatedMessages.push(message);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1296
|
+
return updatedMessages.map((message) => {
|
|
1297
|
+
if (typeof message.content === "string") {
|
|
1298
|
+
try {
|
|
1299
|
+
message.content = JSON.parse(message.content);
|
|
1300
|
+
} catch {
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
return message;
|
|
1304
|
+
});
|
|
1305
|
+
} catch (error$1) {
|
|
1306
|
+
throw new error.MastraError(
|
|
1307
|
+
{
|
|
1308
|
+
id: "CLICKHOUSE_STORAGE_UPDATE_MESSAGES_FAILED",
|
|
1309
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1310
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1311
|
+
details: { messageIds: messages.map((m) => m.id).join(",") }
|
|
1312
|
+
},
|
|
1313
|
+
error$1
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
async getResourceById({ resourceId }) {
|
|
1318
|
+
try {
|
|
1319
|
+
const result = await this.client.query({
|
|
1320
|
+
query: `SELECT id, workingMemory, metadata, createdAt, updatedAt FROM ${storage.TABLE_RESOURCES} WHERE id = {resourceId:String}`,
|
|
1321
|
+
query_params: { resourceId },
|
|
1322
|
+
clickhouse_settings: {
|
|
1323
|
+
date_time_input_format: "best_effort",
|
|
1324
|
+
date_time_output_format: "iso",
|
|
1325
|
+
use_client_time_zone: 1,
|
|
1326
|
+
output_format_json_quote_64bit_integers: 0
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
const rows = await result.json();
|
|
1330
|
+
if (rows.data.length === 0) {
|
|
1331
|
+
return null;
|
|
1332
|
+
}
|
|
1333
|
+
const resource = rows.data[0];
|
|
1334
|
+
return {
|
|
1335
|
+
id: resource.id,
|
|
1336
|
+
workingMemory: resource.workingMemory && typeof resource.workingMemory === "object" ? JSON.stringify(resource.workingMemory) : resource.workingMemory,
|
|
1337
|
+
metadata: resource.metadata && typeof resource.metadata === "string" ? JSON.parse(resource.metadata) : resource.metadata,
|
|
1338
|
+
createdAt: new Date(resource.createdAt),
|
|
1339
|
+
updatedAt: new Date(resource.updatedAt)
|
|
1340
|
+
};
|
|
1341
|
+
} catch (error$1) {
|
|
1342
|
+
throw new error.MastraError(
|
|
1343
|
+
{
|
|
1344
|
+
id: "CLICKHOUSE_STORAGE_GET_RESOURCE_BY_ID_FAILED",
|
|
1345
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1346
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1347
|
+
details: { resourceId }
|
|
1348
|
+
},
|
|
1349
|
+
error$1
|
|
1350
|
+
);
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
async saveResource({ resource }) {
|
|
1354
|
+
try {
|
|
1355
|
+
await this.client.insert({
|
|
1356
|
+
table: storage.TABLE_RESOURCES,
|
|
1357
|
+
format: "JSONEachRow",
|
|
1358
|
+
values: [
|
|
1359
|
+
{
|
|
1360
|
+
id: resource.id,
|
|
1361
|
+
workingMemory: resource.workingMemory,
|
|
1362
|
+
metadata: JSON.stringify(resource.metadata),
|
|
1363
|
+
createdAt: resource.createdAt.toISOString(),
|
|
1364
|
+
updatedAt: resource.updatedAt.toISOString()
|
|
1365
|
+
}
|
|
1366
|
+
],
|
|
1367
|
+
clickhouse_settings: {
|
|
1368
|
+
date_time_input_format: "best_effort",
|
|
1369
|
+
use_client_time_zone: 1,
|
|
1370
|
+
output_format_json_quote_64bit_integers: 0
|
|
1371
|
+
}
|
|
1372
|
+
});
|
|
1373
|
+
return resource;
|
|
1374
|
+
} catch (error$1) {
|
|
1375
|
+
throw new error.MastraError(
|
|
1376
|
+
{
|
|
1377
|
+
id: "CLICKHOUSE_STORAGE_SAVE_RESOURCE_FAILED",
|
|
1378
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1379
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1380
|
+
details: { resourceId: resource.id }
|
|
1381
|
+
},
|
|
1382
|
+
error$1
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
async updateResource({
|
|
1387
|
+
resourceId,
|
|
1388
|
+
workingMemory,
|
|
1389
|
+
metadata
|
|
1390
|
+
}) {
|
|
1391
|
+
try {
|
|
1392
|
+
const existingResource = await this.getResourceById({ resourceId });
|
|
1393
|
+
if (!existingResource) {
|
|
1394
|
+
const newResource = {
|
|
1395
|
+
id: resourceId,
|
|
1396
|
+
workingMemory,
|
|
1397
|
+
metadata: metadata || {},
|
|
1398
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
1399
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1400
|
+
};
|
|
1401
|
+
return this.saveResource({ resource: newResource });
|
|
1402
|
+
}
|
|
1403
|
+
const updatedResource = {
|
|
1404
|
+
...existingResource,
|
|
1405
|
+
workingMemory: workingMemory !== void 0 ? workingMemory : existingResource.workingMemory,
|
|
1406
|
+
metadata: {
|
|
1407
|
+
...existingResource.metadata,
|
|
1408
|
+
...metadata
|
|
1409
|
+
},
|
|
1410
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1411
|
+
};
|
|
1412
|
+
const updateQuery = `
|
|
1413
|
+
ALTER TABLE ${storage.TABLE_RESOURCES}
|
|
1414
|
+
UPDATE workingMemory = {workingMemory:String}, metadata = {metadata:String}, updatedAt = {updatedAt:String}
|
|
1415
|
+
WHERE id = {resourceId:String}
|
|
1416
|
+
`;
|
|
1417
|
+
await this.client.command({
|
|
1418
|
+
query: updateQuery,
|
|
1419
|
+
query_params: {
|
|
1420
|
+
workingMemory: updatedResource.workingMemory,
|
|
1421
|
+
metadata: JSON.stringify(updatedResource.metadata),
|
|
1422
|
+
updatedAt: updatedResource.updatedAt.toISOString().replace("Z", ""),
|
|
1423
|
+
resourceId
|
|
1424
|
+
},
|
|
1425
|
+
clickhouse_settings: {
|
|
1426
|
+
date_time_input_format: "best_effort",
|
|
1427
|
+
use_client_time_zone: 1,
|
|
1428
|
+
output_format_json_quote_64bit_integers: 0
|
|
1429
|
+
}
|
|
1430
|
+
});
|
|
1431
|
+
await this.client.command({
|
|
1432
|
+
query: `OPTIMIZE TABLE ${storage.TABLE_RESOURCES} FINAL`,
|
|
1433
|
+
clickhouse_settings: {
|
|
1434
|
+
date_time_input_format: "best_effort",
|
|
1435
|
+
use_client_time_zone: 1,
|
|
1436
|
+
output_format_json_quote_64bit_integers: 0
|
|
1437
|
+
}
|
|
1438
|
+
});
|
|
1439
|
+
return updatedResource;
|
|
1440
|
+
} catch (error$1) {
|
|
1441
|
+
throw new error.MastraError(
|
|
1442
|
+
{
|
|
1443
|
+
id: "CLICKHOUSE_STORAGE_UPDATE_RESOURCE_FAILED",
|
|
1444
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1445
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1446
|
+
details: { resourceId }
|
|
1447
|
+
},
|
|
1448
|
+
error$1
|
|
1449
|
+
);
|
|
1450
|
+
}
|
|
212
1451
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
1452
|
+
};
|
|
1453
|
+
var StoreOperationsClickhouse = class extends storage.StoreOperations {
|
|
1454
|
+
ttl;
|
|
1455
|
+
client;
|
|
1456
|
+
constructor({ client, ttl }) {
|
|
1457
|
+
super();
|
|
1458
|
+
this.ttl = ttl;
|
|
1459
|
+
this.client = client;
|
|
217
1460
|
}
|
|
218
|
-
async
|
|
219
|
-
await this.
|
|
220
|
-
query: `
|
|
1461
|
+
async hasColumn(table, column) {
|
|
1462
|
+
const result = await this.client.query({
|
|
1463
|
+
query: `DESCRIBE TABLE ${table}`,
|
|
1464
|
+
format: "JSONEachRow"
|
|
221
1465
|
});
|
|
1466
|
+
const columns = await result.json();
|
|
1467
|
+
return columns.some((c) => c.name === column);
|
|
1468
|
+
}
|
|
1469
|
+
getSqlType(type) {
|
|
1470
|
+
switch (type) {
|
|
1471
|
+
case "text":
|
|
1472
|
+
return "String";
|
|
1473
|
+
case "timestamp":
|
|
1474
|
+
return "DateTime64(3)";
|
|
1475
|
+
case "integer":
|
|
1476
|
+
case "bigint":
|
|
1477
|
+
return "Int64";
|
|
1478
|
+
case "jsonb":
|
|
1479
|
+
return "String";
|
|
1480
|
+
default:
|
|
1481
|
+
return super.getSqlType(type);
|
|
1482
|
+
}
|
|
222
1483
|
}
|
|
223
1484
|
async createTable({
|
|
224
1485
|
tableName,
|
|
@@ -233,27 +1494,25 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
233
1494
|
}).join(",\n");
|
|
234
1495
|
const rowTtl = this.ttl?.[tableName]?.row;
|
|
235
1496
|
const sql = tableName === storage.TABLE_WORKFLOW_SNAPSHOT ? `
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
`;
|
|
256
|
-
await this.db.query({
|
|
1497
|
+
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
1498
|
+
${["id String"].concat(columns)}
|
|
1499
|
+
)
|
|
1500
|
+
ENGINE = ${TABLE_ENGINES[tableName] ?? "MergeTree()"}
|
|
1501
|
+
PRIMARY KEY (createdAt, run_id, workflow_name)
|
|
1502
|
+
ORDER BY (createdAt, run_id, workflow_name)
|
|
1503
|
+
${rowTtl ? `TTL toDateTime(${rowTtl.ttlKey ?? "createdAt"}) + INTERVAL ${rowTtl.interval} ${rowTtl.unit}` : ""}
|
|
1504
|
+
SETTINGS index_granularity = 8192
|
|
1505
|
+
` : `
|
|
1506
|
+
CREATE TABLE IF NOT EXISTS ${tableName} (
|
|
1507
|
+
${columns}
|
|
1508
|
+
)
|
|
1509
|
+
ENGINE = ${TABLE_ENGINES[tableName] ?? "MergeTree()"}
|
|
1510
|
+
PRIMARY KEY (createdAt, ${tableName === storage.TABLE_EVALS ? "run_id" : "id"})
|
|
1511
|
+
ORDER BY (createdAt, ${tableName === storage.TABLE_EVALS ? "run_id" : "id"})
|
|
1512
|
+
${this.ttl?.[tableName]?.row ? `TTL toDateTime(createdAt) + INTERVAL ${this.ttl[tableName].row.interval} ${this.ttl[tableName].row.unit}` : ""}
|
|
1513
|
+
SETTINGS index_granularity = 8192
|
|
1514
|
+
`;
|
|
1515
|
+
await this.client.query({
|
|
257
1516
|
query: sql,
|
|
258
1517
|
clickhouse_settings: {
|
|
259
1518
|
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
@@ -263,14 +1522,60 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
263
1522
|
output_format_json_quote_64bit_integers: 0
|
|
264
1523
|
}
|
|
265
1524
|
});
|
|
266
|
-
} catch (error) {
|
|
267
|
-
|
|
268
|
-
|
|
1525
|
+
} catch (error$1) {
|
|
1526
|
+
throw new error.MastraError(
|
|
1527
|
+
{
|
|
1528
|
+
id: "CLICKHOUSE_STORAGE_CREATE_TABLE_FAILED",
|
|
1529
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1530
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1531
|
+
details: { tableName }
|
|
1532
|
+
},
|
|
1533
|
+
error$1
|
|
1534
|
+
);
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
async alterTable({
|
|
1538
|
+
tableName,
|
|
1539
|
+
schema,
|
|
1540
|
+
ifNotExists
|
|
1541
|
+
}) {
|
|
1542
|
+
try {
|
|
1543
|
+
const describeSql = `DESCRIBE TABLE ${tableName}`;
|
|
1544
|
+
const result = await this.client.query({
|
|
1545
|
+
query: describeSql
|
|
1546
|
+
});
|
|
1547
|
+
const rows = await result.json();
|
|
1548
|
+
const existingColumnNames = new Set(rows.data.map((row) => row.name.toLowerCase()));
|
|
1549
|
+
for (const columnName of ifNotExists) {
|
|
1550
|
+
if (!existingColumnNames.has(columnName.toLowerCase()) && schema[columnName]) {
|
|
1551
|
+
const columnDef = schema[columnName];
|
|
1552
|
+
let sqlType = this.getSqlType(columnDef.type);
|
|
1553
|
+
if (columnDef.nullable !== false) {
|
|
1554
|
+
sqlType = `Nullable(${sqlType})`;
|
|
1555
|
+
}
|
|
1556
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : "";
|
|
1557
|
+
const alterSql = `ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS "${columnName}" ${sqlType} ${defaultValue}`.trim();
|
|
1558
|
+
await this.client.query({
|
|
1559
|
+
query: alterSql
|
|
1560
|
+
});
|
|
1561
|
+
this.logger?.debug?.(`Added column ${columnName} to table ${tableName}`);
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
} catch (error$1) {
|
|
1565
|
+
throw new error.MastraError(
|
|
1566
|
+
{
|
|
1567
|
+
id: "CLICKHOUSE_STORAGE_ALTER_TABLE_FAILED",
|
|
1568
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1569
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1570
|
+
details: { tableName }
|
|
1571
|
+
},
|
|
1572
|
+
error$1
|
|
1573
|
+
);
|
|
269
1574
|
}
|
|
270
1575
|
}
|
|
271
1576
|
async clearTable({ tableName }) {
|
|
272
1577
|
try {
|
|
273
|
-
await this.
|
|
1578
|
+
await this.client.query({
|
|
274
1579
|
query: `TRUNCATE TABLE ${tableName}`,
|
|
275
1580
|
clickhouse_settings: {
|
|
276
1581
|
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
@@ -280,20 +1585,34 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
280
1585
|
output_format_json_quote_64bit_integers: 0
|
|
281
1586
|
}
|
|
282
1587
|
});
|
|
283
|
-
} catch (error) {
|
|
284
|
-
|
|
285
|
-
|
|
1588
|
+
} catch (error$1) {
|
|
1589
|
+
throw new error.MastraError(
|
|
1590
|
+
{
|
|
1591
|
+
id: "CLICKHOUSE_STORAGE_CLEAR_TABLE_FAILED",
|
|
1592
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1593
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1594
|
+
details: { tableName }
|
|
1595
|
+
},
|
|
1596
|
+
error$1
|
|
1597
|
+
);
|
|
286
1598
|
}
|
|
287
1599
|
}
|
|
1600
|
+
async dropTable({ tableName }) {
|
|
1601
|
+
await this.client.query({
|
|
1602
|
+
query: `DROP TABLE IF EXISTS ${tableName}`
|
|
1603
|
+
});
|
|
1604
|
+
}
|
|
288
1605
|
async insert({ tableName, record }) {
|
|
1606
|
+
const createdAt = (record.createdAt || record.created_at || /* @__PURE__ */ new Date()).toISOString();
|
|
1607
|
+
const updatedAt = (record.updatedAt || /* @__PURE__ */ new Date()).toISOString();
|
|
289
1608
|
try {
|
|
290
|
-
await this.
|
|
1609
|
+
const result = await this.client.insert({
|
|
291
1610
|
table: tableName,
|
|
292
1611
|
values: [
|
|
293
1612
|
{
|
|
294
1613
|
...record,
|
|
295
|
-
createdAt
|
|
296
|
-
updatedAt
|
|
1614
|
+
createdAt,
|
|
1615
|
+
updatedAt
|
|
297
1616
|
}
|
|
298
1617
|
],
|
|
299
1618
|
format: "JSONEachRow",
|
|
@@ -304,13 +1623,55 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
304
1623
|
use_client_time_zone: 1
|
|
305
1624
|
}
|
|
306
1625
|
});
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
throw error
|
|
1626
|
+
console.info("INSERT RESULT", result);
|
|
1627
|
+
} catch (error$1) {
|
|
1628
|
+
throw new error.MastraError(
|
|
1629
|
+
{
|
|
1630
|
+
id: "CLICKHOUSE_STORAGE_INSERT_FAILED",
|
|
1631
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1632
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1633
|
+
details: { tableName }
|
|
1634
|
+
},
|
|
1635
|
+
error$1
|
|
1636
|
+
);
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
async batchInsert({ tableName, records }) {
|
|
1640
|
+
const recordsToBeInserted = records.map((record) => ({
|
|
1641
|
+
...Object.fromEntries(
|
|
1642
|
+
Object.entries(record).map(([key, value]) => [
|
|
1643
|
+
key,
|
|
1644
|
+
storage.TABLE_SCHEMAS[tableName]?.[key]?.type === "timestamp" ? new Date(value).toISOString() : value
|
|
1645
|
+
])
|
|
1646
|
+
)
|
|
1647
|
+
}));
|
|
1648
|
+
try {
|
|
1649
|
+
await this.client.insert({
|
|
1650
|
+
table: tableName,
|
|
1651
|
+
values: recordsToBeInserted,
|
|
1652
|
+
format: "JSONEachRow",
|
|
1653
|
+
clickhouse_settings: {
|
|
1654
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
1655
|
+
date_time_input_format: "best_effort",
|
|
1656
|
+
use_client_time_zone: 1,
|
|
1657
|
+
output_format_json_quote_64bit_integers: 0
|
|
1658
|
+
}
|
|
1659
|
+
});
|
|
1660
|
+
} catch (error$1) {
|
|
1661
|
+
throw new error.MastraError(
|
|
1662
|
+
{
|
|
1663
|
+
id: "CLICKHOUSE_STORAGE_BATCH_INSERT_FAILED",
|
|
1664
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1665
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1666
|
+
details: { tableName }
|
|
1667
|
+
},
|
|
1668
|
+
error$1
|
|
1669
|
+
);
|
|
310
1670
|
}
|
|
311
1671
|
}
|
|
312
1672
|
async load({ tableName, keys }) {
|
|
313
1673
|
try {
|
|
1674
|
+
const engine = TABLE_ENGINES[tableName] ?? "MergeTree()";
|
|
314
1675
|
const keyEntries = Object.entries(keys);
|
|
315
1676
|
const conditions = keyEntries.map(
|
|
316
1677
|
([key]) => `"${key}" = {var_${key}:${COLUMN_TYPES[storage.TABLE_SCHEMAS[tableName]?.[key]?.type ?? "text"]}}`
|
|
@@ -318,8 +1679,10 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
318
1679
|
const values = keyEntries.reduce((acc, [key, value]) => {
|
|
319
1680
|
return { ...acc, [`var_${key}`]: value };
|
|
320
1681
|
}, {});
|
|
321
|
-
const
|
|
322
|
-
|
|
1682
|
+
const hasUpdatedAt = storage.TABLE_SCHEMAS[tableName]?.updatedAt;
|
|
1683
|
+
const selectClause = `SELECT *, toDateTime64(createdAt, 3) as createdAt${hasUpdatedAt ? ", toDateTime64(updatedAt, 3) as updatedAt" : ""}`;
|
|
1684
|
+
const result = await this.client.query({
|
|
1685
|
+
query: `${selectClause} FROM ${tableName} ${engine.startsWith("ReplacingMergeTree") ? "FINAL" : ""} WHERE ${conditions} ORDER BY createdAt DESC LIMIT 1`,
|
|
323
1686
|
query_params: values,
|
|
324
1687
|
clickhouse_settings: {
|
|
325
1688
|
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
@@ -345,25 +1708,58 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
345
1708
|
}
|
|
346
1709
|
const data = transformRow(rows.data[0]);
|
|
347
1710
|
return data;
|
|
348
|
-
} catch (error) {
|
|
349
|
-
|
|
350
|
-
|
|
1711
|
+
} catch (error$1) {
|
|
1712
|
+
throw new error.MastraError(
|
|
1713
|
+
{
|
|
1714
|
+
id: "CLICKHOUSE_STORAGE_LOAD_FAILED",
|
|
1715
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1716
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1717
|
+
details: { tableName }
|
|
1718
|
+
},
|
|
1719
|
+
error$1
|
|
1720
|
+
);
|
|
351
1721
|
}
|
|
352
1722
|
}
|
|
353
|
-
|
|
1723
|
+
};
|
|
1724
|
+
var ScoresStorageClickhouse = class extends storage.ScoresStorage {
|
|
1725
|
+
client;
|
|
1726
|
+
operations;
|
|
1727
|
+
constructor({ client, operations }) {
|
|
1728
|
+
super();
|
|
1729
|
+
this.client = client;
|
|
1730
|
+
this.operations = operations;
|
|
1731
|
+
}
|
|
1732
|
+
transformScoreRow(row) {
|
|
1733
|
+
const scorer = storage.safelyParseJSON(row.scorer);
|
|
1734
|
+
const preprocessStepResult = storage.safelyParseJSON(row.preprocessStepResult);
|
|
1735
|
+
const analyzeStepResult = storage.safelyParseJSON(row.analyzeStepResult);
|
|
1736
|
+
const metadata = storage.safelyParseJSON(row.metadata);
|
|
1737
|
+
const input = storage.safelyParseJSON(row.input);
|
|
1738
|
+
const output = storage.safelyParseJSON(row.output);
|
|
1739
|
+
const additionalContext = storage.safelyParseJSON(row.additionalContext);
|
|
1740
|
+
const runtimeContext = storage.safelyParseJSON(row.runtimeContext);
|
|
1741
|
+
const entity = storage.safelyParseJSON(row.entity);
|
|
1742
|
+
return {
|
|
1743
|
+
...row,
|
|
1744
|
+
scorer,
|
|
1745
|
+
preprocessStepResult,
|
|
1746
|
+
analyzeStepResult,
|
|
1747
|
+
metadata,
|
|
1748
|
+
input,
|
|
1749
|
+
output,
|
|
1750
|
+
additionalContext,
|
|
1751
|
+
runtimeContext,
|
|
1752
|
+
entity,
|
|
1753
|
+
createdAt: new Date(row.createdAt),
|
|
1754
|
+
updatedAt: new Date(row.updatedAt)
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
async getScoreById({ id }) {
|
|
354
1758
|
try {
|
|
355
|
-
const result = await this.
|
|
356
|
-
query: `SELECT
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
title,
|
|
360
|
-
metadata,
|
|
361
|
-
toDateTime64(createdAt, 3) as createdAt,
|
|
362
|
-
toDateTime64(updatedAt, 3) as updatedAt
|
|
363
|
-
FROM "${storage.TABLE_THREADS}"
|
|
364
|
-
FINAL
|
|
365
|
-
WHERE id = {var_id:String}`,
|
|
366
|
-
query_params: { var_id: threadId },
|
|
1759
|
+
const result = await this.client.query({
|
|
1760
|
+
query: `SELECT * FROM ${storage.TABLE_SCORERS} WHERE id = {var_id:String}`,
|
|
1761
|
+
query_params: { var_id: id },
|
|
1762
|
+
format: "JSONEachRow",
|
|
367
1763
|
clickhouse_settings: {
|
|
368
1764
|
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
369
1765
|
date_time_input_format: "best_effort",
|
|
@@ -372,304 +1768,654 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
372
1768
|
output_format_json_quote_64bit_integers: 0
|
|
373
1769
|
}
|
|
374
1770
|
});
|
|
375
|
-
const
|
|
376
|
-
|
|
377
|
-
if (!thread) {
|
|
1771
|
+
const resultJson = await result.json();
|
|
1772
|
+
if (!Array.isArray(resultJson) || resultJson.length === 0) {
|
|
378
1773
|
return null;
|
|
379
1774
|
}
|
|
380
|
-
return
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
1775
|
+
return this.transformScoreRow(resultJson[0]);
|
|
1776
|
+
} catch (error$1) {
|
|
1777
|
+
throw new error.MastraError(
|
|
1778
|
+
{
|
|
1779
|
+
id: "CLICKHOUSE_STORAGE_GET_SCORE_BY_ID_FAILED",
|
|
1780
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1781
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1782
|
+
details: { scoreId: id }
|
|
1783
|
+
},
|
|
1784
|
+
error$1
|
|
1785
|
+
);
|
|
389
1786
|
}
|
|
390
1787
|
}
|
|
391
|
-
async
|
|
1788
|
+
async saveScore(score) {
|
|
1789
|
+
let parsedScore;
|
|
392
1790
|
try {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
1791
|
+
parsedScore = scores.saveScorePayloadSchema.parse(score);
|
|
1792
|
+
} catch (error$1) {
|
|
1793
|
+
throw new error.MastraError(
|
|
1794
|
+
{
|
|
1795
|
+
id: "CLICKHOUSE_STORAGE_SAVE_SCORE_FAILED_INVALID_SCORE_PAYLOAD",
|
|
1796
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1797
|
+
category: error.ErrorCategory.USER,
|
|
1798
|
+
details: { scoreId: score.id }
|
|
1799
|
+
},
|
|
1800
|
+
error$1
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
try {
|
|
1804
|
+
const record = {
|
|
1805
|
+
...parsedScore
|
|
1806
|
+
};
|
|
1807
|
+
await this.client.insert({
|
|
1808
|
+
table: storage.TABLE_SCORERS,
|
|
1809
|
+
values: [record],
|
|
1810
|
+
format: "JSONEachRow",
|
|
404
1811
|
clickhouse_settings: {
|
|
405
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
406
1812
|
date_time_input_format: "best_effort",
|
|
407
|
-
date_time_output_format: "iso",
|
|
408
1813
|
use_client_time_zone: 1,
|
|
409
1814
|
output_format_json_quote_64bit_integers: 0
|
|
410
1815
|
}
|
|
411
1816
|
});
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
1817
|
+
return { score };
|
|
1818
|
+
} catch (error$1) {
|
|
1819
|
+
throw new error.MastraError(
|
|
1820
|
+
{
|
|
1821
|
+
id: "CLICKHOUSE_STORAGE_SAVE_SCORE_FAILED",
|
|
1822
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1823
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1824
|
+
details: { scoreId: score.id }
|
|
1825
|
+
},
|
|
1826
|
+
error$1
|
|
1827
|
+
);
|
|
423
1828
|
}
|
|
424
1829
|
}
|
|
425
|
-
async
|
|
1830
|
+
async getScoresByRunId({
|
|
1831
|
+
runId,
|
|
1832
|
+
pagination
|
|
1833
|
+
}) {
|
|
426
1834
|
try {
|
|
427
|
-
await this.
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
]
|
|
1835
|
+
const countResult = await this.client.query({
|
|
1836
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_SCORERS} WHERE runId = {var_runId:String}`,
|
|
1837
|
+
query_params: { var_runId: runId },
|
|
1838
|
+
format: "JSONEachRow"
|
|
1839
|
+
});
|
|
1840
|
+
const countRows = await countResult.json();
|
|
1841
|
+
let total = 0;
|
|
1842
|
+
if (Array.isArray(countRows) && countRows.length > 0 && countRows[0]) {
|
|
1843
|
+
const countObj = countRows[0];
|
|
1844
|
+
total = Number(countObj.count);
|
|
1845
|
+
}
|
|
1846
|
+
if (!total) {
|
|
1847
|
+
return {
|
|
1848
|
+
pagination: {
|
|
1849
|
+
total: 0,
|
|
1850
|
+
page: pagination.page,
|
|
1851
|
+
perPage: pagination.perPage,
|
|
1852
|
+
hasMore: false
|
|
1853
|
+
},
|
|
1854
|
+
scores: []
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
const offset = pagination.page * pagination.perPage;
|
|
1858
|
+
const result = await this.client.query({
|
|
1859
|
+
query: `SELECT * FROM ${storage.TABLE_SCORERS} WHERE runId = {var_runId:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
|
|
1860
|
+
query_params: {
|
|
1861
|
+
var_runId: runId,
|
|
1862
|
+
var_limit: pagination.perPage,
|
|
1863
|
+
var_offset: offset
|
|
1864
|
+
},
|
|
436
1865
|
format: "JSONEachRow",
|
|
437
1866
|
clickhouse_settings: {
|
|
438
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
439
1867
|
date_time_input_format: "best_effort",
|
|
1868
|
+
date_time_output_format: "iso",
|
|
440
1869
|
use_client_time_zone: 1,
|
|
441
1870
|
output_format_json_quote_64bit_integers: 0
|
|
442
1871
|
}
|
|
443
1872
|
});
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
1873
|
+
const rows = await result.json();
|
|
1874
|
+
const scores = Array.isArray(rows) ? rows.map((row) => this.transformScoreRow(row)) : [];
|
|
1875
|
+
return {
|
|
1876
|
+
pagination: {
|
|
1877
|
+
total,
|
|
1878
|
+
page: pagination.page,
|
|
1879
|
+
perPage: pagination.perPage,
|
|
1880
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
1881
|
+
},
|
|
1882
|
+
scores
|
|
1883
|
+
};
|
|
1884
|
+
} catch (error$1) {
|
|
1885
|
+
throw new error.MastraError(
|
|
1886
|
+
{
|
|
1887
|
+
id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_RUN_ID_FAILED",
|
|
1888
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1889
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1890
|
+
details: { runId }
|
|
1891
|
+
},
|
|
1892
|
+
error$1
|
|
1893
|
+
);
|
|
448
1894
|
}
|
|
449
1895
|
}
|
|
450
|
-
async
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
1896
|
+
async getScoresByScorerId({
|
|
1897
|
+
scorerId,
|
|
1898
|
+
entityId,
|
|
1899
|
+
entityType,
|
|
1900
|
+
source,
|
|
1901
|
+
pagination
|
|
454
1902
|
}) {
|
|
1903
|
+
let whereClause = `scorerId = {var_scorerId:String}`;
|
|
1904
|
+
if (entityId) {
|
|
1905
|
+
whereClause += ` AND entityId = {var_entityId:String}`;
|
|
1906
|
+
}
|
|
1907
|
+
if (entityType) {
|
|
1908
|
+
whereClause += ` AND entityType = {var_entityType:String}`;
|
|
1909
|
+
}
|
|
1910
|
+
if (source) {
|
|
1911
|
+
whereClause += ` AND source = {var_source:String}`;
|
|
1912
|
+
}
|
|
455
1913
|
try {
|
|
456
|
-
const
|
|
457
|
-
|
|
458
|
-
|
|
1914
|
+
const countResult = await this.client.query({
|
|
1915
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_SCORERS} WHERE ${whereClause}`,
|
|
1916
|
+
query_params: {
|
|
1917
|
+
var_scorerId: scorerId,
|
|
1918
|
+
var_entityId: entityId,
|
|
1919
|
+
var_entityType: entityType,
|
|
1920
|
+
var_source: source
|
|
1921
|
+
},
|
|
1922
|
+
format: "JSONEachRow"
|
|
1923
|
+
});
|
|
1924
|
+
const countRows = await countResult.json();
|
|
1925
|
+
let total = 0;
|
|
1926
|
+
if (Array.isArray(countRows) && countRows.length > 0 && countRows[0]) {
|
|
1927
|
+
const countObj = countRows[0];
|
|
1928
|
+
total = Number(countObj.count);
|
|
459
1929
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
1930
|
+
if (!total) {
|
|
1931
|
+
return {
|
|
1932
|
+
pagination: {
|
|
1933
|
+
total: 0,
|
|
1934
|
+
page: pagination.page,
|
|
1935
|
+
perPage: pagination.perPage,
|
|
1936
|
+
hasMore: false
|
|
1937
|
+
},
|
|
1938
|
+
scores: []
|
|
1939
|
+
};
|
|
1940
|
+
}
|
|
1941
|
+
const offset = pagination.page * pagination.perPage;
|
|
1942
|
+
const result = await this.client.query({
|
|
1943
|
+
query: `SELECT * FROM ${storage.TABLE_SCORERS} WHERE ${whereClause} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
|
|
1944
|
+
query_params: {
|
|
1945
|
+
var_scorerId: scorerId,
|
|
1946
|
+
var_limit: pagination.perPage,
|
|
1947
|
+
var_offset: offset,
|
|
1948
|
+
var_entityId: entityId,
|
|
1949
|
+
var_entityType: entityType,
|
|
1950
|
+
var_source: source
|
|
1951
|
+
},
|
|
478
1952
|
format: "JSONEachRow",
|
|
479
1953
|
clickhouse_settings: {
|
|
480
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
481
1954
|
date_time_input_format: "best_effort",
|
|
1955
|
+
date_time_output_format: "iso",
|
|
482
1956
|
use_client_time_zone: 1,
|
|
483
1957
|
output_format_json_quote_64bit_integers: 0
|
|
484
1958
|
}
|
|
485
1959
|
});
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
1960
|
+
const rows = await result.json();
|
|
1961
|
+
const scores = Array.isArray(rows) ? rows.map((row) => this.transformScoreRow(row)) : [];
|
|
1962
|
+
return {
|
|
1963
|
+
pagination: {
|
|
1964
|
+
total,
|
|
1965
|
+
page: pagination.page,
|
|
1966
|
+
perPage: pagination.perPage,
|
|
1967
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
1968
|
+
},
|
|
1969
|
+
scores
|
|
1970
|
+
};
|
|
1971
|
+
} catch (error$1) {
|
|
1972
|
+
throw new error.MastraError(
|
|
1973
|
+
{
|
|
1974
|
+
id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_SCORER_ID_FAILED",
|
|
1975
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1976
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1977
|
+
details: { scorerId }
|
|
1978
|
+
},
|
|
1979
|
+
error$1
|
|
1980
|
+
);
|
|
490
1981
|
}
|
|
491
1982
|
}
|
|
492
|
-
async
|
|
1983
|
+
async getScoresByEntityId({
|
|
1984
|
+
entityId,
|
|
1985
|
+
entityType,
|
|
1986
|
+
pagination
|
|
1987
|
+
}) {
|
|
493
1988
|
try {
|
|
494
|
-
await this.
|
|
495
|
-
query: `
|
|
496
|
-
query_params: {
|
|
497
|
-
|
|
498
|
-
output_format_json_quote_64bit_integers: 0
|
|
499
|
-
}
|
|
1989
|
+
const countResult = await this.client.query({
|
|
1990
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_SCORERS} WHERE entityId = {var_entityId:String} AND entityType = {var_entityType:String}`,
|
|
1991
|
+
query_params: { var_entityId: entityId, var_entityType: entityType },
|
|
1992
|
+
format: "JSONEachRow"
|
|
500
1993
|
});
|
|
501
|
-
await
|
|
502
|
-
|
|
503
|
-
|
|
1994
|
+
const countRows = await countResult.json();
|
|
1995
|
+
let total = 0;
|
|
1996
|
+
if (Array.isArray(countRows) && countRows.length > 0 && countRows[0]) {
|
|
1997
|
+
const countObj = countRows[0];
|
|
1998
|
+
total = Number(countObj.count);
|
|
1999
|
+
}
|
|
2000
|
+
if (!total) {
|
|
2001
|
+
return {
|
|
2002
|
+
pagination: {
|
|
2003
|
+
total: 0,
|
|
2004
|
+
page: pagination.page,
|
|
2005
|
+
perPage: pagination.perPage,
|
|
2006
|
+
hasMore: false
|
|
2007
|
+
},
|
|
2008
|
+
scores: []
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
const offset = pagination.page * pagination.perPage;
|
|
2012
|
+
const result = await this.client.query({
|
|
2013
|
+
query: `SELECT * FROM ${storage.TABLE_SCORERS} WHERE entityId = {var_entityId:String} AND entityType = {var_entityType:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
|
|
2014
|
+
query_params: {
|
|
2015
|
+
var_entityId: entityId,
|
|
2016
|
+
var_entityType: entityType,
|
|
2017
|
+
var_limit: pagination.perPage,
|
|
2018
|
+
var_offset: offset
|
|
2019
|
+
},
|
|
2020
|
+
format: "JSONEachRow",
|
|
504
2021
|
clickhouse_settings: {
|
|
2022
|
+
date_time_input_format: "best_effort",
|
|
2023
|
+
date_time_output_format: "iso",
|
|
2024
|
+
use_client_time_zone: 1,
|
|
505
2025
|
output_format_json_quote_64bit_integers: 0
|
|
506
2026
|
}
|
|
507
2027
|
});
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
2028
|
+
const rows = await result.json();
|
|
2029
|
+
const scores = Array.isArray(rows) ? rows.map((row) => this.transformScoreRow(row)) : [];
|
|
2030
|
+
return {
|
|
2031
|
+
pagination: {
|
|
2032
|
+
total,
|
|
2033
|
+
page: pagination.page,
|
|
2034
|
+
perPage: pagination.perPage,
|
|
2035
|
+
hasMore: total > (pagination.page + 1) * pagination.perPage
|
|
2036
|
+
},
|
|
2037
|
+
scores
|
|
2038
|
+
};
|
|
2039
|
+
} catch (error$1) {
|
|
2040
|
+
throw new error.MastraError(
|
|
2041
|
+
{
|
|
2042
|
+
id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_ENTITY_ID_FAILED",
|
|
2043
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2044
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2045
|
+
details: { entityId, entityType }
|
|
2046
|
+
},
|
|
2047
|
+
error$1
|
|
2048
|
+
);
|
|
511
2049
|
}
|
|
512
2050
|
}
|
|
513
|
-
async
|
|
2051
|
+
async getScoresBySpan({
|
|
2052
|
+
traceId,
|
|
2053
|
+
spanId,
|
|
2054
|
+
pagination
|
|
2055
|
+
}) {
|
|
514
2056
|
try {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
m.updatedAt as updatedAt,
|
|
537
|
-
m.thread_id AS "threadId"
|
|
538
|
-
FROM ordered_messages m
|
|
539
|
-
WHERE m.id = ANY({var_include:Array(String)})
|
|
540
|
-
OR EXISTS (
|
|
541
|
-
SELECT 1 FROM ordered_messages target
|
|
542
|
-
WHERE target.id = ANY({var_include:Array(String)})
|
|
543
|
-
AND (
|
|
544
|
-
-- Get previous messages based on the max withPreviousMessages
|
|
545
|
-
(m.row_num <= target.row_num + {var_withPreviousMessages:Int64} AND m.row_num > target.row_num)
|
|
546
|
-
OR
|
|
547
|
-
-- Get next messages based on the max withNextMessages
|
|
548
|
-
(m.row_num >= target.row_num - {var_withNextMessages:Int64} AND m.row_num < target.row_num)
|
|
549
|
-
)
|
|
550
|
-
)
|
|
551
|
-
ORDER BY m."createdAt" DESC
|
|
552
|
-
`,
|
|
553
|
-
query_params: {
|
|
554
|
-
var_thread_id: threadId,
|
|
555
|
-
var_include: include.map((i) => i.id),
|
|
556
|
-
var_withPreviousMessages: Math.max(...include.map((i) => i.withPreviousMessages || 0)),
|
|
557
|
-
var_withNextMessages: Math.max(...include.map((i) => i.withNextMessages || 0))
|
|
2057
|
+
const countResult = await this.client.query({
|
|
2058
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_SCORERS} WHERE traceId = {var_traceId:String} AND spanId = {var_spanId:String}`,
|
|
2059
|
+
query_params: {
|
|
2060
|
+
var_traceId: traceId,
|
|
2061
|
+
var_spanId: spanId
|
|
2062
|
+
},
|
|
2063
|
+
format: "JSONEachRow"
|
|
2064
|
+
});
|
|
2065
|
+
const countRows = await countResult.json();
|
|
2066
|
+
let total = 0;
|
|
2067
|
+
if (Array.isArray(countRows) && countRows.length > 0 && countRows[0]) {
|
|
2068
|
+
const countObj = countRows[0];
|
|
2069
|
+
total = Number(countObj.count);
|
|
2070
|
+
}
|
|
2071
|
+
if (!total) {
|
|
2072
|
+
return {
|
|
2073
|
+
pagination: {
|
|
2074
|
+
total: 0,
|
|
2075
|
+
page: pagination.page,
|
|
2076
|
+
perPage: pagination.perPage,
|
|
2077
|
+
hasMore: false
|
|
558
2078
|
},
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
date_time_input_format: "best_effort",
|
|
562
|
-
date_time_output_format: "iso",
|
|
563
|
-
use_client_time_zone: 1,
|
|
564
|
-
output_format_json_quote_64bit_integers: 0
|
|
565
|
-
}
|
|
566
|
-
});
|
|
567
|
-
const rows2 = await includeResult.json();
|
|
568
|
-
messages.push(...transformRows(rows2.data));
|
|
2079
|
+
scores: []
|
|
2080
|
+
};
|
|
569
2081
|
}
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
content,
|
|
575
|
-
role,
|
|
576
|
-
type,
|
|
577
|
-
toDateTime64(createdAt, 3) as createdAt,
|
|
578
|
-
thread_id AS "threadId"
|
|
579
|
-
FROM "${storage.TABLE_MESSAGES}"
|
|
580
|
-
WHERE thread_id = {threadId:String}
|
|
581
|
-
AND id NOT IN ({exclude:Array(String)})
|
|
582
|
-
ORDER BY "createdAt" DESC
|
|
583
|
-
LIMIT {limit:Int64}
|
|
584
|
-
`,
|
|
2082
|
+
const limit = pagination.perPage + 1;
|
|
2083
|
+
const offset = pagination.page * pagination.perPage;
|
|
2084
|
+
const result = await this.client.query({
|
|
2085
|
+
query: `SELECT * FROM ${storage.TABLE_SCORERS} WHERE traceId = {var_traceId:String} AND spanId = {var_spanId:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
|
|
585
2086
|
query_params: {
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
limit
|
|
2087
|
+
var_traceId: traceId,
|
|
2088
|
+
var_spanId: spanId,
|
|
2089
|
+
var_limit: limit,
|
|
2090
|
+
var_offset: offset
|
|
589
2091
|
},
|
|
2092
|
+
format: "JSONEachRow",
|
|
2093
|
+
clickhouse_settings: {
|
|
2094
|
+
date_time_input_format: "best_effort",
|
|
2095
|
+
date_time_output_format: "iso",
|
|
2096
|
+
use_client_time_zone: 1,
|
|
2097
|
+
output_format_json_quote_64bit_integers: 0
|
|
2098
|
+
}
|
|
2099
|
+
});
|
|
2100
|
+
const rows = await result.json();
|
|
2101
|
+
const transformedRows = Array.isArray(rows) ? rows.map((row) => this.transformScoreRow(row)) : [];
|
|
2102
|
+
const hasMore = transformedRows.length > pagination.perPage;
|
|
2103
|
+
const scores = hasMore ? transformedRows.slice(0, pagination.perPage) : transformedRows;
|
|
2104
|
+
return {
|
|
2105
|
+
pagination: {
|
|
2106
|
+
total,
|
|
2107
|
+
page: pagination.page,
|
|
2108
|
+
perPage: pagination.perPage,
|
|
2109
|
+
hasMore
|
|
2110
|
+
},
|
|
2111
|
+
scores
|
|
2112
|
+
};
|
|
2113
|
+
} catch (error$1) {
|
|
2114
|
+
throw new error.MastraError(
|
|
2115
|
+
{
|
|
2116
|
+
id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_SPAN_FAILED",
|
|
2117
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2118
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2119
|
+
details: { traceId, spanId }
|
|
2120
|
+
},
|
|
2121
|
+
error$1
|
|
2122
|
+
);
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
};
|
|
2126
|
+
var TracesStorageClickhouse = class extends storage.TracesStorage {
|
|
2127
|
+
client;
|
|
2128
|
+
operations;
|
|
2129
|
+
constructor({ client, operations }) {
|
|
2130
|
+
super();
|
|
2131
|
+
this.client = client;
|
|
2132
|
+
this.operations = operations;
|
|
2133
|
+
}
|
|
2134
|
+
async getTracesPaginated(args) {
|
|
2135
|
+
const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
|
|
2136
|
+
const fromDate = dateRange?.start;
|
|
2137
|
+
const toDate = dateRange?.end;
|
|
2138
|
+
const currentOffset = page * perPage;
|
|
2139
|
+
const queryArgs = {};
|
|
2140
|
+
const conditions = [];
|
|
2141
|
+
if (name) {
|
|
2142
|
+
conditions.push(`name LIKE CONCAT({var_name:String}, '%')`);
|
|
2143
|
+
queryArgs.var_name = name;
|
|
2144
|
+
}
|
|
2145
|
+
if (scope) {
|
|
2146
|
+
conditions.push(`scope = {var_scope:String}`);
|
|
2147
|
+
queryArgs.var_scope = scope;
|
|
2148
|
+
}
|
|
2149
|
+
if (attributes) {
|
|
2150
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
2151
|
+
conditions.push(`JSONExtractString(attributes, '${key}') = {var_attr_${key}:String}`);
|
|
2152
|
+
queryArgs[`var_attr_${key}`] = value;
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
if (filters) {
|
|
2156
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
2157
|
+
conditions.push(`${key} = {var_col_${key}:${storage.TABLE_SCHEMAS.mastra_traces?.[key]?.type ?? "text"}}`);
|
|
2158
|
+
queryArgs[`var_col_${key}`] = value;
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
if (fromDate) {
|
|
2162
|
+
conditions.push(`createdAt >= parseDateTime64BestEffort({var_from_date:String})`);
|
|
2163
|
+
queryArgs.var_from_date = fromDate.toISOString();
|
|
2164
|
+
}
|
|
2165
|
+
if (toDate) {
|
|
2166
|
+
conditions.push(`createdAt <= parseDateTime64BestEffort({var_to_date:String})`);
|
|
2167
|
+
queryArgs.var_to_date = toDate.toISOString();
|
|
2168
|
+
}
|
|
2169
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
2170
|
+
try {
|
|
2171
|
+
const countResult = await this.client.query({
|
|
2172
|
+
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_TRACES} ${whereClause}`,
|
|
2173
|
+
query_params: queryArgs,
|
|
590
2174
|
clickhouse_settings: {
|
|
591
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
592
2175
|
date_time_input_format: "best_effort",
|
|
593
2176
|
date_time_output_format: "iso",
|
|
594
2177
|
use_client_time_zone: 1,
|
|
595
2178
|
output_format_json_quote_64bit_integers: 0
|
|
596
2179
|
}
|
|
597
2180
|
});
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
2181
|
+
const countData = await countResult.json();
|
|
2182
|
+
const total = Number(countData.data?.[0]?.count ?? 0);
|
|
2183
|
+
if (total === 0) {
|
|
2184
|
+
return {
|
|
2185
|
+
traces: [],
|
|
2186
|
+
total: 0,
|
|
2187
|
+
page,
|
|
2188
|
+
perPage,
|
|
2189
|
+
hasMore: false
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
const result = await this.client.query({
|
|
2193
|
+
query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${storage.TABLE_TRACES} ${whereClause} ORDER BY "createdAt" DESC LIMIT {var_limit:UInt32} OFFSET {var_offset:UInt32}`,
|
|
2194
|
+
query_params: { ...queryArgs, var_limit: perPage, var_offset: currentOffset },
|
|
2195
|
+
clickhouse_settings: {
|
|
2196
|
+
date_time_input_format: "best_effort",
|
|
2197
|
+
date_time_output_format: "iso",
|
|
2198
|
+
use_client_time_zone: 1,
|
|
2199
|
+
output_format_json_quote_64bit_integers: 0
|
|
607
2200
|
}
|
|
608
2201
|
});
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
2202
|
+
if (!result) {
|
|
2203
|
+
return {
|
|
2204
|
+
traces: [],
|
|
2205
|
+
total,
|
|
2206
|
+
page,
|
|
2207
|
+
perPage,
|
|
2208
|
+
hasMore: false
|
|
2209
|
+
};
|
|
2210
|
+
}
|
|
2211
|
+
const resp = await result.json();
|
|
2212
|
+
const rows = resp.data;
|
|
2213
|
+
const traces = rows.map((row) => ({
|
|
2214
|
+
id: row.id,
|
|
2215
|
+
parentSpanId: row.parentSpanId,
|
|
2216
|
+
traceId: row.traceId,
|
|
2217
|
+
name: row.name,
|
|
2218
|
+
scope: row.scope,
|
|
2219
|
+
kind: row.kind,
|
|
2220
|
+
status: storage.safelyParseJSON(row.status),
|
|
2221
|
+
events: storage.safelyParseJSON(row.events),
|
|
2222
|
+
links: storage.safelyParseJSON(row.links),
|
|
2223
|
+
attributes: storage.safelyParseJSON(row.attributes),
|
|
2224
|
+
startTime: row.startTime,
|
|
2225
|
+
endTime: row.endTime,
|
|
2226
|
+
other: storage.safelyParseJSON(row.other),
|
|
2227
|
+
createdAt: row.createdAt
|
|
2228
|
+
}));
|
|
2229
|
+
return {
|
|
2230
|
+
traces,
|
|
2231
|
+
total,
|
|
2232
|
+
page,
|
|
2233
|
+
perPage,
|
|
2234
|
+
hasMore: currentOffset + traces.length < total
|
|
2235
|
+
};
|
|
2236
|
+
} catch (error$1) {
|
|
2237
|
+
if (error$1?.message?.includes("no such table") || error$1?.message?.includes("does not exist")) {
|
|
2238
|
+
return {
|
|
2239
|
+
traces: [],
|
|
2240
|
+
total: 0,
|
|
2241
|
+
page,
|
|
2242
|
+
perPage,
|
|
2243
|
+
hasMore: false
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
throw new error.MastraError(
|
|
2247
|
+
{
|
|
2248
|
+
id: "CLICKHOUSE_STORAGE_GET_TRACES_PAGINATED_FAILED",
|
|
2249
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2250
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2251
|
+
details: {
|
|
2252
|
+
name: name ?? null,
|
|
2253
|
+
scope: scope ?? null,
|
|
2254
|
+
page,
|
|
2255
|
+
perPage,
|
|
2256
|
+
attributes: attributes ? JSON.stringify(attributes) : null,
|
|
2257
|
+
filters: filters ? JSON.stringify(filters) : null,
|
|
2258
|
+
dateRange: dateRange ? JSON.stringify(dateRange) : null
|
|
2259
|
+
}
|
|
2260
|
+
},
|
|
2261
|
+
error$1
|
|
2262
|
+
);
|
|
613
2263
|
}
|
|
614
2264
|
}
|
|
615
|
-
async
|
|
616
|
-
|
|
2265
|
+
async getTraces({
|
|
2266
|
+
name,
|
|
2267
|
+
scope,
|
|
2268
|
+
page,
|
|
2269
|
+
perPage,
|
|
2270
|
+
attributes,
|
|
2271
|
+
filters,
|
|
2272
|
+
fromDate,
|
|
2273
|
+
toDate
|
|
2274
|
+
}) {
|
|
2275
|
+
const limit = perPage;
|
|
2276
|
+
const offset = page * perPage;
|
|
2277
|
+
const args = {};
|
|
2278
|
+
const conditions = [];
|
|
2279
|
+
if (name) {
|
|
2280
|
+
conditions.push(`name LIKE CONCAT({var_name:String}, '%')`);
|
|
2281
|
+
args.var_name = name;
|
|
2282
|
+
}
|
|
2283
|
+
if (scope) {
|
|
2284
|
+
conditions.push(`scope = {var_scope:String}`);
|
|
2285
|
+
args.var_scope = scope;
|
|
2286
|
+
}
|
|
2287
|
+
if (attributes) {
|
|
2288
|
+
Object.entries(attributes).forEach(([key, value]) => {
|
|
2289
|
+
conditions.push(`JSONExtractString(attributes, '${key}') = {var_attr_${key}:String}`);
|
|
2290
|
+
args[`var_attr_${key}`] = value;
|
|
2291
|
+
});
|
|
2292
|
+
}
|
|
2293
|
+
if (filters) {
|
|
2294
|
+
Object.entries(filters).forEach(([key, value]) => {
|
|
2295
|
+
conditions.push(`${key} = {var_col_${key}:${storage.TABLE_SCHEMAS.mastra_traces?.[key]?.type ?? "text"}}`);
|
|
2296
|
+
args[`var_col_${key}`] = value;
|
|
2297
|
+
});
|
|
2298
|
+
}
|
|
2299
|
+
if (fromDate) {
|
|
2300
|
+
conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
|
|
2301
|
+
args.var_from_date = fromDate.getTime() / 1e3;
|
|
2302
|
+
}
|
|
2303
|
+
if (toDate) {
|
|
2304
|
+
conditions.push(`createdAt <= {var_to_date:DateTime64(3)}`);
|
|
2305
|
+
args.var_to_date = toDate.getTime() / 1e3;
|
|
2306
|
+
}
|
|
2307
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
617
2308
|
try {
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
}
|
|
622
|
-
const thread = await this.getThreadById({ threadId });
|
|
623
|
-
if (!thread) {
|
|
624
|
-
throw new Error(`Thread ${threadId} not found`);
|
|
625
|
-
}
|
|
626
|
-
await this.db.insert({
|
|
627
|
-
table: storage.TABLE_MESSAGES,
|
|
628
|
-
format: "JSONEachRow",
|
|
629
|
-
values: messages.map((message) => ({
|
|
630
|
-
id: message.id,
|
|
631
|
-
thread_id: threadId,
|
|
632
|
-
content: typeof message.content === "string" ? message.content : JSON.stringify(message.content),
|
|
633
|
-
createdAt: message.createdAt.toISOString(),
|
|
634
|
-
role: message.role,
|
|
635
|
-
type: message.type
|
|
636
|
-
})),
|
|
2309
|
+
const result = await this.client.query({
|
|
2310
|
+
query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${storage.TABLE_TRACES} ${whereClause} ORDER BY "createdAt" DESC LIMIT ${limit} OFFSET ${offset}`,
|
|
2311
|
+
query_params: args,
|
|
637
2312
|
clickhouse_settings: {
|
|
638
2313
|
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
639
2314
|
date_time_input_format: "best_effort",
|
|
2315
|
+
date_time_output_format: "iso",
|
|
640
2316
|
use_client_time_zone: 1,
|
|
641
2317
|
output_format_json_quote_64bit_integers: 0
|
|
642
2318
|
}
|
|
643
2319
|
});
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
2320
|
+
if (!result) {
|
|
2321
|
+
return [];
|
|
2322
|
+
}
|
|
2323
|
+
const resp = await result.json();
|
|
2324
|
+
const rows = resp.data;
|
|
2325
|
+
return rows.map((row) => ({
|
|
2326
|
+
id: row.id,
|
|
2327
|
+
parentSpanId: row.parentSpanId,
|
|
2328
|
+
traceId: row.traceId,
|
|
2329
|
+
name: row.name,
|
|
2330
|
+
scope: row.scope,
|
|
2331
|
+
kind: row.kind,
|
|
2332
|
+
status: storage.safelyParseJSON(row.status),
|
|
2333
|
+
events: storage.safelyParseJSON(row.events),
|
|
2334
|
+
links: storage.safelyParseJSON(row.links),
|
|
2335
|
+
attributes: storage.safelyParseJSON(row.attributes),
|
|
2336
|
+
startTime: row.startTime,
|
|
2337
|
+
endTime: row.endTime,
|
|
2338
|
+
other: storage.safelyParseJSON(row.other),
|
|
2339
|
+
createdAt: row.createdAt
|
|
2340
|
+
}));
|
|
2341
|
+
} catch (error$1) {
|
|
2342
|
+
if (error$1?.message?.includes("no such table") || error$1?.message?.includes("does not exist")) {
|
|
2343
|
+
return [];
|
|
2344
|
+
}
|
|
2345
|
+
throw new error.MastraError(
|
|
2346
|
+
{
|
|
2347
|
+
id: "CLICKHOUSE_STORAGE_GET_TRACES_FAILED",
|
|
2348
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2349
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2350
|
+
details: {
|
|
2351
|
+
name: name ?? null,
|
|
2352
|
+
scope: scope ?? null,
|
|
2353
|
+
page,
|
|
2354
|
+
perPage,
|
|
2355
|
+
attributes: attributes ? JSON.stringify(attributes) : null,
|
|
2356
|
+
filters: filters ? JSON.stringify(filters) : null,
|
|
2357
|
+
fromDate: fromDate?.toISOString() ?? null,
|
|
2358
|
+
toDate: toDate?.toISOString() ?? null
|
|
2359
|
+
}
|
|
2360
|
+
},
|
|
2361
|
+
error$1
|
|
2362
|
+
);
|
|
648
2363
|
}
|
|
649
2364
|
}
|
|
2365
|
+
async batchTraceInsert(args) {
|
|
2366
|
+
await this.operations.batchInsert({ tableName: storage.TABLE_TRACES, records: args.records });
|
|
2367
|
+
}
|
|
2368
|
+
};
|
|
2369
|
+
var WorkflowsStorageClickhouse = class extends storage.WorkflowsStorage {
|
|
2370
|
+
client;
|
|
2371
|
+
operations;
|
|
2372
|
+
constructor({ client, operations }) {
|
|
2373
|
+
super();
|
|
2374
|
+
this.operations = operations;
|
|
2375
|
+
this.client = client;
|
|
2376
|
+
}
|
|
2377
|
+
updateWorkflowResults({
|
|
2378
|
+
// workflowName,
|
|
2379
|
+
// runId,
|
|
2380
|
+
// stepId,
|
|
2381
|
+
// result,
|
|
2382
|
+
// runtimeContext,
|
|
2383
|
+
}) {
|
|
2384
|
+
throw new Error("Method not implemented.");
|
|
2385
|
+
}
|
|
2386
|
+
updateWorkflowState({
|
|
2387
|
+
// workflowName,
|
|
2388
|
+
// runId,
|
|
2389
|
+
// opts,
|
|
2390
|
+
}) {
|
|
2391
|
+
throw new Error("Method not implemented.");
|
|
2392
|
+
}
|
|
650
2393
|
async persistWorkflowSnapshot({
|
|
651
2394
|
workflowName,
|
|
652
2395
|
runId,
|
|
2396
|
+
resourceId,
|
|
653
2397
|
snapshot
|
|
654
2398
|
}) {
|
|
655
2399
|
try {
|
|
656
|
-
const currentSnapshot = await this.load({
|
|
2400
|
+
const currentSnapshot = await this.operations.load({
|
|
657
2401
|
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
658
2402
|
keys: { workflow_name: workflowName, run_id: runId }
|
|
659
2403
|
});
|
|
660
2404
|
const now = /* @__PURE__ */ new Date();
|
|
661
2405
|
const persisting = currentSnapshot ? {
|
|
662
2406
|
...currentSnapshot,
|
|
2407
|
+
resourceId,
|
|
663
2408
|
snapshot: JSON.stringify(snapshot),
|
|
664
2409
|
updatedAt: now.toISOString()
|
|
665
2410
|
} : {
|
|
666
2411
|
workflow_name: workflowName,
|
|
667
2412
|
run_id: runId,
|
|
2413
|
+
resourceId,
|
|
668
2414
|
snapshot: JSON.stringify(snapshot),
|
|
669
2415
|
createdAt: now.toISOString(),
|
|
670
2416
|
updatedAt: now.toISOString()
|
|
671
2417
|
};
|
|
672
|
-
await this.
|
|
2418
|
+
await this.client.insert({
|
|
673
2419
|
table: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
674
2420
|
format: "JSONEachRow",
|
|
675
2421
|
values: [persisting],
|
|
@@ -680,9 +2426,16 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
680
2426
|
output_format_json_quote_64bit_integers: 0
|
|
681
2427
|
}
|
|
682
2428
|
});
|
|
683
|
-
} catch (error) {
|
|
684
|
-
|
|
685
|
-
|
|
2429
|
+
} catch (error$1) {
|
|
2430
|
+
throw new error.MastraError(
|
|
2431
|
+
{
|
|
2432
|
+
id: "CLICKHOUSE_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
|
|
2433
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2434
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2435
|
+
details: { workflowName, runId }
|
|
2436
|
+
},
|
|
2437
|
+
error$1
|
|
2438
|
+
);
|
|
686
2439
|
}
|
|
687
2440
|
}
|
|
688
2441
|
async loadWorkflowSnapshot({
|
|
@@ -690,7 +2443,7 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
690
2443
|
runId
|
|
691
2444
|
}) {
|
|
692
2445
|
try {
|
|
693
|
-
const result = await this.load({
|
|
2446
|
+
const result = await this.operations.load({
|
|
694
2447
|
tableName: storage.TABLE_WORKFLOW_SNAPSHOT,
|
|
695
2448
|
keys: {
|
|
696
2449
|
workflow_name: workflowName,
|
|
@@ -701,9 +2454,16 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
701
2454
|
return null;
|
|
702
2455
|
}
|
|
703
2456
|
return result.snapshot;
|
|
704
|
-
} catch (error) {
|
|
705
|
-
|
|
706
|
-
|
|
2457
|
+
} catch (error$1) {
|
|
2458
|
+
throw new error.MastraError(
|
|
2459
|
+
{
|
|
2460
|
+
id: "CLICKHOUSE_STORAGE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
|
|
2461
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2462
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2463
|
+
details: { workflowName, runId }
|
|
2464
|
+
},
|
|
2465
|
+
error$1
|
|
2466
|
+
);
|
|
707
2467
|
}
|
|
708
2468
|
}
|
|
709
2469
|
parseWorkflowRun(row) {
|
|
@@ -740,7 +2500,7 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
740
2500
|
values.var_workflow_name = workflowName;
|
|
741
2501
|
}
|
|
742
2502
|
if (resourceId) {
|
|
743
|
-
const hasResourceId = await this.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
|
|
2503
|
+
const hasResourceId = await this.operations.hasColumn(storage.TABLE_WORKFLOW_SNAPSHOT, "resourceId");
|
|
744
2504
|
if (hasResourceId) {
|
|
745
2505
|
conditions.push(`resourceId = {var_resourceId:String}`);
|
|
746
2506
|
values.var_resourceId = resourceId;
|
|
@@ -761,7 +2521,7 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
761
2521
|
const offsetClause = offset !== void 0 ? `OFFSET ${offset}` : "";
|
|
762
2522
|
let total = 0;
|
|
763
2523
|
if (limit !== void 0 && offset !== void 0) {
|
|
764
|
-
const countResult = await this.
|
|
2524
|
+
const countResult = await this.client.query({
|
|
765
2525
|
query: `SELECT COUNT(*) as count FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[storage.TABLE_WORKFLOW_SNAPSHOT].startsWith("ReplacingMergeTree") ? "FINAL" : ""} ${whereClause}`,
|
|
766
2526
|
query_params: values,
|
|
767
2527
|
format: "JSONEachRow"
|
|
@@ -769,21 +2529,21 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
769
2529
|
const countRows = await countResult.json();
|
|
770
2530
|
total = Number(countRows[0]?.count ?? 0);
|
|
771
2531
|
}
|
|
772
|
-
const result = await this.
|
|
2532
|
+
const result = await this.client.query({
|
|
773
2533
|
query: `
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
2534
|
+
SELECT
|
|
2535
|
+
workflow_name,
|
|
2536
|
+
run_id,
|
|
2537
|
+
snapshot,
|
|
2538
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
2539
|
+
toDateTime64(updatedAt, 3) as updatedAt,
|
|
2540
|
+
resourceId
|
|
2541
|
+
FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[storage.TABLE_WORKFLOW_SNAPSHOT].startsWith("ReplacingMergeTree") ? "FINAL" : ""}
|
|
2542
|
+
${whereClause}
|
|
2543
|
+
ORDER BY createdAt DESC
|
|
2544
|
+
${limitClause}
|
|
2545
|
+
${offsetClause}
|
|
2546
|
+
`,
|
|
787
2547
|
query_params: values,
|
|
788
2548
|
format: "JSONEachRow"
|
|
789
2549
|
});
|
|
@@ -793,9 +2553,16 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
793
2553
|
return this.parseWorkflowRun(row);
|
|
794
2554
|
});
|
|
795
2555
|
return { runs, total: total || runs.length };
|
|
796
|
-
} catch (error) {
|
|
797
|
-
|
|
798
|
-
|
|
2556
|
+
} catch (error$1) {
|
|
2557
|
+
throw new error.MastraError(
|
|
2558
|
+
{
|
|
2559
|
+
id: "CLICKHOUSE_STORAGE_GET_WORKFLOW_RUNS_FAILED",
|
|
2560
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2561
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2562
|
+
details: { workflowName: workflowName ?? "", resourceId: resourceId ?? "" }
|
|
2563
|
+
},
|
|
2564
|
+
error$1
|
|
2565
|
+
);
|
|
799
2566
|
}
|
|
800
2567
|
}
|
|
801
2568
|
async getWorkflowRunById({
|
|
@@ -814,18 +2581,19 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
814
2581
|
values.var_workflow_name = workflowName;
|
|
815
2582
|
}
|
|
816
2583
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
817
|
-
const result = await this.
|
|
2584
|
+
const result = await this.client.query({
|
|
818
2585
|
query: `
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
2586
|
+
SELECT
|
|
2587
|
+
workflow_name,
|
|
2588
|
+
run_id,
|
|
2589
|
+
snapshot,
|
|
2590
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
2591
|
+
toDateTime64(updatedAt, 3) as updatedAt,
|
|
2592
|
+
resourceId
|
|
2593
|
+
FROM ${storage.TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[storage.TABLE_WORKFLOW_SNAPSHOT].startsWith("ReplacingMergeTree") ? "FINAL" : ""}
|
|
2594
|
+
${whereClause}
|
|
2595
|
+
ORDER BY createdAt DESC LIMIT 1
|
|
2596
|
+
`,
|
|
829
2597
|
query_params: values,
|
|
830
2598
|
format: "JSONEachRow"
|
|
831
2599
|
});
|
|
@@ -834,18 +2602,280 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
834
2602
|
return null;
|
|
835
2603
|
}
|
|
836
2604
|
return this.parseWorkflowRun(resultJson[0]);
|
|
837
|
-
} catch (error) {
|
|
838
|
-
|
|
839
|
-
|
|
2605
|
+
} catch (error$1) {
|
|
2606
|
+
throw new error.MastraError(
|
|
2607
|
+
{
|
|
2608
|
+
id: "CLICKHOUSE_STORAGE_GET_WORKFLOW_RUN_BY_ID_FAILED",
|
|
2609
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2610
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2611
|
+
details: { runId: runId ?? "", workflowName: workflowName ?? "" }
|
|
2612
|
+
},
|
|
2613
|
+
error$1
|
|
2614
|
+
);
|
|
840
2615
|
}
|
|
841
2616
|
}
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
2617
|
+
};
|
|
2618
|
+
|
|
2619
|
+
// src/storage/index.ts
|
|
2620
|
+
var ClickhouseStore = class extends storage.MastraStorage {
|
|
2621
|
+
db;
|
|
2622
|
+
ttl = {};
|
|
2623
|
+
stores;
|
|
2624
|
+
constructor(config) {
|
|
2625
|
+
super({ name: "ClickhouseStore" });
|
|
2626
|
+
this.db = client.createClient({
|
|
2627
|
+
url: config.url,
|
|
2628
|
+
username: config.username,
|
|
2629
|
+
password: config.password,
|
|
2630
|
+
clickhouse_settings: {
|
|
2631
|
+
date_time_input_format: "best_effort",
|
|
2632
|
+
date_time_output_format: "iso",
|
|
2633
|
+
// This is crucial
|
|
2634
|
+
use_client_time_zone: 1,
|
|
2635
|
+
output_format_json_quote_64bit_integers: 0
|
|
2636
|
+
}
|
|
846
2637
|
});
|
|
847
|
-
|
|
848
|
-
|
|
2638
|
+
this.ttl = config.ttl;
|
|
2639
|
+
const operations = new StoreOperationsClickhouse({ client: this.db, ttl: this.ttl });
|
|
2640
|
+
const workflows = new WorkflowsStorageClickhouse({ client: this.db, operations });
|
|
2641
|
+
const scores = new ScoresStorageClickhouse({ client: this.db, operations });
|
|
2642
|
+
const legacyEvals = new LegacyEvalsStorageClickhouse({ client: this.db, operations });
|
|
2643
|
+
const traces = new TracesStorageClickhouse({ client: this.db, operations });
|
|
2644
|
+
const memory = new MemoryStorageClickhouse({ client: this.db, operations });
|
|
2645
|
+
this.stores = {
|
|
2646
|
+
operations,
|
|
2647
|
+
workflows,
|
|
2648
|
+
scores,
|
|
2649
|
+
legacyEvals,
|
|
2650
|
+
traces,
|
|
2651
|
+
memory
|
|
2652
|
+
};
|
|
2653
|
+
}
|
|
2654
|
+
get supports() {
|
|
2655
|
+
return {
|
|
2656
|
+
selectByIncludeResourceScope: true,
|
|
2657
|
+
resourceWorkingMemory: true,
|
|
2658
|
+
hasColumn: true,
|
|
2659
|
+
createTable: true,
|
|
2660
|
+
deleteMessages: false,
|
|
2661
|
+
getScoresBySpan: true
|
|
2662
|
+
};
|
|
2663
|
+
}
|
|
2664
|
+
async getEvalsByAgentName(agentName, type) {
|
|
2665
|
+
return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
|
|
2666
|
+
}
|
|
2667
|
+
async getEvals(options) {
|
|
2668
|
+
return this.stores.legacyEvals.getEvals(options);
|
|
2669
|
+
}
|
|
2670
|
+
async batchInsert({ tableName, records }) {
|
|
2671
|
+
await this.stores.operations.batchInsert({ tableName, records });
|
|
2672
|
+
}
|
|
2673
|
+
async optimizeTable({ tableName }) {
|
|
2674
|
+
try {
|
|
2675
|
+
await this.db.command({
|
|
2676
|
+
query: `OPTIMIZE TABLE ${tableName} FINAL`
|
|
2677
|
+
});
|
|
2678
|
+
} catch (error$1) {
|
|
2679
|
+
throw new error.MastraError(
|
|
2680
|
+
{
|
|
2681
|
+
id: "CLICKHOUSE_STORAGE_OPTIMIZE_TABLE_FAILED",
|
|
2682
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2683
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2684
|
+
details: { tableName }
|
|
2685
|
+
},
|
|
2686
|
+
error$1
|
|
2687
|
+
);
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
async materializeTtl({ tableName }) {
|
|
2691
|
+
try {
|
|
2692
|
+
await this.db.command({
|
|
2693
|
+
query: `ALTER TABLE ${tableName} MATERIALIZE TTL;`
|
|
2694
|
+
});
|
|
2695
|
+
} catch (error$1) {
|
|
2696
|
+
throw new error.MastraError(
|
|
2697
|
+
{
|
|
2698
|
+
id: "CLICKHOUSE_STORAGE_MATERIALIZE_TTL_FAILED",
|
|
2699
|
+
domain: error.ErrorDomain.STORAGE,
|
|
2700
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
2701
|
+
details: { tableName }
|
|
2702
|
+
},
|
|
2703
|
+
error$1
|
|
2704
|
+
);
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2707
|
+
async createTable({
|
|
2708
|
+
tableName,
|
|
2709
|
+
schema
|
|
2710
|
+
}) {
|
|
2711
|
+
return this.stores.operations.createTable({ tableName, schema });
|
|
2712
|
+
}
|
|
2713
|
+
async dropTable({ tableName }) {
|
|
2714
|
+
return this.stores.operations.dropTable({ tableName });
|
|
2715
|
+
}
|
|
2716
|
+
async alterTable({
|
|
2717
|
+
tableName,
|
|
2718
|
+
schema,
|
|
2719
|
+
ifNotExists
|
|
2720
|
+
}) {
|
|
2721
|
+
return this.stores.operations.alterTable({ tableName, schema, ifNotExists });
|
|
2722
|
+
}
|
|
2723
|
+
async clearTable({ tableName }) {
|
|
2724
|
+
return this.stores.operations.clearTable({ tableName });
|
|
2725
|
+
}
|
|
2726
|
+
async insert({ tableName, record }) {
|
|
2727
|
+
return this.stores.operations.insert({ tableName, record });
|
|
2728
|
+
}
|
|
2729
|
+
async load({ tableName, keys }) {
|
|
2730
|
+
return this.stores.operations.load({ tableName, keys });
|
|
2731
|
+
}
|
|
2732
|
+
async updateWorkflowResults({
|
|
2733
|
+
workflowName,
|
|
2734
|
+
runId,
|
|
2735
|
+
stepId,
|
|
2736
|
+
result,
|
|
2737
|
+
runtimeContext
|
|
2738
|
+
}) {
|
|
2739
|
+
return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
|
|
2740
|
+
}
|
|
2741
|
+
async updateWorkflowState({
|
|
2742
|
+
workflowName,
|
|
2743
|
+
runId,
|
|
2744
|
+
opts
|
|
2745
|
+
}) {
|
|
2746
|
+
return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
|
|
2747
|
+
}
|
|
2748
|
+
async persistWorkflowSnapshot({
|
|
2749
|
+
workflowName,
|
|
2750
|
+
runId,
|
|
2751
|
+
resourceId,
|
|
2752
|
+
snapshot
|
|
2753
|
+
}) {
|
|
2754
|
+
return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, resourceId, snapshot });
|
|
2755
|
+
}
|
|
2756
|
+
async loadWorkflowSnapshot({
|
|
2757
|
+
workflowName,
|
|
2758
|
+
runId
|
|
2759
|
+
}) {
|
|
2760
|
+
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
2761
|
+
}
|
|
2762
|
+
async getWorkflowRuns({
|
|
2763
|
+
workflowName,
|
|
2764
|
+
fromDate,
|
|
2765
|
+
toDate,
|
|
2766
|
+
limit,
|
|
2767
|
+
offset,
|
|
2768
|
+
resourceId
|
|
2769
|
+
} = {}) {
|
|
2770
|
+
return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
|
|
2771
|
+
}
|
|
2772
|
+
async getWorkflowRunById({
|
|
2773
|
+
runId,
|
|
2774
|
+
workflowName
|
|
2775
|
+
}) {
|
|
2776
|
+
return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
|
|
2777
|
+
}
|
|
2778
|
+
async getTraces(args) {
|
|
2779
|
+
return this.stores.traces.getTraces(args);
|
|
2780
|
+
}
|
|
2781
|
+
async getTracesPaginated(args) {
|
|
2782
|
+
return this.stores.traces.getTracesPaginated(args);
|
|
2783
|
+
}
|
|
2784
|
+
async batchTraceInsert(args) {
|
|
2785
|
+
return this.stores.traces.batchTraceInsert(args);
|
|
2786
|
+
}
|
|
2787
|
+
async getThreadById({ threadId }) {
|
|
2788
|
+
return this.stores.memory.getThreadById({ threadId });
|
|
2789
|
+
}
|
|
2790
|
+
async getThreadsByResourceId({ resourceId }) {
|
|
2791
|
+
return this.stores.memory.getThreadsByResourceId({ resourceId });
|
|
2792
|
+
}
|
|
2793
|
+
async saveThread({ thread }) {
|
|
2794
|
+
return this.stores.memory.saveThread({ thread });
|
|
2795
|
+
}
|
|
2796
|
+
async updateThread({
|
|
2797
|
+
id,
|
|
2798
|
+
title,
|
|
2799
|
+
metadata
|
|
2800
|
+
}) {
|
|
2801
|
+
return this.stores.memory.updateThread({ id, title, metadata });
|
|
2802
|
+
}
|
|
2803
|
+
async deleteThread({ threadId }) {
|
|
2804
|
+
return this.stores.memory.deleteThread({ threadId });
|
|
2805
|
+
}
|
|
2806
|
+
async getThreadsByResourceIdPaginated(args) {
|
|
2807
|
+
return this.stores.memory.getThreadsByResourceIdPaginated(args);
|
|
2808
|
+
}
|
|
2809
|
+
async getMessages({
|
|
2810
|
+
threadId,
|
|
2811
|
+
resourceId,
|
|
2812
|
+
selectBy,
|
|
2813
|
+
format
|
|
2814
|
+
}) {
|
|
2815
|
+
return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
|
|
2816
|
+
}
|
|
2817
|
+
async getMessagesById({
|
|
2818
|
+
messageIds,
|
|
2819
|
+
format
|
|
2820
|
+
}) {
|
|
2821
|
+
return this.stores.memory.getMessagesById({ messageIds, format });
|
|
2822
|
+
}
|
|
2823
|
+
async saveMessages(args) {
|
|
2824
|
+
return this.stores.memory.saveMessages(args);
|
|
2825
|
+
}
|
|
2826
|
+
async getMessagesPaginated(args) {
|
|
2827
|
+
return this.stores.memory.getMessagesPaginated(args);
|
|
2828
|
+
}
|
|
2829
|
+
async updateMessages(args) {
|
|
2830
|
+
return this.stores.memory.updateMessages(args);
|
|
2831
|
+
}
|
|
2832
|
+
async getResourceById({ resourceId }) {
|
|
2833
|
+
return this.stores.memory.getResourceById({ resourceId });
|
|
2834
|
+
}
|
|
2835
|
+
async saveResource({ resource }) {
|
|
2836
|
+
return this.stores.memory.saveResource({ resource });
|
|
2837
|
+
}
|
|
2838
|
+
async updateResource({
|
|
2839
|
+
resourceId,
|
|
2840
|
+
workingMemory,
|
|
2841
|
+
metadata
|
|
2842
|
+
}) {
|
|
2843
|
+
return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
|
|
2844
|
+
}
|
|
2845
|
+
async getScoreById({ id }) {
|
|
2846
|
+
return this.stores.scores.getScoreById({ id });
|
|
2847
|
+
}
|
|
2848
|
+
async saveScore(_score) {
|
|
2849
|
+
return this.stores.scores.saveScore(_score);
|
|
2850
|
+
}
|
|
2851
|
+
async getScoresByRunId({
|
|
2852
|
+
runId,
|
|
2853
|
+
pagination
|
|
2854
|
+
}) {
|
|
2855
|
+
return this.stores.scores.getScoresByRunId({ runId, pagination });
|
|
2856
|
+
}
|
|
2857
|
+
async getScoresByEntityId({
|
|
2858
|
+
entityId,
|
|
2859
|
+
entityType,
|
|
2860
|
+
pagination
|
|
2861
|
+
}) {
|
|
2862
|
+
return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
|
|
2863
|
+
}
|
|
2864
|
+
async getScoresByScorerId({
|
|
2865
|
+
scorerId,
|
|
2866
|
+
pagination,
|
|
2867
|
+
entityId,
|
|
2868
|
+
entityType,
|
|
2869
|
+
source
|
|
2870
|
+
}) {
|
|
2871
|
+
return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
|
|
2872
|
+
}
|
|
2873
|
+
async getScoresBySpan({
|
|
2874
|
+
traceId,
|
|
2875
|
+
spanId,
|
|
2876
|
+
pagination
|
|
2877
|
+
}) {
|
|
2878
|
+
return this.stores.scores.getScoresBySpan({ traceId, spanId, pagination });
|
|
849
2879
|
}
|
|
850
2880
|
async close() {
|
|
851
2881
|
await this.db.close();
|
|
@@ -855,3 +2885,5 @@ var ClickhouseStore = class extends storage.MastraStorage {
|
|
|
855
2885
|
exports.COLUMN_TYPES = COLUMN_TYPES;
|
|
856
2886
|
exports.ClickhouseStore = ClickhouseStore;
|
|
857
2887
|
exports.TABLE_ENGINES = TABLE_ENGINES;
|
|
2888
|
+
//# sourceMappingURL=index.cjs.map
|
|
2889
|
+
//# sourceMappingURL=index.cjs.map
|