@dataclouder/nest-vertex 0.0.56 → 0.0.58

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.
Files changed (50) hide show
  1. package/comfyui/controllers/comfy-sdk.controller.js +12 -2
  2. package/comfyui/services/comfy-connection.service.js +4 -5
  3. package/comfyui/services/comfy-sdk.service.js +1 -1
  4. package/controllers/stt/adapter-stt.controller.d.ts +10 -0
  5. package/controllers/stt/adapter-stt.controller.js +79 -0
  6. package/controllers/stt/groq-stt.controller.js +1 -1
  7. package/controllers/stt/local-stt.controller.d.ts +8 -0
  8. package/controllers/stt/local-stt.controller.js +62 -0
  9. package/controllers/tts/vertex-gemini-tts.controller.js +1 -1
  10. package/controllers/tts/vertex-tts-adapter.controller.js +2 -2
  11. package/models/adapter.models.d.ts +1 -1
  12. package/models/key-balancer.models.d.ts +2 -0
  13. package/nest-vertex.module.js +7 -6
  14. package/package.json +1 -1
  15. package/services/vertex-gemini-chat.service.d.ts +1 -0
  16. package/services/vertex-gemini-chat.service.js +21 -14
  17. package/services/vertex-image.service.js +20 -16
  18. package/services/whisper/groq.service.js +1 -0
  19. package/services/whisper/local-stt.service.d.ts +7 -0
  20. package/services/whisper/local-stt.service.js +138 -0
  21. package/drizzle/drizzle.module.d.ts +0 -2
  22. package/drizzle/drizzle.module.js +0 -35
  23. package/drizzle/drizzle.service.d.ts +0 -10
  24. package/drizzle/drizzle.service.js +0 -68
  25. package/drizzle/dto/create-key-balancer.dto.d.ts +0 -9
  26. package/drizzle/dto/create-key-balancer.dto.js +0 -54
  27. package/drizzle/dto/create-key-usage.dto.d.ts +0 -6
  28. package/drizzle/dto/create-key-usage.dto.js +0 -11
  29. package/drizzle/dto/create-user-request.dto.d.ts +0 -7
  30. package/drizzle/dto/create-user-request.dto.js +0 -47
  31. package/drizzle/dto/update-key-balancer.dto.d.ts +0 -5
  32. package/drizzle/dto/update-key-balancer.dto.js +0 -9
  33. package/drizzle/dto/update-user-request.dto.d.ts +0 -5
  34. package/drizzle/dto/update-user-request.dto.js +0 -9
  35. package/drizzle/key-balancer.controller.d.ts +0 -13
  36. package/drizzle/key-balancer.controller.js +0 -103
  37. package/drizzle/key-balancer.model.d.ts +0 -10
  38. package/drizzle/key-balancer.model.js +0 -3
  39. package/drizzle/key-balancer.service.d.ts +0 -11
  40. package/drizzle/key-balancer.service.js +0 -50
  41. package/drizzle/key-usage.service.d.ts +0 -17
  42. package/drizzle/key-usage.service.js +0 -63
  43. package/drizzle/schema.d.ts +0 -395
  44. package/drizzle/schema.js +0 -33
  45. package/drizzle/user-requests.controller.d.ts +0 -47
  46. package/drizzle/user-requests.controller.js +0 -81
  47. package/drizzle/user-requests.service.d.ts +0 -47
  48. package/drizzle/user-requests.service.js +0 -47
  49. package/services/metric-ai.service.d.ts +0 -11
  50. package/services/metric-ai.service.js +0 -48
@@ -21,8 +21,18 @@ let ComfySDKController = class ComfySDKController {
21
21
  return this.comfySDKService.testMethod();
22
22
  }
23
23
  async statusEndpoint() {
24
- const status = await this.comfySDKService.getStatus();
25
- return status;
24
+ try {
25
+ const status = await this.comfySDKService.getStatus();
26
+ return status;
27
+ }
28
+ catch (e) {
29
+ const response = {
30
+ status: 'Server Down',
31
+ numAvailable: 0,
32
+ servers: [],
33
+ };
34
+ return response;
35
+ }
26
36
  }
27
37
  };
28
38
  exports.ComfySDKController = ComfySDKController;
