@mastra/clickhouse 0.0.0-toolOptionTypes-20250917085558 → 0.0.0-top-level-fix-20251211111608

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { createClient } from '@clickhouse/client';
2
2
  import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
3
- import { TABLE_AI_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_EVALS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, MastraStorage, StoreOperations, TABLE_SCHEMAS, WorkflowsStorage, ScoresStorage, safelyParseJSON, LegacyEvalsStorage, TracesStorage, MemoryStorage, resolveMessageLimit } from '@mastra/core/storage';
3
+ import { TABLE_SPANS, TABLE_RESOURCES, TABLE_SCORERS, TABLE_THREADS, TABLE_TRACES, TABLE_WORKFLOW_SNAPSHOT, TABLE_MESSAGES, MastraStorage, createStorageErrorId, 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
+ import { saveScorePayloadSchema } from '@mastra/core/evals';
5
6
 
6
7
  // src/storage/index.ts
7
8
  var TABLE_ENGINES = {
@@ -9,11 +10,11 @@ var TABLE_ENGINES = {
9
10
  [TABLE_WORKFLOW_SNAPSHOT]: `ReplacingMergeTree()`,
10
11
  [TABLE_TRACES]: `MergeTree()`,
11
12
  [TABLE_THREADS]: `ReplacingMergeTree()`,
12
- [TABLE_EVALS]: `MergeTree()`,
13
13
  [TABLE_SCORERS]: `MergeTree()`,
14
14
  [TABLE_RESOURCES]: `ReplacingMergeTree()`,
15
- // TODO: verify this is the correct engine for ai spans when implementing clickhouse storage
16
- [TABLE_AI_SPANS]: `ReplacingMergeTree()`
15
+ // TODO: verify this is the correct engine for Spans when implementing clickhouse storage
16
+ [TABLE_SPANS]: `ReplacingMergeTree()`,
17
+ mastra_agents: `ReplacingMergeTree()`
17
18
  };
18
19
  var COLUMN_TYPES = {
19
20
  text: "String",
@@ -44,8 +45,26 @@ function transformRows(rows) {
44
45
  return rows.map((row) => transformRow(row));
45
46
  }
46
47
 
47
- // src/storage/domains/legacy-evals/index.ts
48
- var LegacyEvalsStorageClickhouse = class extends LegacyEvalsStorage {
48
+ // src/storage/domains/memory/index.ts
49
+ function serializeMetadata(metadata) {
50
+ if (!metadata || Object.keys(metadata).length === 0) {
51
+ return "{}";
52
+ }
53
+ return JSON.stringify(metadata);
54
+ }
55
+ function parseMetadata(metadata) {
56
+ if (!metadata) return {};
57
+ if (typeof metadata === "object") return metadata;
58
+ if (typeof metadata !== "string") return {};
59
+ const trimmed = metadata.trim();
60
+ if (trimmed === "" || trimmed === "null") return {};
61
+ try {
62
+ return JSON.parse(trimmed);
63
+ } catch {
64
+ return {};
65
+ }
66
+ }
67
+ var MemoryStorageClickhouse = class extends MemoryStorage {
49
68
  client;
50
69
  operations;
51
70
  constructor({ client, operations }) {
@@ -53,127 +72,128 @@ var LegacyEvalsStorageClickhouse = class extends LegacyEvalsStorage {
53
72
  this.client = client;
54
73
  this.operations = operations;
55
74
  }
56
- transformEvalRow(row) {
57
- row = transformRow(row);
58
- let resultValue;
59
- try {
60
- if (row.result && typeof row.result === "string" && row.result.trim() !== "") {
61
- resultValue = JSON.parse(row.result);
62
- } else if (typeof row.result === "object" && row.result !== null) {
63
- resultValue = row.result;
64
- } else if (row.result === null || row.result === void 0 || row.result === "") {
65
- resultValue = { score: 0 };
66
- } else {
67
- throw new Error(`Invalid or empty result field: ${JSON.stringify(row.result)}`);
68
- }
69
- } catch (error) {
70
- console.error("Error parsing result field:", row.result, error);
71
- throw new MastraError({
72
- id: "CLICKHOUSE_STORAGE_INVALID_RESULT_FORMAT",
73
- text: `Invalid result format: ${JSON.stringify(row.result)}`,
74
- domain: ErrorDomain.STORAGE,
75
- category: ErrorCategory.USER
76
- });
77
- }
78
- let testInfoValue;
79
- try {
80
- if (row.test_info && typeof row.test_info === "string" && row.test_info.trim() !== "" && row.test_info !== "null") {
81
- testInfoValue = JSON.parse(row.test_info);
82
- } else if (typeof row.test_info === "object" && row.test_info !== null) {
83
- testInfoValue = row.test_info;
84
- }
85
- } catch {
86
- testInfoValue = void 0;
87
- }
88
- if (!resultValue || typeof resultValue !== "object" || !("score" in resultValue)) {
89
- throw new MastraError({
90
- id: "CLICKHOUSE_STORAGE_INVALID_METRIC_FORMAT",
91
- text: `Invalid MetricResult format: ${JSON.stringify(resultValue)}`,
92
- domain: ErrorDomain.STORAGE,
93
- category: ErrorCategory.USER
94
- });
95
- }
96
- return {
97
- input: row.input,
98
- output: row.output,
99
- result: resultValue,
100
- agentName: row.agent_name,
101
- metricName: row.metric_name,
102
- instructions: row.instructions,
103
- testInfo: testInfoValue,
104
- globalRunId: row.global_run_id,
105
- runId: row.run_id,
106
- createdAt: row.created_at
107
- };
108
- }
109
- async getEvalsByAgentName(agentName, type) {
75
+ async listMessagesById({ messageIds }) {
76
+ if (messageIds.length === 0) return { messages: [] };
110
77
  try {
111
- const baseQuery = `SELECT *, toDateTime64(created_at, 3) as createdAt FROM ${TABLE_EVALS} WHERE agent_name = {var_agent_name:String}`;
112
- const typeCondition = type === "test" ? " AND test_info IS NOT NULL AND test_info != 'null' AND JSONExtractString(test_info, 'testPath') IS NOT NULL AND JSONExtractString(test_info, 'testPath') != ''" : type === "live" ? " AND (test_info IS NULL OR test_info = 'null' OR JSONExtractString(test_info, 'testPath') IS NULL OR JSONExtractString(test_info, 'testPath') = '')" : "";
113
78
  const result = await this.client.query({
114
- query: `${baseQuery}${typeCondition} ORDER BY createdAt DESC`,
115
- query_params: { var_agent_name: agentName },
79
+ query: `
80
+ SELECT
81
+ id,
82
+ content,
83
+ role,
84
+ type,
85
+ toDateTime64(createdAt, 3) as createdAt,
86
+ thread_id AS "threadId",
87
+ "resourceId"
88
+ FROM "${TABLE_MESSAGES}"
89
+ WHERE id IN {messageIds:Array(String)}
90
+ ORDER BY "createdAt" DESC
91
+ `,
92
+ query_params: {
93
+ messageIds
94
+ },
116
95
  clickhouse_settings: {
96
+ // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
117
97
  date_time_input_format: "best_effort",
118
98
  date_time_output_format: "iso",
119
99
  use_client_time_zone: 1,
120
100
  output_format_json_quote_64bit_integers: 0
121
101
  }
122
102
  });
123
- if (!result) {
124
- return [];
125
- }
126
103
  const rows = await result.json();
127
- return rows.data.map((row) => this.transformEvalRow(row));
104
+ const messages = transformRows(rows.data);
105
+ messages.forEach((message) => {
106
+ if (typeof message.content === "string") {
107
+ try {
108
+ message.content = JSON.parse(message.content);
109
+ } catch {
110
+ }
111
+ }
112
+ });
113
+ const list = new MessageList().add(messages, "memory");
114
+ return { messages: list.get.all.db() };
128
115
  } catch (error) {
129
- if (error?.message?.includes("no such table") || error?.message?.includes("does not exist")) {
130
- return [];
131
- }
132
116
  throw new MastraError(
133
117
  {
134
- id: "CLICKHOUSE_STORAGE_GET_EVALS_BY_AGENT_FAILED",
118
+ id: createStorageErrorId("CLICKHOUSE", "LIST_MESSAGES_BY_ID", "FAILED"),
135
119
  domain: ErrorDomain.STORAGE,
136
120
  category: ErrorCategory.THIRD_PARTY,
137
- details: { agentName, type: type ?? null }
121
+ details: { messageIds: JSON.stringify(messageIds) }
138
122
  },
139
123
  error
140
124
  );
141
125
  }
142
126
  }
143
- async getEvals(options = {}) {
144
- const { agentName, type, page = 0, perPage = 100, dateRange } = options;
145
- const fromDate = dateRange?.start;
146
- const toDate = dateRange?.end;
147
- const conditions = [];
148
- if (agentName) {
149
- conditions.push(`agent_name = {var_agent_name:String}`);
150
- }
151
- if (type === "test") {
152
- conditions.push(
153
- `(test_info IS NOT NULL AND test_info != 'null' AND JSONExtractString(test_info, 'testPath') IS NOT NULL AND JSONExtractString(test_info, 'testPath') != '')`
154
- );
155
- } else if (type === "live") {
156
- conditions.push(
157
- `(test_info IS NULL OR test_info = 'null' OR JSONExtractString(test_info, 'testPath') IS NULL OR JSONExtractString(test_info, 'testPath') = '')`
127
+ async listMessages(args) {
128
+ const { threadId, resourceId, include, filter, perPage: perPageInput, page = 0, orderBy } = args;
129
+ const rawThreadIds = Array.isArray(threadId) ? threadId : [threadId];
130
+ const threadIds = rawThreadIds.filter((id) => id !== void 0 && id !== null).map((id) => (typeof id === "string" ? id : String(id)).trim()).filter((id) => id.length > 0);
131
+ if (page < 0) {
132
+ throw new MastraError(
133
+ {
134
+ id: createStorageErrorId("CLICKHOUSE", "LIST_MESSAGES", "INVALID_PAGE"),
135
+ domain: ErrorDomain.STORAGE,
136
+ category: ErrorCategory.USER,
137
+ details: { page }
138
+ },
139
+ new Error("page must be >= 0")
158
140
  );
159
141
  }
160
- if (fromDate) {
161
- conditions.push(`created_at >= parseDateTime64BestEffort({var_from_date:String})`);
162
- fromDate.toISOString();
163
- }
164
- if (toDate) {
165
- conditions.push(`created_at <= parseDateTime64BestEffort({var_to_date:String})`);
166
- toDate.toISOString();
142
+ if (threadIds.length === 0) {
143
+ throw new MastraError(
144
+ {
145
+ id: createStorageErrorId("CLICKHOUSE", "LIST_MESSAGES", "INVALID_THREAD_ID"),
146
+ domain: ErrorDomain.STORAGE,
147
+ category: ErrorCategory.THIRD_PARTY,
148
+ details: { threadId: Array.isArray(threadId) ? JSON.stringify(threadId) : String(threadId) }
149
+ },
150
+ new Error("threadId must be a non-empty string or array of non-empty strings")
151
+ );
167
152
  }
168
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
153
+ const perPageForQuery = normalizePerPage(perPageInput, 40);
154
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPageForQuery);
169
155
  try {
170
- const countResult = await this.client.query({
171
- query: `SELECT COUNT(*) as count FROM ${TABLE_EVALS} ${whereClause}`,
172
- query_params: {
173
- ...agentName ? { var_agent_name: agentName } : {},
174
- ...fromDate ? { var_from_date: fromDate.toISOString() } : {},
175
- ...toDate ? { var_to_date: toDate.toISOString() } : {}
176
- },
156
+ const threadCondition = threadIds.length === 1 ? `thread_id = {threadId0:String}` : `thread_id IN (${threadIds.map((_, i) => `{threadId${i}:String}`).join(", ")})`;
157
+ let dataQuery = `
158
+ SELECT
159
+ id,
160
+ content,
161
+ role,
162
+ type,
163
+ toDateTime64(createdAt, 3) as createdAt,
164
+ thread_id AS "threadId",
165
+ resourceId
166
+ FROM ${TABLE_MESSAGES}
167
+ WHERE ${threadCondition}
168
+ `;
169
+ const dataParams = {};
170
+ threadIds.forEach((tid, i) => {
171
+ dataParams[`threadId${i}`] = tid;
172
+ });
173
+ if (resourceId) {
174
+ dataQuery += ` AND resourceId = {resourceId:String}`;
175
+ dataParams.resourceId = resourceId;
176
+ }
177
+ if (filter?.dateRange?.start) {
178
+ const startDate = filter.dateRange.start instanceof Date ? filter.dateRange.start.toISOString() : new Date(filter.dateRange.start).toISOString();
179
+ dataQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
180
+ dataParams.fromDate = startDate;
181
+ }
182
+ if (filter?.dateRange?.end) {
183
+ const endDate = filter.dateRange.end instanceof Date ? filter.dateRange.end.toISOString() : new Date(filter.dateRange.end).toISOString();
184
+ dataQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
185
+ dataParams.toDate = endDate;
186
+ }
187
+ const { field, direction } = this.parseOrderBy(orderBy, "ASC");
188
+ dataQuery += ` ORDER BY "${field}" ${direction}`;
189
+ if (perPageForResponse === false) ; else {
190
+ dataQuery += ` LIMIT {limit:Int64} OFFSET {offset:Int64}`;
191
+ dataParams.limit = perPageForQuery;
192
+ dataParams.offset = offset;
193
+ }
194
+ const result = await this.client.query({
195
+ query: dataQuery,
196
+ query_params: dataParams,
177
197
  clickhouse_settings: {
178
198
  date_time_input_format: "best_effort",
179
199
  date_time_output_format: "iso",
@@ -181,28 +201,31 @@ var LegacyEvalsStorageClickhouse = class extends LegacyEvalsStorage {
181
201
  output_format_json_quote_64bit_integers: 0
182
202
  }
183
203
  });
184
- const countData = await countResult.json();
185
- const total = Number(countData.data?.[0]?.count ?? 0);
186
- const currentOffset = page * perPage;
187
- const hasMore = currentOffset + perPage < total;
188
- if (total === 0) {
189
- return {
190
- evals: [],
191
- total: 0,
192
- page,
193
- perPage,
194
- hasMore: false
195
- };
204
+ const rows = await result.json();
205
+ const paginatedMessages = transformRows(rows.data);
206
+ const paginatedCount = paginatedMessages.length;
207
+ let countQuery = `SELECT count() as total FROM ${TABLE_MESSAGES} WHERE ${threadCondition}`;
208
+ const countParams = {};
209
+ threadIds.forEach((tid, i) => {
210
+ countParams[`threadId${i}`] = tid;
211
+ });
212
+ if (resourceId) {
213
+ countQuery += ` AND resourceId = {resourceId:String}`;
214
+ countParams.resourceId = resourceId;
196
215
  }
197
- const dataResult = await this.client.query({
198
- query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${TABLE_EVALS} ${whereClause} ORDER BY created_at DESC LIMIT {var_limit:UInt32} OFFSET {var_offset:UInt32}`,
199
- query_params: {
200
- ...agentName ? { var_agent_name: agentName } : {},
201
- ...fromDate ? { var_from_date: fromDate.toISOString() } : {},
202
- ...toDate ? { var_to_date: toDate.toISOString() } : {},
203
- var_limit: perPage || 100,
204
- var_offset: currentOffset || 0
205
- },
216
+ if (filter?.dateRange?.start) {
217
+ const startDate = filter.dateRange.start instanceof Date ? filter.dateRange.start.toISOString() : new Date(filter.dateRange.start).toISOString();
218
+ countQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
219
+ countParams.fromDate = startDate;
220
+ }
221
+ if (filter?.dateRange?.end) {
222
+ const endDate = filter.dateRange.end instanceof Date ? filter.dateRange.end.toISOString() : new Date(filter.dateRange.end).toISOString();
223
+ countQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
224
+ countParams.toDate = endDate;
225
+ }
226
+ const countResult = await this.client.query({
227
+ query: countQuery,
228
+ query_params: countParams,
206
229
  clickhouse_settings: {
207
230
  date_time_input_format: "best_effort",
208
231
  date_time_output_format: "iso",
@@ -210,62 +233,39 @@ var LegacyEvalsStorageClickhouse = class extends LegacyEvalsStorage {
210
233
  output_format_json_quote_64bit_integers: 0
211
234
  }
212
235
  });
213
- const rows = await dataResult.json();
214
- return {
215
- evals: rows.data.map((row) => this.transformEvalRow(row)),
216
- total,
217
- page,
218
- perPage,
219
- hasMore
220
- };
221
- } catch (error) {
222
- if (error?.message?.includes("no such table") || error?.message?.includes("does not exist")) {
236
+ const countData = await countResult.json();
237
+ const total = countData.data[0].total;
238
+ if (total === 0 && paginatedCount === 0 && (!include || include.length === 0)) {
223
239
  return {
224
- evals: [],
240
+ messages: [],
225
241
  total: 0,
226
242
  page,
227
- perPage,
243
+ perPage: perPageForResponse,
228
244
  hasMore: false
229
245
  };
230
246
  }
231
- throw new MastraError(
232
- {
233
- id: "CLICKHOUSE_STORAGE_GET_EVALS_FAILED",
234
- domain: ErrorDomain.STORAGE,
235
- category: ErrorCategory.THIRD_PARTY,
236
- details: { agentName: agentName ?? "all", type: type ?? "all" }
237
- },
238
- error
239
- );
240
- }
241
- }
242
- };
243
- var MemoryStorageClickhouse = class extends MemoryStorage {
244
- client;
245
- operations;
246
- constructor({ client, operations }) {
247
- super();
248
- this.client = client;
249
- this.operations = operations;
250
- }
251
- async getMessages({
252
- threadId,
253
- resourceId,
254
- selectBy,
255
- format
256
- }) {
257
- try {
258
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
259
- const messages = [];
260
- const limit = resolveMessageLimit({ last: selectBy?.last, defaultLimit: 40 });
261
- const include = selectBy?.include || [];
262
- if (include.length) {
247
+ const messageIds = new Set(paginatedMessages.map((m) => m.id));
248
+ let includeMessages = [];
249
+ if (include && include.length > 0) {
250
+ const includesNeedingThread = include.filter((inc) => !inc.threadId);
251
+ const threadByMessageId = /* @__PURE__ */ new Map();
252
+ if (includesNeedingThread.length > 0) {
253
+ const { messages: includeLookup } = await this.listMessagesById({
254
+ messageIds: includesNeedingThread.map((inc) => inc.id)
255
+ });
256
+ for (const msg of includeLookup) {
257
+ if (msg.threadId) {
258
+ threadByMessageId.set(msg.id, msg.threadId);
259
+ }
260
+ }
261
+ }
263
262
  const unionQueries = [];
264
263
  const params = [];
265
264
  let paramIdx = 1;
266
265
  for (const inc of include) {
267
266
  const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
268
- const searchId = inc.threadId || threadId;
267
+ const searchThreadId = inc.threadId ?? threadByMessageId.get(id);
268
+ if (!searchThreadId) continue;
269
269
  unionQueries.push(`
270
270
  SELECT * FROM (
271
271
  WITH numbered_messages AS (
@@ -280,155 +280,97 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
280
280
  FROM numbered_messages
281
281
  WHERE id = {var_include_id_${paramIdx}:String}
282
282
  )
283
- SELECT DISTINCT m.id, m.content, m.role, m.type, m."createdAt", m.thread_id AS "threadId"
283
+ SELECT DISTINCT m.id, m.content, m.role, m.type, m."createdAt", m.thread_id AS "threadId", m."resourceId"
284
284
  FROM numbered_messages m
285
285
  CROSS JOIN target_positions t
286
286
  WHERE m.row_num BETWEEN (t.target_pos - {var_withPreviousMessages_${paramIdx}:Int64}) AND (t.target_pos + {var_withNextMessages_${paramIdx}:Int64})
287
287
  ) AS query_${paramIdx}
288
288
  `);
289
289
  params.push(
290
- { [`var_thread_id_${paramIdx}`]: searchId },
290
+ { [`var_thread_id_${paramIdx}`]: searchThreadId },
291
291
  { [`var_include_id_${paramIdx}`]: id },
292
292
  { [`var_withPreviousMessages_${paramIdx}`]: withPreviousMessages },
293
293
  { [`var_withNextMessages_${paramIdx}`]: withNextMessages }
294
294
  );
295
295
  paramIdx++;
296
296
  }
297
- const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" DESC';
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
297
+ if (unionQueries.length > 0) {
298
+ const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" ASC';
299
+ const mergedParams = params.reduce((acc, paramObj) => ({ ...acc, ...paramObj }), {});
300
+ const includeResult = await this.client.query({
301
+ query: finalQuery,
302
+ query_params: mergedParams,
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 includeRows = await includeResult.json();
311
+ includeMessages = transformRows(includeRows.data);
312
+ for (const includeMsg of includeMessages) {
313
+ if (!messageIds.has(includeMsg.id)) {
314
+ paginatedMessages.push(includeMsg);
315
+ messageIds.add(includeMsg.id);
316
+ }
307
317
  }
308
- });
309
- const rows2 = await includeResult.json();
310
- const includedMessages = transformRows(rows2.data);
311
- const seen = /* @__PURE__ */ new Set();
312
- const dedupedMessages = includedMessages.filter((message) => {
313
- if (seen.has(message.id)) return false;
314
- seen.add(message.id);
315
- return true;
316
- });
317
- messages.push(...dedupedMessages);
318
+ }
318
319
  }
319
- const result = await this.client.query({
320
- query: `
321
- SELECT
322
- id,
323
- content,
324
- role,
325
- type,
326
- toDateTime64(createdAt, 3) as createdAt,
327
- thread_id AS "threadId"
328
- FROM "${TABLE_MESSAGES}"
329
- WHERE thread_id = {threadId:String}
330
- AND id NOT IN ({exclude:Array(String)})
331
- ORDER BY "createdAt" DESC
332
- LIMIT {limit:Int64}
333
- `,
334
- query_params: {
335
- threadId,
336
- exclude: messages.map((m) => m.id),
337
- limit
338
- },
339
- clickhouse_settings: {
340
- // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
341
- date_time_input_format: "best_effort",
342
- date_time_output_format: "iso",
343
- use_client_time_zone: 1,
344
- output_format_json_quote_64bit_integers: 0
320
+ const list = new MessageList().add(paginatedMessages, "memory");
321
+ let finalMessages = list.get.all.db();
322
+ finalMessages = finalMessages.sort((a, b) => {
323
+ const isDateField = field === "createdAt" || field === "updatedAt";
324
+ const aValue = isDateField ? new Date(a[field]).getTime() : a[field];
325
+ const bValue = isDateField ? new Date(b[field]).getTime() : b[field];
326
+ if (aValue === bValue) {
327
+ return a.id.localeCompare(b.id);
345
328
  }
346
- });
347
- const rows = await result.json();
348
- messages.push(...transformRows(rows.data));
349
- messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
350
- messages.forEach((message) => {
351
- if (typeof message.content === "string") {
352
- try {
353
- message.content = JSON.parse(message.content);
354
- } catch {
355
- }
329
+ if (typeof aValue === "number" && typeof bValue === "number") {
330
+ return direction === "ASC" ? aValue - bValue : bValue - aValue;
356
331
  }
332
+ return direction === "ASC" ? String(aValue).localeCompare(String(bValue)) : String(bValue).localeCompare(String(aValue));
357
333
  });
358
- const list = new MessageList({ threadId, resourceId }).add(messages, "memory");
359
- if (format === `v2`) return list.get.all.v2();
360
- return list.get.all.v1();
361
- } catch (error) {
362
- throw new MastraError(
363
- {
364
- id: "CLICKHOUSE_STORAGE_GET_MESSAGES_FAILED",
365
- domain: ErrorDomain.STORAGE,
366
- category: ErrorCategory.THIRD_PARTY,
367
- details: { threadId, resourceId: resourceId ?? "" }
368
- },
369
- error
334
+ const threadIdSet = new Set(threadIds);
335
+ const returnedThreadMessageIds = new Set(
336
+ finalMessages.filter((m) => m.threadId && threadIdSet.has(m.threadId)).map((m) => m.id)
370
337
  );
371
- }
372
- }
373
- async getMessagesById({
374
- messageIds,
375
- format
376
- }) {
377
- if (messageIds.length === 0) return [];
378
- try {
379
- const result = await this.client.query({
380
- query: `
381
- SELECT
382
- id,
383
- content,
384
- role,
385
- type,
386
- toDateTime64(createdAt, 3) as createdAt,
387
- thread_id AS "threadId",
388
- "resourceId"
389
- FROM "${TABLE_MESSAGES}"
390
- WHERE id IN {messageIds:Array(String)}
391
- ORDER BY "createdAt" DESC
392
- `,
393
- query_params: {
394
- messageIds
395
- },
396
- clickhouse_settings: {
397
- // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
398
- date_time_input_format: "best_effort",
399
- date_time_output_format: "iso",
400
- use_client_time_zone: 1,
401
- output_format_json_quote_64bit_integers: 0
402
- }
403
- });
404
- const rows = await result.json();
405
- const messages = transformRows(rows.data);
406
- messages.forEach((message) => {
407
- if (typeof message.content === "string") {
408
- try {
409
- message.content = JSON.parse(message.content);
410
- } catch {
411
- }
412
- }
413
- });
414
- const list = new MessageList().add(messages, "memory");
415
- if (format === `v1`) return list.get.all.v1();
416
- return list.get.all.v2();
338
+ const allThreadMessagesReturned = returnedThreadMessageIds.size >= total;
339
+ const hasMore = perPageForResponse === false ? false : allThreadMessagesReturned ? false : offset + paginatedCount < total;
340
+ return {
341
+ messages: finalMessages,
342
+ total,
343
+ page,
344
+ perPage: perPageForResponse,
345
+ hasMore
346
+ };
417
347
  } catch (error) {
418
- throw new MastraError(
348
+ const mastraError = new MastraError(
419
349
  {
420
- id: "CLICKHOUSE_STORAGE_GET_MESSAGES_BY_ID_FAILED",
350
+ id: createStorageErrorId("CLICKHOUSE", "LIST_MESSAGES", "FAILED"),
421
351
  domain: ErrorDomain.STORAGE,
422
352
  category: ErrorCategory.THIRD_PARTY,
423
- details: { messageIds: JSON.stringify(messageIds) }
353
+ details: {
354
+ threadId: Array.isArray(threadId) ? threadId.join(",") : threadId,
355
+ resourceId: resourceId ?? ""
356
+ }
424
357
  },
425
358
  error
426
359
  );
360
+ this.logger?.error?.(mastraError.toString());
361
+ this.logger?.trackException?.(mastraError);
362
+ return {
363
+ messages: [],
364
+ total: 0,
365
+ page,
366
+ perPage: perPageForResponse,
367
+ hasMore: false
368
+ };
427
369
  }
428
370
  }
429
371
  async saveMessages(args) {
430
- const { messages, format = "v1" } = args;
431
- if (messages.length === 0) return messages;
372
+ const { messages } = args;
373
+ if (messages.length === 0) return { messages };
432
374
  for (const message of messages) {
433
375
  const resourceId = message.resourceId;
434
376
  if (!resourceId) {
@@ -552,7 +494,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
552
494
  id: thread.id,
553
495
  resourceId: thread.resourceId,
554
496
  title: thread.title,
555
- metadata: thread.metadata,
497
+ metadata: serializeMetadata(thread.metadata),
556
498
  createdAt: thread.createdAt,
557
499
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
558
500
  })),
@@ -564,12 +506,11 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
564
506
  })
565
507
  ]);
566
508
  const list = new MessageList().add(messages, "memory");
567
- if (format === `v2`) return list.get.all.v2();
568
- return list.get.all.v1();
509
+ return { messages: list.get.all.db() };
569
510
  } catch (error) {
570
511
  throw new MastraError(
571
512
  {
572
- id: "CLICKHOUSE_STORAGE_SAVE_MESSAGES_FAILED",
513
+ id: createStorageErrorId("CLICKHOUSE", "SAVE_MESSAGES", "FAILED"),
573
514
  domain: ErrorDomain.STORAGE,
574
515
  category: ErrorCategory.THIRD_PARTY
575
516
  },
@@ -588,8 +529,9 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
588
529
  toDateTime64(createdAt, 3) as createdAt,
589
530
  toDateTime64(updatedAt, 3) as updatedAt
590
531
  FROM "${TABLE_THREADS}"
591
- FINAL
592
- WHERE id = {var_id:String}`,
532
+ WHERE id = {var_id:String}
533
+ ORDER BY updatedAt DESC
534
+ LIMIT 1`,
593
535
  query_params: { var_id: threadId },
594
536
  clickhouse_settings: {
595
537
  // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
@@ -606,14 +548,14 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
606
548
  }
607
549
  return {
608
550
  ...thread,
609
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
551
+ metadata: parseMetadata(thread.metadata),
610
552
  createdAt: thread.createdAt,
611
553
  updatedAt: thread.updatedAt
612
554
  };
613
555
  } catch (error) {
614
556
  throw new MastraError(
615
557
  {
616
- id: "CLICKHOUSE_STORAGE_GET_THREAD_BY_ID_FAILED",
558
+ id: createStorageErrorId("CLICKHOUSE", "GET_THREAD_BY_ID", "FAILED"),
617
559
  domain: ErrorDomain.STORAGE,
618
560
  category: ErrorCategory.THIRD_PARTY,
619
561
  details: { threadId }
@@ -622,47 +564,6 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
622
564
  );
623
565
  }
624
566
  }
625
- async getThreadsByResourceId({ resourceId }) {
626
- try {
627
- const result = await this.client.query({
628
- query: `SELECT
629
- id,
630
- "resourceId",
631
- title,
632
- metadata,
633
- toDateTime64(createdAt, 3) as createdAt,
634
- toDateTime64(updatedAt, 3) as updatedAt
635
- FROM "${TABLE_THREADS}"
636
- WHERE "resourceId" = {var_resourceId:String}`,
637
- query_params: { var_resourceId: resourceId },
638
- clickhouse_settings: {
639
- // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
640
- date_time_input_format: "best_effort",
641
- date_time_output_format: "iso",
642
- use_client_time_zone: 1,
643
- output_format_json_quote_64bit_integers: 0
644
- }
645
- });
646
- const rows = await result.json();
647
- const threads = transformRows(rows.data);
648
- return threads.map((thread) => ({
649
- ...thread,
650
- metadata: typeof thread.metadata === "string" ? JSON.parse(thread.metadata) : thread.metadata,
651
- createdAt: thread.createdAt,
652
- updatedAt: thread.updatedAt
653
- }));
654
- } catch (error) {
655
- throw new MastraError(
656
- {
657
- id: "CLICKHOUSE_STORAGE_GET_THREADS_BY_RESOURCE_ID_FAILED",
658
- domain: ErrorDomain.STORAGE,
659
- category: ErrorCategory.THIRD_PARTY,
660
- details: { resourceId }
661
- },
662
- error
663
- );
664
- }
665
- }
666
567
  async saveThread({ thread }) {
667
568
  try {
668
569
  await this.client.insert({
@@ -670,6 +571,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
670
571
  values: [
671
572
  {
672
573
  ...thread,
574
+ metadata: serializeMetadata(thread.metadata),
673
575
  createdAt: thread.createdAt.toISOString(),
674
576
  updatedAt: thread.updatedAt.toISOString()
675
577
  }
@@ -686,7 +588,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
686
588
  } catch (error) {
687
589
  throw new MastraError(
688
590
  {
689
- id: "CLICKHOUSE_STORAGE_SAVE_THREAD_FAILED",
591
+ id: createStorageErrorId("CLICKHOUSE", "SAVE_THREAD", "FAILED"),
690
592
  domain: ErrorDomain.STORAGE,
691
593
  category: ErrorCategory.THIRD_PARTY,
692
594
  details: { threadId: thread.id }
@@ -723,7 +625,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
723
625
  id: updatedThread.id,
724
626
  resourceId: updatedThread.resourceId,
725
627
  title: updatedThread.title,
726
- metadata: updatedThread.metadata,
628
+ metadata: serializeMetadata(updatedThread.metadata),
727
629
  createdAt: updatedThread.createdAt,
728
630
  updatedAt: updatedThread.updatedAt.toISOString()
729
631
  }
@@ -738,7 +640,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
738
640
  } catch (error) {
739
641
  throw new MastraError(
740
642
  {
741
- id: "CLICKHOUSE_STORAGE_UPDATE_THREAD_FAILED",
643
+ id: createStorageErrorId("CLICKHOUSE", "UPDATE_THREAD", "FAILED"),
742
644
  domain: ErrorDomain.STORAGE,
743
645
  category: ErrorCategory.THIRD_PARTY,
744
646
  details: { threadId: id, title }
@@ -759,177 +661,42 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
759
661
  await this.client.command({
760
662
  query: `DELETE FROM "${TABLE_THREADS}" WHERE id = {var_id:String};`,
761
663
  query_params: { var_id: threadId },
762
- clickhouse_settings: {
763
- output_format_json_quote_64bit_integers: 0
764
- }
765
- });
766
- } catch (error) {
767
- throw new MastraError(
768
- {
769
- id: "CLICKHOUSE_STORAGE_DELETE_THREAD_FAILED",
770
- domain: ErrorDomain.STORAGE,
771
- category: ErrorCategory.THIRD_PARTY,
772
- details: { threadId }
773
- },
774
- error
775
- );
776
- }
777
- }
778
- async getThreadsByResourceIdPaginated(args) {
779
- const { resourceId, page = 0, perPage = 100 } = args;
780
- try {
781
- const currentOffset = page * perPage;
782
- const countResult = await this.client.query({
783
- query: `SELECT count() as total FROM ${TABLE_THREADS} WHERE resourceId = {resourceId:String}`,
784
- query_params: { resourceId },
785
- clickhouse_settings: {
786
- date_time_input_format: "best_effort",
787
- date_time_output_format: "iso",
788
- use_client_time_zone: 1,
789
- output_format_json_quote_64bit_integers: 0
790
- }
791
- });
792
- const countData = await countResult.json();
793
- const total = countData.data[0].total;
794
- if (total === 0) {
795
- return {
796
- threads: [],
797
- total: 0,
798
- page,
799
- perPage,
800
- hasMore: false
801
- };
802
- }
803
- const dataResult = await this.client.query({
804
- query: `
805
- SELECT
806
- id,
807
- resourceId,
808
- title,
809
- metadata,
810
- toDateTime64(createdAt, 3) as createdAt,
811
- toDateTime64(updatedAt, 3) as updatedAt
812
- FROM ${TABLE_THREADS}
813
- WHERE resourceId = {resourceId:String}
814
- ORDER BY createdAt DESC
815
- LIMIT {limit:Int64} OFFSET {offset:Int64}
816
- `,
817
- query_params: {
818
- resourceId,
819
- limit: perPage,
820
- offset: currentOffset
821
- },
822
- clickhouse_settings: {
823
- date_time_input_format: "best_effort",
824
- date_time_output_format: "iso",
825
- use_client_time_zone: 1,
826
- output_format_json_quote_64bit_integers: 0
827
- }
828
- });
829
- const rows = await dataResult.json();
830
- const threads = transformRows(rows.data);
831
- return {
832
- threads,
833
- total,
834
- page,
835
- perPage,
836
- hasMore: currentOffset + threads.length < total
837
- };
838
- } catch (error) {
839
- throw new MastraError(
840
- {
841
- id: "CLICKHOUSE_STORAGE_GET_THREADS_BY_RESOURCE_ID_PAGINATED_FAILED",
842
- domain: ErrorDomain.STORAGE,
843
- category: ErrorCategory.THIRD_PARTY,
844
- details: { resourceId, page }
845
- },
846
- error
847
- );
848
- }
849
- }
850
- async getMessagesPaginated(args) {
851
- const { threadId, resourceId, selectBy, format = "v1" } = args;
852
- const page = selectBy?.pagination?.page || 0;
853
- const perPageInput = selectBy?.pagination?.perPage;
854
- const perPage = perPageInput !== void 0 ? perPageInput : resolveMessageLimit({ last: selectBy?.last, defaultLimit: 20 });
855
- try {
856
- if (!threadId.trim()) throw new Error("threadId must be a non-empty string");
857
- const offset = page * perPage;
858
- const dateRange = selectBy?.pagination?.dateRange;
859
- const fromDate = dateRange?.start;
860
- const toDate = dateRange?.end;
861
- const messages = [];
862
- if (selectBy?.include?.length) {
863
- const include = selectBy.include;
864
- const unionQueries = [];
865
- const params = [];
866
- let paramIdx = 1;
867
- for (const inc of include) {
868
- const { id, withPreviousMessages = 0, withNextMessages = 0 } = inc;
869
- const searchId = inc.threadId || threadId;
870
- unionQueries.push(`
871
- SELECT * FROM (
872
- WITH numbered_messages AS (
873
- SELECT
874
- id, content, role, type, "createdAt", thread_id, "resourceId",
875
- ROW_NUMBER() OVER (ORDER BY "createdAt" ASC) as row_num
876
- FROM "${TABLE_MESSAGES}"
877
- WHERE thread_id = {var_thread_id_${paramIdx}:String}
878
- ),
879
- target_positions AS (
880
- SELECT row_num as target_pos
881
- FROM numbered_messages
882
- WHERE id = {var_include_id_${paramIdx}:String}
883
- )
884
- SELECT DISTINCT m.id, m.content, m.role, m.type, m."createdAt", m.thread_id AS "threadId"
885
- FROM numbered_messages m
886
- CROSS JOIN target_positions t
887
- WHERE m.row_num BETWEEN (t.target_pos - {var_withPreviousMessages_${paramIdx}:Int64}) AND (t.target_pos + {var_withNextMessages_${paramIdx}:Int64})
888
- ) AS query_${paramIdx}
889
- `);
890
- params.push(
891
- { [`var_thread_id_${paramIdx}`]: searchId },
892
- { [`var_include_id_${paramIdx}`]: id },
893
- { [`var_withPreviousMessages_${paramIdx}`]: withPreviousMessages },
894
- { [`var_withNextMessages_${paramIdx}`]: withNextMessages }
895
- );
896
- paramIdx++;
897
- }
898
- const finalQuery = unionQueries.join(" UNION ALL ") + ' ORDER BY "createdAt" DESC';
899
- const mergedParams = params.reduce((acc, paramObj) => ({ ...acc, ...paramObj }), {});
900
- const includeResult = await this.client.query({
901
- query: finalQuery,
902
- query_params: mergedParams,
903
- clickhouse_settings: {
904
- date_time_input_format: "best_effort",
905
- date_time_output_format: "iso",
906
- use_client_time_zone: 1,
907
- output_format_json_quote_64bit_integers: 0
908
- }
909
- });
910
- const rows2 = await includeResult.json();
911
- const includedMessages = transformRows(rows2.data);
912
- const seen = /* @__PURE__ */ new Set();
913
- const dedupedMessages = includedMessages.filter((message) => {
914
- if (seen.has(message.id)) return false;
915
- seen.add(message.id);
916
- return true;
917
- });
918
- messages.push(...dedupedMessages);
919
- }
920
- let countQuery = `SELECT count() as total FROM ${TABLE_MESSAGES} WHERE thread_id = {threadId:String}`;
921
- const countParams = { threadId };
922
- if (fromDate) {
923
- countQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
924
- countParams.fromDate = fromDate.toISOString();
925
- }
926
- if (toDate) {
927
- countQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
928
- countParams.toDate = toDate.toISOString();
929
- }
664
+ clickhouse_settings: {
665
+ output_format_json_quote_64bit_integers: 0
666
+ }
667
+ });
668
+ } catch (error) {
669
+ throw new MastraError(
670
+ {
671
+ id: createStorageErrorId("CLICKHOUSE", "DELETE_THREAD", "FAILED"),
672
+ domain: ErrorDomain.STORAGE,
673
+ category: ErrorCategory.THIRD_PARTY,
674
+ details: { threadId }
675
+ },
676
+ error
677
+ );
678
+ }
679
+ }
680
+ async listThreadsByResourceId(args) {
681
+ const { resourceId, page = 0, perPage: perPageInput, orderBy } = args;
682
+ const perPage = normalizePerPage(perPageInput, 100);
683
+ if (page < 0) {
684
+ throw new MastraError(
685
+ {
686
+ id: createStorageErrorId("CLICKHOUSE", "LIST_THREADS_BY_RESOURCE_ID", "INVALID_PAGE"),
687
+ domain: ErrorDomain.STORAGE,
688
+ category: ErrorCategory.USER,
689
+ details: { page }
690
+ },
691
+ new Error("page must be >= 0")
692
+ );
693
+ }
694
+ const { offset, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
695
+ const { field, direction } = this.parseOrderBy(orderBy);
696
+ try {
930
697
  const countResult = await this.client.query({
931
- query: countQuery,
932
- query_params: countParams,
698
+ query: `SELECT count(DISTINCT id) as total FROM ${TABLE_THREADS} WHERE resourceId = {resourceId:String}`,
699
+ query_params: { resourceId },
933
700
  clickhouse_settings: {
934
701
  date_time_input_format: "best_effort",
935
702
  date_time_output_format: "iso",
@@ -939,58 +706,46 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
939
706
  });
940
707
  const countData = await countResult.json();
941
708
  const total = countData.data[0].total;
942
- if (total === 0 && messages.length === 0) {
709
+ if (total === 0) {
943
710
  return {
944
- messages: [],
711
+ threads: [],
945
712
  total: 0,
946
713
  page,
947
- perPage,
714
+ perPage: perPageForResponse,
948
715
  hasMore: false
949
716
  };
950
717
  }
951
- const excludeIds = messages.map((m) => m.id);
952
- let dataQuery = `
953
- SELECT
954
- id,
955
- content,
956
- role,
957
- type,
958
- toDateTime64(createdAt, 3) as createdAt,
959
- thread_id AS "threadId",
960
- resourceId
961
- FROM ${TABLE_MESSAGES}
962
- WHERE thread_id = {threadId:String}
963
- `;
964
- const dataParams = { threadId };
965
- if (fromDate) {
966
- dataQuery += ` AND createdAt >= parseDateTime64BestEffort({fromDate:String}, 3)`;
967
- dataParams.fromDate = fromDate.toISOString();
968
- }
969
- if (toDate) {
970
- dataQuery += ` AND createdAt <= parseDateTime64BestEffort({toDate:String}, 3)`;
971
- dataParams.toDate = toDate.toISOString();
972
- }
973
- if (excludeIds.length > 0) {
974
- dataQuery += ` AND id NOT IN ({excludeIds:Array(String)})`;
975
- dataParams.excludeIds = excludeIds;
976
- }
977
- if (selectBy?.last) {
978
- dataQuery += `
979
- ORDER BY createdAt DESC
980
- LIMIT {limit:Int64}
981
- `;
982
- dataParams.limit = perPage;
983
- } else {
984
- dataQuery += `
985
- ORDER BY createdAt ASC
986
- LIMIT {limit:Int64} OFFSET {offset:Int64}
987
- `;
988
- dataParams.limit = perPage;
989
- dataParams.offset = offset;
990
- }
991
- const result = await this.client.query({
992
- query: dataQuery,
993
- query_params: dataParams,
718
+ const dataResult = await this.client.query({
719
+ query: `
720
+ WITH ranked_threads AS (
721
+ SELECT
722
+ id,
723
+ resourceId,
724
+ title,
725
+ metadata,
726
+ toDateTime64(createdAt, 3) as createdAt,
727
+ toDateTime64(updatedAt, 3) as updatedAt,
728
+ ROW_NUMBER() OVER (PARTITION BY id ORDER BY updatedAt DESC) as row_num
729
+ FROM ${TABLE_THREADS}
730
+ WHERE resourceId = {resourceId:String}
731
+ )
732
+ SELECT
733
+ id,
734
+ resourceId,
735
+ title,
736
+ metadata,
737
+ createdAt,
738
+ updatedAt
739
+ FROM ranked_threads
740
+ WHERE row_num = 1
741
+ ORDER BY "${field}" ${direction === "DESC" ? "DESC" : "ASC"}
742
+ LIMIT {perPage:Int64} OFFSET {offset:Int64}
743
+ `,
744
+ query_params: {
745
+ resourceId,
746
+ perPage,
747
+ offset
748
+ },
994
749
  clickhouse_settings: {
995
750
  date_time_input_format: "best_effort",
996
751
  date_time_output_format: "iso",
@@ -998,35 +753,28 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
998
753
  output_format_json_quote_64bit_integers: 0
999
754
  }
1000
755
  });
1001
- const rows = await result.json();
1002
- const paginatedMessages = transformRows(rows.data);
1003
- messages.push(...paginatedMessages);
1004
- if (selectBy?.last) {
1005
- messages.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime());
1006
- }
756
+ const rows = await dataResult.json();
757
+ const threads = transformRows(rows.data).map((thread) => ({
758
+ ...thread,
759
+ metadata: parseMetadata(thread.metadata)
760
+ }));
1007
761
  return {
1008
- messages: format === "v2" ? messages : messages,
762
+ threads,
1009
763
  total,
1010
764
  page,
1011
- perPage,
765
+ perPage: perPageForResponse,
1012
766
  hasMore: offset + perPage < total
1013
767
  };
1014
768
  } catch (error) {
1015
- const mastraError = new MastraError(
769
+ throw new MastraError(
1016
770
  {
1017
- id: "CLICKHOUSE_STORAGE_GET_MESSAGES_PAGINATED_FAILED",
771
+ id: createStorageErrorId("CLICKHOUSE", "LIST_THREADS_BY_RESOURCE_ID", "FAILED"),
1018
772
  domain: ErrorDomain.STORAGE,
1019
773
  category: ErrorCategory.THIRD_PARTY,
1020
- details: {
1021
- threadId,
1022
- resourceId: resourceId ?? ""
1023
- }
774
+ details: { resourceId, page }
1024
775
  },
1025
776
  error
1026
777
  );
1027
- this.logger?.trackException?.(mastraError);
1028
- this.logger?.error?.(mastraError.toString());
1029
- return { messages: [], total: 0, page, perPage: perPageInput || 40, hasMore: false };
1030
778
  }
1031
779
  }
1032
780
  async updateMessages(args) {
@@ -1109,7 +857,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1109
857
  UPDATE ${setClauses.join(", ")}
1110
858
  WHERE id = {var_id_${paramIdx}:String}
1111
859
  `;
1112
- console.log("Updating message:", id, "with query:", updateQuery, "values:", values);
860
+ console.info("Updating message:", id, "with query:", updateQuery, "values:", values);
1113
861
  updatePromises.push(
1114
862
  this.client.command({
1115
863
  query: updateQuery,
@@ -1168,7 +916,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1168
916
  }
1169
917
  }
1170
918
  if (needsRetry) {
1171
- console.log("Update not applied correctly, retrying with DELETE + INSERT for message:", id);
919
+ console.info("Update not applied correctly, retrying with DELETE + INSERT for message:", id);
1172
920
  await this.client.command({
1173
921
  query: `DELETE FROM ${TABLE_MESSAGES} WHERE id = {messageId:String}`,
1174
922
  query_params: { messageId: id },
@@ -1226,7 +974,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1226
974
  const now = (/* @__PURE__ */ new Date()).toISOString().replace("Z", "");
1227
975
  const threadUpdatePromises = Array.from(threadIdsToUpdate).map(async (threadId) => {
1228
976
  const threadResult = await this.client.query({
1229
- query: `SELECT id, resourceId, title, metadata, createdAt FROM ${TABLE_THREADS} WHERE id = {threadId:String}`,
977
+ query: `SELECT id, resourceId, title, metadata, createdAt FROM ${TABLE_THREADS} WHERE id = {threadId:String} ORDER BY updatedAt DESC LIMIT 1`,
1230
978
  query_params: { threadId },
1231
979
  clickhouse_settings: {
1232
980
  date_time_input_format: "best_effort",
@@ -1255,7 +1003,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1255
1003
  id: existingThread.id,
1256
1004
  resourceId: existingThread.resourceId,
1257
1005
  title: existingThread.title,
1258
- metadata: existingThread.metadata,
1006
+ metadata: typeof existingThread.metadata === "string" ? existingThread.metadata : serializeMetadata(existingThread.metadata),
1259
1007
  createdAt: existingThread.createdAt,
1260
1008
  updatedAt: now
1261
1009
  }
@@ -1302,7 +1050,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1302
1050
  } catch (error) {
1303
1051
  throw new MastraError(
1304
1052
  {
1305
- id: "CLICKHOUSE_STORAGE_UPDATE_MESSAGES_FAILED",
1053
+ id: createStorageErrorId("CLICKHOUSE", "UPDATE_MESSAGES", "FAILED"),
1306
1054
  domain: ErrorDomain.STORAGE,
1307
1055
  category: ErrorCategory.THIRD_PARTY,
1308
1056
  details: { messageIds: messages.map((m) => m.id).join(",") }
@@ -1314,7 +1062,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1314
1062
  async getResourceById({ resourceId }) {
1315
1063
  try {
1316
1064
  const result = await this.client.query({
1317
- query: `SELECT id, workingMemory, metadata, createdAt, updatedAt FROM ${TABLE_RESOURCES} WHERE id = {resourceId:String}`,
1065
+ query: `SELECT id, workingMemory, metadata, createdAt, updatedAt FROM ${TABLE_RESOURCES} WHERE id = {resourceId:String} ORDER BY updatedAt DESC LIMIT 1`,
1318
1066
  query_params: { resourceId },
1319
1067
  clickhouse_settings: {
1320
1068
  date_time_input_format: "best_effort",
@@ -1338,7 +1086,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1338
1086
  } catch (error) {
1339
1087
  throw new MastraError(
1340
1088
  {
1341
- id: "CLICKHOUSE_STORAGE_GET_RESOURCE_BY_ID_FAILED",
1089
+ id: createStorageErrorId("CLICKHOUSE", "GET_RESOURCE_BY_ID", "FAILED"),
1342
1090
  domain: ErrorDomain.STORAGE,
1343
1091
  category: ErrorCategory.THIRD_PARTY,
1344
1092
  details: { resourceId }
@@ -1371,7 +1119,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1371
1119
  } catch (error) {
1372
1120
  throw new MastraError(
1373
1121
  {
1374
- id: "CLICKHOUSE_STORAGE_SAVE_RESOURCE_FAILED",
1122
+ id: createStorageErrorId("CLICKHOUSE", "SAVE_RESOURCE", "FAILED"),
1375
1123
  domain: ErrorDomain.STORAGE,
1376
1124
  category: ErrorCategory.THIRD_PARTY,
1377
1125
  details: { resourceId: resource.id }
@@ -1437,7 +1185,7 @@ var MemoryStorageClickhouse = class extends MemoryStorage {
1437
1185
  } catch (error) {
1438
1186
  throw new MastraError(
1439
1187
  {
1440
- id: "CLICKHOUSE_STORAGE_UPDATE_RESOURCE_FAILED",
1188
+ id: createStorageErrorId("CLICKHOUSE", "UPDATE_RESOURCE", "FAILED"),
1441
1189
  domain: ErrorDomain.STORAGE,
1442
1190
  category: ErrorCategory.THIRD_PARTY,
1443
1191
  details: { resourceId }
@@ -1486,6 +1234,9 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1486
1234
  const columns = Object.entries(schema).map(([name, def]) => {
1487
1235
  const constraints = [];
1488
1236
  if (!def.nullable) constraints.push("NOT NULL");
1237
+ if (name === "metadata" && def.type === "text" && def.nullable) {
1238
+ constraints.push("DEFAULT '{}'");
1239
+ }
1489
1240
  const columnTtl = this.ttl?.[tableName]?.columns?.[name];
1490
1241
  return `"${name}" ${COLUMN_TYPES[def.type]} ${constraints.join(" ")} ${columnTtl ? `TTL toDateTime(${columnTtl.ttlKey ?? "createdAt"}) + INTERVAL ${columnTtl.interval} ${columnTtl.unit}` : ""}`;
1491
1242
  }).join(",\n");
@@ -1504,8 +1255,8 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1504
1255
  ${columns}
1505
1256
  )
1506
1257
  ENGINE = ${TABLE_ENGINES[tableName] ?? "MergeTree()"}
1507
- PRIMARY KEY (createdAt, ${tableName === TABLE_EVALS ? "run_id" : "id"})
1508
- ORDER BY (createdAt, ${tableName === TABLE_EVALS ? "run_id" : "id"})
1258
+ PRIMARY KEY (createdAt, ${"id"})
1259
+ ORDER BY (createdAt, ${"id"})
1509
1260
  ${this.ttl?.[tableName]?.row ? `TTL toDateTime(createdAt) + INTERVAL ${this.ttl[tableName].row.interval} ${this.ttl[tableName].row.unit}` : ""}
1510
1261
  SETTINGS index_granularity = 8192
1511
1262
  `;
@@ -1522,7 +1273,7 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1522
1273
  } catch (error) {
1523
1274
  throw new MastraError(
1524
1275
  {
1525
- id: "CLICKHOUSE_STORAGE_CREATE_TABLE_FAILED",
1276
+ id: createStorageErrorId("CLICKHOUSE", "CREATE_TABLE", "FAILED"),
1526
1277
  domain: ErrorDomain.STORAGE,
1527
1278
  category: ErrorCategory.THIRD_PARTY,
1528
1279
  details: { tableName }
@@ -1561,7 +1312,7 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1561
1312
  } catch (error) {
1562
1313
  throw new MastraError(
1563
1314
  {
1564
- id: "CLICKHOUSE_STORAGE_ALTER_TABLE_FAILED",
1315
+ id: createStorageErrorId("CLICKHOUSE", "ALTER_TABLE", "FAILED"),
1565
1316
  domain: ErrorDomain.STORAGE,
1566
1317
  category: ErrorCategory.THIRD_PARTY,
1567
1318
  details: { tableName }
@@ -1585,7 +1336,7 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1585
1336
  } catch (error) {
1586
1337
  throw new MastraError(
1587
1338
  {
1588
- id: "CLICKHOUSE_STORAGE_CLEAR_TABLE_FAILED",
1339
+ id: createStorageErrorId("CLICKHOUSE", "CLEAR_TABLE", "FAILED"),
1589
1340
  domain: ErrorDomain.STORAGE,
1590
1341
  category: ErrorCategory.THIRD_PARTY,
1591
1342
  details: { tableName }
@@ -1620,11 +1371,11 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1620
1371
  use_client_time_zone: 1
1621
1372
  }
1622
1373
  });
1623
- console.log("INSERT RESULT", result);
1374
+ console.info("INSERT RESULT", result);
1624
1375
  } catch (error) {
1625
1376
  throw new MastraError(
1626
1377
  {
1627
- id: "CLICKHOUSE_STORAGE_INSERT_FAILED",
1378
+ id: createStorageErrorId("CLICKHOUSE", "INSERT", "FAILED"),
1628
1379
  domain: ErrorDomain.STORAGE,
1629
1380
  category: ErrorCategory.THIRD_PARTY,
1630
1381
  details: { tableName }
@@ -1657,7 +1408,7 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1657
1408
  } catch (error) {
1658
1409
  throw new MastraError(
1659
1410
  {
1660
- id: "CLICKHOUSE_STORAGE_BATCH_INSERT_FAILED",
1411
+ id: createStorageErrorId("CLICKHOUSE", "BATCH_INSERT", "FAILED"),
1661
1412
  domain: ErrorDomain.STORAGE,
1662
1413
  category: ErrorCategory.THIRD_PARTY,
1663
1414
  details: { tableName }
@@ -1708,7 +1459,7 @@ var StoreOperationsClickhouse = class extends StoreOperations {
1708
1459
  } catch (error) {
1709
1460
  throw new MastraError(
1710
1461
  {
1711
- id: "CLICKHOUSE_STORAGE_LOAD_FAILED",
1462
+ id: createStorageErrorId("CLICKHOUSE", "LOAD", "FAILED"),
1712
1463
  domain: ErrorDomain.STORAGE,
1713
1464
  category: ErrorCategory.THIRD_PARTY,
1714
1465
  details: { tableName }
@@ -1726,30 +1477,15 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1726
1477
  this.client = client;
1727
1478
  this.operations = operations;
1728
1479
  }
1480
+ /**
1481
+ * ClickHouse-specific score row transformation.
1482
+ * Converts timestamps to Date objects and filters out '_null_' values.
1483
+ */
1729
1484
  transformScoreRow(row) {
1730
- const scorer = safelyParseJSON(row.scorer);
1731
- const preprocessStepResult = safelyParseJSON(row.preprocessStepResult);
1732
- const analyzeStepResult = safelyParseJSON(row.analyzeStepResult);
1733
- const metadata = safelyParseJSON(row.metadata);
1734
- const input = safelyParseJSON(row.input);
1735
- const output = safelyParseJSON(row.output);
1736
- const additionalContext = safelyParseJSON(row.additionalContext);
1737
- const runtimeContext = safelyParseJSON(row.runtimeContext);
1738
- const entity = safelyParseJSON(row.entity);
1739
- return {
1740
- ...row,
1741
- scorer,
1742
- preprocessStepResult,
1743
- analyzeStepResult,
1744
- metadata,
1745
- input,
1746
- output,
1747
- additionalContext,
1748
- runtimeContext,
1749
- entity,
1750
- createdAt: new Date(row.createdAt),
1751
- updatedAt: new Date(row.updatedAt)
1752
- };
1485
+ return transformScoreRow(row, {
1486
+ convertTimestamps: true,
1487
+ nullValuePattern: "_null_"
1488
+ });
1753
1489
  }
1754
1490
  async getScoreById({ id }) {
1755
1491
  try {
@@ -1773,7 +1509,7 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1773
1509
  } catch (error) {
1774
1510
  throw new MastraError(
1775
1511
  {
1776
- id: "CLICKHOUSE_STORAGE_GET_SCORE_BY_ID_FAILED",
1512
+ id: createStorageErrorId("CLICKHOUSE", "GET_SCORE_BY_ID", "FAILED"),
1777
1513
  domain: ErrorDomain.STORAGE,
1778
1514
  category: ErrorCategory.THIRD_PARTY,
1779
1515
  details: { scoreId: id }
@@ -1783,10 +1519,44 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1783
1519
  }
1784
1520
  }
1785
1521
  async saveScore(score) {
1522
+ let parsedScore;
1786
1523
  try {
1787
- const record = {
1788
- ...score
1789
- };
1524
+ parsedScore = saveScorePayloadSchema.parse(score);
1525
+ } catch (error) {
1526
+ throw new MastraError(
1527
+ {
1528
+ id: createStorageErrorId("CLICKHOUSE", "SAVE_SCORE", "VALIDATION_FAILED"),
1529
+ domain: ErrorDomain.STORAGE,
1530
+ category: ErrorCategory.USER,
1531
+ details: {
1532
+ scorer: score.scorer?.id ?? "unknown",
1533
+ entityId: score.entityId ?? "unknown",
1534
+ entityType: score.entityType ?? "unknown",
1535
+ traceId: score.traceId ?? "",
1536
+ spanId: score.spanId ?? ""
1537
+ }
1538
+ },
1539
+ error
1540
+ );
1541
+ }
1542
+ const now = /* @__PURE__ */ new Date();
1543
+ const id = crypto.randomUUID();
1544
+ const createdAt = now;
1545
+ const updatedAt = now;
1546
+ try {
1547
+ const record = {};
1548
+ for (const key of Object.keys(SCORERS_SCHEMA)) {
1549
+ if (key === "id") {
1550
+ record[key] = id;
1551
+ continue;
1552
+ }
1553
+ if (key === "createdAt" || key === "updatedAt") {
1554
+ record[key] = now.toISOString();
1555
+ continue;
1556
+ }
1557
+ const value = parsedScore[key];
1558
+ record[key] = value === void 0 || value === null ? "_null_" : value;
1559
+ }
1790
1560
  await this.client.insert({
1791
1561
  table: TABLE_SCORERS,
1792
1562
  values: [record],
@@ -1797,20 +1567,20 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1797
1567
  output_format_json_quote_64bit_integers: 0
1798
1568
  }
1799
1569
  });
1800
- return { score };
1570
+ return { score: { ...parsedScore, id, createdAt, updatedAt } };
1801
1571
  } catch (error) {
1802
1572
  throw new MastraError(
1803
1573
  {
1804
- id: "CLICKHOUSE_STORAGE_SAVE_SCORE_FAILED",
1574
+ id: createStorageErrorId("CLICKHOUSE", "SAVE_SCORE", "FAILED"),
1805
1575
  domain: ErrorDomain.STORAGE,
1806
1576
  category: ErrorCategory.THIRD_PARTY,
1807
- details: { scoreId: score.id }
1577
+ details: { scoreId: id }
1808
1578
  },
1809
1579
  error
1810
1580
  );
1811
1581
  }
1812
1582
  }
1813
- async getScoresByRunId({
1583
+ async listScoresByRunId({
1814
1584
  runId,
1815
1585
  pagination
1816
1586
  }) {
@@ -1826,24 +1596,28 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1826
1596
  const countObj = countRows[0];
1827
1597
  total = Number(countObj.count);
1828
1598
  }
1599
+ const { page, perPage: perPageInput } = pagination;
1829
1600
  if (!total) {
1830
1601
  return {
1831
1602
  pagination: {
1832
1603
  total: 0,
1833
- page: pagination.page,
1834
- perPage: pagination.perPage,
1604
+ page,
1605
+ perPage: perPageInput,
1835
1606
  hasMore: false
1836
1607
  },
1837
1608
  scores: []
1838
1609
  };
1839
1610
  }
1840
- const offset = pagination.page * pagination.perPage;
1611
+ const perPage = normalizePerPage(perPageInput, 100);
1612
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1613
+ const limitValue = perPageInput === false ? total : perPage;
1614
+ const end = perPageInput === false ? total : start + perPage;
1841
1615
  const result = await this.client.query({
1842
1616
  query: `SELECT * FROM ${TABLE_SCORERS} WHERE runId = {var_runId:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
1843
1617
  query_params: {
1844
1618
  var_runId: runId,
1845
- var_limit: pagination.perPage,
1846
- var_offset: offset
1619
+ var_limit: limitValue,
1620
+ var_offset: start
1847
1621
  },
1848
1622
  format: "JSONEachRow",
1849
1623
  clickhouse_settings: {
@@ -1858,16 +1632,16 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1858
1632
  return {
1859
1633
  pagination: {
1860
1634
  total,
1861
- page: pagination.page,
1862
- perPage: pagination.perPage,
1863
- hasMore: total > (pagination.page + 1) * pagination.perPage
1635
+ page,
1636
+ perPage: perPageForResponse,
1637
+ hasMore: end < total
1864
1638
  },
1865
1639
  scores
1866
1640
  };
1867
1641
  } catch (error) {
1868
1642
  throw new MastraError(
1869
1643
  {
1870
- id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_RUN_ID_FAILED",
1644
+ id: createStorageErrorId("CLICKHOUSE", "LIST_SCORES_BY_RUN_ID", "FAILED"),
1871
1645
  domain: ErrorDomain.STORAGE,
1872
1646
  category: ErrorCategory.THIRD_PARTY,
1873
1647
  details: { runId }
@@ -1876,7 +1650,7 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1876
1650
  );
1877
1651
  }
1878
1652
  }
1879
- async getScoresByScorerId({
1653
+ async listScoresByScorerId({
1880
1654
  scorerId,
1881
1655
  entityId,
1882
1656
  entityType,
@@ -1910,24 +1684,28 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1910
1684
  const countObj = countRows[0];
1911
1685
  total = Number(countObj.count);
1912
1686
  }
1687
+ const { page, perPage: perPageInput } = pagination;
1913
1688
  if (!total) {
1914
1689
  return {
1915
1690
  pagination: {
1916
1691
  total: 0,
1917
- page: pagination.page,
1918
- perPage: pagination.perPage,
1692
+ page,
1693
+ perPage: perPageInput,
1919
1694
  hasMore: false
1920
1695
  },
1921
1696
  scores: []
1922
1697
  };
1923
1698
  }
1924
- const offset = pagination.page * pagination.perPage;
1699
+ const perPage = normalizePerPage(perPageInput, 100);
1700
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1701
+ const limitValue = perPageInput === false ? total : perPage;
1702
+ const end = perPageInput === false ? total : start + perPage;
1925
1703
  const result = await this.client.query({
1926
1704
  query: `SELECT * FROM ${TABLE_SCORERS} WHERE ${whereClause} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
1927
1705
  query_params: {
1928
1706
  var_scorerId: scorerId,
1929
- var_limit: pagination.perPage,
1930
- var_offset: offset,
1707
+ var_limit: limitValue,
1708
+ var_offset: start,
1931
1709
  var_entityId: entityId,
1932
1710
  var_entityType: entityType,
1933
1711
  var_source: source
@@ -1945,16 +1723,16 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1945
1723
  return {
1946
1724
  pagination: {
1947
1725
  total,
1948
- page: pagination.page,
1949
- perPage: pagination.perPage,
1950
- hasMore: total > (pagination.page + 1) * pagination.perPage
1726
+ page,
1727
+ perPage: perPageForResponse,
1728
+ hasMore: end < total
1951
1729
  },
1952
1730
  scores
1953
1731
  };
1954
1732
  } catch (error) {
1955
1733
  throw new MastraError(
1956
1734
  {
1957
- id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_SCORER_ID_FAILED",
1735
+ id: createStorageErrorId("CLICKHOUSE", "LIST_SCORES_BY_SCORER_ID", "FAILED"),
1958
1736
  domain: ErrorDomain.STORAGE,
1959
1737
  category: ErrorCategory.THIRD_PARTY,
1960
1738
  details: { scorerId }
@@ -1963,7 +1741,7 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1963
1741
  );
1964
1742
  }
1965
1743
  }
1966
- async getScoresByEntityId({
1744
+ async listScoresByEntityId({
1967
1745
  entityId,
1968
1746
  entityType,
1969
1747
  pagination
@@ -1980,25 +1758,29 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
1980
1758
  const countObj = countRows[0];
1981
1759
  total = Number(countObj.count);
1982
1760
  }
1761
+ const { page, perPage: perPageInput } = pagination;
1983
1762
  if (!total) {
1984
1763
  return {
1985
1764
  pagination: {
1986
1765
  total: 0,
1987
- page: pagination.page,
1988
- perPage: pagination.perPage,
1766
+ page,
1767
+ perPage: perPageInput,
1989
1768
  hasMore: false
1990
1769
  },
1991
1770
  scores: []
1992
1771
  };
1993
1772
  }
1994
- const offset = pagination.page * pagination.perPage;
1773
+ const perPage = normalizePerPage(perPageInput, 100);
1774
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1775
+ const limitValue = perPageInput === false ? total : perPage;
1776
+ const end = perPageInput === false ? total : start + perPage;
1995
1777
  const result = await this.client.query({
1996
1778
  query: `SELECT * FROM ${TABLE_SCORERS} WHERE entityId = {var_entityId:String} AND entityType = {var_entityType:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
1997
1779
  query_params: {
1998
1780
  var_entityId: entityId,
1999
1781
  var_entityType: entityType,
2000
- var_limit: pagination.perPage,
2001
- var_offset: offset
1782
+ var_limit: limitValue,
1783
+ var_offset: start
2002
1784
  },
2003
1785
  format: "JSONEachRow",
2004
1786
  clickhouse_settings: {
@@ -2013,16 +1795,16 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
2013
1795
  return {
2014
1796
  pagination: {
2015
1797
  total,
2016
- page: pagination.page,
2017
- perPage: pagination.perPage,
2018
- hasMore: total > (pagination.page + 1) * pagination.perPage
1798
+ page,
1799
+ perPage: perPageForResponse,
1800
+ hasMore: end < total
2019
1801
  },
2020
1802
  scores
2021
1803
  };
2022
1804
  } catch (error) {
2023
1805
  throw new MastraError(
2024
1806
  {
2025
- id: "CLICKHOUSE_STORAGE_GET_SCORES_BY_ENTITY_ID_FAILED",
1807
+ id: createStorageErrorId("CLICKHOUSE", "LIST_SCORES_BY_ENTITY_ID", "FAILED"),
2026
1808
  domain: ErrorDomain.STORAGE,
2027
1809
  category: ErrorCategory.THIRD_PARTY,
2028
1810
  details: { entityId, entityType }
@@ -2031,76 +1813,51 @@ var ScoresStorageClickhouse = class extends ScoresStorage {
2031
1813
  );
2032
1814
  }
2033
1815
  }
2034
- };
2035
- var TracesStorageClickhouse = class extends TracesStorage {
2036
- client;
2037
- operations;
2038
- constructor({ client, operations }) {
2039
- super();
2040
- this.client = client;
2041
- this.operations = operations;
2042
- }
2043
- async getTracesPaginated(args) {
2044
- const { name, scope, page = 0, perPage = 100, attributes, filters, dateRange } = args;
2045
- const fromDate = dateRange?.start;
2046
- const toDate = dateRange?.end;
2047
- const currentOffset = page * perPage;
2048
- const queryArgs = {};
2049
- const conditions = [];
2050
- if (name) {
2051
- conditions.push(`name LIKE CONCAT({var_name:String}, '%')`);
2052
- queryArgs.var_name = name;
2053
- }
2054
- if (scope) {
2055
- conditions.push(`scope = {var_scope:String}`);
2056
- queryArgs.var_scope = scope;
2057
- }
2058
- if (attributes) {
2059
- Object.entries(attributes).forEach(([key, value]) => {
2060
- conditions.push(`JSONExtractString(attributes, '${key}') = {var_attr_${key}:String}`);
2061
- queryArgs[`var_attr_${key}`] = value;
2062
- });
2063
- }
2064
- if (filters) {
2065
- Object.entries(filters).forEach(([key, value]) => {
2066
- conditions.push(`${key} = {var_col_${key}:${TABLE_SCHEMAS.mastra_traces?.[key]?.type ?? "text"}}`);
2067
- queryArgs[`var_col_${key}`] = value;
2068
- });
2069
- }
2070
- if (fromDate) {
2071
- conditions.push(`createdAt >= parseDateTime64BestEffort({var_from_date:String})`);
2072
- queryArgs.var_from_date = fromDate.toISOString();
2073
- }
2074
- if (toDate) {
2075
- conditions.push(`createdAt <= parseDateTime64BestEffort({var_to_date:String})`);
2076
- queryArgs.var_to_date = toDate.toISOString();
2077
- }
2078
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
1816
+ async listScoresBySpan({
1817
+ traceId,
1818
+ spanId,
1819
+ pagination
1820
+ }) {
2079
1821
  try {
2080
1822
  const countResult = await this.client.query({
2081
- query: `SELECT COUNT(*) as count FROM ${TABLE_TRACES} ${whereClause}`,
2082
- query_params: queryArgs,
2083
- clickhouse_settings: {
2084
- date_time_input_format: "best_effort",
2085
- date_time_output_format: "iso",
2086
- use_client_time_zone: 1,
2087
- output_format_json_quote_64bit_integers: 0
2088
- }
1823
+ query: `SELECT COUNT(*) as count FROM ${TABLE_SCORERS} WHERE traceId = {var_traceId:String} AND spanId = {var_spanId:String}`,
1824
+ query_params: {
1825
+ var_traceId: traceId,
1826
+ var_spanId: spanId
1827
+ },
1828
+ format: "JSONEachRow"
2089
1829
  });
2090
- const countData = await countResult.json();
2091
- const total = Number(countData.data?.[0]?.count ?? 0);
2092
- if (total === 0) {
1830
+ const countRows = await countResult.json();
1831
+ let total = 0;
1832
+ if (Array.isArray(countRows) && countRows.length > 0 && countRows[0]) {
1833
+ const countObj = countRows[0];
1834
+ total = Number(countObj.count);
1835
+ }
1836
+ const { page, perPage: perPageInput } = pagination;
1837
+ if (!total) {
2093
1838
  return {
2094
- traces: [],
2095
- total: 0,
2096
- page,
2097
- perPage,
2098
- hasMore: false
1839
+ pagination: {
1840
+ total: 0,
1841
+ page,
1842
+ perPage: perPageInput,
1843
+ hasMore: false
1844
+ },
1845
+ scores: []
2099
1846
  };
2100
1847
  }
1848
+ const perPage = normalizePerPage(perPageInput, 100);
1849
+ const { offset: start, perPage: perPageForResponse } = calculatePagination(page, perPageInput, perPage);
1850
+ const limitValue = perPageInput === false ? total : perPage;
1851
+ const end = perPageInput === false ? total : start + perPage;
2101
1852
  const result = await this.client.query({
2102
- query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${TABLE_TRACES} ${whereClause} ORDER BY "createdAt" DESC LIMIT {var_limit:UInt32} OFFSET {var_offset:UInt32}`,
2103
- query_params: { ...queryArgs, var_limit: perPage, var_offset: currentOffset },
1853
+ query: `SELECT * FROM ${TABLE_SCORERS} WHERE traceId = {var_traceId:String} AND spanId = {var_spanId:String} ORDER BY createdAt DESC LIMIT {var_limit:Int64} OFFSET {var_offset:Int64}`,
1854
+ query_params: {
1855
+ var_traceId: traceId,
1856
+ var_spanId: spanId,
1857
+ var_limit: limitValue,
1858
+ var_offset: start
1859
+ },
1860
+ format: "JSONEachRow",
2104
1861
  clickhouse_settings: {
2105
1862
  date_time_input_format: "best_effort",
2106
1863
  date_time_output_format: "iso",
@@ -2108,172 +1865,29 @@ var TracesStorageClickhouse = class extends TracesStorage {
2108
1865
  output_format_json_quote_64bit_integers: 0
2109
1866
  }
2110
1867
  });
2111
- if (!result) {
2112
- return {
2113
- traces: [],
2114
- total,
2115
- page,
2116
- perPage,
2117
- hasMore: false
2118
- };
2119
- }
2120
- const resp = await result.json();
2121
- const rows = resp.data;
2122
- const traces = rows.map((row) => ({
2123
- id: row.id,
2124
- parentSpanId: row.parentSpanId,
2125
- traceId: row.traceId,
2126
- name: row.name,
2127
- scope: row.scope,
2128
- kind: row.kind,
2129
- status: safelyParseJSON(row.status),
2130
- events: safelyParseJSON(row.events),
2131
- links: safelyParseJSON(row.links),
2132
- attributes: safelyParseJSON(row.attributes),
2133
- startTime: row.startTime,
2134
- endTime: row.endTime,
2135
- other: safelyParseJSON(row.other),
2136
- createdAt: row.createdAt
2137
- }));
1868
+ const rows = await result.json();
1869
+ const scores = Array.isArray(rows) ? rows.map((row) => this.transformScoreRow(row)) : [];
2138
1870
  return {
2139
- traces,
2140
- total,
2141
- page,
2142
- perPage,
2143
- hasMore: currentOffset + traces.length < total
2144
- };
2145
- } catch (error) {
2146
- if (error?.message?.includes("no such table") || error?.message?.includes("does not exist")) {
2147
- return {
2148
- traces: [],
2149
- total: 0,
1871
+ pagination: {
1872
+ total,
2150
1873
  page,
2151
- perPage,
2152
- hasMore: false
2153
- };
2154
- }
2155
- throw new MastraError(
2156
- {
2157
- id: "CLICKHOUSE_STORAGE_GET_TRACES_PAGINATED_FAILED",
2158
- domain: ErrorDomain.STORAGE,
2159
- category: ErrorCategory.THIRD_PARTY,
2160
- details: {
2161
- name: name ?? null,
2162
- scope: scope ?? null,
2163
- page,
2164
- perPage,
2165
- attributes: attributes ? JSON.stringify(attributes) : null,
2166
- filters: filters ? JSON.stringify(filters) : null,
2167
- dateRange: dateRange ? JSON.stringify(dateRange) : null
2168
- }
1874
+ perPage: perPageForResponse,
1875
+ hasMore: end < total
2169
1876
  },
2170
- error
2171
- );
2172
- }
2173
- }
2174
- async getTraces({
2175
- name,
2176
- scope,
2177
- page,
2178
- perPage,
2179
- attributes,
2180
- filters,
2181
- fromDate,
2182
- toDate
2183
- }) {
2184
- const limit = perPage;
2185
- const offset = page * perPage;
2186
- const args = {};
2187
- const conditions = [];
2188
- if (name) {
2189
- conditions.push(`name LIKE CONCAT({var_name:String}, '%')`);
2190
- args.var_name = name;
2191
- }
2192
- if (scope) {
2193
- conditions.push(`scope = {var_scope:String}`);
2194
- args.var_scope = scope;
2195
- }
2196
- if (attributes) {
2197
- Object.entries(attributes).forEach(([key, value]) => {
2198
- conditions.push(`JSONExtractString(attributes, '${key}') = {var_attr_${key}:String}`);
2199
- args[`var_attr_${key}`] = value;
2200
- });
2201
- }
2202
- if (filters) {
2203
- Object.entries(filters).forEach(([key, value]) => {
2204
- conditions.push(`${key} = {var_col_${key}:${TABLE_SCHEMAS.mastra_traces?.[key]?.type ?? "text"}}`);
2205
- args[`var_col_${key}`] = value;
2206
- });
2207
- }
2208
- if (fromDate) {
2209
- conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
2210
- args.var_from_date = fromDate.getTime() / 1e3;
2211
- }
2212
- if (toDate) {
2213
- conditions.push(`createdAt <= {var_to_date:DateTime64(3)}`);
2214
- args.var_to_date = toDate.getTime() / 1e3;
2215
- }
2216
- const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2217
- try {
2218
- const result = await this.client.query({
2219
- query: `SELECT *, toDateTime64(createdAt, 3) as createdAt FROM ${TABLE_TRACES} ${whereClause} ORDER BY "createdAt" DESC LIMIT ${limit} OFFSET ${offset}`,
2220
- query_params: args,
2221
- clickhouse_settings: {
2222
- // Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
2223
- date_time_input_format: "best_effort",
2224
- date_time_output_format: "iso",
2225
- use_client_time_zone: 1,
2226
- output_format_json_quote_64bit_integers: 0
2227
- }
2228
- });
2229
- if (!result) {
2230
- return [];
2231
- }
2232
- const resp = await result.json();
2233
- const rows = resp.data;
2234
- return rows.map((row) => ({
2235
- id: row.id,
2236
- parentSpanId: row.parentSpanId,
2237
- traceId: row.traceId,
2238
- name: row.name,
2239
- scope: row.scope,
2240
- kind: row.kind,
2241
- status: safelyParseJSON(row.status),
2242
- events: safelyParseJSON(row.events),
2243
- links: safelyParseJSON(row.links),
2244
- attributes: safelyParseJSON(row.attributes),
2245
- startTime: row.startTime,
2246
- endTime: row.endTime,
2247
- other: safelyParseJSON(row.other),
2248
- createdAt: row.createdAt
2249
- }));
1877
+ scores
1878
+ };
2250
1879
  } catch (error) {
2251
- if (error?.message?.includes("no such table") || error?.message?.includes("does not exist")) {
2252
- return [];
2253
- }
2254
1880
  throw new MastraError(
2255
1881
  {
2256
- id: "CLICKHOUSE_STORAGE_GET_TRACES_FAILED",
1882
+ id: createStorageErrorId("CLICKHOUSE", "LIST_SCORES_BY_SPAN", "FAILED"),
2257
1883
  domain: ErrorDomain.STORAGE,
2258
1884
  category: ErrorCategory.THIRD_PARTY,
2259
- details: {
2260
- name: name ?? null,
2261
- scope: scope ?? null,
2262
- page,
2263
- perPage,
2264
- attributes: attributes ? JSON.stringify(attributes) : null,
2265
- filters: filters ? JSON.stringify(filters) : null,
2266
- fromDate: fromDate?.toISOString() ?? null,
2267
- toDate: toDate?.toISOString() ?? null
2268
- }
1885
+ details: { traceId, spanId }
2269
1886
  },
2270
1887
  error
2271
1888
  );
2272
1889
  }
2273
1890
  }
2274
- async batchTraceInsert(args) {
2275
- await this.operations.batchInsert({ tableName: TABLE_TRACES, records: args.records });
2276
- }
2277
1891
  };
2278
1892
  var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2279
1893
  client;
@@ -2288,16 +1902,26 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2288
1902
  // runId,
2289
1903
  // stepId,
2290
1904
  // result,
2291
- // runtimeContext,
1905
+ // requestContext,
2292
1906
  }) {
2293
- throw new Error("Method not implemented.");
1907
+ throw new MastraError({
1908
+ id: createStorageErrorId("CLICKHOUSE", "UPDATE_WORKFLOW_RESULTS", "NOT_IMPLEMENTED"),
1909
+ domain: ErrorDomain.STORAGE,
1910
+ category: ErrorCategory.SYSTEM,
1911
+ text: "Method not implemented."
1912
+ });
2294
1913
  }
2295
1914
  updateWorkflowState({
2296
1915
  // workflowName,
2297
1916
  // runId,
2298
1917
  // opts,
2299
1918
  }) {
2300
- throw new Error("Method not implemented.");
1919
+ throw new MastraError({
1920
+ id: createStorageErrorId("CLICKHOUSE", "UPDATE_WORKFLOW_STATE", "NOT_IMPLEMENTED"),
1921
+ domain: ErrorDomain.STORAGE,
1922
+ category: ErrorCategory.SYSTEM,
1923
+ text: "Method not implemented."
1924
+ });
2301
1925
  }
2302
1926
  async persistWorkflowSnapshot({
2303
1927
  workflowName,
@@ -2338,7 +1962,7 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2338
1962
  } catch (error) {
2339
1963
  throw new MastraError(
2340
1964
  {
2341
- id: "CLICKHOUSE_STORAGE_PERSIST_WORKFLOW_SNAPSHOT_FAILED",
1965
+ id: createStorageErrorId("CLICKHOUSE", "PERSIST_WORKFLOW_SNAPSHOT", "FAILED"),
2342
1966
  domain: ErrorDomain.STORAGE,
2343
1967
  category: ErrorCategory.THIRD_PARTY,
2344
1968
  details: { workflowName, runId }
@@ -2366,7 +1990,7 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2366
1990
  } catch (error) {
2367
1991
  throw new MastraError(
2368
1992
  {
2369
- id: "CLICKHOUSE_STORAGE_LOAD_WORKFLOW_SNAPSHOT_FAILED",
1993
+ id: createStorageErrorId("CLICKHOUSE", "LOAD_WORKFLOW_SNAPSHOT", "FAILED"),
2370
1994
  domain: ErrorDomain.STORAGE,
2371
1995
  category: ErrorCategory.THIRD_PARTY,
2372
1996
  details: { workflowName, runId }
@@ -2393,13 +2017,14 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2393
2017
  resourceId: row.resourceId
2394
2018
  };
2395
2019
  }
2396
- async getWorkflowRuns({
2020
+ async listWorkflowRuns({
2397
2021
  workflowName,
2398
2022
  fromDate,
2399
2023
  toDate,
2400
- limit,
2401
- offset,
2402
- resourceId
2024
+ page,
2025
+ perPage,
2026
+ resourceId,
2027
+ status
2403
2028
  } = {}) {
2404
2029
  try {
2405
2030
  const conditions = [];
@@ -2408,6 +2033,10 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2408
2033
  conditions.push(`workflow_name = {var_workflow_name:String}`);
2409
2034
  values.var_workflow_name = workflowName;
2410
2035
  }
2036
+ if (status) {
2037
+ conditions.push(`JSONExtractString(snapshot, 'status') = {var_status:String}`);
2038
+ values.var_status = status;
2039
+ }
2411
2040
  if (resourceId) {
2412
2041
  const hasResourceId = await this.operations.hasColumn(TABLE_WORKFLOW_SNAPSHOT, "resourceId");
2413
2042
  if (hasResourceId) {
@@ -2426,10 +2055,13 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2426
2055
  values.var_to_date = toDate.getTime() / 1e3;
2427
2056
  }
2428
2057
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
2429
- const limitClause = limit !== void 0 ? `LIMIT ${limit}` : "";
2430
- const offsetClause = offset !== void 0 ? `OFFSET ${offset}` : "";
2058
+ const usePagination = perPage !== void 0 && page !== void 0;
2059
+ const normalizedPerPage = usePagination ? normalizePerPage(perPage, Number.MAX_SAFE_INTEGER) : 0;
2060
+ const offset = usePagination ? page * normalizedPerPage : 0;
2061
+ const limitClause = usePagination ? `LIMIT ${normalizedPerPage}` : "";
2062
+ const offsetClause = usePagination ? `OFFSET ${offset}` : "";
2431
2063
  let total = 0;
2432
- if (limit !== void 0 && offset !== void 0) {
2064
+ if (usePagination) {
2433
2065
  const countResult = await this.client.query({
2434
2066
  query: `SELECT COUNT(*) as count FROM ${TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[TABLE_WORKFLOW_SNAPSHOT].startsWith("ReplacingMergeTree") ? "FINAL" : ""} ${whereClause}`,
2435
2067
  query_params: values,
@@ -2465,7 +2097,7 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2465
2097
  } catch (error) {
2466
2098
  throw new MastraError(
2467
2099
  {
2468
- id: "CLICKHOUSE_STORAGE_GET_WORKFLOW_RUNS_FAILED",
2100
+ id: createStorageErrorId("CLICKHOUSE", "LIST_WORKFLOW_RUNS", "FAILED"),
2469
2101
  domain: ErrorDomain.STORAGE,
2470
2102
  category: ErrorCategory.THIRD_PARTY,
2471
2103
  details: { workflowName: workflowName ?? "", resourceId: resourceId ?? "" }
@@ -2514,7 +2146,7 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2514
2146
  } catch (error) {
2515
2147
  throw new MastraError(
2516
2148
  {
2517
- id: "CLICKHOUSE_STORAGE_GET_WORKFLOW_RUN_BY_ID_FAILED",
2149
+ id: createStorageErrorId("CLICKHOUSE", "GET_WORKFLOW_RUN_BY_ID", "FAILED"),
2518
2150
  domain: ErrorDomain.STORAGE,
2519
2151
  category: ErrorCategory.THIRD_PARTY,
2520
2152
  details: { runId: runId ?? "", workflowName: workflowName ?? "" }
@@ -2523,6 +2155,28 @@ var WorkflowsStorageClickhouse = class extends WorkflowsStorage {
2523
2155
  );
2524
2156
  }
2525
2157
  }
2158
+ async deleteWorkflowRunById({ runId, workflowName }) {
2159
+ try {
2160
+ const values = {
2161
+ var_runId: runId,
2162
+ var_workflow_name: workflowName
2163
+ };
2164
+ await this.client.command({
2165
+ query: `DELETE FROM ${TABLE_WORKFLOW_SNAPSHOT} WHERE run_id = {var_runId:String} AND workflow_name = {var_workflow_name:String}`,
2166
+ query_params: values
2167
+ });
2168
+ } catch (error) {
2169
+ throw new MastraError(
2170
+ {
2171
+ id: createStorageErrorId("CLICKHOUSE", "DELETE_WORKFLOW_RUN_BY_ID", "FAILED"),
2172
+ domain: ErrorDomain.STORAGE,
2173
+ category: ErrorCategory.THIRD_PARTY,
2174
+ details: { runId, workflowName }
2175
+ },
2176
+ error
2177
+ );
2178
+ }
2179
+ }
2526
2180
  };
2527
2181
 
2528
2182
  // src/storage/index.ts
@@ -2531,7 +2185,7 @@ var ClickhouseStore = class extends MastraStorage {
2531
2185
  ttl = {};
2532
2186
  stores;
2533
2187
  constructor(config) {
2534
- super({ name: "ClickhouseStore" });
2188
+ super({ id: config.id, name: "ClickhouseStore", disableInit: config.disableInit });
2535
2189
  this.db = createClient({
2536
2190
  url: config.url,
2537
2191
  username: config.username,
@@ -2548,15 +2202,11 @@ var ClickhouseStore = class extends MastraStorage {
2548
2202
  const operations = new StoreOperationsClickhouse({ client: this.db, ttl: this.ttl });
2549
2203
  const workflows = new WorkflowsStorageClickhouse({ client: this.db, operations });
2550
2204
  const scores = new ScoresStorageClickhouse({ client: this.db, operations });
2551
- const legacyEvals = new LegacyEvalsStorageClickhouse({ client: this.db, operations });
2552
- const traces = new TracesStorageClickhouse({ client: this.db, operations });
2553
2205
  const memory = new MemoryStorageClickhouse({ client: this.db, operations });
2554
2206
  this.stores = {
2555
2207
  operations,
2556
2208
  workflows,
2557
2209
  scores,
2558
- legacyEvals,
2559
- traces,
2560
2210
  memory
2561
2211
  };
2562
2212
  }
@@ -2566,15 +2216,10 @@ var ClickhouseStore = class extends MastraStorage {
2566
2216
  resourceWorkingMemory: true,
2567
2217
  hasColumn: true,
2568
2218
  createTable: true,
2569
- deleteMessages: false
2219
+ deleteMessages: false,
2220
+ listScoresBySpan: true
2570
2221
  };
2571
2222
  }
2572
- async getEvalsByAgentName(agentName, type) {
2573
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
2574
- }
2575
- async getEvals(options) {
2576
- return this.stores.legacyEvals.getEvals(options);
2577
- }
2578
2223
  async batchInsert({ tableName, records }) {
2579
2224
  await this.stores.operations.batchInsert({ tableName, records });
2580
2225
  }
@@ -2586,7 +2231,7 @@ var ClickhouseStore = class extends MastraStorage {
2586
2231
  } catch (error) {
2587
2232
  throw new MastraError(
2588
2233
  {
2589
- id: "CLICKHOUSE_STORAGE_OPTIMIZE_TABLE_FAILED",
2234
+ id: createStorageErrorId("CLICKHOUSE", "OPTIMIZE_TABLE", "FAILED"),
2590
2235
  domain: ErrorDomain.STORAGE,
2591
2236
  category: ErrorCategory.THIRD_PARTY,
2592
2237
  details: { tableName }
@@ -2603,7 +2248,7 @@ var ClickhouseStore = class extends MastraStorage {
2603
2248
  } catch (error) {
2604
2249
  throw new MastraError(
2605
2250
  {
2606
- id: "CLICKHOUSE_STORAGE_MATERIALIZE_TTL_FAILED",
2251
+ id: createStorageErrorId("CLICKHOUSE", "MATERIALIZE_TTL", "FAILED"),
2607
2252
  domain: ErrorDomain.STORAGE,
2608
2253
  category: ErrorCategory.THIRD_PARTY,
2609
2254
  details: { tableName }
@@ -2642,9 +2287,9 @@ var ClickhouseStore = class extends MastraStorage {
2642
2287
  runId,
2643
2288
  stepId,
2644
2289
  result,
2645
- runtimeContext
2290
+ requestContext
2646
2291
  }) {
2647
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
2292
+ return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, requestContext });
2648
2293
  }
2649
2294
  async updateWorkflowState({
2650
2295
  workflowName,
@@ -2667,15 +2312,8 @@ var ClickhouseStore = class extends MastraStorage {
2667
2312
  }) {
2668
2313
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
2669
2314
  }
2670
- async getWorkflowRuns({
2671
- workflowName,
2672
- fromDate,
2673
- toDate,
2674
- limit,
2675
- offset,
2676
- resourceId
2677
- } = {}) {
2678
- return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
2315
+ async listWorkflowRuns(args = {}) {
2316
+ return this.stores.workflows.listWorkflowRuns(args);
2679
2317
  }
2680
2318
  async getWorkflowRunById({
2681
2319
  runId,
@@ -2683,21 +2321,12 @@ var ClickhouseStore = class extends MastraStorage {
2683
2321
  }) {
2684
2322
  return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
2685
2323
  }
2686
- async getTraces(args) {
2687
- return this.stores.traces.getTraces(args);
2688
- }
2689
- async getTracesPaginated(args) {
2690
- return this.stores.traces.getTracesPaginated(args);
2691
- }
2692
- async batchTraceInsert(args) {
2693
- return this.stores.traces.batchTraceInsert(args);
2324
+ async deleteWorkflowRunById({ runId, workflowName }) {
2325
+ return this.stores.workflows.deleteWorkflowRunById({ runId, workflowName });
2694
2326
  }
2695
2327
  async getThreadById({ threadId }) {
2696
2328
  return this.stores.memory.getThreadById({ threadId });
2697
2329
  }
2698
- async getThreadsByResourceId({ resourceId }) {
2699
- return this.stores.memory.getThreadsByResourceId({ resourceId });
2700
- }
2701
2330
  async saveThread({ thread }) {
2702
2331
  return this.stores.memory.saveThread({ thread });
2703
2332
  }
@@ -2711,29 +2340,9 @@ var ClickhouseStore = class extends MastraStorage {
2711
2340
  async deleteThread({ threadId }) {
2712
2341
  return this.stores.memory.deleteThread({ threadId });
2713
2342
  }
2714
- async getThreadsByResourceIdPaginated(args) {
2715
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
2716
- }
2717
- async getMessages({
2718
- threadId,
2719
- resourceId,
2720
- selectBy,
2721
- format
2722
- }) {
2723
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
2724
- }
2725
- async getMessagesById({
2726
- messageIds,
2727
- format
2728
- }) {
2729
- return this.stores.memory.getMessagesById({ messageIds, format });
2730
- }
2731
2343
  async saveMessages(args) {
2732
2344
  return this.stores.memory.saveMessages(args);
2733
2345
  }
2734
- async getMessagesPaginated(args) {
2735
- return this.stores.memory.getMessagesPaginated(args);
2736
- }
2737
2346
  async updateMessages(args) {
2738
2347
  return this.stores.memory.updateMessages(args);
2739
2348
  }
@@ -2753,30 +2362,37 @@ var ClickhouseStore = class extends MastraStorage {
2753
2362
  async getScoreById({ id }) {
2754
2363
  return this.stores.scores.getScoreById({ id });
2755
2364
  }
2756
- async saveScore(_score) {
2757
- return this.stores.scores.saveScore(_score);
2365
+ async saveScore(score) {
2366
+ return this.stores.scores.saveScore(score);
2758
2367
  }
2759
- async getScoresByRunId({
2368
+ async listScoresByRunId({
2760
2369
  runId,
2761
2370
  pagination
2762
2371
  }) {
2763
- return this.stores.scores.getScoresByRunId({ runId, pagination });
2372
+ return this.stores.scores.listScoresByRunId({ runId, pagination });
2764
2373
  }
2765
- async getScoresByEntityId({
2374
+ async listScoresByEntityId({
2766
2375
  entityId,
2767
2376
  entityType,
2768
2377
  pagination
2769
2378
  }) {
2770
- return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
2379
+ return this.stores.scores.listScoresByEntityId({ entityId, entityType, pagination });
2771
2380
  }
2772
- async getScoresByScorerId({
2381
+ async listScoresByScorerId({
2773
2382
  scorerId,
2774
2383
  pagination,
2775
2384
  entityId,
2776
2385
  entityType,
2777
2386
  source
2778
2387
  }) {
2779
- return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
2388
+ return this.stores.scores.listScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
2389
+ }
2390
+ async listScoresBySpan({
2391
+ traceId,
2392
+ spanId,
2393
+ pagination
2394
+ }) {
2395
+ return this.stores.scores.listScoresBySpan({ traceId, spanId, pagination });
2780
2396
  }
2781
2397
  async close() {
2782
2398
  await this.db.close();