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