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

Commit dbc63a0

Browse files
feat: support multi process in cortex (#965)
1 parent d07e092 commit dbc63a0

36 files changed

+187
-202
lines changed

cortex-js/src/app.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { NestFactory } from '@nestjs/core';
22
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
33
import { AppModule } from './app.module';
4-
import { FileManagerService } from './infrastructure/services/file-manager/file-manager.service';
4+
import { fileManagerService } from './infrastructure/services/file-manager/file-manager.service';
55
import { ValidationPipe } from '@nestjs/common';
66
import { TelemetryUsecases } from './usecases/telemetry/telemetry.usecases';
77
export const getApp = async () => {
@@ -14,8 +14,7 @@ export const getApp = async () => {
1414
// Set the global prefix for the API /v1/
1515
app.setGlobalPrefix('v1');
1616

17-
const fileService = app.get(FileManagerService);
18-
await fileService.getConfig();
17+
await fileManagerService.getConfig();
1918

2019
const telemetryService = await app.resolve(TelemetryUsecases);
2120
await telemetryService.initInterval();

cortex-js/src/command.module.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import { EnginesListCommand } from './infrastructure/commanders/engines/engines-
2828
import { EnginesGetCommand } from './infrastructure/commanders/engines/engines-get.command';
2929
import { EnginesInitCommand } from './infrastructure/commanders/engines/engines-init.command';
3030
import { EnginesSetCommand } from './infrastructure/commanders/engines/engines-set.command';
31-
import { CortexClientModule } from './infrastructure/commanders/services/cortex.client.module';
3231

3332
@Module({
3433
imports: [
@@ -42,7 +41,6 @@ import { CortexClientModule } from './infrastructure/commanders/services/cortex.
4241
FileManagerModule,
4342
TelemetryModule,
4443
ContextModule,
45-
CortexClientModule,
4644
],
4745
providers: [
4846
CortexCommand,

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ import { CommandRunner } from 'nest-commander';
22
import { Injectable } from '@nestjs/common';
33
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
44
import ora from 'ora';
5+
import { CortexClient } from './services/cortex.client';
6+
import { fileManagerService } from '../services/file-manager/file-manager.service';
57

68
@Injectable()
79
export abstract class BaseCommand extends CommandRunner {
10+
cortex: CortexClient;
811
constructor(readonly cortexUseCases: CortexUsecases) {
912
super();
1013
}
@@ -26,6 +29,9 @@ export abstract class BaseCommand extends CommandRunner {
2629
process.exit(1);
2730
}
2831
checkingSpinner.succeed('API server is online');
32+
if (!this.cortex) {
33+
this.cortex = new CortexClient();
34+
}
2935
await this.runCommand(passedParam, options);
3036
}
3137
}

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
77
import { BaseCommand } from './base.command';
88
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
9-
import { FileManagerService } from '../services/file-manager/file-manager.service';
109
import { join } from 'path';
1110
import yaml from 'js-yaml';
1211
import si from 'systeminformation';
@@ -16,7 +15,7 @@ import { BenchmarkHardware } from '@/domain/telemetry/telemetry.interface';
1615
import { defaultBenchmarkConfiguration } from '../constants/benchmark';
1716
import { inspect } from 'util';
1817
import { Cortex } from '@cortexso/cortex.js';
19-
import { CortexClient } from './services/cortex.client';
18+
import { fileManagerService } from '../services/file-manager/file-manager.service';
2019

2120
@SubCommand({
2221
name: 'benchmark',
@@ -29,10 +28,8 @@ import { CortexClient } from './services/cortex.client';
2928
})
3029
export class BenchmarkCommand extends BaseCommand {
3130
constructor(
32-
private readonly cortexUsecases: CortexUsecases,
33-
private readonly fileService: FileManagerService,
31+
readonly cortexUsecases: CortexUsecases,
3432
private readonly telemetryUsecases: TelemetryUsecases,
35-
private readonly cortex: CortexClient,
3633
) {
3734
super(cortexUsecases);
3835
}
@@ -108,7 +105,7 @@ export class BenchmarkCommand extends BaseCommand {
108105
* @returns the benchmark configuration
109106
*/
110107
private async getBenchmarkConfig() {
111-
const benchmarkFolder = await this.fileService.getBenchmarkPath();
108+
const benchmarkFolder = await fileManagerService.getBenchmarkPath();
112109
const configurationPath = join(benchmarkFolder, 'config.yaml');
113110
if (existsSync(configurationPath)) {
114111
return yaml.load(
@@ -301,7 +298,7 @@ export class BenchmarkCommand extends BaseCommand {
301298
bar.stop();
302299

303300
const outputFilePath = join(
304-
await this.fileService.getBenchmarkPath(),
301+
await fileManagerService.getBenchmarkPath(),
305302
'output.json',
306303
);
307304
await this.telemetryUsecases.sendBenchmarkEvent({

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ import { BaseCommand } from './base.command';
1212
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
1313
import { Engines } from './types/engine.interface';
1414
import { join } from 'path';
15-
import { FileManagerService } from '../services/file-manager/file-manager.service';
15+
import { fileManagerService } from '../services/file-manager/file-manager.service';
1616
import { isRemoteEngine } from '@/utils/normalize-model-id';
1717
import { Cortex } from '@cortexso/cortex.js';
1818
import { ChatClient } from './services/chat-client';
1919
import { downloadProgress } from '@/utils/download-progress';
20-
import { CortexClient } from './services/cortex.client';
2120
import { DownloadType } from '@/domain/models/download.interface';
21+
import { CortexClient } from './services/cortex.client';
2222

2323
type ChatOptions = {
2424
threadId?: string;
@@ -44,19 +44,17 @@ export class ChatCommand extends BaseCommand {
4444
constructor(
4545
private readonly inquirerService: InquirerService,
4646
private readonly telemetryUsecases: TelemetryUsecases,
47-
private readonly fileService: FileManagerService,
4847
protected readonly cortexUsecases: CortexUsecases,
4948
protected readonly contextService: ContextService,
50-
protected readonly cortex: CortexClient,
5149
) {
5250
super(cortexUsecases);
53-
this.chatClient = new ChatClient(this.cortex);
5451
}
5552

5653
async runCommand(
5754
passedParams: string[],
5855
options: ChatOptions,
5956
): Promise<void> {
57+
this.chatClient = new ChatClient(this.cortex);
6058
let modelId = passedParams[0];
6159
// First attempt to get message from input or options
6260
// Extract input from 1 to end of array
@@ -89,7 +87,9 @@ export class ChatCommand extends BaseCommand {
8987
// Pull engine if not exist
9088
if (
9189
!isRemoteEngine(engine) &&
92-
!existsSync(join(await this.fileService.getCortexCppEnginePath(), engine))
90+
!existsSync(
91+
join(await fileManagerService.getCortexCppEnginePath(), engine),
92+
)
9393
) {
9494
console.log('Downloading engine...');
9595
await this.cortex.engines.init(engine);
@@ -107,7 +107,7 @@ export class ChatCommand extends BaseCommand {
107107
TelemetrySource.CLI,
108108
);
109109

110-
const preset = await this.fileService.getPreset(options.preset);
110+
const preset = await fileManagerService.getPreset(options.preset);
111111

112112
return this.chatClient.chat(
113113
modelId,

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

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { ContextService } from '../services/context/context.service';
1515
import { EnginesCommand } from './engines.command';
1616
import { defaultCortexJsHost, defaultCortexJsPort } from '../constants/cortex';
1717
import { getApp } from '@/app';
18-
import { FileManagerService } from '../services/file-manager/file-manager.service';
18+
import { fileManagerService } from '../services/file-manager/file-manager.service';
1919
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
2020
import { ServeStopCommand } from './serve-stop.command';
2121
import ora from 'ora';
@@ -27,6 +27,7 @@ type ServeOptions = {
2727
logs?: boolean;
2828
dataFolder?: string;
2929
version?: boolean;
30+
name?: string;
3031
};
3132

3233
@RootCommand({
@@ -54,24 +55,34 @@ export class CortexCommand extends CommandRunner {
5455
configPort: number;
5556
constructor(
5657
readonly contextService: ContextService,
57-
readonly fileManagerService: FileManagerService,
5858
readonly cortexUseCases: CortexUsecases,
5959
) {
6060
super();
6161
}
6262

6363
async run(passedParams: string[], options?: ServeOptions): Promise<void> {
64+
if (options?.name) {
65+
const isProfileConfigExists = fileManagerService.profileConfigExists(
66+
options.name,
67+
);
68+
if (!isProfileConfigExists) {
69+
await fileManagerService.writeConfigFile({
70+
...fileManagerService.defaultConfig(),
71+
apiServerHost: options?.address || defaultCortexJsHost,
72+
apiServerPort: options?.port || defaultCortexJsPort,
73+
});
74+
}
75+
}
6476
const {
6577
apiServerHost: configApiServerHost,
6678
apiServerPort: configApiServerPort,
67-
} = await this.fileManagerService.getConfig();
79+
} = await fileManagerService.getConfig();
6880

6981
this.configHost = configApiServerHost || defaultCortexJsHost;
7082
this.configPort = configApiServerPort || defaultCortexJsPort;
7183

7284
this.host = options?.address || configApiServerHost || defaultCortexJsHost;
7385
this.port = options?.port || configApiServerPort || defaultCortexJsPort;
74-
7586
const showLogs = options?.logs || false;
7687
const showVersion = options?.version || false;
7788
const dataFolderPath = options?.dataFolder;
@@ -85,7 +96,7 @@ export class CortexCommand extends CommandRunner {
8596
}
8697

8798
private async startServer(attach: boolean, dataFolderPath?: string) {
88-
const config = await this.fileManagerService.getConfig();
99+
const config = await fileManagerService.getConfig();
89100
try {
90101
const startEngineSpinner = ora('Starting Cortex engine...');
91102
await this.cortexUseCases.startCortex().catch((e) => {
@@ -103,12 +114,12 @@ export class CortexCommand extends CommandRunner {
103114
process.exit(0);
104115
}
105116
if (dataFolderPath) {
106-
await this.fileManagerService.writeConfigFile({
117+
await fileManagerService.writeConfigFile({
107118
...config,
108119
dataFolderPath,
109120
});
110121
// load config again to create the data folder
111-
await this.fileManagerService.getConfig(dataFolderPath);
122+
await fileManagerService.getConfig(dataFolderPath);
112123
}
113124
if (attach) {
114125
const app = await getApp();
@@ -124,7 +135,7 @@ export class CortexCommand extends CommandRunner {
124135
`API Playground available at http://${this.host}:${this.port}/api`,
125136
),
126137
);
127-
await this.fileManagerService.writeConfigFile({
138+
await fileManagerService.writeConfigFile({
128139
...config,
129140
apiServerHost: this.host,
130141
apiServerPort: this.port,
@@ -134,7 +145,7 @@ export class CortexCommand extends CommandRunner {
134145
} catch (e) {
135146
console.error(e);
136147
// revert the data folder path if it was set
137-
await this.fileManagerService.writeConfigFile({
148+
await fileManagerService.writeConfigFile({
138149
...config,
139150
});
140151
console.error(`Failed to start server. Is port ${this.port} in use?`);
@@ -181,4 +192,12 @@ export class CortexCommand extends CommandRunner {
181192
parseVersion() {
182193
return true;
183194
}
195+
@Option({
196+
flags: '-n, --name <name>',
197+
description: 'Name of the process',
198+
})
199+
parseName(value: string) {
200+
fileManagerService.setConfigProfile(value);
201+
return value;
202+
}
184203
}

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
44
import { BaseCommand } from './base.command';
55
import { Cortex } from '@cortexso/cortex.js';
66
import ora from 'ora';
7-
import { CortexClient } from './services/cortex.client';
87

98
interface EmbeddingCommandOptions {
109
encoding_format?: string;
@@ -24,7 +23,6 @@ interface EmbeddingCommandOptions {
2423
export class EmbeddingCommand extends BaseCommand {
2524
constructor(
2625
private readonly inquirerService: InquirerService,
27-
private readonly cortex: CortexClient,
2826
readonly cortexUsecases: CortexUsecases,
2927
) {
3028
super(cortexUsecases);

cortex-js/src/infrastructure/commanders/engines/engines-get.command.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ContextService } from '@/infrastructure/services/context/context.servic
44
import { EngineNamesMap, Engines } from '../types/engine.interface';
55
import { BaseCommand } from '../base.command';
66
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
7-
import { CortexClient } from '../services/cortex.client';
87

98
@SubCommand({
109
name: '<name> get',
@@ -18,7 +17,6 @@ export class EnginesGetCommand extends BaseCommand {
1817
constructor(
1918
readonly contextService: ContextService,
2019
readonly cortexUsecases: CortexUsecases,
21-
private readonly cortex: CortexClient,
2220
) {
2321
super(cortexUsecases);
2422
}

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

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,12 @@ import { SetCommandContext } from '../decorators/CommandContext';
33
import { ContextService } from '@/infrastructure/services/context/context.service';
44
import { Engines } from '../types/engine.interface';
55
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
6-
import { FileManagerService } from '@/infrastructure/services/file-manager/file-manager.service';
76
import { BaseCommand } from '../base.command';
87
import { defaultInstallationOptions } from '@/utils/init';
98
import { Presets, SingleBar } from 'cli-progress';
10-
import { CortexClient } from '../services/cortex.client';
119
import ora from 'ora';
1210
import { InitEngineDto } from '@/infrastructure/dtos/engines/engines.dto';
11+
import { fileManagerService } from '@/infrastructure/services/file-manager/file-manager.service';
1312

1413
@SubCommand({
1514
name: '<name> init',
@@ -22,9 +21,7 @@ import { InitEngineDto } from '@/infrastructure/dtos/engines/engines.dto';
2221
export class EnginesInitCommand extends BaseCommand {
2322
constructor(
2423
private readonly cortexUsecases: CortexUsecases,
25-
private readonly fileManagerService: FileManagerService,
2624
readonly contextService: ContextService,
27-
private readonly cortex: CortexClient,
2825
) {
2926
super(cortexUsecases);
3027
}
@@ -41,7 +38,7 @@ export class EnginesInitCommand extends BaseCommand {
4138
}
4239
: {};
4340

44-
const configs = await this.fileManagerService.getConfig();
41+
const configs = await fileManagerService.getConfig();
4542
const host = configs.cortexCppHost;
4643
const port = configs.cortexCppPort;
4744
// Should stop cortex before installing engine

cortex-js/src/infrastructure/commanders/engines/engines-list.command.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { ContextService } from '@/infrastructure/services/context/context.servic
44
import { EngineNamesMap } from '../types/engine.interface';
55
import { CortexUsecases } from '@/usecases/cortex/cortex.usecases';
66
import { BaseCommand } from '../base.command';
7-
import { CortexClient } from '../services/cortex.client';
87

98
@SubCommand({
109
name: 'list',
@@ -15,7 +14,6 @@ export class EnginesListCommand extends BaseCommand {
1514
constructor(
1615
readonly contextService: ContextService,
1716
readonly cortexUseCases: CortexUsecases,
18-
private readonly cortex: CortexClient,
1917
) {
2018
super(cortexUseCases);
2119
}

0 commit comments

Comments
 (0)