@@ -58,7 +58,6 @@ let ComfyConnectionService = ComfyConnectionService_1 = class ComfyConnectionSer
58
58
  try {
59
59
  await this.checkApiStatus();
60
60
  this.logger.log('Successfully connected to ComfyUI server.');
61
- this.connectWebSocket();
62
61
  }
63
62
  catch (error) {
64
63
  this.logger.error('Failed to connect to ComfyUI server:', error.message || error);
@@ -109,7 +108,7 @@ let ComfyConnectionService = ComfyConnectionService_1 = class ComfyConnectionSer
109
108
  this.logger.log('Disconnected from ComfyUI WebSocket. Attempting to reconnect...');
110
109
  setTimeout(() => this.connectWebSocket(), 5000);
111
110
  });
112
- this.ws.on('error', (error) => {
111
+ this.ws.on('error', error => {
113
112
  this.logger.error('ComfyUI WebSocket error:', error);
114
113
  });
115
114
  }
@@ -177,7 +176,7 @@ let ComfyConnectionService = ComfyConnectionService_1 = class ComfyConnectionSer
177
176
  prompt: workflow,
178
177
  client_id: this.clientId,
179
178
  };
180
- return (0, rxjs_1.firstValueFrom)(this.httpService.post(url, payload)).then((res) => res.data);
179
+ return (0, rxjs_1.firstValueFrom)(this.httpService.post(url, payload)).then(res => res.data);
181
180
  }
182
181
  async uploadImage(imageBuffer, filename) {
183
182
  const url = `http://${this.comfyApiHost}/upload/image`;
@@ -198,11 +197,11 @@ let ComfyConnectionService = ComfyConnectionService_1 = class ComfyConnectionSer
198
197
  reject(new Error(`Media generation timed out after ${timeoutMs / 1000} seconds for prompt ${prompt_id}.`));
199
198
  }, timeoutMs);
