@mastra/clickhouse 0.0.0-switch-to-core-20250424015131 → 0.0.0-vector-query-sources-20250516172905

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.
@@ -11,7 +11,14 @@ import {
11
11
  TABLE_TRACES,
12
12
  TABLE_WORKFLOW_SNAPSHOT,
13
13
  } from '@mastra/core/storage';
14
- import type { EvalRow, StorageColumn, StorageGetMessagesArg, TABLE_NAMES } from '@mastra/core/storage';
14
+ import type {
15
+ EvalRow,
16
+ StorageColumn,
17
+ StorageGetMessagesArg,
18
+ TABLE_NAMES,
19
+ WorkflowRun,
20
+ WorkflowRuns,
21
+ } from '@mastra/core/storage';
15
22
  import type { WorkflowRunState } from '@mastra/core/workflows';
16
23
 
17
24
  function safelyParseJSON(jsonString: string): any {
@@ -203,6 +210,8 @@ export class ClickhouseStore extends MastraStorage {
203
210
  perPage,
204
211
  attributes,
205
212
  filters,
213
+ fromDate,
214
+ toDate,
206
215
  }: {
207
216
  name?: string;
208
217
  scope?: string;
@@ -210,6 +219,8 @@ export class ClickhouseStore extends MastraStorage {
210
219
  perPage: number;
211
220
  attributes?: Record<string, string>;
212
221
  filters?: Record<string, any>;
222
+ fromDate?: Date;
223
+ toDate?: Date;
213
224
  }): Promise<any[]> {
214
225
  const limit = perPage;
215
226
  const offset = page * perPage;
@@ -241,6 +252,16 @@ export class ClickhouseStore extends MastraStorage {
241
252
  });
242
253
  }
243
254
 
255
+ if (fromDate) {
256
+ conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
257
+ args.var_from_date = fromDate.getTime() / 1000; // Convert to Unix timestamp
258
+ }
259
+
260
+ if (toDate) {
261
+ conditions.push(`createdAt <= {var_to_date:DateTime64(3)}`);
262
+ args.var_to_date = toDate.getTime() / 1000; // Convert to Unix timestamp
263
+ }
264
+
244
265
  const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
245
266
 
