@mastra/clickhouse 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/dist/index.cjs +81 -65
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +82 -66
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.map +1 -1
- package/dist/storage/domains/scores/index.d.ts +4 -0
- package/dist/storage/domains/scores/index.d.ts.map +1 -1
- package/dist/storage/domains/workflows/index.d.ts +1 -1
- package/dist/storage/domains/workflows/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -1
- package/dist/storage/index.d.ts.map +1 -1
- package/package.json +7 -5
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createClient } from '@clickhouse/client';
|
|
2
2
|
import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
|
|
3
|
-
import { TABLE_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, MastraStorage, StoreOperations, TABLE_SCHEMAS, WorkflowsStorage, normalizePerPage, ScoresStorage,
|
|
3
|
+
import { TABLE_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, MastraStorage, StoreOperations, TABLE_SCHEMAS, WorkflowsStorage, normalizePerPage, ScoresStorage, transformScoreRow, SCORERS_SCHEMA, calculatePagination, MemoryStorage, safelyParseJSON } from '@mastra/core/storage';
|
|
4
4
|
import { MessageList } from '@mastra/core/agent';
|
|
5
5
|
import { saveScorePayloadSchema } from '@mastra/core/evals';
|
|
6
6
|
|
|
@@ -125,6 +125,8 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
125
125
|
}
|
|
126
126
|
async listMessages(args) {
|
|
127
127
|
const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
|
|
128
|
+
const rawThreadIds = Array.isArray(threadId) ? threadId : [threadId];
|
|
129
|
+
const threadIds = rawThreadIds.filter((id) => id !== void 0 && id !== null).map((id) => (typeof id === "string" ? id : String(id)).trim()).filter((id) => id.length > 0);
|
|
128
130
|
if (page < 0) {
|
|
129
131
|
throw new MastraError(
|
|
130
132
|
{
|
|
@@ -136,20 +138,21 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
136
138
|
new Error("page must be >= 0")
|
|
137
139
|
);
|
|
138
140
|
}
|
|
139
|
-
if (
|
|
141
|
+
if (threadIds.length === 0) {
|
|
140
142
|
throw new MastraError(
|
|
141
143
|
{
|
|
142
144
|
id: "STORAGE_CLICKHOUSE_LIST_MESSAGES_INVALID_THREAD_ID",
|
|
143
145
|
domain: ErrorDomain.STORAGE,
|
|
144
146
|
category: ErrorCategory.THIRD_PARTY,
|
|
145
|
-
details: { threadId }
|
|
147
|
+
details: { threadId: Array.isArray(threadId) ? JSON.stringify(threadId) : String(threadId) }
|
|
146
148
|
},
|
|
147
|
-
new Error("threadId must be a non-empty string")
|
|
149
|
+
new Error("threadId must be a non-empty string or array of non-empty strings")
|
|
148
150
|
);
|
|
149
151
|
}
|
|
150
152
|
const perPageForQuery = normalizePerPage(perPageInput, 40);
|
|
151
153
|
const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPageForQuery);
|
|
152
154
|
try {
|
|
155
|
+
const threadCondition = threadIds.length === 1 ? `thread_id = {threadId0:String}` : `thread_id IN (${threadIds.map((_, i) => `{threadId${i}:String}`).join(", ")})`;
|
|
153
156
|
let dataQuery = `
|
|
154
157
|
SELECT
|
|
155
158
|
id,
|
|
@@ -160,9 +163,12 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
160
163
|
thread_id AS "threadId",
|
|
161
164
|
resourceId
|
|
162
165
|
FROM ${TABLE_MESSAGES}
|
|
163
|
-
WHERE
|
|
166
|
+
WHERE ${threadCondition}
|
|
164
167
|
`;
|
|
165
|
-
const dataParams = {
|
|
168
|
+
const dataParams = {};
|
|
169
|
+
threadIds.forEach((tid, i) => {
|
|
170
|
+
dataParams[`threadId${i}`] = tid;
|
|
171
|
+
});
|
|
166
172
|
if (resourceId) {
|
|
167
173
|
dataQuery += ` AND resourceId = {resourceId:String}`;
|
|
168
174
|
dataParams.resourceId = resourceId;
|
|
@@ -197,8 +203,11 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
197
203
|
const rows = await result.json();
|
|
198
204
|
const paginatedMessages = transformRows(rows.data);
|
|
199
205
|
const paginatedCount = paginatedMessages.length;
|
|
200
|
-
let countQuery = `SELECT count() as total FROM ${TABLE_MESSAGES} WHERE
|
|
201
|
-
const countParams = {
|
|
206
|
+
let countQuery = `SELECT count() as total FROM ${TABLE_MESSAGES} WHERE ${threadCondition}`;
|
|
207
|
+
const countParams = {};
|
|
208
|
+
threadIds.forEach((tid, i) => {
|
|
209
|
+
countParams[`threadId${i}`] = tid;
|
|
210
|
+
});
|
|
202
211
|
if (resourceId) {
|
|
203
212
|
countQuery += ` AND resourceId = {resourceId:String}`;
|
|
204
213
|
countParams.resourceId = resourceId;
|
|
@@ -237,12 +246,25 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
237
246
|
const messageIds = new Set(paginatedMessages.map((m) => m.id));
|
|
238
247
|
let includeMessages = [];
|
|
239
248
|
if (include && include.length > 0) {
|
|
249
|
+
const includesNeedingThread = include.filter((inc) => !inc.threadId);
|
|
250
|
+
const threadByMessageId = /* @__PURE__ */ new Map();
|
|
251
|
+
if (includesNeedingThread.length > 0) {
|
|
252
|
+
const { messages: includeLookup } = await this.listMessagesById({
|
|
253
|
+
messageIds: includesNeedingThread.map((inc) => inc.id)
|
|
254
|
+
});
|
|
255
|
+
for (const msg of includeLookup) {
|
|
256
|
+
if (msg.threadId) {
|
|
257
|
+
threadByMessageId.set(msg.id, msg.threadId);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
240
261
|
const unionQueries = [];
|
|
241
262
|
const params = [];
|
|
242
263
|
let paramIdx = 1;
|
|
243
264
|
for (const inc of include) {
|
|
244
265
|
const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
|
|
245
|
-
const
|
|
266
|
+
const searchThreadId = inc.threadId ?? threadByMessageId.get(id);
|
|
267
|
+
if (!searchThreadId) continue;
|
|
246
268
|
unionQueries.push(`
|
|
247
269
|
SELECT * FROM (
|
|
248
270
|
WITH numbered_messages AS (
|
|
@@ -264,31 +286,33 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
264
286
|
) AS query_${paramIdx}
|
|
265
287
|
`);
|
|
266
288
|
params.push(
|
|
267
|
-
{ [`var_thread_id_${paramIdx}`]:
|
|
289
|
+
{ [`var_thread_id_${paramIdx}`]: searchThreadId },
|
|
268
290
|
{ [`var_include_id_${paramIdx}`]: id },
|
|
269
291
|
{ [`var_withPreviousMessages_${paramIdx}`]: withPreviousMessages },
|
|
270
292
|
{ [`var_withNextMessages_${paramIdx}`]: withNextMessages }
|
|
271
293
|
);
|
|
272
294
|
paramIdx++;
|
|
273
295
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
query
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
296
|
+
if (unionQueries.length > 0) {
|
|
297
|
+
const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
|
|
298
|
+
const mergedParams = params.reduce((acc, paramObj) => ({ ...acc, ...paramObj }), {});
|
|
299
|
+
const includeResult = await this.client.query({
|
|
300
|
+
query: finalQuery,
|
|
301
|
+
query_params: mergedParams,
|
|
302
|
+
clickhouse_settings: {
|
|
303
|
+
date_time_input_format: "best_effort",
|
|
304
|
+
date_time_output_format: "iso",
|
|
305
|
+
use_client_time_zone: 1,
|
|
306
|
+
output_format_json_quote_64bit_integers: 0
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
const includeRows = await includeResult.json();
|
|
310
|
+
includeMessages = transformRows(includeRows.data);
|
|
311
|
+
for (const includeMsg of includeMessages) {
|
|
312
|
+
if (!messageIds.has(includeMsg.id)) {
|
|
313
|
+
paginatedMessages.push(includeMsg);
|
|
314
|
+
messageIds.add(includeMsg.id);
|
|
315
|
+
}
|
|
292
316
|
}
|
|
293
317
|
}
|
|
294
318
|
}
|
|
@@ -306,7 +330,10 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
306
330
|
}
|
|
307
331
|
return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
|
|
308
332
|
});
|
|
309
|
-
const
|
|
333
|
+
const threadIdSet = new Set(threadIds);
|
|
334
|
+
const returnedThreadMessageIds = new Set(
|
|
335
|
+
finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
|
|
336
|
+
);
|
|
310
337
|
const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
|
|
311
338
|
const hasMore = perPageForResponse === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
|
|
312
339
|
return {
|
|
@@ -323,7 +350,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
|
|
|
323
350
|
domain: ErrorDomain.STORAGE,
|
|
324
351
|
category: ErrorCategory.THIRD_PARTY,
|
|
325
352
|
details: {
|
|
326
|
-
threadId,
|
|
353
|
+
threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
|
|
327
354
|
resourceId: resourceId ?? ""
|
|
328
355
|
}
|
|
329
356
|
},
|
|
@@ -1449,30 +1476,15 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
|
|
|
1449
1476
|
this.client = client;
|
|
1450
1477
|
this.operations = operations;
|
|
1451
1478
|
}
|
|
1479
|
+
/**
|
|
1480
|
+
* ClickHouse-specific score row transformation.
|
|
1481
|
+
* Converts timestamps to Date objects and filters out '_null_' values.
|
|
1482
|
+
*/
|
|
1452
1483
|
transformScoreRow(row) {
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
const input = safelyParseJSON(row.input);
|
|
1458
|
-
const output = safelyParseJSON(row.output);
|
|
1459
|
-
const additionalContext = safelyParseJSON(row.additionalContext);
|
|
1460
|
-
const requestContext = safelyParseJSON(row.requestContext);
|
|
1461
|
-
const entity = safelyParseJSON(row.entity);
|
|
1462
|
-
return {
|
|
1463
|
-
...row,
|
|
1464
|
-
scorer,
|
|
1465
|
-
preprocessStepResult,
|
|
1466
|
-
analyzeStepResult,
|
|
1467
|
-
metadata,
|
|
1468
|
-
input,
|
|
1469
|
-
output,
|
|
1470
|
-
additionalContext,
|
|
1471
|
-
requestContext,
|
|
1472
|
-
entity,
|
|
1473
|
-
createdAt: new Date(row.createdAt),
|
|
1474
|
-
updatedAt: new Date(row.updatedAt)
|
|
1475
|
-
};
|
|
1484
|
+
return transformScoreRow(row, {
|
|
1485
|
+
convertTimestamps: true,
|
|
1486
|
+
nullValuePattern: "_null_"
|
|
1487
|
+
});
|
|
1476
1488
|
}
|
|
1477
1489
|
async getScoreById({ id }) {
|
|
1478
1490
|
try {
|
|
@@ -1521,9 +1533,15 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
|
|
|
1521
1533
|
);
|
|
1522
1534
|
}
|
|
1523
1535
|
try {
|
|
1524
|
-
const record = {
|
|
1525
|
-
|
|
1526
|
-
|
|
1536
|
+
const record = {};
|
|
1537
|
+
for (const key of Object.keys(SCORERS_SCHEMA)) {
|
|
1538
|
+
const value = parsedScore[key];
|
|
1539
|
+
if (key === "createdAt" || key === "updatedAt") {
|
|
1540
|
+
record[key] = (/* @__PURE__ */ new Date()).toISOString();
|
|
1541
|
+
continue;
|
|
1542
|
+
}
|
|
1543
|
+
record[key] = value === void 0 || value === null ? "_null_" : value;
|
|
1544
|
+
}
|
|
1527
1545
|
await this.client.insert({
|
|
1528
1546
|
table: TABLE_SCORERS,
|
|
1529
1547
|
values: [record],
|
|
@@ -1980,7 +1998,8 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
|
|
|
1980
1998
|
toDate,
|
|
1981
1999
|
page,
|
|
1982
2000
|
perPage,
|
|
1983
|
-
resourceId
|
|
2001
|
+
resourceId,
|
|
2002
|
+
status
|
|
1984
2003
|
} = {}) {
|
|
1985
2004
|
try {
|
|
1986
2005
|
const conditions = [];
|
|
@@ -1989,6 +2008,10 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
|
|
|
1989
2008
|
conditions.push(`workflow_name = {var_workflow_name:String}`);
|
|
1990
2009
|
values.var_workflow_name = workflowName;
|
|
1991
2010
|
}
|
|
2011
|
+
if (status) {
|
|
2012
|
+
conditions.push(`JSONExtractString(snapshot, 'status') = {var_status:String}`);
|
|
2013
|
+
values.var_status = status;
|
|
2014
|
+
}
|
|
1992
2015
|
if (resourceId) {
|
|
1993
2016
|
const hasResourceId = await this.operations.hasColumn(TABLE_WORKFLOW_SNAPSHOT, "resourceId");
|
|
1994
2017
|
if (hasResourceId) {
|
|
@@ -2242,15 +2265,8 @@ var ClickhouseStore = class extends MastraStorage {
|
|
|
2242
2265
|
}) {
|
|
2243
2266
|
return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
|
|
2244
2267
|
}
|
|
2245
|
-
async listWorkflowRuns({
|
|
2246
|
-
|
|
2247
|
-
fromDate,
|
|
2248
|
-
toDate,
|
|
2249
|
-
perPage,
|
|
2250
|
-
page,
|
|
2251
|
-
resourceId
|
|
2252
|
-
} = {}) {
|
|
2253
|
-
return this.stores.workflows.listWorkflowRuns({ workflowName, fromDate, toDate, perPage, page, resourceId });
|
|
2268
|
+
async listWorkflowRuns(args = {}) {
|
|
2269
|
+
return this.stores.workflows.listWorkflowRuns(args);
|
|
2254
2270
|
}
|
|
2255
2271
|
async getWorkflowRunById({
|
|
2256
2272
|
runId,
|