200
199
  this.pendingPrompts.set(prompt_id, {
201
- resolve: (output) => {
200
+ resolve: output => {
202
201
  clearTimeout(timeout);
203
202
  resolve(output);
204
203
  },
205
- reject: (error) => {
204
+ reject: error => {
206
205
  clearTimeout(timeout);
207
206
  reject(error);
208
207
  },
@@ -62,7 +62,7 @@ let ComfySDKService = ComfySDKService_1 = class ComfySDKService {
62
62
  this.generatedAssetService = generatedAssetService;
63
63
  this.httpService = httpService;
64
64
  this.storageFactory = storageFactory;
65
- this.api = new comfyui_sdk_1.ComfyApi('http://192.168.2.224:8188').init();
65
+ this.api = new comfyui_sdk_1.ComfyApi(process.env.COMFYUI_API_HOST || 'http://192.168.2.2:8188').init();
66
66
  console.log('what is in the comfy api?', this.api.apiHost);
67
67
  }
68
68
  init() {
@@ -0,0 +1,10 @@
1
+ import { type MulterFile } from '@webundsoehne/nest-fastify-file-upload';
2
+ import { GroqService } from '../../services/whisper/groq.service';
3
+ import { LocalSttService } from '../../services/whisper/local-stt.service';
4
+ export declare class AdapterSttController {
5
+ private readonly groqService;
6
+ private readonly localSttService;
7
+ private readonly logger;
8
+ constructor(groqService: GroqService, localSttService: LocalSttService);
9
+ processAudio(file: MulterFile, provider?: 'local' | 'groq'): Promise<any>;
10
+ }
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var AdapterSttController_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.AdapterSttController = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const nest_fastify_file_upload_1 = require("@webundsoehne/nest-fastify-file-upload");
19
+ const swagger_1 = require("@nestjs/swagger");
20
+ const nest_core_1 = require("@dataclouder/nest-core");
21
+ const groq_service_1 = require("../../services/whisper/groq.service");
22
+ const local_stt_service_1 = require("../../services/whisper/local-stt.service");
23
+ let AdapterSttController = AdapterSttController_1 = class AdapterSttController {
24
+ groqService;
25
+ localSttService;
26
+ logger = new common_1.Logger(AdapterSttController_1.name);
27
+ constructor(groqService, localSttService) {
28
+ this.groqService = groqService;
29
+ this.localSttService = localSttService;
30
+ }
31
+ async processAudio(file, provider = 'local') {
32
+ this.logger.log(`Receive request with provider: ${provider}`);
33
+ if (!file || !file.buffer) {
34
+ this.logger.error('No file buffer received.');
35
+ return { error: 'No file uploaded or file buffer is missing.' };
36
+ }
37
+ this.logger.log(`Received file: ${file.originalname}, mimetype: ${file.mimetype}, size: ${file.size}`);
38
+ try {
39
+ let result;
40
+ if (provider === 'groq') {
41
+ result = await this.groqService.transcribeAudio(file.buffer, file.originalname, file.mimetype);
42
+ }
43
+ else {
44
+ result = await this.localSttService.transcribeAudio(file.buffer, file.originalname, file.mimetype);
45
+ }
46
+ return result;
47
+ }
48
+ catch (error) {
49
+ this.logger.error('Error during transcription process:', error);
50
+ return { error: 'Failed to transcribe audio.', details: error.message };
51
+ }
52
+ }
53
+ };
54
+ exports.AdapterSttController = AdapterSttController;
55
+ __decorate([
56
+ (0, common_1.Post)('transcribe-bytes'),
57
+ (0, common_1.UseInterceptors)((0, nest_fastify_file_upload_1.FileInterceptor)('file')),
58
+ (0, swagger_1.ApiConsumes)('multipart/form-data'),
59
+ (0, nest_fastify_file_upload_1.ApiFileBody)('file'),
60
+ (0, swagger_1.ApiQuery)({
61
+ name: 'provider',
62
+ enum: ['local', 'groq'],
63
+ required: false,
64
+ description: 'The provider to use for transcription. Defaults to "local".',
65
+ }),
66
+ __param(0, (0, common_1.UploadedFile)('file')),
67
+ __param(1, (0, common_1.Query)('provider')),
68
+ __metadata("design:type", Function),
69
+ __metadata("design:paramtypes", [Object, String]),
70
+ __metadata("design:returntype", Promise)
71
+ ], AdapterSttController.prototype, "processAudio", null);
72
+ exports.AdapterSttController = AdapterSttController = AdapterSttController_1 = __decorate([
73
+ (0, swagger_1.ApiTags)('Speech-to-Text'),
74
+ (0, common_1.Controller)('api/ai-services/adapter/stt'),
75
+ (0, common_1.UseFilters)(nest_core_1.AllExceptionsHandler),
76
+ __metadata("design:paramtypes", [groq_service_1.GroqService,
77
+ local_stt_service_1.LocalSttService])
78
+ ], AdapterSttController);
79
+ //# sourceMappingURL=adapter-stt.controller.js.map
@@ -55,7 +55,7 @@ __decorate([
55
55
  ], GroqSttController.prototype, "processAudio", null);
56
56
  exports.GroqSttController = GroqSttController = GroqSttController_1 = __decorate([
57
57
  (0, swagger_1.ApiTags)('Speech-to-Text'),
58
- (0, common_1.Controller)('api/groq-stt'),
58
+ (0, common_1.Controller)('api/ai-services/groq/stt'),
59
59
  (0, common_1.UseFilters)(nest_core_1.AllExceptionsHandler),
60
60
  __metadata("design:paramtypes", [groq_service_1.GroqService])
61
61
  ], GroqSttController);
@@ -0,0 +1,8 @@
1
+ import { type MulterFile } from '@webundsoehne/nest-fastify-file-upload';
2
+ import { LocalSttService } from '../../services/whisper/local-stt.service';
3
+ export declare class LocalSttController {
4
+ private readonly localSttService;
5
+ private readonly logger;
6
+ constructor(localSttService: LocalSttService);
7
+ processAudio(file: MulterFile): Promise<any>;
8
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ var LocalSttController_1;
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.LocalSttController = void 0;
17
+ const common_1 = require("@nestjs/common");
18
+ const nest_fastify_file_upload_1 = require("@webundsoehne/nest-fastify-file-upload");
19
+ const swagger_1 = require("@nestjs/swagger");
20
+ const nest_core_1 = require("@dataclouder/nest-core");
21
+ const local_stt_service_1 = require("../../services/whisper/local-stt.service");
22
+ let LocalSttController = LocalSttController_1 = class LocalSttController {
23
+ localSttService;
24
+ logger = new common_1.Logger(LocalSttController_1.name);
25
+ constructor(localSttService) {
26
+ this.localSttService = localSttService;
27
+ }
28
+ async processAudio(file) {
29
+ this.logger.log('Receive requests');
30
+ if (!file || !file.buffer) {
31
+ this.logger.error('No file buffer received.');
32
+ return { error: 'No file uploaded or file buffer is missing.' };
33
+ }
34
+ this.logger.log(`Received file: ${file.originalname}, mimetype: ${file.mimetype}, size: ${file.size}`);
35
+ try {
36
+ const result = await this.localSttService.transcribeAudio(file.buffer, file.originalname, file.mimetype);
37
+ return result;
38
+ }
39
+ catch (error) {
40
+ this.logger.error('Error during transcription process:', error);
41
+ return { error: 'Failed to transcribe audio.', details: error.message };
42
+ }
43
+ }
44
+ };
45
+ exports.LocalSttController = LocalSttController;
46
+ __decorate([
47
+ (0, common_1.Post)('transcribe-bytes'),
48
+ (0, common_1.UseInterceptors)((0, nest_fastify_file_upload_1.FileInterceptor)('file')),
49
+ (0, swagger_1.ApiConsumes)('multipart/form-data'),
50
+ (0, nest_fastify_file_upload_1.ApiFileBody)('file'),
51
+ __param(0, (0, common_1.UploadedFile)('file')),
52
+ __metadata("design:type", Function),
53
+ __metadata("design:paramtypes", [Object]),
54
+ __metadata("design:returntype", Promise)
55
+ ], LocalSttController.prototype, "processAudio", null);
56
+ exports.LocalSttController = LocalSttController = LocalSttController_1 = __decorate([
57
+ (0, swagger_1.ApiTags)('Speech-to-Text'),
58
+ (0, common_1.Controller)('api/ai-services/local/stt'),
59
+ (0, common_1.UseFilters)(nest_core_1.AllExceptionsHandler),
60
+ __metadata("design:paramtypes", [local_stt_service_1.LocalSttService])
61
+ ], LocalSttController);
62
+ //# sourceMappingURL=local-stt.controller.js.map
@@ -79,7 +79,7 @@ __decorate([
79
79
  __metadata("design:returntype", Promise)
80
80
  ], VertexGeminiTtsController.prototype, "synthesizeSpeech", null);
81
81
  exports.VertexGeminiTtsController = VertexGeminiTtsController = __decorate([
82
- (0, swagger_1.ApiTags)('Vertex Gemini TTS'),
82
+ (0, swagger_1.ApiTags)('Text To Speech Gemini'),
83
83
  (0, common_1.Controller)('api/vertex-gemini/tts'),
84
84
  (0, common_1.UseFilters)(nest_core_1.AllExceptionsHandler),
85
85
  __metadata("design:paramtypes", [vertex_gemini_tts_service_1.VertexGeminiTtsService])
@@ -104,8 +104,8 @@ __decorate([
104
104
  __metadata("design:returntype", Promise)
105
105
  ], VertexTtsAdapterController.prototype, "listVoices", null);
106
106
  exports.VertexTtsAdapterController = VertexTtsAdapterController = __decorate([
107
- (0, swagger_1.ApiTags)('Vertex TTS Adapter'),
108
- (0, common_1.Controller)('api/vertex-adapter/tts'),
107
+ (0, swagger_1.ApiTags)('Text To Speech Adapter'),
108
+ (0, common_1.Controller)('api/ai-services/adapter/tts'),
109
109
  (0, common_2.UseFilters)(nest_core_1.AllExceptionsHandler),
110
110
  __metadata("design:paramtypes", [vertex_tts_service_1.VertextTtsService])
111
111
  ], VertexTtsAdapterController);
@@ -21,7 +21,7 @@ export interface ChatJsonResponse extends MessageLLM {
21
21
  export interface ChatLLMRequestAdapter {
22
22
  messages: MessageLLM[];
23
23
  provider?: string;
24
- model?: IAIModel;
24
+ model?: Partial<IAIModel>;
25
25
  returnJson?: boolean;
26
26
  keyType?: TierType;
27
27
  }
@@ -50,4 +50,6 @@ export interface AvailableKeyResult {
50
50
  type: string;
51
51
  error?: string;
52
52
  errorDescription?: string;
53
+ service?: string;
54
+ provider?: string;
53
55
  }
@@ -36,15 +36,16 @@ const veo_video_controller_1 = require("./controllers/video/veo-video.controller
36
36
  const google_genai_service_1 = require("./services/google-genai.service");
37
37
  const groq_stt_controller_1 = require("./controllers/stt/groq-stt.controller");
38
38
  const groq_service_1 = require("./services/whisper/groq.service");
39
+ const local_stt_controller_1 = require("./controllers/stt/local-stt.controller");
40
+ const local_stt_service_1 = require("./services/whisper/local-stt.service");
39
41
  const comfy_sdk_service_1 = require("./comfyui/services/comfy-sdk.service");
40
42
  const vertex_gemini_tts_controller_1 = require("./controllers/tts/vertex-gemini-tts.controller");
41
43
  const vertex_gemini_tts_service_1 = require("./services/vertex-gemini-tts.service");
42
- const drizzle_module_1 = require("./drizzle/drizzle.module");
43
44
  const nest_auth_1 = require("@dataclouder/nest-auth");
44
- const metric_ai_service_1 = require("./services/metric-ai.service");
45
45
  const groq_llm_service_1 = require("./services/llm/groq-llm.service");
46
46
  const groq_llm_controller_1 = require("./controllers/llm/groq-llm.controller");
47
47
  const video_gen_adapter_controller_1 = require("./controllers/video/video-gen-adapter.controller");
48
+ const adapter_stt_controller_1 = require("./controllers/stt/adapter-stt.controller");
48
49
  let NestVertexModule = class NestVertexModule {
49
50
  };
50
51
  exports.NestVertexModule = NestVertexModule;
@@ -56,7 +57,6 @@ exports.NestVertexModule = NestVertexModule = __decorate([
56
57
  nest_mongo_1.DCMongoDBModule,
57
58
  mongoose_1.MongooseModule.forFeature([{ name: generated_asset_entity_1.GeneratedAsset.name, schema: generated_asset_entity_1.GeneratedAssetSchema }]),
58
59
  comfyui_module_1.ComfyUIModule,
59
- drizzle_module_1.DrizzleModule,
60
60
  nest_auth_1.NestAuthModule,
61
61
  ],
62
62
  providers: [
@@ -74,9 +74,9 @@ exports.NestVertexModule = NestVertexModule = __decorate([
74
74
  vertex_veo_genai_service_1.VertexVeoGenaiService,
75
75
  google_genai_service_1.GoogleGenaiService,
76
76
  groq_service_1.GroqService,
77
+ local_stt_service_1.LocalSttService,
77
78
  comfy_sdk_service_1.ComfySDKService,
78
79
  vertex_gemini_tts_service_1.VertexGeminiTtsService,
79
- metric_ai_service_1.MetricAIService,
80
80
  groq_llm_service_1.GroqLlmService,
81
81
  ],
82
82
  exports: [
@@ -94,11 +94,10 @@ exports.NestVertexModule = NestVertexModule = __decorate([
94
94
  vertex_veo_genai_service_1.VertexVeoGenaiService,
95
95
  google_genai_service_1.GoogleGenaiService,
96
96
  groq_service_1.GroqService,
97
+ local_stt_service_1.LocalSttService,
97
98
  comfyui_module_1.ComfyUIModule,
98
99
  comfy_sdk_service_1.ComfySDKService,
99
100
  vertex_gemini_tts_service_1.VertexGeminiTtsService,
100
- drizzle_module_1.DrizzleModule,
101
- metric_ai_service_1.MetricAIService,
102
101
  groq_llm_service_1.GroqLlmService,
103
102
  ],
104
103
  controllers: [
@@ -112,7 +111,9 @@ exports.NestVertexModule = NestVertexModule = __decorate([
112
111
  vertex_comfy_controller_1.VertexComfyController,
113
112
  veo_video_controller_1.VertexVeoGenerationController,
114
113
  groq_stt_controller_1.GroqSttController,
114
+ local_stt_controller_1.LocalSttController,
115
115
  vertex_gemini_tts_controller_1.VertexGeminiTtsController,
116
+ adapter_stt_controller_1.AdapterSttController,
116
117
  ],
117
118
  })
118
119
  ], NestVertexModule);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataclouder/nest-vertex",
3
- "version": "0.0.56",
3
+ "version": "0.0.58",
4
4
  "description": "NestJS Vertex AI library for Dataclouder",
5
5
  "author": "dataclouder",
6
6
  "license": "MIT",
@@ -15,6 +15,7 @@ export declare class GeminiChatService {
15
15
  chatStream(messages: MessageLLM[], model?: string, keyType?: TierType): Promise<AsyncIterable<ChatMessageDict>>;
16
16
  listModels(): Promise<Record<string, string>[]>;
17
17
  getDefaultQualityModel(quality: EModelQuality): string;
18
+ private getBestModel;
18
19
  private _extractJsonWithRecovery;
19
20
  chatAndExtractJson(messages: MessageLLM[], model?: string, keyType?: TierType): Promise<ChatJsonResponse>;
20
21
  describeImageByUrl(dto: DescribeImageRequestAdapter): Promise<any>;
@@ -93,8 +93,8 @@ let GeminiChatService = GeminiChatService_1 = class GeminiChatService {
93
93
  this.logger.debug(`Received Gemini response text. ${response?.text.slice(0, 50).replace(/\n/g, '')} ...`);
94
94
  const responseText = response?.text ?? '';
95
95
  const tokens = {
96
- input: response?.usageMetadata?.candidatesTokenCount,
97
- output: response?.usageMetadata?.promptTokenCount,
96
+ input: response?.usageMetadata?.promptTokenCount,
97
+ output: response?.usageMetadata?.candidatesTokenCount,
98
98
  total: response?.usageMetadata?.totalTokenCount,
99
99
  };
100
100
  return {
@@ -201,6 +201,19 @@ let GeminiChatService = GeminiChatService_1 = class GeminiChatService {
201
201
  return gemini_models_1.GeminiModels.Gemini2_5Pro;
202
202
  }
203
203
  }
204
+ getBestModel(conversation) {
205
+ if (!conversation.model) {
206
+ return { provider: 'google', modelName: gemini_models_1.GeminiModels.Gemini2_5Lite };
207
+ }
208
+ const { quality, modelName, provider } = conversation.model;
209
+ if (quality) {
210
+ return { provider: 'google', modelName: this.getDefaultQualityModel(quality) };
211
+ }
212
+ if (modelName && provider) {
213
+ return { provider, modelName };
214
+ }
215
+ return { provider: 'google', modelName: gemini_models_1.GeminiModels.Gemini2_5Lite };
216
+ }
204
217
  async _extractJsonWithRecovery(responseText, model, keyType) {
205
218
  try {
206
219
  const json = (0, llm_models_1.extractJsonFromResponse)(responseText);
@@ -286,36 +299,30 @@ let GeminiChatService = GeminiChatService_1 = class GeminiChatService {
286
299
  }
287
300
  async chatWithConversation(conversation) {
288
301
  const startTime = Date.now();
289
- if (!conversation?.model) {
290
- conversation.model = { provider: 'google', modelName: gemini_models_1.GeminiModels.Gemini2_5Lite, id: 'no-id' };
291
- }
302
+ const { provider, modelName } = this.getBestModel(conversation);
292
303
  const tierType = conversation.tierType || key_balancer_models_1.TierType.TIER_1;
293
- if (conversation?.model?.quality) {
294
- conversation.model.provider = 'google';
295
- conversation.model.modelName = this.getDefaultQualityModel(conversation.model.quality);
296
- }
297
304
  const returnJson = conversation.returnJson;
298
305
  if (returnJson) {
299
- const obj = await this.chatAndExtractJson(conversation.messages, conversation.model.modelName, tierType);
306
+ const obj = await this.chatAndExtractJson(conversation.messages, modelName, tierType);
300
307
  const endTime = Date.now();
301
308
  const processTime = (endTime - startTime) / 1000;
302
309
  const metadata = {
303
310
  type: 'json',
304
- provider: conversation.model.provider,
305
- model: conversation.model.modelName,
311
+ provider,
312
+ model: modelName,
306
313
  processTime,
307
314
  ...obj?.metadata,
308
315
  };
309
316
  return { content: obj.json, role: adapter_models_1.ChatRole.Assistant, metadata };
310
317
  }
311
318
  else {
312
- const response = await this.chat(conversation.messages, conversation.model.modelName, tierType);
319
+ const response = await this.chat(conversation.messages, modelName, tierType);
313
320
  const endTime = Date.now();
314
321
  const processTime = (endTime - startTime) / 1000;
315
322
  return {
316
323
  content: response.content,
317
324
  role: response.role,
318
- metadata: { provider: conversation.model.provider, model: conversation.model.modelName, processTime, tokens: response.metadata.tokens },
325
+ metadata: { provider, model: modelName, processTime, tokens: response.metadata.tokens },
319
326
  };
320
327
  }
321
328
  }
@@ -38,32 +38,36 @@ let ImageVertexService = ImageVertexService_1 = class ImageVertexService {
38
38
  let apiKey;
39
39
  let keyId;
40
40
  let availableKey = {};
41
- if (this.gemini_key) {
42
- apiKey = this.gemini_key;
43
- keyId = 'local';
44
- }
45
- else {
46
- this.logger.log(`Vertex Image"Getting key for model: ${model} and tier: ${tierType}`);
41
+ try {
42
+ this.logger.log(`Vertex Image - Getting key for model: ${model} and tier: ${tierType}`);
47
43
  availableKey = await this.keyBalancerApiService.getBestKey({
48
44
  provider: 'google',
49
45
  service: model,
50
46
  tierType: tierType,
51
47
  aiType: key_balancer_models_1.ModelType.IMAGE,
52
48
  }, null);
53
- if (availableKey === null) {
54
- this.logger.error('KEY BALANCER IS DOWN: :::: No available API key from key balancer.');
55
- }
56
- if (availableKey?.error === 'RateLimited') {
57
- this.logger.error('No available API key from key balancer.');
58
- throw new Error('RateLimited');
59
- }
60
- if (!availableKey || availableKey?.error) {
61
- this.logger.error('No available API key from key balancer.');
62
- throw new Error('Not available API key');
49
+ if (!availableKey || availableKey.error) {
50
+ throw new Error('No available API key from key balancer or error received.');
63
51
  }
52
+ this.logger.log(` USING Balanced key 🖼️ ${availableKey.name} ${availableKey.id}`);
64
53
  apiKey = availableKey.key;
65
54
  keyId = availableKey.id;
66
55
  }
56
+ catch (error) {
57
+ this.logger.warn(`Failed to get key from KeyBalancer: ${error.message}. Falling back to GEMINI_API_KEY.`);
58
+ if (this.gemini_key) {
59
+ apiKey = this.gemini_key;
60
+ keyId = 'local-gemini-key';
61
+ }
62
+ else {
63
+ this.logger.error('Fallback to GEMINI_API_KEY failed as it is not set.');
64
+ throw new Error('No available API key from KeyBalancer and no fallback GEMINI_API_KEY set.');
65
+ }
66
+ }
67
+ if (!apiKey) {
68
+ this.logger.error('Could not obtain an API key.');
69
+ throw new Error('Not available API key');
70
+ }
67
71
  return {
68
72
  client: new genai_1.GoogleGenAI({ apiKey }),
69
73
  keyId,
@@ -113,6 +113,7 @@ let GroqService = GroqService_1 = class GroqService {
113
113
  tierType: key_balancer_models_1.TierType.FREE_TIER,
114
114
  aiType: key_balancer_models_1.ModelType.AUDIO,
115
115
  }, null);
116
+ console.log(`Using key: ${keyResult.name} {${keyResult?.service}}`);
116
117
  const transcription = await this.getClientWithKey(keyResult.key).audio.transcriptions.create({
117
118
  file: file,
118
119
  model: 'whisper-large-v3-turbo',
@@ -0,0 +1,7 @@
1
+ export declare class LocalSttService {
2
+ private readonly logger;
3
+ private readonly openai;
4
+ constructor();
5
+ private getExtensionFromMimeType;
6
+ transcribeAudio(fileBuffer: Buffer, originalFileName: string, mimeType: string): Promise<any>;
7
+ }
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var LocalSttService_1;
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.LocalSttService = void 0;
47
+ const common_1 = require("@nestjs/common");
48
+ const openai_1 = __importStar(require("openai"));
49
+ const path = __importStar(require("path"));
50
+ let LocalSttService = LocalSttService_1 = class LocalSttService {
51
+ logger = new common_1.Logger(LocalSttService_1.name);
52
+ openai;
53
+ constructor() {
54
+ const aiServerHost = process.env.AI_LAB_HOST;
55
+ console.log('Connecting to host AI_LAB_HOST', aiServerHost);
56
+ this.openai = new openai_1.default({
57
+ baseURL: `${aiServerHost}:3171/v1`,
58
+ apiKey: '',
59
+ });
60
+ }
61
+ getExtensionFromMimeType(mimeType) {
62
+ switch (mimeType?.toLowerCase()) {
63
+ case 'audio/wav':
64
+ case 'audio/x-wav':
65
+ return '.wav';
66
+ case 'audio/mpeg':
67
+ return '.mp3';
68
+ case 'audio/mp4':
69
+ case 'video/mp4':
70
+ return '.mp4';
71
+ case 'audio/flac':
72
+ return '.flac';
73
+ case 'audio/ogg':
74
+ return '.ogg';
75
+ case 'audio/opus':
76
+ return '.opus';
77
+ case 'audio/webm':
78
+ case 'video/webm':
79
+ return '.webm';
80
+ case 'audio/mpga':
81
+ return '.mpga';
82
+ case 'audio/m4a':
83
+ return '.m4a';
84
+ default:
85
+ this.logger.warn(`Unsupported or unknown mime type provided: ${mimeType}`);
86
+ return null;
87
+ }
88
+ }
89
+ async transcribeAudio(fileBuffer, originalFileName, mimeType) {
90
+ this.logger.log(`Attempting to transcribe file: ${originalFileName} (${mimeType})`);
91
+ const extension = this.getExtensionFromMimeType(mimeType);
92
+ let effectiveFileName = originalFileName;
93
+ if (extension) {
94
+ const currentExt = path.extname(originalFileName).toLowerCase();
95
+ if (currentExt !== extension) {
96
+ const baseName = path.basename(originalFileName, currentExt);
97
+ effectiveFileName = `${baseName}${extension}`;
98
+ this.logger.log(`Adjusted filename to: ${effectiveFileName} based on mime type: ${mimeType}`);
99
+ }
100
+ else {
101
+ this.logger.log(`Filename ${originalFileName} already has correct extension ${extension}`);
102
+ }
103
+ }
104
+ else {
105
+ this.logger.warn(`Could not determine valid extension for mime type ${mimeType}. Using original filename: ${originalFileName}. Transcription may fail if the filename lacks a supported extension.`);
106
+ }
107
+ try {
108
+ console.log(' -> Request to...', this.openai.baseURL);
109
+ const result = await this.openai.audio.transcriptions.create({
110
+ model: 'rtlingo/mobiuslabsgmbh-faster-whisper-large-v3-turbo',
111
+ file: await (0, openai_1.toFile)(fileBuffer, effectiveFileName, { type: mimeType }),
112
+ response_format: 'verbose_json',
113
+ timestamp_granularities: ['word'],
114
+ });
115
+ if (result?.segments) {
116
+ delete result.segments;
117
+ }
118
+ if (result?.words?.length) {
119
+ result.words.forEach((word) => {
120
+ delete word?.probability;
121
+ });
122
+ }
123
+ this.logger.log(`Transcription successful for file: ${result.text}, lang: ${result.language}, duration: ${result.duration}`);
124
+ return result;
125
+ }
126
+ catch (error) {
127
+ this.logger.error(`Error during transcription for file ${effectiveFileName}:`, error?.error || error);
128
+ const errorMessage = error?.error?.message || (error instanceof Error ? error.message : 'Unknown error during transcription');
129
+ throw new Error(`Failed to transcribe audio: ${errorMessage}`);
130
+ }
131
+ }
132
+ };
133
+ exports.LocalSttService = LocalSttService;
134
+ exports.LocalSttService = LocalSttService = LocalSttService_1 = __decorate([
135
+ (0, common_1.Injectable)(),
136
+ __metadata("design:paramtypes", [])
137
+ ], LocalSttService);
138
+ //# sourceMappingURL=local-stt.service.js.map
@@ -1,2 +0,0 @@
1
- export declare class DrizzleModule {
2
- }