Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit febf4d8

Browse files
feat: add analytic metric, send benchmark to server
1 parent 199ed56 commit febf4d8

File tree

16 files changed

+449
-81
lines changed

16 files changed

+449
-81
lines changed

cortex-js/src/app.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
33
import { AppModule } from './app.module';
44
import { FileManagerService } from './infrastructure/services/file-manager/file-manager.service';
55
import { ValidationPipe } from '@nestjs/common';
6+
import { TelemetryUsecases } from './usecases/telemetry/telemetry.usecases';
67
export const getApp = async () => {
78
const app = await NestFactory.create(AppModule, {
89
snapshot: true,
@@ -16,6 +17,9 @@ export const getApp = async () => {
1617
const fileService = app.get(FileManagerService);
1718
await fileService.getConfig();
1819

20+
const telemetryService = await app.resolve(TelemetryUsecases);
21+
await telemetryService.initInterval();
22+
1923
app.useGlobalPipes(
2024
new ValidationPipe({
2125
transform: true,

cortex-js/src/command.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,26 @@ async function bootstrap() {
1515
logger: ['warn', 'error'],
1616
errorHandler: async (error) => {
1717
await telemetryUseCase!.createCrashReport(error, TelemetrySource.CLI);
18+
console.error(error);
1819
process.exit(1);
1920
},
2021
serviceErrorHandler: async (error) => {
2122
await telemetryUseCase!.createCrashReport(error, TelemetrySource.CLI);
23+
console.error(error);
2224
process.exit(1);
2325
},
2426
});
2527

2628
telemetryUseCase = await app.resolve(TelemetryUsecases);
2729
contextService = await app.resolve(ContextService);
2830

29-
telemetryUseCase!.sendCrashReport();
31+
const anonymousData = await telemetryUseCase!.updateAnonymousData();
3032

3133
await contextService!.init(async () => {
3234
contextService!.set('source', TelemetrySource.CLI);
35+
contextService!.set('sessionId', anonymousData?.sessionId);
36+
telemetryUseCase!.sendActivationEvent(TelemetrySource.CLI);
37+
telemetryUseCase!.sendCrashReport();
3338
return CommandFactory.runApplication(app);
3439
});
3540
}
Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,50 @@
1+
import { ModelStat } from '@/infrastructure/commanders/types/model-stat.interface';
12
import {
3+
BenchmarkHardware,
24
CrashReportAttributes,
5+
EventAttributes,
36
Telemetry,
7+
TelemetryAnonymized,
48
TelemetrySource,
59
} from '../telemetry/telemetry.interface';
610

711
export abstract class TelemetryRepository {
812
abstract readCrashReports(
913
callback: (Telemetry: Telemetry) => void,
1014
): Promise<void>;
15+
1116
abstract createCrashReport(
1217
crashReport: CrashReportAttributes,
1318
source?: TelemetrySource,
1419
): Promise<void>;
20+
1521
abstract getLastCrashReport(): Promise<Telemetry | null>;
22+
1623
abstract markLastCrashReportAsSent(): Promise<void>;
24+
1725
abstract sendTelemetryToOTelCollector(
1826
endpoint: string,
1927
telemetry: Telemetry,
2028
): Promise<void>;
21-
abstract sendTelemetryToServer(telemetry: Telemetry): Promise<void>;
29+
30+
abstract sendTelemetryToServer(
31+
telemetryEvent: Telemetry['event'],
32+
): Promise<void>;
33+
34+
abstract sendEvent(
35+
events: EventAttributes[],
36+
source: TelemetrySource,
37+
): Promise<void>;
38+
39+
abstract getAnonymizedData(): Promise<TelemetryAnonymized | null>;
40+
41+
abstract updateAnonymousData(data: TelemetryAnonymized): Promise<void>;
42+
43+
abstract sendBenchmarkToServer(data: {
44+
hardware: BenchmarkHardware;
45+
results: any;
46+
metrics: any;
47+
model: ModelStat;
48+
sessionId: string;
49+
}): Promise<void>;
2250
}

cortex-js/src/domain/telemetry/crash-report.interface.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

cortex-js/src/domain/telemetry/telemetry.interface.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,7 @@ export interface TelemetryResource {
88
source?: TelemetrySource;
99
cpu?: string;
1010
gpus?: string;
11-
// todo: consider about sessionId
12-
// sessionId: string;
13-
}
14-
15-
export interface CrashReportEvent {
16-
modelId?: string;
17-
sessionId: string;
18-
stack?: string;
11+
sessionId?: string;
1912
}
2013

2114
export interface Resource {
@@ -77,6 +70,7 @@ export interface CrashReportAttributes {
7770
stack?: string;
7871
message: string;
7972
payload: CrashReportPayload;
73+
sessionId?: string;
8074
}
8175

8276
export interface TelemetryEventMetadata {
@@ -90,3 +84,31 @@ export interface Telemetry {
9084
resourceLogs: TelemetryEvent[];
9185
};
9286
}
87+
88+
export enum EventName {
89+
INIT = 'init',
90+
DOWNLOAD_MODEL = 'download-model',
91+
CHAT = 'chat',
92+
ACTIVATE = 'activate',
93+
NEW_ACTIVATE = 'new_activate',
94+
}
95+
96+
export interface EventAttributes {
97+
name: string;
98+
modelId?: string;
99+
sessionId?: string;
100+
}
101+
102+
export interface TelemetryAnonymized {
103+
sessionId: string | null;
104+
lastActiveAt?: string | null;
105+
}
106+
export interface BenchmarkHardware {
107+
gpu: any[];
108+
cpu: any;
109+
board: any;
110+
disk: any[];
111+
chassis: any;
112+
memLayout: any[];
113+
os: any;
114+
}

cortex-js/src/infrastructure/commanders/chat.command.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import { PSCliUsecases } from './usecases/ps.cli.usecases';
1010
import { ModelsUsecases } from '@/usecases/models/models.usecases';
1111
import { SetCommandContext } from './decorators/CommandContext';
1212
import { ModelStat } from './types/model-stat.interface';
13+
import { TelemetryUsecases } from '@/usecases/telemetry/telemetry.usecases';
14+
import {
15+
EventName,
16+
TelemetrySource,
17+
} from '@/domain/telemetry/telemetry.interface';
1318
import { ContextService } from '../services/context/context.service';
1419

1520
type ChatOptions = {
@@ -36,6 +41,7 @@ export class ChatCommand extends CommandRunner {
3641
private readonly modelsUsecases: ModelsUsecases,
3742
private readonly psCliUsecases: PSCliUsecases,
3843
readonly contextService: ContextService,
44+
private readonly telemetryUsecases: TelemetryUsecases,
3945
) {
4046
super();
4147
}
@@ -66,14 +72,23 @@ export class ChatCommand extends CommandRunner {
6672
}
6773

6874
if (!message) options.attach = true;
69-
70-
return this.chatCliUsecases.chat(
75+
const result = await this.chatCliUsecases.chat(
7176
modelId,
7277
options.threadId,
7378
message, // Accept both message from inputs or arguments
7479
options.attach,
7580
false, // Do not stop cortex session or loaded model
7681
);
82+
this.telemetryUsecases.sendEvent(
83+
[
84+
{
85+
name: EventName.CHAT,
86+
modelId,
87+
},
88+
],
89+
TelemetrySource.CLI,
90+
);
91+
return result;
7792
}
7893

7994
modelInquiry = async (models: ModelStat[]) => {

cortex-js/src/infrastructure/commanders/init.command.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import {
77
import { InitCliUsecases } from './usecases/init.cli.usecases';
88
import { InitOptions } from './types/init-options.interface';
99
import { SetCommandContext } from './decorators/CommandContext';
10+
import { TelemetryUsecases } from '@/usecases/telemetry/telemetry.usecases';
11+
import {
12+
EventName,
13+
TelemetrySource,
14+
} from '@/domain/telemetry/telemetry.interface';
1015
import { ContextService } from '../services/context/context.service';
1116

1217
@SubCommand({
@@ -24,6 +29,7 @@ export class InitCommand extends CommandRunner {
2429
private readonly inquirerService: InquirerService,
2530
private readonly initUsecases: InitCliUsecases,
2631
readonly contextService: ContextService,
32+
private readonly telemetryUsecases: TelemetryUsecases,
2733
) {
2834
super();
2935
}
@@ -42,6 +48,14 @@ export class InitCommand extends CommandRunner {
4248
const version = passedParams[0] ?? 'latest';
4349

4450
await this.initUsecases.installEngine(options, version);
51+
this.telemetryUsecases.sendEvent(
52+
[
53+
{
54+
name: EventName.INIT,
55+
},
56+
],
57+
TelemetrySource.CLI,
58+
);
4559
}
4660
}
4761

cortex-js/src/infrastructure/commanders/models/model-pull.command.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { exit } from 'node:process';
33
import { SetCommandContext } from '../decorators/CommandContext';
44
import { ModelsCliUsecases } from '@commanders/usecases/models.cli.usecases';
55
import { ModelNotFoundException } from '@/infrastructure/exception/model-not-found.exception';
6+
import { TelemetryUsecases } from '@/usecases/telemetry/telemetry.usecases';
7+
import {
8+
EventName,
9+
TelemetrySource,
10+
} from '@/domain/telemetry/telemetry.interface';
611
import { ContextService } from '@/infrastructure/services/context/context.service';
712
import { existsSync } from 'fs';
813
import { join } from 'node:path';
@@ -25,6 +30,7 @@ export class ModelPullCommand extends CommandRunner {
2530
private readonly initUsecases: InitCliUsecases,
2631
private readonly fileService: FileManagerService,
2732
readonly contextService: ContextService,
33+
private readonly telemetryUsecases: TelemetryUsecases,
2834
) {
2935
super();
3036
}
@@ -59,7 +65,15 @@ export class ModelPullCommand extends CommandRunner {
5965
engine,
6066
);
6167
}
62-
68+
this.telemetryUsecases.sendEvent(
69+
[
70+
{
71+
name: EventName.DOWNLOAD_MODEL,
72+
modelId: passedParams[0],
73+
},
74+
],
75+
TelemetrySource.CLI,
76+
);
6377
console.log('\nDownload complete!');
6478
exit(0);
6579
}

0 commit comments

Comments
 (0)