@mastra/clickhouse 0.0.0-vnextWorkflows-20250422142014 → 0.0.0-workflow-deno-20250616115451
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/.turbo/turbo-build.log +23 -0
- package/CHANGELOG.md +521 -2
- package/dist/_tsup-dts-rollup.d.cts +57 -16
- package/dist/_tsup-dts-rollup.d.ts +57 -16
- package/dist/index.cjs +220 -46
- package/dist/index.js +220 -46
- package/package.json +14 -10
- package/src/storage/index.test.ts +470 -118
- package/src/storage/index.ts +279 -58
package/src/storage/index.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { ClickHouseClient } from '@clickhouse/client';
|
|
2
2
|
import { createClient } from '@clickhouse/client';
|
|
3
|
+
import { MessageList } from '@mastra/core/agent';
|
|
3
4
|
import type { MetricResult, TestInfo } from '@mastra/core/eval';
|
|
4
|
-
import type {
|
|
5
|
+
import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
|
|
5
6
|
import {
|
|
6
7
|
MastraStorage,
|
|
7
8
|
TABLE_EVALS,
|
|
@@ -11,7 +12,17 @@ import {
|
|
|
11
12
|
TABLE_TRACES,
|
|
12
13
|
TABLE_WORKFLOW_SNAPSHOT,
|
|
13
14
|
} from '@mastra/core/storage';
|
|
14
|
-
import type {
|
|
15
|
+
import type {
|
|
16
|
+
EvalRow,
|
|
17
|
+
PaginationInfo,
|
|
18
|
+
StorageColumn,
|
|
19
|
+
StorageGetMessagesArg,
|
|
20
|
+
TABLE_NAMES,
|
|
21
|
+
WorkflowRun,
|
|
22
|
+
WorkflowRuns,
|
|
23
|
+
StorageGetTracesArg,
|
|
24
|
+
} from '@mastra/core/storage';
|
|
25
|
+
import type { Trace } from '@mastra/core/telemetry';
|
|
15
26
|
import type { WorkflowRunState } from '@mastra/core/workflows';
|
|
16
27
|
|
|
17
28
|
function safelyParseJSON(jsonString: string): any {
|
|
@@ -203,6 +214,8 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
203
214
|
perPage,
|
|
204
215
|
attributes,
|
|
205
216
|
filters,
|
|
217
|
+
fromDate,
|
|
218
|
+
toDate,
|
|
206
219
|
}: {
|
|
207
220
|
name?: string;
|
|
208
221
|
scope?: string;
|
|
@@ -210,6 +223,8 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
210
223
|
perPage: number;
|
|
211
224
|
attributes?: Record<string, string>;
|
|
212
225
|
filters?: Record<string, any>;
|
|
226
|
+
fromDate?: Date;
|
|
227
|
+
toDate?: Date;
|
|
213
228
|
}): Promise<any[]> {
|
|
214
229
|
const limit = perPage;
|
|
215
230
|
const offset = page * perPage;
|
|
@@ -241,6 +256,16 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
241
256
|
});
|
|
242
257
|
}
|
|
243
258
|
|
|
259
|
+
if (fromDate) {
|
|
260
|
+
conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
|
|
261
|
+
args.var_from_date = fromDate.getTime() / 1000; // Convert to Unix timestamp
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (toDate) {
|
|
265
|
+
conditions.push(`createdAt <= {var_to_date:DateTime64(3)}`);
|
|
266
|
+
args.var_to_date = toDate.getTime() / 1000; // Convert to Unix timestamp
|
|
267
|
+
}
|
|
268
|
+
|
|
244
269
|
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
245
270
|
|
|
246
271
|
const result = await this.db.query({
|
|
@@ -316,7 +341,6 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
316
341
|
${['id String'].concat(columns)}
|
|
317
342
|
)
|
|
318
343
|
ENGINE = ${TABLE_ENGINES[tableName]}
|
|
319
|
-
PARTITION BY "createdAt"
|
|
320
344
|
PRIMARY KEY (createdAt, run_id, workflow_name)
|
|
321
345
|
ORDER BY (createdAt, run_id, workflow_name)
|
|
322
346
|
${rowTtl ? `TTL toDateTime(${rowTtl.ttlKey ?? 'createdAt'}) + INTERVAL ${rowTtl.interval} ${rowTtl.unit}` : ''}
|
|
@@ -327,7 +351,6 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
327
351
|
${columns}
|
|
328
352
|
)
|
|
329
353
|
ENGINE = ${TABLE_ENGINES[tableName]}
|
|
330
|
-
PARTITION BY "createdAt"
|
|
331
354
|
PRIMARY KEY (createdAt, ${tableName === TABLE_EVALS ? 'run_id' : 'id'})
|
|
332
355
|
ORDER BY (createdAt, ${tableName === TABLE_EVALS ? 'run_id' : 'id'})
|
|
333
356
|
${this.ttl?.[tableName]?.row ? `TTL toDateTime(createdAt) + INTERVAL ${this.ttl[tableName].row.interval} ${this.ttl[tableName].row.unit}` : ''}
|
|
@@ -350,6 +373,73 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
350
373
|
}
|
|
351
374
|
}
|
|
352
375
|
|
|
376
|
+
protected getSqlType(type: StorageColumn['type']): string {
|
|
377
|
+
switch (type) {
|
|
378
|
+
case 'text':
|
|
379
|
+
return 'String';
|
|
380
|
+
case 'timestamp':
|
|
381
|
+
return 'DateTime64(3)';
|
|
382
|
+
case 'integer':
|
|
383
|
+
case 'bigint':
|
|
384
|
+
return 'Int64';
|
|
385
|
+
case 'jsonb':
|
|
386
|
+
return 'String';
|
|
387
|
+
default:
|
|
388
|
+
return super.getSqlType(type); // fallback to base implementation
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Alters table schema to add columns if they don't exist
|
|
394
|
+
* @param tableName Name of the table
|
|
395
|
+
* @param schema Schema of the table
|
|
396
|
+
* @param ifNotExists Array of column names to add if they don't exist
|
|
397
|
+
*/
|
|
398
|
+
async alterTable({
|
|
399
|
+
tableName,
|
|
400
|
+
schema,
|
|
401
|
+
ifNotExists,
|
|
402
|
+
}: {
|
|
403
|
+
tableName: TABLE_NAMES;
|
|
404
|
+
schema: Record<string, StorageColumn>;
|
|
405
|
+
ifNotExists: string[];
|
|
406
|
+
}): Promise<void> {
|
|
407
|
+
try {
|
|
408
|
+
// 1. Get existing columns
|
|
409
|
+
const describeSql = `DESCRIBE TABLE ${tableName}`;
|
|
410
|
+
const result = await this.db.query({
|
|
411
|
+
query: describeSql,
|
|
412
|
+
});
|
|
413
|
+
const rows = await result.json();
|
|
414
|
+
const existingColumnNames = new Set(rows.data.map((row: any) => row.name.toLowerCase()));
|
|
415
|
+
|
|
416
|
+
// 2. Add missing columns
|
|
417
|
+
for (const columnName of ifNotExists) {
|
|
418
|
+
if (!existingColumnNames.has(columnName.toLowerCase()) && schema[columnName]) {
|
|
419
|
+
const columnDef = schema[columnName];
|
|
420
|
+
let sqlType = this.getSqlType(columnDef.type);
|
|
421
|
+
if (columnDef.nullable !== false) {
|
|
422
|
+
sqlType = `Nullable(${sqlType})`;
|
|
423
|
+
}
|
|
424
|
+
const defaultValue = columnDef.nullable === false ? this.getDefaultValue(columnDef.type) : '';
|
|
425
|
+
// Use backticks or double quotes as needed for identifiers
|
|
426
|
+
const alterSql =
|
|
427
|
+
`ALTER TABLE ${tableName} ADD COLUMN IF NOT EXISTS "${columnName}" ${sqlType} ${defaultValue}`.trim();
|
|
428
|
+
|
|
429
|
+
await this.db.query({
|
|
430
|
+
query: alterSql,
|
|
431
|
+
});
|
|
432
|
+
this.logger?.debug?.(`Added column ${columnName} to table ${tableName}`);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
this.logger?.error?.(
|
|
437
|
+
`Error altering table ${tableName}: ${error instanceof Error ? error.message : String(error)}`,
|
|
438
|
+
);
|
|
439
|
+
throw new Error(`Failed to alter table ${tableName}: ${error}`);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
353
443
|
async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
|
|
354
444
|
try {
|
|
355
445
|
await this.db.query({
|
|
@@ -580,15 +670,18 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
580
670
|
|
|
581
671
|
await this.db.insert({
|
|
582
672
|
table: TABLE_THREADS,
|
|
673
|
+
format: 'JSONEachRow',
|
|
583
674
|
values: [
|
|
584
675
|
{
|
|
585
|
-
|
|
676
|
+
id: updatedThread.id,
|
|
677
|
+
resourceId: updatedThread.resourceId,
|
|
678
|
+
title: updatedThread.title,
|
|
679
|
+
metadata: updatedThread.metadata,
|
|
680
|
+
createdAt: updatedThread.createdAt,
|
|
586
681
|
updatedAt: updatedThread.updatedAt.toISOString(),
|
|
587
682
|
},
|
|
588
683
|
],
|
|
589
|
-
format: 'JSONEachRow',
|
|
590
684
|
clickhouse_settings: {
|
|
591
|
-
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
592
685
|
date_time_input_format: 'best_effort',
|
|
593
686
|
use_client_time_zone: 1,
|
|
594
687
|
output_format_json_quote_64bit_integers: 0,
|
|
@@ -606,7 +699,7 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
606
699
|
try {
|
|
607
700
|
// First delete all messages associated with this thread
|
|
608
701
|
await this.db.command({
|
|
609
|
-
query: `DELETE FROM "${TABLE_MESSAGES}" WHERE thread_id =
|
|
702
|
+
query: `DELETE FROM "${TABLE_MESSAGES}" WHERE thread_id = {var_thread_id:String};`,
|
|
610
703
|
query_params: { var_thread_id: threadId },
|
|
611
704
|
clickhouse_settings: {
|
|
612
705
|
output_format_json_quote_64bit_integers: 0,
|
|
@@ -627,7 +720,14 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
627
720
|
}
|
|
628
721
|
}
|
|
629
722
|
|
|
630
|
-
async getMessages
|
|
723
|
+
public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
|
|
724
|
+
public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;
|
|
725
|
+
public async getMessages({
|
|
726
|
+
threadId,
|
|
727
|
+
resourceId,
|
|
728
|
+
selectBy,
|
|
729
|
+
format,
|
|
730
|
+
}: StorageGetMessagesArg & { format?: 'v1' | 'v2' }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
|
|
631
731
|
try {
|
|
632
732
|
const messages: any[] = [];
|
|
633
733
|
const limit = typeof selectBy?.last === `number` ? selectBy.last : 40;
|
|
@@ -734,18 +834,26 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
734
834
|
}
|
|
735
835
|
});
|
|
736
836
|
|
|
737
|
-
|
|
837
|
+
const list = new MessageList({ threadId, resourceId }).add(messages, 'memory');
|
|
838
|
+
if (format === `v2`) return list.get.all.v2();
|
|
839
|
+
return list.get.all.v1();
|
|
738
840
|
} catch (error) {
|
|
739
841
|
console.error('Error getting messages:', error);
|
|
740
842
|
throw error;
|
|
741
843
|
}
|
|
742
844
|
}
|
|
743
845
|
|
|
744
|
-
async saveMessages(
|
|
846
|
+
async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;
|
|
847
|
+
async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;
|
|
848
|
+
async saveMessages(
|
|
849
|
+
args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },
|
|
850
|
+
): Promise<MastraMessageV2[] | MastraMessageV1[]> {
|
|
851
|
+
const { messages, format = 'v1' } = args;
|
|
745
852
|
if (messages.length === 0) return messages;
|
|
746
853
|
|
|
747
854
|
try {
|
|
748
855
|
const threadId = messages[0]?.threadId;
|
|
856
|
+
const resourceId = messages[0]?.resourceId;
|
|
749
857
|
if (!threadId) {
|
|
750
858
|
throw new Error('Thread ID is required');
|
|
751
859
|
}
|
|
@@ -756,26 +864,52 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
756
864
|
throw new Error(`Thread ${threadId} not found`);
|
|
757
865
|
}
|
|
758
866
|
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
867
|
+
// Execute message inserts and thread update in parallel for better performance
|
|
868
|
+
await Promise.all([
|
|
869
|
+
// Insert messages
|
|
870
|
+
this.db.insert({
|
|
871
|
+
table: TABLE_MESSAGES,
|
|
872
|
+
format: 'JSONEachRow',
|
|
873
|
+
values: messages.map(message => ({
|
|
874
|
+
id: message.id,
|
|
875
|
+
thread_id: threadId,
|
|
876
|
+
content: typeof message.content === 'string' ? message.content : JSON.stringify(message.content),
|
|
877
|
+
createdAt: message.createdAt.toISOString(),
|
|
878
|
+
role: message.role,
|
|
879
|
+
type: message.type || 'v2',
|
|
880
|
+
})),
|
|
881
|
+
clickhouse_settings: {
|
|
882
|
+
// Allows to insert serialized JS Dates (such as '2023-12-06T10:54:48.000Z')
|
|
883
|
+
date_time_input_format: 'best_effort',
|
|
884
|
+
use_client_time_zone: 1,
|
|
885
|
+
output_format_json_quote_64bit_integers: 0,
|
|
886
|
+
},
|
|
887
|
+
}),
|
|
888
|
+
// Update thread's updatedAt timestamp
|
|
889
|
+
this.db.insert({
|
|
890
|
+
table: TABLE_THREADS,
|
|
891
|
+
format: 'JSONEachRow',
|
|
892
|
+
values: [
|
|
893
|
+
{
|
|
894
|
+
id: thread.id,
|
|
895
|
+
resourceId: thread.resourceId,
|
|
896
|
+
title: thread.title,
|
|
897
|
+
metadata: thread.metadata,
|
|
898
|
+
createdAt: thread.createdAt,
|
|
899
|
+
updatedAt: new Date().toISOString(),
|
|
900
|
+
},
|
|
901
|
+
],
|
|
902
|
+
clickhouse_settings: {
|
|
903
|
+
date_time_input_format: 'best_effort',
|
|
904
|
+
use_client_time_zone: 1,
|
|
905
|
+
output_format_json_quote_64bit_integers: 0,
|
|
906
|
+
},
|
|
907
|
+
}),
|
|
908
|
+
]);
|
|
777
909
|
|
|
778
|
-
|
|
910
|
+
const list = new MessageList({ threadId, resourceId }).add(messages, 'memory');
|
|
911
|
+
if (format === `v2`) return list.get.all.v2();
|
|
912
|
+
return list.get.all.v1();
|
|
779
913
|
} catch (error) {
|
|
780
914
|
console.error('Error saving messages:', error);
|
|
781
915
|
throw error;
|
|
@@ -856,28 +990,42 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
856
990
|
}
|
|
857
991
|
}
|
|
858
992
|
|
|
993
|
+
private parseWorkflowRun(row: any): WorkflowRun {
|
|
994
|
+
let parsedSnapshot: WorkflowRunState | string = row.snapshot as string;
|
|
995
|
+
if (typeof parsedSnapshot === 'string') {
|
|
996
|
+
try {
|
|
997
|
+
parsedSnapshot = JSON.parse(row.snapshot as string) as WorkflowRunState;
|
|
998
|
+
} catch (e) {
|
|
999
|
+
// If parsing fails, return the raw snapshot string
|
|
1000
|
+
console.warn(`Failed to parse snapshot for workflow ${row.workflow_name}: ${e}`);
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
return {
|
|
1005
|
+
workflowName: row.workflow_name,
|
|
1006
|
+
runId: row.run_id,
|
|
1007
|
+
snapshot: parsedSnapshot,
|
|
1008
|
+
createdAt: new Date(row.createdAt),
|
|
1009
|
+
updatedAt: new Date(row.updatedAt),
|
|
1010
|
+
resourceId: row.resourceId,
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
|
|
859
1014
|
async getWorkflowRuns({
|
|
860
1015
|
workflowName,
|
|
861
1016
|
fromDate,
|
|
862
1017
|
toDate,
|
|
863
1018
|
limit,
|
|
864
1019
|
offset,
|
|
1020
|
+
resourceId,
|
|
865
1021
|
}: {
|
|
866
1022
|
workflowName?: string;
|
|
867
1023
|
fromDate?: Date;
|
|
868
1024
|
toDate?: Date;
|
|
869
1025
|
limit?: number;
|
|
870
1026
|
offset?: number;
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
workflowName: string;
|
|
874
|
-
runId: string;
|
|
875
|
-
snapshot: WorkflowRunState | string;
|
|
876
|
-
createdAt: Date;
|
|
877
|
-
updatedAt: Date;
|
|
878
|
-
}>;
|
|
879
|
-
total: number;
|
|
880
|
-
}> {
|
|
1027
|
+
resourceId?: string;
|
|
1028
|
+
} = {}): Promise<WorkflowRuns> {
|
|
881
1029
|
try {
|
|
882
1030
|
const conditions: string[] = [];
|
|
883
1031
|
const values: Record<string, any> = {};
|
|
@@ -887,6 +1035,16 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
887
1035
|
values.var_workflow_name = workflowName;
|
|
888
1036
|
}
|
|
889
1037
|
|
|
1038
|
+
if (resourceId) {
|
|
1039
|
+
const hasResourceId = await this.hasColumn(TABLE_WORKFLOW_SNAPSHOT, 'resourceId');
|
|
1040
|
+
if (hasResourceId) {
|
|
1041
|
+
conditions.push(`resourceId = {var_resourceId:String}`);
|
|
1042
|
+
values.var_resourceId = resourceId;
|
|
1043
|
+
} else {
|
|
1044
|
+
console.warn(`[${TABLE_WORKFLOW_SNAPSHOT}] resourceId column not found. Skipping resourceId filter.`);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
890
1048
|
if (fromDate) {
|
|
891
1049
|
conditions.push(`createdAt >= {var_from_date:DateTime64(3)}`);
|
|
892
1050
|
values.var_from_date = fromDate.getTime() / 1000; // Convert to Unix timestamp
|
|
@@ -921,7 +1079,8 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
921
1079
|
run_id,
|
|
922
1080
|
snapshot,
|
|
923
1081
|
toDateTime64(createdAt, 3) as createdAt,
|
|
924
|
-
toDateTime64(updatedAt, 3) as updatedAt
|
|
1082
|
+
toDateTime64(updatedAt, 3) as updatedAt,
|
|
1083
|
+
resourceId
|
|
925
1084
|
FROM ${TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[TABLE_WORKFLOW_SNAPSHOT].startsWith('ReplacingMergeTree') ? 'FINAL' : ''}
|
|
926
1085
|
${whereClause}
|
|
927
1086
|
ORDER BY createdAt DESC
|
|
@@ -935,23 +1094,7 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
935
1094
|
const resultJson = await result.json();
|
|
936
1095
|
const rows = resultJson as any[];
|
|
937
1096
|
const runs = rows.map(row => {
|
|
938
|
-
|
|
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
|
-
};
|
|
1097
|
+
return this.parseWorkflowRun(row);
|
|
955
1098
|
});
|
|
956
1099
|
|
|
957
1100
|
// Use runs.length as total when not paginating
|
|
@@ -962,6 +1105,84 @@ export class ClickhouseStore extends MastraStorage {
|
|
|
962
1105
|
}
|
|
963
1106
|
}
|
|
964
1107
|
|
|
1108
|
+
async getWorkflowRunById({
|
|
1109
|
+
runId,
|
|
1110
|
+
workflowName,
|
|
1111
|
+
}: {
|
|
1112
|
+
runId: string;
|
|
1113
|
+
workflowName?: string;
|
|
1114
|
+
}): Promise<WorkflowRun | null> {
|
|
1115
|
+
try {
|
|
1116
|
+
const conditions: string[] = [];
|
|
1117
|
+
const values: Record<string, any> = {};
|
|
1118
|
+
|
|
1119
|
+
if (runId) {
|
|
1120
|
+
conditions.push(`run_id = {var_runId:String}`);
|
|
1121
|
+
values.var_runId = runId;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
if (workflowName) {
|
|
1125
|
+
conditions.push(`workflow_name = {var_workflow_name:String}`);
|
|
1126
|
+
values.var_workflow_name = workflowName;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
1130
|
+
|
|
1131
|
+
// Get results
|
|
1132
|
+
const result = await this.db.query({
|
|
1133
|
+
query: `
|
|
1134
|
+
SELECT
|
|
1135
|
+
workflow_name,
|
|
1136
|
+
run_id,
|
|
1137
|
+
snapshot,
|
|
1138
|
+
toDateTime64(createdAt, 3) as createdAt,
|
|
1139
|
+
toDateTime64(updatedAt, 3) as updatedAt,
|
|
1140
|
+
resourceId
|
|
1141
|
+
FROM ${TABLE_WORKFLOW_SNAPSHOT} ${TABLE_ENGINES[TABLE_WORKFLOW_SNAPSHOT].startsWith('ReplacingMergeTree') ? 'FINAL' : ''}
|
|
1142
|
+
${whereClause}
|
|
1143
|
+
`,
|
|
1144
|
+
query_params: values,
|
|
1145
|
+
format: 'JSONEachRow',
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
const resultJson = await result.json();
|
|
1149
|
+
if (!Array.isArray(resultJson) || resultJson.length === 0) {
|
|
1150
|
+
return null;
|
|
1151
|
+
}
|
|
1152
|
+
return this.parseWorkflowRun(resultJson[0]);
|
|
1153
|
+
} catch (error) {
|
|
1154
|
+
console.error('Error getting workflow run by ID:', error);
|
|
1155
|
+
throw error;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
private async hasColumn(table: string, column: string): Promise<boolean> {
|
|
1160
|
+
const result = await this.db.query({
|
|
1161
|
+
query: `DESCRIBE TABLE ${table}`,
|
|
1162
|
+
format: 'JSONEachRow',
|
|
1163
|
+
});
|
|
1164
|
+
const columns = (await result.json()) as { name: string }[];
|
|
1165
|
+
return columns.some(c => c.name === column);
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
async getTracesPaginated(_args: StorageGetTracesArg): Promise<PaginationInfo & { traces: Trace[] }> {
|
|
1169
|
+
throw new Error('Method not implemented.');
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
async getThreadsByResourceIdPaginated(_args: {
|
|
1173
|
+
resourceId: string;
|
|
1174
|
+
page?: number;
|
|
1175
|
+
perPage?: number;
|
|
1176
|
+
}): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
|
|
1177
|
+
throw new Error('Method not implemented.');
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
async getMessagesPaginated(
|
|
1181
|
+
_args: StorageGetMessagesArg,
|
|
1182
|
+
): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
|
|
1183
|
+
throw new Error('Method not implemented.');
|
|
1184
|
+
}
|
|
1185
|
+
|
|
965
1186
|
async close(): Promise<void> {
|
|
966
1187
|
await this.db.close();
|
|
967
1188
|
}
|