246
267
  const result = await this.db.query({
@@ -316,7 +337,6 @@ export class ClickhouseStore extends MastraStorage {
316
337
  ${['id String'].concat(columns)}
317
338
  )
318
339
  ENGINE = ${TABLE_ENGINES[tableName]}
319
- PARTITION BY "createdAt"
320
340
  PRIMARY KEY (createdAt, run_id, workflow_name)
321
341
  ORDER BY (createdAt, run_id, workflow_name)
322
342
  ${rowTtl ? `TTL toDateTime(${rowTtl.ttlKey ?? 'createdAt'}) + INTERVAL ${rowTtl.interval} ${rowTtl.unit}` : ''}
@@ -327,7 +347,6 @@ export class ClickhouseStore extends MastraStorage {
327
347
  ${columns}
328
348
  )
329
349
  ENGINE = ${TABLE_ENGINES[tableName]}
330
- PARTITION BY "createdAt"
331
350
  PRIMARY KEY (createdAt, ${tableName === TABLE_EVALS ? 'run_id' : 'id'})
332
351
  ORDER BY (createdAt, ${tableName === TABLE_EVALS ? 'run_id' : 'id'})
333
352
  ${this.ttl?.[tableName]?.row ? `TTL toDateTime(createdAt) + INTERVAL ${this.ttl[tableName].row.interval} ${this.ttl[tableName].row.unit}` : ''}
@@ -606,7 +625,7 @@ export class ClickhouseStore extends MastraStorage {
606
625
  try {
607
626
  // First delete all messages associated with this thread
608
627
  await this.db.command({
609
- query: `DELETE FROM "${TABLE_MESSAGES}" WHERE thread_id = '${threadId}';`,
628
+ query: `DELETE FROM "${TABLE_MESSAGES}" WHERE thread_id = {var_thread_id:String};`,
610
629
  query_params: { var_thread_id: threadId },
611
630
  clickhouse_settings: {
612
631
  output_format_json_quote_64bit_integers: 0,
@@ -627,7 +646,7 @@ export class ClickhouseStore extends MastraStorage {
627
646
  }
628
647
  }
629
648
 
630
- async getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T> {
649
+ async getMessages<T = unknown>({ threadId, selectBy }: StorageGetMessagesArg): Promise<T[]> {
631
650
  try {
632
651
  const messages: any[] = [];
633
652
  const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
@@ -734,7 +753,7 @@ export class ClickhouseStore extends MastraStorage {
734
753
  }
735
754
  });
736
755
 
737
- return messages as T;
756
+ return messages as T[];
738
757
  } catch (error) {
739
758
  console.error('Error getting messages:', error);
740
759
  throw error;
@@ -856,28 +875,42 @@ export class ClickhouseStore extends MastraStorage {
856
875
  }
857
876
  }
858
877
 
878
+ private parseWorkflowRun(row: any): WorkflowRun {
879
+ let parsedSnapshot: WorkflowRunState | string = row.snapshot as string;
880
+ if (typeof parsedSnapshot === 'string') {
881
+ try {
882
+ parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;
883
+ } catch (e) {
884
+ // If parsing fails, return the raw snapshot string
885
+ console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
886
+ }
887
+ }
888
+
889
+ return {
890
+ workflowName: row.workflow_name,
891
+ runId: row.run_id,
892
+ snapshot: parsedSnapshot,
893
+ createdAt: new Date(row.createdAt),
894
+ updatedAt: new Date(row.updatedAt),
895
+ resourceId: row.resourceId,
896
+ };
897
+ }
898
+
859
899
  async getWorkflowRuns({
860
900
  workflowName,
861
901
  fromDate,
862
902
  toDate,
863
903
  limit,
864
904
  offset,
905
+ resourceId,
865
906
  }: {
866
907
  workflowName?: string;
867
908
  fromDate?: Date;
868
909
  toDate?: Date;
869
910
  limit?: number;
870
911
  offset?: number;
871
- } = {}): Promise<{
872
- runs: Array<{
873
- workflowName: string;
874
- runId: string;
875
- snapshot: WorkflowRunState | string;
876
- createdAt: Date;
877
- updatedAt: Date;
878
- }>;
879
- total: number;
880
- }> {
912
+ resourceId?: string;
913
+ } = {}): Promise<WorkflowRuns> {
881
914
  try {
882
915
  const conditions: string[] = [];
883
916
  const values: Record<string, any> = {};
@@ -887,6 +920,16 @@ export class ClickhouseStore extends MastraStorage {
887
920
  values.var_workflow_name = workflowName;
888
921
  }
889
922
 
923
+ if (resourceId) {
924
+ const hasResourceId = await this.hasColumn(TABLE_WORKFLOW_SNAPSHOT, 'resourceId');
925
+ if (hasResourceId) {
926
+ conditions.push(`resourceId = {var_resourceId:String}`);
927
+ values.var_resourceId = resourceId;
928
+ } else {
929
+ console.warn(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
930
+ }
931
+ }
932
+
890
933
  if (fromDate) {
891
934
  conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
892
935
  values.var_from_date = fromDate.getTime() / 1000; // Convert to Unix timestamp
@@ -921,7 +964,8 @@ export class ClickhouseStore extends MastraStorage {
921
964
  run_id,
922
965
  snapshot,
923
966
  toDateTime64(createdAt, 3) as createdAt,
924
- toDateTime64(updatedAt, 3) as updatedAt
967
+ toDateTime64(updatedAt, 3) as updatedAt,
968
+ resourceId
925
969
  FROM ${TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[TABLE_WORKFLOW_SNAPSHOT].startsWith('ReplacingMergeTree') ? 'FINAL' : ''}
926
970
  ${whereClause}
927
971
  ORDER BY createdAt DESC
@@ -935,23 +979,7 @@ export class ClickhouseStore extends MastraStorage {
935
979
  const resultJson = await result.json();
936
980
  const rows = resultJson as any[];
937
981
  const runs = rows.map(row => {
938
- let parsedSnapshot: WorkflowRunState | string = row.snapshot;
939
- if (typeof parsedSnapshot === 'string') {
940
- try {
941
- parsedSnapshot = JSON.parse(row.snapshot) as WorkflowRunState;
942
- } catch (e) {
943
- // If parsing fails, return the raw snapshot string
944
- console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
945
- }
946
- }
947
-
948
- return {
949
- workflowName: row.workflow_name,
950
- runId: row.run_id,
951
- snapshot: parsedSnapshot,
952
- createdAt: new Date(row.createdAt),
953
- updatedAt: new Date(row.updatedAt),
954
- };
982
+ return this.parseWorkflowRun(row);
955
983
  });
956
984
 
957
985
  // Use runs.length as total when not paginating
@@ -962,6 +990,66 @@ export class ClickhouseStore extends MastraStorage {
962
990
  }
963
991
  }
964
992
 
993
+ async getWorkflowRunById({
994
+ runId,
995
+ workflowName,
996
+ }: {
997
+ runId: string;
998
+ workflowName?: string;
999
+ }): Promise<WorkflowRun | null> {
1000
+ try {
1001
+ const conditions: string[] = [];
1002
+ const values: Record<string, any> = {};
1003
+
1004
+ if (runId) {
1005
+ conditions.push(`run_id = {var_runId:String}`);
1006
+ values.var_runId = runId;
1007
+ }
1008
+
1009
+ if (workflowName) {
1010
+ conditions.push(`workflow_name = {var_workflow_name:String}`);
1011
+ values.var_workflow_name = workflowName;
1012
+ }
1013
+
1014
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
1015
+
1016
+ // Get results
1017
+ const result = await this.db.query({
1018
+ query: `
1019
+ SELECT
1020
+ workflow_name,
1021
+ run_id,
1022
+ snapshot,
1023
+ toDateTime64(createdAt, 3) as createdAt,
1024
+ toDateTime64(updatedAt, 3) as updatedAt,
1025
+ resourceId
1026
+ FROM ${TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[TABLE_WORKFLOW_SNAPSHOT].startsWith('ReplacingMergeTree') ? 'FINAL' : ''}
1027
+ ${whereClause}
1028
+ `,
1029
+ query_params: values,
1030
+ format: 'JSONEachRow',
1031
+ });
1032
+
1033
+ const resultJson = await result.json();
1034
+ if (!Array.isArray(resultJson) || resultJson.length === 0) {
1035
+ return null;
1036
+ }
1037
+ return this.parseWorkflowRun(resultJson[0]);
1038
+ } catch (error) {
1039
+ console.error('Error getting workflow run by ID:', error);
1040
+ throw error;
1041
+ }
1042
+ }
1043
+
1044
+ private async hasColumn(table: string, column: string): Promise<boolean> {
1045
+ const result = await this.db.query({
1046
+ query: `DESCRIBE TABLE ${table}`,
1047
+ format: 'JSONEachRow',
1048
+ });
1049
+ const columns = (await result.json()) as { name: string }[];
1050
+ return columns.some(c => c.name === column);
1051
+ }
1052
+
965
1053
  async close(): Promise<void> {
966
1054
  await this.db.close();
967
1055
  }