@mastra/clickhouse 0.14.2 → 0.14.3-alpha.1

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.
@@ -1,456 +0,0 @@
1
- import type { ClickHouseClient } from '@clickhouse/client';
2
- import { createClient } from '@clickhouse/client';
3
- import type { MastraMessageContentV2 } from '@mastra/core/agent';
4
- import { MastraError, ErrorDomain, ErrorCategory } from '@mastra/core/error';
5
- import type { MastraMessageV1, MastraMessageV2, StorageThreadType } from '@mastra/core/memory';
6
- import type { ScoreRowData, ScoringSource } from '@mastra/core/scores';
7
- import { MastraStorage } from '@mastra/core/storage';
8
- import type {
9
- TABLE_SCHEMAS,
10
- EvalRow,
11
- PaginationInfo,
12
- StorageColumn,
13
- StorageGetMessagesArg,
14
- TABLE_NAMES,
15
- WorkflowRun,
16
- WorkflowRuns,
17
- StorageGetTracesArg,
18
- StorageGetTracesPaginatedArg,
19
- StoragePagination,
20
- StorageDomains,
21
- PaginationArgs,
22
- StorageResourceType,
23
- } from '@mastra/core/storage';
24
- import type { Trace } from '@mastra/core/telemetry';
25
- import type { StepResult, WorkflowRunState } from '@mastra/core/workflows';
26
- import { LegacyEvalsStorageClickhouse } from './domains/legacy-evals';
27
- import { MemoryStorageClickhouse } from './domains/memory';
28
- import { StoreOperationsClickhouse } from './domains/operations';
29
- import { ScoresStorageClickhouse } from './domains/scores';
30
- import { TracesStorageClickhouse } from './domains/traces';
31
- import { WorkflowsStorageClickhouse } from './domains/workflows';
32
-
33
- type IntervalUnit =
34
- | 'NANOSECOND'
35
- | 'MICROSECOND'
36
- | 'MILLISECOND'
37
- | 'SECOND'
38
- | 'MINUTE'
39
- | 'HOUR'
40
- | 'DAY'
41
- | 'WEEK'
42
- | 'MONTH'
43
- | 'QUARTER'
44
- | 'YEAR';
45
-
46
- export type ClickhouseConfig = {
47
- url: string;
48
- username: string;
49
- password: string;
50
- ttl?: {
51
- [TableKey in TABLE_NAMES]?: {
52
- row?: { interval: number; unit: IntervalUnit; ttlKey?: string };
53
- columns?: Partial<{
54
- [ColumnKey in keyof (typeof TABLE_SCHEMAS)[TableKey]]: {
55
- interval: number;
56
- unit: IntervalUnit;
57
- ttlKey?: string;
58
- };
59
- }>;
60
- };
61
- };
62
- };
63
-
64
- export class ClickhouseStore extends MastraStorage {
65
- protected db: ClickHouseClient;
66
- protected ttl: ClickhouseConfig['ttl'] = {};
67
-
68
- stores: StorageDomains;
69
-
70
- constructor(config: ClickhouseConfig) {
71
- super({ name: 'ClickhouseStore' });
72
-
73
- this.db = createClient({
74
- url: config.url,
75
- username: config.username,
76
- password: config.password,
77
- clickhouse_settings: {
78
- date_time_input_format: 'best_effort',
79
- date_time_output_format: 'iso', // This is crucial
80
- use_client_time_zone: 1,
81
- output_format_json_quote_64bit_integers: 0,
82
- },
83
- });
84
- this.ttl = config.ttl;
85
-
86
- const operations = new StoreOperationsClickhouse({ client: this.db, ttl: this.ttl });
87
- const workflows = new WorkflowsStorageClickhouse({ client: this.db, operations });
88
- const scores = new ScoresStorageClickhouse({ client: this.db, operations });
89
- const legacyEvals = new LegacyEvalsStorageClickhouse({ client: this.db, operations });
90
- const traces = new TracesStorageClickhouse({ client: this.db, operations });
91
- const memory = new MemoryStorageClickhouse({ client: this.db, operations });
92
-
93
- this.stores = {
94
- operations,
95
- workflows,
96
- scores,
97
- legacyEvals,
98
- traces,
99
- memory,
100
- };
101
- }
102
-
103
- get supports(): {
104
- selectByIncludeResourceScope: boolean;
105
- resourceWorkingMemory: boolean;
106
- hasColumn: boolean;
107
- createTable: boolean;
108
- deleteMessages: boolean;
109
- } {
110
- return {
111
- selectByIncludeResourceScope: true,
112
- resourceWorkingMemory: true,
113
- hasColumn: true,
114
- createTable: true,
115
- deleteMessages: false,
116
- };
117
- }
118
-
119
- async getEvalsByAgentName(agentName: string, type?: 'test' | 'live'): Promise<EvalRow[]> {
120
- return this.stores.legacyEvals.getEvalsByAgentName(agentName, type);
121
- }
122
-
123
- async getEvals(
124
- options: { agentName?: string; type?: 'test' | 'live' } & PaginationArgs,
125
- ): Promise<PaginationInfo & { evals: EvalRow[] }> {
126
- return this.stores.legacyEvals.getEvals(options);
127
- }
128
-
129
- async batchInsert({ tableName, records }: { tableName: TABLE_NAMES; records: Record<string, any>[] }): Promise<void> {
130
- await this.stores.operations.batchInsert({ tableName, records });
131
- // await this.optimizeTable({ tableName });
132
- }
133
-
134
- async optimizeTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
135
- try {
136
- await this.db.command({
137
- query: `OPTIMIZE TABLE ${tableName} FINAL`,
138
- });
139
- } catch (error: any) {
140
- throw new MastraError(
141
- {
142
- id: 'CLICKHOUSE_STORAGE_OPTIMIZE_TABLE_FAILED',
143
- domain: ErrorDomain.STORAGE,
144
- category: ErrorCategory.THIRD_PARTY,
145
- details: { tableName },
146
- },
147
- error,
148
- );
149
- }
150
- }
151
-
152
- async materializeTtl({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
153
- try {
154
- await this.db.command({
155
- query: `ALTER TABLE ${tableName} MATERIALIZE TTL;`,
156
- });
157
- } catch (error: any) {
158
- throw new MastraError(
159
- {
160
- id: 'CLICKHOUSE_STORAGE_MATERIALIZE_TTL_FAILED',
161
- domain: ErrorDomain.STORAGE,
162
- category: ErrorCategory.THIRD_PARTY,
163
- details: { tableName },
164
- },
165
- error,
166
- );
167
- }
168
- }
169
-
170
- async createTable({
171
- tableName,
172
- schema,
173
- }: {
174
- tableName: TABLE_NAMES;
175
- schema: Record<string, StorageColumn>;
176
- }): Promise<void> {
177
- return this.stores.operations.createTable({ tableName, schema });
178
- }
179
-
180
- async dropTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
181
- return this.stores.operations.dropTable({ tableName });
182
- }
183
-
184
- async alterTable({
185
- tableName,
186
- schema,
187
- ifNotExists,
188
- }: {
189
- tableName: TABLE_NAMES;
190
- schema: Record<string, StorageColumn>;
191
- ifNotExists: string[];
192
- }): Promise<void> {
193
- return this.stores.operations.alterTable({ tableName, schema, ifNotExists });
194
- }
195
-
196
- async clearTable({ tableName }: { tableName: TABLE_NAMES }): Promise<void> {
197
- return this.stores.operations.clearTable({ tableName });
198
- }
199
-
200
- async insert({ tableName, record }: { tableName: TABLE_NAMES; record: Record<string, any> }): Promise<void> {
201
- return this.stores.operations.insert({ tableName, record });
202
- }
203
-
204
- async load<R>({ tableName, keys }: { tableName: TABLE_NAMES; keys: Record<string, string> }): Promise<R | null> {
205
- return this.stores.operations.load({ tableName, keys });
206
- }
207
-
208
- async updateWorkflowResults({
209
- workflowName,
210
- runId,
211
- stepId,
212
- result,
213
- runtimeContext,
214
- }: {
215
- workflowName: string;
216
- runId: string;
217
- stepId: string;
218
- result: StepResult<any, any, any, any>;
219
- runtimeContext: Record<string, any>;
220
- }): Promise<Record<string, StepResult<any, any, any, any>>> {
221
- return this.stores.workflows.updateWorkflowResults({ workflowName, runId, stepId, result, runtimeContext });
222
- }
223
-
224
- async updateWorkflowState({
225
- workflowName,
226
- runId,
227
- opts,
228
- }: {
229
- workflowName: string;
230
- runId: string;
231
- opts: {
232
- status: string;
233
- result?: StepResult<any, any, any, any>;
234
- error?: string;
235
- suspendedPaths?: Record<string, number[]>;
236
- waitingPaths?: Record<string, number[]>;
237
- };
238
- }): Promise<WorkflowRunState | undefined> {
239
- return this.stores.workflows.updateWorkflowState({ workflowName, runId, opts });
240
- }
241
-
242
- async persistWorkflowSnapshot({
243
- workflowName,
244
- runId,
245
- snapshot,
246
- }: {
247
- workflowName: string;
248
- runId: string;
249
- snapshot: WorkflowRunState;
250
- }): Promise<void> {
251
- return this.stores.workflows.persistWorkflowSnapshot({ workflowName, runId, snapshot });
252
- }
253
-
254
- async loadWorkflowSnapshot({
255
- workflowName,
256
- runId,
257
- }: {
258
- workflowName: string;
259
- runId: string;
260
- }): Promise<WorkflowRunState | null> {
261
- return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
262
- }
263
-
264
- async getWorkflowRuns({
265
- workflowName,
266
- fromDate,
267
- toDate,
268
- limit,
269
- offset,
270
- resourceId,
271
- }: {
272
- workflowName?: string;
273
- fromDate?: Date;
274
- toDate?: Date;
275
- limit?: number;
276
- offset?: number;
277
- resourceId?: string;
278
- } = {}): Promise<WorkflowRuns> {
279
- return this.stores.workflows.getWorkflowRuns({ workflowName, fromDate, toDate, limit, offset, resourceId });
280
- }
281
-
282
- async getWorkflowRunById({
283
- runId,
284
- workflowName,
285
- }: {
286
- runId: string;
287
- workflowName?: string;
288
- }): Promise<WorkflowRun | null> {
289
- return this.stores.workflows.getWorkflowRunById({ runId, workflowName });
290
- }
291
-
292
- async getTraces(args: StorageGetTracesArg): Promise<any[]> {
293
- return this.stores.traces.getTraces(args);
294
- }
295
-
296
- async getTracesPaginated(args: StorageGetTracesPaginatedArg): Promise<PaginationInfo & { traces: Trace[] }> {
297
- return this.stores.traces.getTracesPaginated(args);
298
- }
299
-
300
- async batchTraceInsert(args: { records: Trace[] }): Promise<void> {
301
- return this.stores.traces.batchTraceInsert(args);
302
- }
303
-
304
- async getThreadById({ threadId }: { threadId: string }): Promise<StorageThreadType | null> {
305
- return this.stores.memory.getThreadById({ threadId });
306
- }
307
-
308
- async getThreadsByResourceId({ resourceId }: { resourceId: string }): Promise<StorageThreadType[]> {
309
- return this.stores.memory.getThreadsByResourceId({ resourceId });
310
- }
311
-
312
- async saveThread({ thread }: { thread: StorageThreadType }): Promise<StorageThreadType> {
313
- return this.stores.memory.saveThread({ thread });
314
- }
315
-
316
- async updateThread({
317
- id,
318
- title,
319
- metadata,
320
- }: {
321
- id: string;
322
- title: string;
323
- metadata: Record<string, unknown>;
324
- }): Promise<StorageThreadType> {
325
- return this.stores.memory.updateThread({ id, title, metadata });
326
- }
327
-
328
- async deleteThread({ threadId }: { threadId: string }): Promise<void> {
329
- return this.stores.memory.deleteThread({ threadId });
330
- }
331
-
332
- async getThreadsByResourceIdPaginated(args: {
333
- resourceId: string;
334
- page: number;
335
- perPage: number;
336
- }): Promise<PaginationInfo & { threads: StorageThreadType[] }> {
337
- return this.stores.memory.getThreadsByResourceIdPaginated(args);
338
- }
339
-
340
- public async getMessages(args: StorageGetMessagesArg & { format?: 'v1' }): Promise<MastraMessageV1[]>;
341
- public async getMessages(args: StorageGetMessagesArg & { format: 'v2' }): Promise<MastraMessageV2[]>;
342
- public async getMessages({
343
- threadId,
344
- resourceId,
345
- selectBy,
346
- format,
347
- }: StorageGetMessagesArg & { format?: 'v1' | 'v2' }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
348
- return this.stores.memory.getMessages({ threadId, resourceId, selectBy, format });
349
- }
350
-
351
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format: 'v1' }): Promise<MastraMessageV1[]>;
352
- async getMessagesById({ messageIds, format }: { messageIds: string[]; format?: 'v2' }): Promise<MastraMessageV2[]>;
353
- async getMessagesById({
354
- messageIds,
355
- format,
356
- }: {
357
- messageIds: string[];
358
- format?: 'v1' | 'v2';
359
- }): Promise<MastraMessageV1[] | MastraMessageV2[]> {
360
- return this.stores.memory.getMessagesById({ messageIds, format });
361
- }
362
-
363
- async saveMessages(args: { messages: MastraMessageV1[]; format?: undefined | 'v1' }): Promise<MastraMessageV1[]>;
364
- async saveMessages(args: { messages: MastraMessageV2[]; format: 'v2' }): Promise<MastraMessageV2[]>;
365
- async saveMessages(
366
- args: { messages: MastraMessageV1[]; format?: undefined | 'v1' } | { messages: MastraMessageV2[]; format: 'v2' },
367
- ): Promise<MastraMessageV2[] | MastraMessageV1[]> {
368
- return this.stores.memory.saveMessages(args);
369
- }
370
-
371
- async getMessagesPaginated(
372
- args: StorageGetMessagesArg & { format?: 'v1' | 'v2' },
373
- ): Promise<PaginationInfo & { messages: MastraMessageV1[] | MastraMessageV2[] }> {
374
- return this.stores.memory.getMessagesPaginated(args);
375
- }
376
-
377
- async updateMessages(args: {
378
- messages: (Partial<Omit<MastraMessageV2, 'createdAt'>> & {
379
- id: string;
380
- threadId?: string;
381
- content?: { metadata?: MastraMessageContentV2['metadata']; content?: MastraMessageContentV2['content'] };
382
- })[];
383
- }): Promise<MastraMessageV2[]> {
384
- return this.stores.memory.updateMessages(args);
385
- }
386
-
387
- async getResourceById({ resourceId }: { resourceId: string }): Promise<StorageResourceType | null> {
388
- return this.stores.memory.getResourceById({ resourceId });
389
- }
390
-
391
- async saveResource({ resource }: { resource: StorageResourceType }): Promise<StorageResourceType> {
392
- return this.stores.memory.saveResource({ resource });
393
- }
394
-
395
- async updateResource({
396
- resourceId,
397
- workingMemory,
398
- metadata,
399
- }: {
400
- resourceId: string;
401
- workingMemory?: string;
402
- metadata?: Record<string, unknown>;
403
- }): Promise<StorageResourceType> {
404
- return this.stores.memory.updateResource({ resourceId, workingMemory, metadata });
405
- }
406
-
407
- async getScoreById({ id }: { id: string }): Promise<ScoreRowData | null> {
408
- return this.stores.scores.getScoreById({ id });
409
- }
410
-
411
- async saveScore(_score: ScoreRowData): Promise<{ score: ScoreRowData }> {
412
- return this.stores.scores.saveScore(_score);
413
- }
414
-
415
- async getScoresByRunId({
416
- runId,
417
- pagination,
418
- }: {
419
- runId: string;
420
- pagination: StoragePagination;
421
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
422
- return this.stores.scores.getScoresByRunId({ runId, pagination });
423
- }
424
-
425
- async getScoresByEntityId({
426
- entityId,
427
- entityType,
428
- pagination,
429
- }: {
430
- pagination: StoragePagination;
431
- entityId: string;
432
- entityType: string;
433
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
434
- return this.stores.scores.getScoresByEntityId({ entityId, entityType, pagination });
435
- }
436
-
437
- async getScoresByScorerId({
438
- scorerId,
439
- pagination,
440
- entityId,
441
- entityType,
442
- source,
443
- }: {
444
- scorerId: string;
445
- pagination: StoragePagination;
446
- entityId?: string;
447
- entityType?: string;
448
- source?: ScoringSource;
449
- }): Promise<{ pagination: PaginationInfo; scores: ScoreRowData[] }> {
450
- return this.stores.scores.getScoresByScorerId({ scorerId, pagination, entityId, entityType, source });
451
- }
452
-
453
- async close(): Promise<void> {
454
- await this.db.close();
455
- }
456
- }
@@ -1,9 +0,0 @@
1
- {
2
- "extends": ["./tsconfig.json", "../../tsconfig.build.json"],
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src"
6
- },
7
- "include": ["src/**/*"],
8
- "exclude": ["node_modules", "**/*.test.ts", "src/**/*.mock.ts"]
9
- }
package/tsconfig.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.node.json",
3
- "include": ["src/**/*", "tsup.config.ts"],
4
- "exclude": ["node_modules", "**/*.test.ts"]
5
- }
package/tsup.config.ts DELETED
@@ -1,17 +0,0 @@
1
- import { generateTypes } from '@internal/types-builder';
2
- import { defineConfig } from 'tsup';
3
-
4
- export default defineConfig({
5
- entry: ['src/index.ts'],
6
- format: ['esm', 'cjs'],
7
- clean: true,
8
- dts: false,
9
- splitting: true,
10
- treeshake: {
11
- preset: 'smallest',
12
- },
13
- sourcemap: true,
14
- onSuccess: async () => {
15
- await generateTypes(process.cwd());
16
- },
17
- });
package/vitest.config.ts DELETED
@@ -1,12 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
-
3
- export default defineConfig({
4
- test: {
5
- environment: 'node',
6
- include: ['src/**/*.test.ts'],
7
- exclude: ['src/**/*.performance.test.ts'],
8
- coverage: {
9
- reporter: ['text', 'json', 'html'],
10
- },
11
- },
12
- });