diff --git a/cortex-js/src/extensions/extensions.module.ts b/cortex-js/src/extensions/extensions.module.ts index d9c57d6fd..ad8430be6 100644 --- a/cortex-js/src/extensions/extensions.module.ts +++ b/cortex-js/src/extensions/extensions.module.ts @@ -4,23 +4,27 @@ import MistralEngineExtension from './mistral.engine'; import OpenAIEngineExtension from './openai.engine'; import { HttpModule, HttpService } from '@nestjs/axios'; import { ConfigsUsecases } from '@/usecases/configs/configs.usecase'; -import { FileManagerModule } from '@/infrastructure/services/file-manager/file-manager.module'; +import { ConfigsModule } from '@/usecases/configs/configs.module'; +import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; const provider = { provide: 'EXTENSIONS_PROVIDER', - inject: [HttpService, ConfigsUsecases], - useFactory: (httpService: HttpService, configUsecases: ConfigsUsecases) => [ - new OpenAIEngineExtension(httpService, configUsecases), - new GroqEngineExtension(httpService, configUsecases), - new MistralEngineExtension(httpService, configUsecases), + inject: [HttpService, ConfigsUsecases, EventEmitter2], + useFactory: ( + httpService: HttpService, + configUsecases: ConfigsUsecases, + eventEmitter: EventEmitter2, + ) => [ + new OpenAIEngineExtension(httpService, configUsecases, eventEmitter), + new GroqEngineExtension(httpService, configUsecases, eventEmitter), + new MistralEngineExtension(httpService, configUsecases, eventEmitter), ], }; @Module({ - // Do not import ConfigsModule here to avoid circular dependency - imports: [HttpModule, FileManagerModule], + imports: [HttpModule, ConfigsModule], controllers: [], - providers: [ConfigsUsecases, provider], - exports: [ConfigsUsecases, provider], + providers: [provider], + exports: [provider], }) export class ExtensionsModule {} diff --git a/cortex-js/src/extensions/groq.engine.ts b/cortex-js/src/extensions/groq.engine.ts index 73a376019..cc7dfdbc9 100644 --- a/cortex-js/src/extensions/groq.engine.ts +++ b/cortex-js/src/extensions/groq.engine.ts @@ -1,6 +1,7 @@ import { HttpService } from '@nestjs/axios'; import { OAIEngineExtension } from '../domain/abstracts/oai.abstract'; import { ConfigsUsecases } from '@/usecases/configs/configs.usecase'; +import { EventEmitter2 } from '@nestjs/event-emitter'; /** * A class that implements the InferenceExtension interface from the @janhq/core package. @@ -18,8 +19,15 @@ export default class GroqEngineExtension extends OAIEngineExtension { constructor( protected readonly httpService: HttpService, protected readonly configsUsecases: ConfigsUsecases, + protected readonly eventEmmitter: EventEmitter2, ) { super(httpService); + + eventEmmitter.on('config.updated', async (data) => { + if (data.group === this.name) { + this.apiKey = data.value; + } + }); } async onLoad() { @@ -27,7 +35,7 @@ export default class GroqEngineExtension extends OAIEngineExtension { this.name, )) as unknown as { apiKey: string }; - this.apiKey = configs?.apiKey + this.apiKey = configs?.apiKey; if (!configs?.apiKey) await this.configsUsecases.saveConfig('apiKey', '', this.name); } diff --git a/cortex-js/src/extensions/mistral.engine.ts b/cortex-js/src/extensions/mistral.engine.ts index 19beb6961..2bf5accd3 100644 --- a/cortex-js/src/extensions/mistral.engine.ts +++ b/cortex-js/src/extensions/mistral.engine.ts @@ -1,6 +1,7 @@ import { HttpService } from '@nestjs/axios'; import { OAIEngineExtension } from '../domain/abstracts/oai.abstract'; import { ConfigsUsecases } from '@/usecases/configs/configs.usecase'; +import { EventEmitter2 } from '@nestjs/event-emitter'; /** * A class that implements the InferenceExtension interface from the @janhq/core package. @@ -18,8 +19,15 @@ export default class MistralEngineExtension extends OAIEngineExtension { constructor( protected readonly httpService: HttpService, protected readonly configsUsecases: ConfigsUsecases, + protected readonly eventEmmitter: EventEmitter2, ) { super(httpService); + + eventEmmitter.on('config.updated', async (data) => { + if (data.group === this.name) { + this.apiKey = data.value; + } + }); } async onLoad() { diff --git a/cortex-js/src/extensions/openai.engine.ts b/cortex-js/src/extensions/openai.engine.ts index 9f3b9bd01..aa10d857c 100644 --- a/cortex-js/src/extensions/openai.engine.ts +++ b/cortex-js/src/extensions/openai.engine.ts @@ -1,6 +1,7 @@ import { HttpService } from '@nestjs/axios'; import { OAIEngineExtension } from '../domain/abstracts/oai.abstract'; import { ConfigsUsecases } from '@/usecases/configs/configs.usecase'; +import { EventEmitter2 } from '@nestjs/event-emitter'; /** * A class that implements the InferenceExtension interface from the @janhq/core package. @@ -18,8 +19,15 @@ export default class OpenAIEngineExtension extends OAIEngineExtension { constructor( protected readonly httpService: HttpService, protected readonly configsUsecases: ConfigsUsecases, + protected readonly eventEmmitter: EventEmitter2, ) { super(httpService); + + eventEmmitter.on('config.updated', async (data) => { + if (data.group === this.name) { + this.apiKey = data.value; + } + }); } async onLoad() { diff --git a/cortex-js/src/usecases/configs/configs.module.ts b/cortex-js/src/usecases/configs/configs.module.ts index a5592df0e..afa4bca2f 100644 --- a/cortex-js/src/usecases/configs/configs.module.ts +++ b/cortex-js/src/usecases/configs/configs.module.ts @@ -1,10 +1,9 @@ import { Module } from '@nestjs/common'; import { FileManagerModule } from '@/infrastructure/services/file-manager/file-manager.module'; import { ConfigsUsecases } from './configs.usecase'; -import { ExtensionModule } from '@/infrastructure/repositories/extensions/extension.module'; @Module({ - imports: [FileManagerModule, ExtensionModule], + imports: [FileManagerModule], controllers: [], providers: [ConfigsUsecases], exports: [ConfigsUsecases], diff --git a/cortex-js/src/usecases/configs/configs.usecase.ts b/cortex-js/src/usecases/configs/configs.usecase.ts index f1b47b7ee..4cff2e3f5 100644 --- a/cortex-js/src/usecases/configs/configs.usecase.ts +++ b/cortex-js/src/usecases/configs/configs.usecase.ts @@ -1,10 +1,14 @@ import { CommonResponseDto } from '@/infrastructure/dtos/common/common-response.dto'; import { FileManagerService } from '@/infrastructure/services/file-manager/file-manager.service'; import { Injectable } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; @Injectable() export class ConfigsUsecases { - constructor(private readonly fileManagerService: FileManagerService) {} + constructor( + private readonly fileManagerService: FileManagerService, + private readonly eventEmitter: EventEmitter2, + ) {} /** * Save a configuration to the .cortexrc file. @@ -33,11 +37,22 @@ export class ConfigsUsecases { : {}), }; - return this.fileManagerService.writeConfigFile(newConfigs).then(() => { - return { - message: 'The config has been successfully updated.', - }; - }); + return this.fileManagerService + .writeConfigFile(newConfigs) + .then(async () => { + if (group) { + this.eventEmitter.emit('config.updated', { + group, + key, + value, + }); + } + }) + .then(() => { + return { + message: 'The config has been successfully updated.', + }; + }); } /**