@solidstarters/solid-core 1.2.178 → 1.2.180

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 (42) hide show
  1. package/dist/controllers/ai-interaction.controller.js.map +1 -1
  2. package/dist/controllers/service.controller.d.ts +8 -1
  3. package/dist/controllers/service.controller.d.ts.map +1 -1
  4. package/dist/controllers/service.controller.js +39 -2
  5. package/dist/controllers/service.controller.js.map +1 -1
  6. package/dist/helpers/date.helper.d.ts +2 -0
  7. package/dist/helpers/date.helper.d.ts.map +1 -0
  8. package/dist/helpers/date.helper.js +18 -0
  9. package/dist/helpers/date.helper.js.map +1 -0
  10. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
  11. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +23 -17
  12. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  13. package/dist/seeders/seed-data/solid-core-metadata.json +2 -1
  14. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  15. package/dist/services/ai-interaction.service.js +11 -3
  16. package/dist/services/ai-interaction.service.js.map +1 -1
  17. package/dist/services/excel.service.js +2 -2
  18. package/dist/services/excel.service.js.map +1 -1
  19. package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -1
  20. package/dist/services/genai/ingest-metadata.service.js +9 -8
  21. package/dist/services/genai/ingest-metadata.service.js.map +1 -1
  22. package/dist/services/import-transaction.service.d.ts.map +1 -1
  23. package/dist/services/import-transaction.service.js +37 -10
  24. package/dist/services/import-transaction.service.js.map +1 -1
  25. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.d.ts.map +1 -1
  26. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.js +2 -2
  27. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.js.map +1 -1
  28. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js +2 -2
  29. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js.map +1 -1
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +3 -2
  32. package/src/controllers/ai-interaction.controller.ts +1 -1
  33. package/src/controllers/service.controller.ts +40 -2
  34. package/src/helpers/date.helper.ts +13 -0
  35. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +27 -18
  36. package/src/seeders/seed-data/solid-core-metadata.json +3 -1
  37. package/src/services/ai-interaction.service.ts +14 -7
  38. package/src/services/excel.service.ts +2 -2
  39. package/src/services/genai/ingest-metadata.service.ts +34 -8
  40. package/src/services/import-transaction.service.ts +46 -11
  41. package/src/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.ts +3 -2
  42. package/src/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ai-interaction.controller.js","sourceRoot":"","sources":["../../src/controllers/ai-interaction.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { Controller, Post, Body, Param, UploadedFiles, UseInterceptors, Put, Get, Query, Delete, Patch } from '@nestjs/common';\nimport { AnyFilesInterceptor } from \"@nestjs/platform-express\";\nimport { ApiBearerAuth, ApiQuery, ApiTags } from '@nestjs/swagger';\nimport { AiInteractionService } from '../services/ai-interaction.service';\nimport { CreateAiInteractionDto } from '../dtos/create-ai-interaction.dto';\nimport { UpdateAiInteractionDto } from '../dtos/update-ai-interaction.dto';\nimport { InvokeAiPromptDto } from '../dtos/invoke-ai-prompt.dto';\nimport { ActiveUser } from 'src/decorators/active-user.decorator';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\n\nenum ShowSoftDeleted {\n INCLUSIVE = \"inclusive\",\n EXCLUSIVE = \"exclusive\",\n}\n\n@ApiTags('Solid Core')\n@Controller('ai-interaction')\nexport class AiInteractionController {\n constructor(private readonly service: AiInteractionService) { }\n\n @ApiBearerAuth(\"jwt\")\n @Post()\n @UseInterceptors(AnyFilesInterceptor())\n create(@Body() createDto: CreateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.create(createDto, files);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/bulk')\n @UseInterceptors(AnyFilesInterceptor())\n insertMany(@Body() createDtos: CreateAiInteractionDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {\n return this.service.insertMany(createDtos, filesArray);\n }\n\n\n @ApiBearerAuth(\"jwt\")\n @Put(':id')\n @UseInterceptors(AnyFilesInterceptor())\n update(@Param('id') id: number, @Body() updateDto: UpdateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.update(id, updateDto, files);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Patch(':id')\n @UseInterceptors(AnyFilesInterceptor())\n partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.update(id, updateDto, files, true);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/bulk-recover')\n async recoverMany(@Body() ids: number[]) {\n return this.service.recoverMany(ids);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get('/recover/:id')\n async recover(@Param('id') id: number) {\n return this.service.recover(id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @ApiQuery({ name: 'showSoftDeleted', required: false, enum: ShowSoftDeleted })\n @ApiQuery({ name: 'limit', required: false, type: Number })\n @ApiQuery({ name: 'offset', required: false, type: Number })\n @ApiQuery({ name: 'fields', required: false, type: Array })\n @ApiQuery({ name: 'sort', required: false, type: Array })\n @ApiQuery({ name: 'groupBy', required: false, type: Array })\n @ApiQuery({ name: 'populate', required: false, type: Array })\n @ApiQuery({ name: 'populateMedia', required: false, type: Array })\n @ApiQuery({ name: 'filters', required: false, type: Array })\n @Get()\n async findMany(@Query() query: any) {\n return this.service.find(query);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get(':id')\n async findOne(@Param('id') id: string, @Query() query: any) {\n return this.service.findOne(+id, query);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Delete('/bulk')\n async deleteMany(@Body() ids: number[]) {\n return this.service.deleteMany(ids);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Delete(':id')\n async delete(@Param('id') id: number) {\n return this.service.delete(id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/trigger-mcp-client-job')\n async triggerMcpClientJob(@Body() dto: InvokeAiPromptDto, @ActiveUser() activeUser: ActiveUserData) {\n return this.service.triggerMcpClientJob(dto,activeUser.sub);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post(':id/apply-solid-ai-interaction')\n async applySolidAiInteraction(@Param('id') id: number) {\n return this.service.applySolidAiInteraction(+id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/run-mcp-prompt')\n async runMcpPrompt(@Body() dto: InvokeAiPromptDto) {\n return this.service.runMcpPrompt(dto.prompt);\n }\n}\n"]}
1
+ {"version":3,"file":"ai-interaction.controller.js","sourceRoot":"","sources":["../../src/controllers/ai-interaction.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { Controller, Post, Body, Param, UploadedFiles, UseInterceptors, Put, Get, Query, Delete, Patch } from '@nestjs/common';\nimport { AnyFilesInterceptor } from \"@nestjs/platform-express\";\nimport { ApiBearerAuth, ApiQuery, ApiTags } from '@nestjs/swagger';\nimport { AiInteractionService } from '../services/ai-interaction.service';\nimport { CreateAiInteractionDto } from '../dtos/create-ai-interaction.dto';\nimport { UpdateAiInteractionDto } from '../dtos/update-ai-interaction.dto';\nimport { InvokeAiPromptDto } from '../dtos/invoke-ai-prompt.dto';\nimport { ActiveUser } from 'src/decorators/active-user.decorator';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\n\nenum ShowSoftDeleted {\n INCLUSIVE = \"inclusive\",\n EXCLUSIVE = \"exclusive\",\n}\n\n@ApiTags('Solid Core')\n@Controller('ai-interaction')\nexport class AiInteractionController {\n constructor(private readonly service: AiInteractionService) { }\n\n @ApiBearerAuth(\"jwt\")\n @Post()\n @UseInterceptors(AnyFilesInterceptor())\n create(@Body() createDto: CreateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.create(createDto, files);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/bulk')\n @UseInterceptors(AnyFilesInterceptor())\n insertMany(@Body() createDtos: CreateAiInteractionDto[], @UploadedFiles() filesArray: Express.Multer.File[][] = []) {\n return this.service.insertMany(createDtos, filesArray);\n }\n\n\n @ApiBearerAuth(\"jwt\")\n @Put(':id')\n @UseInterceptors(AnyFilesInterceptor())\n update(@Param('id') id: number, @Body() updateDto: UpdateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.update(id, updateDto, files);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Patch(':id')\n @UseInterceptors(AnyFilesInterceptor())\n partialUpdate(@Param('id') id: number, @Body() updateDto: UpdateAiInteractionDto, @UploadedFiles() files: Array<Express.Multer.File>) {\n return this.service.update(id, updateDto, files, true);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/bulk-recover')\n async recoverMany(@Body() ids: number[]) {\n return this.service.recoverMany(ids);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get('/recover/:id')\n async recover(@Param('id') id: number) {\n return this.service.recover(id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @ApiQuery({ name: 'showSoftDeleted', required: false, enum: ShowSoftDeleted })\n @ApiQuery({ name: 'limit', required: false, type: Number })\n @ApiQuery({ name: 'offset', required: false, type: Number })\n @ApiQuery({ name: 'fields', required: false, type: Array })\n @ApiQuery({ name: 'sort', required: false, type: Array })\n @ApiQuery({ name: 'groupBy', required: false, type: Array })\n @ApiQuery({ name: 'populate', required: false, type: Array })\n @ApiQuery({ name: 'populateMedia', required: false, type: Array })\n @ApiQuery({ name: 'filters', required: false, type: Array })\n @Get()\n async findMany(@Query() query: any) {\n return this.service.find(query);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get(':id')\n async findOne(@Param('id') id: string, @Query() query: any) {\n return this.service.findOne(+id, query);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Delete('/bulk')\n async deleteMany(@Body() ids: number[]) {\n return this.service.deleteMany(ids);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Delete(':id')\n async delete(@Param('id') id: number) {\n return this.service.delete(id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/trigger-mcp-client-job')\n async triggerMcpClientJob(@Body() dto: InvokeAiPromptDto, @ActiveUser() activeUser: ActiveUserData) {\n return this.service.triggerMcpClientJob(dto, activeUser.sub);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post(':id/apply-solid-ai-interaction')\n async applySolidAiInteraction(@Param('id') id: number) {\n return this.service.applySolidAiInteraction(+id);\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('/run-mcp-prompt')\n async runMcpPrompt(@Body() dto: InvokeAiPromptDto) {\n return this.service.runMcpPrompt(dto.prompt);\n }\n}\n"]}
@@ -1,15 +1,21 @@
1
1
  import { ErrorMapperService } from 'src/helpers/error-mapper.service';
2
2
  import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
3
3
  import { AiInteractionService } from 'src/services/ai-interaction.service';
4
+ import { IngestMetadataService } from 'src/services/genai/ingest-metadata.service';
4
5
  import { MqMessageService } from 'src/services/mq-message.service';
5
6
  import { SolidRegistry } from '../helpers/solid-registry';
7
+ export interface PostProcessCodeGenConfig {
8
+ runModuleMetadataSeeder?: boolean;
9
+ runSolidIngestion?: boolean;
10
+ }
6
11
  export declare class ServiceController {
7
12
  private readonly solidRegistry;
8
13
  private readonly aiInteractionService;
9
14
  private readonly mqMessageService;
10
15
  private readonly errorMapper;
16
+ private readonly ingestMetadataService;
11
17
  private readonly logger;
12
- constructor(solidRegistry: SolidRegistry, aiInteractionService: AiInteractionService, mqMessageService: MqMessageService, errorMapper: ErrorMapperService);
18
+ constructor(solidRegistry: SolidRegistry, aiInteractionService: AiInteractionService, mqMessageService: MqMessageService, errorMapper: ErrorMapperService, ingestMetadataService: IngestMetadataService);
13
19
  pingPong(): {
14
20
  pong: string;
15
21
  };
@@ -24,5 +30,6 @@ export declare class ServiceController {
24
30
  seedData(seedData: any): Promise<{
25
31
  message: string;
26
32
  }>;
33
+ postProcessCodeGeneration(config: PostProcessCodeGenConfig): Promise<void>;
27
34
  }
28
35
  //# sourceMappingURL=service.controller.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/service.controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG1D,qBAIa,iBAAiB;IAItB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IANhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;gBAGxC,aAAa,EAAE,aAAa,EAC5B,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,kBAAkB;IAKpD,QAAQ;;;IAMF,WAAW,CAAe,UAAU,EAAE,cAAc;;;;;;;;IAyDpD,QAAQ,CAAS,QAAQ,EAAE,GAAG;;;CAiCvC"}
1
+ {"version":3,"file":"service.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/service.controller.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,MAAM,WAAW,wBAAwB;IACrC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC/B;AACD,qBAIa,iBAAiB;IAItB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IACrC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAP1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;gBAGxC,aAAa,EAAE,aAAa,EAC5B,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,gBAAgB,EAClC,WAAW,EAAE,kBAAkB,EAC/B,qBAAqB,EAAE,qBAAqB;IAMjE,QAAQ;;;IAMF,WAAW,CAAe,UAAU,EAAE,cAAc;;;;;;;;IAyDpD,QAAQ,CAAS,QAAQ,EAAE,GAAG;;;IAiB9B,yBAAyB,CAAS,MAAM,EAAG,wBAAwB;CAgD5E"}
@@ -21,14 +21,16 @@ const active_user_decorator_1 = require("../decorators/active-user.decorator");
21
21
  const public_decorator_1 = require("../decorators/public.decorator");
22
22
  const error_mapper_service_1 = require("../helpers/error-mapper.service");
23
23
  const ai_interaction_service_1 = require("../services/ai-interaction.service");
24
+ const ingest_metadata_service_1 = require("../services/genai/ingest-metadata.service");
24
25
  const mq_message_service_1 = require("../services/mq-message.service");
25
26
  const solid_registry_1 = require("../helpers/solid-registry");
26
27
  let ServiceController = ServiceController_1 = class ServiceController {
27
- constructor(solidRegistry, aiInteractionService, mqMessageService, errorMapper) {
28
+ constructor(solidRegistry, aiInteractionService, mqMessageService, errorMapper, ingestMetadataService) {
28
29
  this.solidRegistry = solidRegistry;
29
30
  this.aiInteractionService = aiInteractionService;
30
31
  this.mqMessageService = mqMessageService;
31
32
  this.errorMapper = errorMapper;
33
+ this.ingestMetadataService = ingestMetadataService;
32
34
  this.logger = new common_1.Logger(ServiceController_1.name);
33
35
  }
34
36
  pingPong() {
@@ -83,6 +85,31 @@ let ServiceController = ServiceController_1 = class ServiceController {
83
85
  await seeder.seed();
84
86
  return { message: `seed data for ${seedData.seeder}` };
85
87
  }
88
+ async postProcessCodeGeneration(config) {
89
+ config.runModuleMetadataSeeder = config.runModuleMetadataSeeder ?? true;
90
+ config.runSolidIngestion = config.runSolidIngestion ?? true;
91
+ if (config.runModuleMetadataSeeder) {
92
+ this.logger.debug(`Running the Module Metadata Seeder Service as part of post-process code generation`);
93
+ const seeder = this.solidRegistry
94
+ .getSeeders()
95
+ .filter((seeder) => seeder.name === 'ModuleMetadataSeederService')
96
+ .map((seeder) => seeder.instance)
97
+ .pop();
98
+ if (!seeder) {
99
+ this.logger.error(`Seeder service ModuleMetadataSeederService not found. Does your service have a seed() method?`);
100
+ }
101
+ else {
102
+ await seeder.seed();
103
+ }
104
+ }
105
+ else {
106
+ this.logger.debug(`Skipping the Module Metadata Seeder Service as part of post-process code generation`);
107
+ }
108
+ if (config.runSolidIngestion) {
109
+ this.logger.debug(`Running the Solid ingestion command as part of post-process code generation`);
110
+ await this.ingestMetadataService.ingest();
111
+ }
112
+ }
86
113
  };
87
114
  exports.ServiceController = ServiceController;
88
115
  __decorate([
@@ -111,12 +138,22 @@ __decorate([
111
138
  __metadata("design:paramtypes", [Object]),
112
139
  __metadata("design:returntype", Promise)
113
140
  ], ServiceController.prototype, "seedData", null);
141
+ __decorate([
142
+ (0, swagger_1.ApiBearerAuth)("jwt"),
143
+ (0, common_1.Post)('code-generation/post-process'),
144
+ openapi.ApiResponse({ status: 201 }),
145
+ __param(0, (0, common_1.Body)()),
146
+ __metadata("design:type", Function),
147
+ __metadata("design:paramtypes", [Object]),
148
+ __metadata("design:returntype", Promise)
149
+ ], ServiceController.prototype, "postProcessCodeGeneration", null);
114
150
  exports.ServiceController = ServiceController = ServiceController_1 = __decorate([
115
151
  (0, common_1.Controller)(''),
116
152
  (0, swagger_1.ApiTags)("Common"),
117
153
  __metadata("design:paramtypes", [solid_registry_1.SolidRegistry,
118
154
  ai_interaction_service_1.AiInteractionService,
119
155
  mq_message_service_1.MqMessageService,
120
- error_mapper_service_1.ErrorMapperService])
156
+ error_mapper_service_1.ErrorMapperService,
157
+ ingest_metadata_service_1.IngestMetadataService])
121
158
  ], ServiceController);
122
159
  //# sourceMappingURL=service.controller.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"service.controller.js","sourceRoot":"","sources":["../../src/controllers/service.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,2CAAqE;AACrE,6CAAyD;AACzD,+EAAkE;AAClE,qEAAyD;AACzD,0EAAsE;AAEtE,+EAA2E;AAC3E,uEAAmE;AACnE,8DAA0D;AAOnD,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAG1B,YACqB,aAA4B,EAC5B,oBAA0C,EAC1C,gBAAkC,EAClC,WAA+B;QAH/B,kBAAa,GAAb,aAAa,CAAe;QAC5B,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,gBAAW,GAAX,WAAW,CAAoB;QANnC,WAAM,GAAG,IAAI,eAAM,CAAC,mBAAiB,CAAC,IAAI,CAAC,CAAC;IAOzD,CAAC;IAIL,QAAQ;QACJ,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAIK,AAAN,KAAK,CAAC,WAAW,CAAe,UAA0B;QAItD,MAAM,QAAQ,GAAG,eAAe,UAAU,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,GAAG,GAAE,EAAC,MAAM,EAAC,kBAAkB,EAAE,UAAU,EAAC,iBAAiB,EAAC,CAAA;QACpE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,mBAAmB,CAC3F,GAAG,EACH,UAAU,CAAC,GAAG,EACd,IAAI,EACJ,QAAQ,CACX,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,cAAc,qBAAqB,eAAe,EAAE,CAAC,CAAC;QAGvH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,cAAc,EAAE;YAC7E,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI;YACxB,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,IAAI;YACnB,cAAc,EAAE,KAAK;SACxB,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;QAE1E,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,mFAAmF,eAAe,EAAE,CAAC,CAAA;QAGvH,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC;YAC3D,OAAO,EAAE;gBACL,iBAAiB,EAAE;oBACf,EAAE,EAAE;wBACA,GAAG,EAAE,eAAe;qBACvB;iBACJ;aACJ;SACJ,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,gBAAgB,CAAC,EAAE,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAA;QAEpE,OAAO;YACH,OAAO,EAAE,QAAQ;YACjB,gBAAgB,EAAE;gBACd,MAAM,EAAE,gBAAgB,CAAC,MAAM;gBAC/B,SAAS,EAAE,gBAAgB,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,gBAAgB,CAAC,YAAY,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC5I,YAAY,EAAE,gBAAgB,CAAC,YAAY;aAC9C;SACJ,CAAC;IACN,CAAC;IAKK,AAAN,KAAK,CAAC,QAAQ,CAAS,QAAa;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa;aAC5B,UAAU,EAAE;aACZ,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,CAAC;aACnD,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC;aAChC,GAAG,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,QAAQ,CAAC,MAAM,qDAAqD,CAAC,CAAC;YAC1G,OAAO;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,yCAAyC,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QACpF,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,EAAE,OAAO,EAAE,iBAAiB,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IAC3D,CAAC;CAoBJ,CAAA;AA5GY,8CAAiB;AAY1B;IAFC,IAAA,yBAAM,GAAE;IACR,IAAA,YAAG,EAAC,MAAM,CAAC;;;;;iDAGX;AAIK;IAFL,IAAA,uBAAa,EAAC,KAAK,CAAC;IACpB,IAAA,YAAG,EAAC,UAAU,CAAC;;IACG,WAAA,IAAA,kCAAU,GAAE,CAAA;;;;oDAoD9B;AAKK;IAHL,IAAA,yBAAM,GAAE;IAER,IAAA,aAAI,EAAC,MAAM,CAAC;;IACG,WAAA,IAAA,aAAI,GAAE,CAAA;;;;iDAarB;4BAxFQ,iBAAiB;IAJ7B,IAAA,mBAAU,EAAC,EAAE,CAAC;IACd,IAAA,iBAAO,EAAC,QAAQ,CAAC;qCAOsB,8BAAa;QACN,6CAAoB;QACxB,qCAAgB;QACrB,yCAAkB;GAP3C,iBAAiB,CA4G7B","sourcesContent":["import { Body, Controller, Get, Logger, Post } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { ActiveUser } from 'src/decorators/active-user.decorator';\nimport { Public } from 'src/decorators/public.decorator';\nimport { ErrorMapperService } from 'src/helpers/error-mapper.service';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { AiInteractionService } from 'src/services/ai-interaction.service';\nimport { MqMessageService } from 'src/services/mq-message.service';\nimport { SolidRegistry } from '../helpers/solid-registry';\n\n\n@Controller('')\n@ApiTags(\"Common\")\n// @UseGuards(ThrottlerGuard)\n// @SkipThrottle({ short: true, login: true, burst: true, sustained: true }) // Skip all\nexport class ServiceController {\n private readonly logger = new Logger(ServiceController.name);\n\n constructor(\n private readonly solidRegistry: SolidRegistry,\n private readonly aiInteractionService: AiInteractionService,\n private readonly mqMessageService: MqMessageService,\n private readonly errorMapper: ErrorMapperService\n ) { }\n\n @Public()\n @Get('ping')\n pingPong() {\n return { pong: 'v1.0.2' };\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get('mcp/ping')\n async mcpPingPong(@ActiveUser() activeUser: ActiveUserData) {\n // TODO: do a MCP client invocation, wait for response and return.\n // If failure then decide shape to return.\n\n const threadId = `pingPongTxn-${activeUser.sub}`;\n const dto ={prompt:\"Can you do 1 + 1\", moduleName:\"solidCoreModule\"}\n const { queueMessageId, aiInteractionId } = await this.aiInteractionService.triggerMcpClientJob(\n dto,\n activeUser.sub,\n true,\n threadId\n );\n\n this.logger.debug(`mcp ping pong job triggered: queueMessageId=${queueMessageId}, aiInteractionId=${aiInteractionId}`);\n\n // Wait up to 2 minutes, start at 500ms poll, back off to max 2s, throw if failed:\n const result = await this.mqMessageService.waitForTerminalStatus(queueMessageId, {\n timeoutMs: 2 * 60 * 1000,\n intervalMs: 500,\n maxIntervalMs: 2000,\n throwOnFailure: false,\n });\n\n this.logger.debug(`mcp ping pong job finished with stage=${result.stage}`)\n\n this.logger.debug(`mcp ping pong trying to find genai (child) interaction for aiInteraction for id=${aiInteractionId}`)\n\n // @ts-ignore\n const genAiInteractions = await this.aiInteractionService.find({\n filters: {\n parentInteraction: {\n id: {\n $eq: aiInteractionId\n }\n }\n }\n });\n\n const genAiInteraction = genAiInteractions['records'][0];\n this.logger.debug(genAiInteraction.message);\n\n this.logger.debug(`identified gen-ai interaction with id=${genAiInteraction.id}`);\n this.logger.debug(`proceeding with applying the gen-ai interaction`)\n\n return {\n mcpPong: 'v1.0.2',\n genAiInteraction: {\n status: genAiInteraction.status,\n errorCode: genAiInteraction.status === 'failed' ? this.errorMapper.mapMessage(genAiInteraction.errorMessage, genAiInteraction.metadata) : '',\n errorMessage: genAiInteraction.errorMessage,\n }\n };\n }\n\n @Public()\n // @SkipThrottle({ short: false, login: true, burst: true, sustained: true }) //Enable the short throttle only\n @Post('seed')\n async seedData(@Body() seedData: any) {\n const seeder = this.solidRegistry\n .getSeeders()\n .filter((seeder) => seeder.name === seedData.seeder)\n .map((seeder) => seeder.instance)\n .pop();\n if (!seeder) {\n this.logger.error(`Seeder service ${seedData.seeder} not found. Does your service have a seed() method?`);\n return;\n }\n this.logger.log(`Running the seed() method for seeder :${seeder.constructor.name}`);\n await seeder.seed();\n return { message: `seed data for ${seedData.seeder}` };\n }\n\n // @Public()\n // @Get('play')\n // play() {\n // return this.solidRegistry.getControllers();\n // }\n\n // //This method identifies a provider as a seeder if it has a seed method i.e duck typing\n // private isSeeder(provider: InstanceWrapper) {\n // const { instance } = provider;\n // if (!instance) return false;\n\n // const seedMethod = this.metadataScanner\n // .getAllMethodNames(Object.getPrototypeOf(instance))\n // .find((methodName) => methodName === 'seed');\n // if (!seedMethod) return false;\n // return true;\n // }\n\n}\n"]}
1
+ {"version":3,"file":"service.controller.js","sourceRoot":"","sources":["../../src/controllers/service.controller.ts"],"names":[],"mappings":"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","sourcesContent":["import { Body, Controller, Get, Logger, Post } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { ActiveUser } from 'src/decorators/active-user.decorator';\nimport { Public } from 'src/decorators/public.decorator';\nimport { ErrorMapperService } from 'src/helpers/error-mapper.service';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { AiInteractionService } from 'src/services/ai-interaction.service';\nimport { IngestMetadataService } from 'src/services/genai/ingest-metadata.service';\nimport { MqMessageService } from 'src/services/mq-message.service';\nimport { SolidRegistry } from '../helpers/solid-registry';\n\nexport interface PostProcessCodeGenConfig {\n runModuleMetadataSeeder?: boolean; // If true, regenerate module metadata\n runSolidIngestion?: boolean; // If true, run solid ingestion command\n}\n@Controller('')\n@ApiTags(\"Common\")\n// @UseGuards(ThrottlerGuard)\n// @SkipThrottle({ short: true, login: true, burst: true, sustained: true }) // Skip all\nexport class ServiceController {\n private readonly logger = new Logger(ServiceController.name);\n\n constructor(\n private readonly solidRegistry: SolidRegistry,\n private readonly aiInteractionService: AiInteractionService,\n private readonly mqMessageService: MqMessageService,\n private readonly errorMapper: ErrorMapperService,\n private readonly ingestMetadataService: IngestMetadataService,\n \n ) { }\n\n @Public()\n @Get('ping')\n pingPong() {\n return { pong: 'v1.0.2' };\n }\n\n @ApiBearerAuth(\"jwt\")\n @Get('mcp/ping')\n async mcpPingPong(@ActiveUser() activeUser: ActiveUserData) {\n // TODO: do a MCP client invocation, wait for response and return.\n // If failure then decide shape to return.\n\n const threadId = `pingPongTxn-${activeUser.sub}`;\n const dto ={prompt:\"Can you do 1 + 1\", moduleName:\"solidCoreModule\"}\n const { queueMessageId, aiInteractionId } = await this.aiInteractionService.triggerMcpClientJob(\n dto,\n activeUser.sub,\n true,\n threadId\n );\n\n this.logger.debug(`mcp ping pong job triggered: queueMessageId=${queueMessageId}, aiInteractionId=${aiInteractionId}`);\n\n // Wait up to 2 minutes, start at 500ms poll, back off to max 2s, throw if failed:\n const result = await this.mqMessageService.waitForTerminalStatus(queueMessageId, {\n timeoutMs: 2 * 60 * 1000,\n intervalMs: 500,\n maxIntervalMs: 2000,\n throwOnFailure: false,\n });\n\n this.logger.debug(`mcp ping pong job finished with stage=${result.stage}`)\n\n this.logger.debug(`mcp ping pong trying to find genai (child) interaction for aiInteraction for id=${aiInteractionId}`)\n\n // @ts-ignore\n const genAiInteractions = await this.aiInteractionService.find({\n filters: {\n parentInteraction: {\n id: {\n $eq: aiInteractionId\n }\n }\n }\n });\n\n const genAiInteraction = genAiInteractions['records'][0];\n this.logger.debug(genAiInteraction.message);\n\n this.logger.debug(`identified gen-ai interaction with id=${genAiInteraction.id}`);\n this.logger.debug(`proceeding with applying the gen-ai interaction`)\n\n return {\n mcpPong: 'v1.0.2',\n genAiInteraction: {\n status: genAiInteraction.status,\n errorCode: genAiInteraction.status === 'failed' ? this.errorMapper.mapMessage(genAiInteraction.errorMessage, genAiInteraction.metadata) : '',\n errorMessage: genAiInteraction.errorMessage,\n }\n };\n }\n\n @Public()\n // @SkipThrottle({ short: false, login: true, burst: true, sustained: true }) //Enable the short throttle only\n @Post('seed')\n async seedData(@Body() seedData: any) {\n const seeder = this.solidRegistry\n .getSeeders()\n .filter((seeder) => seeder.name === seedData.seeder)\n .map((seeder) => seeder.instance)\n .pop();\n if (!seeder) {\n this.logger.error(`Seeder service ${seedData.seeder} not found. Does your service have a seed() method?`);\n return;\n }\n this.logger.log(`Running the seed() method for seeder :${seeder.constructor.name}`);\n await seeder.seed();\n return { message: `seed data for ${seedData.seeder}` };\n }\n\n @ApiBearerAuth(\"jwt\")\n @Post('code-generation/post-process')\n async postProcessCodeGeneration(@Body() config : PostProcessCodeGenConfig) {\n // Set defaults if not provided\n config.runModuleMetadataSeeder = config.runModuleMetadataSeeder ?? true;\n config.runSolidIngestion = config.runSolidIngestion ?? true;\n\n // Run the Module Metadata Seeder Service\n if (config.runModuleMetadataSeeder) {\n this.logger.debug(`Running the Module Metadata Seeder Service as part of post-process code generation`);\n const seeder = this.solidRegistry\n .getSeeders()\n .filter((seeder) => seeder.name === 'ModuleMetadataSeederService')\n .map((seeder) => seeder.instance)\n .pop();\n if (!seeder) {\n this.logger.error(`Seeder service ModuleMetadataSeederService not found. Does your service have a seed() method?`);\n } else {\n await seeder.seed();\n }\n } else {\n this.logger.debug(`Skipping the Module Metadata Seeder Service as part of post-process code generation`);\n }\n \n // Run the Solid ingestion command\n if (config.runSolidIngestion) {\n this.logger.debug(`Running the Solid ingestion command as part of post-process code generation`);\n await this.ingestMetadataService.ingest();\n }\n }\n\n\n // @Public()\n // @Get('play')\n // play() {\n // return this.solidRegistry.getControllers();\n // }\n\n // //This method identifies a provider as a seeder if it has a seed method i.e duck typing\n // private isSeeder(provider: InstanceWrapper) {\n // const { instance } = provider;\n // if (!instance) return false;\n\n // const seedMethod = this.metadataScanner\n // .getAllMethodNames(Object.getPrototypeOf(instance))\n // .find((methodName) => methodName === 'seed');\n // if (!seedMethod) return false;\n // return true;\n // }\n\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function parseFlexibleDate(value: string): Date | null;
2
+ //# sourceMappingURL=date.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.helper.d.ts","sourceRoot":"","sources":["../../src/helpers/date.helper.ts"],"names":[],"mappings":"AAGA,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAQ1D"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseFlexibleDate = parseFlexibleDate;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
8
+ function parseFlexibleDate(value) {
9
+ if (!value)
10
+ return null;
11
+ const formats = ['DD-MM-YYYY', 'YYYY-MM-DD'];
12
+ const parsed = (0, dayjs_1.default)(value, formats, true);
13
+ if (!parsed.isValid()) {
14
+ return null;
15
+ }
16
+ return parsed.toDate();
17
+ }
18
+ //# sourceMappingURL=date.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.helper.js","sourceRoot":"","sources":["../../src/helpers/date.helper.ts"],"names":[],"mappings":";;;;;AAGA,8CAQG;AAXH,kDAA0B;AAG1B,SAAgB,iBAAiB,CAAC,KAAa;IAC3C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAA,eAAK,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACzB,CAAC","sourcesContent":["import dayjs from 'dayjs';\n\n\nexport function parseFlexibleDate(value: string): Date | null {\n if (!value) return null;\n const formats = ['DD-MM-YYYY', 'YYYY-MM-DD'];\n const parsed = dayjs(value, formats, true); // true = strict parsing\n if (!parsed.isValid()) {\n return null;\n }\n return parsed.toDate();\n }\n "]}
@@ -1 +1 @@
1
- {"version":3,"file":"trigger-mcp-client-subscriber-database.service.d.ts","sourceRoot":"","sources":["../../../src/jobs/database/trigger-mcp-client-subscriber-database.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,qBACa,kCAAmC,SAAQ,kBAAkB,CAAC,uBAAuB,CAAC;IAI3F,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,MAAM,EAAE,aAAa;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IANvD,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAuD;gBAG3F,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa,EACrB,oBAAoB,EAAE,oBAAoB;IAKvD,OAAO,IAAI,mBAAmB;IAM9B,mBAAmB,CAAC,UAAU,EAAE,WAAW;IA8BrC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,uBAAuB,CAAC;CA8HjE"}
1
+ {"version":3,"file":"trigger-mcp-client-subscriber-database.service.d.ts","sourceRoot":"","sources":["../../../src/jobs/database/trigger-mcp-client-subscriber-database.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,qBACa,kCAAmC,SAAQ,kBAAkB,CAAC,uBAAuB,CAAC;IAI3F,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,MAAM,EAAE,aAAa;IAC9B,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IANvD,OAAO,CAAC,QAAQ,CAAC,gCAAgC,CAAuD;gBAG3F,gBAAgB,EAAE,gBAAgB,EAClC,qBAAqB,EAAE,qBAAqB,EAC5C,MAAM,EAAE,aAAa,EACrB,oBAAoB,EAAE,oBAAoB;IAKvD,OAAO,IAAI,mBAAmB;IAM9B,mBAAmB,CAAC,UAAU,EAAE,WAAW;IA8BrC,SAAS,CAAC,OAAO,EAAE,YAAY,CAAC,uBAAuB,CAAC;CAuIjE"}
@@ -85,28 +85,32 @@ let TriggerMcpClientSubscriberDatabase = TriggerMcpClientSubscriberDatabase_1 =
85
85
  responseTimeMs: 0,
86
86
  metadata: '',
87
87
  isApplied: false,
88
- status: ''
88
+ status: 'pending'
89
89
  });
90
90
  const finalPrompt = `
91
- # User Prompt:
92
- ${prompt}
93
-
94
- # System Instructions:
95
- - aiInteractionId: ${genAiInteraction.id}
96
- - moduleName:${message.payload.moduleName}
97
- - You will be invoking tools if needed.
98
- - If a tool is invoked, you must return **exactly** the raw output from the tool, without any additional formatting, commentary, or text.
99
- - Do not wrap the result in quotes, JSON, or markdown fences.
100
- - Do not explain what the result means.
101
- - Your final response must be identical to the tool output.
102
- `;
91
+ # User Prompt:
92
+ ${prompt}
93
+
94
+ # System Instructions:
95
+ - aiInteractionId: ${genAiInteraction.id}
96
+ - moduleName:${message.payload.moduleName}
97
+ - You will be invoking tools if needed.
98
+ - If a tool is invoked, you must return **exactly** the raw output from the tool, without any json envelopes, additional formatting, commentary, or text.
99
+ - Do not wrap the result in quotes, JSON, or markdown fences.
100
+ - Do not explain what the result means.
101
+
102
+ # Past Interactions:
103
+ This section contains the last 10 interactions done between the human and LLM. These are sorted by oldest first.
104
+ Use these interactions to further identify concerns based on the current User Prompt.
105
+
106
+ `;
103
107
  const aiResponse = await this.aiInteractionService.runMcpPrompt(finalPrompt);
104
108
  this.triggerMcpClientSubscriberLogger.log(`aiResponse: `);
105
109
  this.triggerMcpClientSubscriberLogger.log(JSON.stringify(aiResponse));
106
110
  if (!aiResponse.success) {
107
111
  this.triggerMcpClientSubscriberLogger.log(`Gen ai has returned with a false status code`);
108
- const errorsStr = aiResponse.errors.join('\n ');
109
- const errorTrace = aiResponse.error_trace.join('\n');
112
+ const errorsStr = aiResponse.errors?.join('\n ');
113
+ const errorTrace = aiResponse.error_trace?.join('\n');
110
114
  await this.aiInteractionService.update(genAiInteraction.id, {
111
115
  errorMessage: `${errorsStr}\n\n${errorTrace}`,
112
116
  modelUsed: aiResponse.model,
@@ -117,12 +121,14 @@ let TriggerMcpClientSubscriberDatabase = TriggerMcpClientSubscriberDatabase_1 =
117
121
  throw new Error(errorsStr);
118
122
  }
119
123
  else {
124
+ let nestedResponse = this.cleanNestedResponse(aiResponse);
125
+ const errorsStr = nestedResponse.status == "error" && nestedResponse.errors.join('\n ');
120
126
  await this.aiInteractionService.update(genAiInteraction.id, {
121
- errorMessage: '',
127
+ errorMessage: nestedResponse.status == "error" ? `${errorsStr}` : "",
122
128
  modelUsed: aiResponse.model,
123
129
  responseTimeMs: aiResponse.duration_ms,
124
130
  isApplied: aiInteraction.isApplied,
125
- status: aiResponse.success ? 'succeeded' : 'failed'
131
+ status: aiResponse.success && nestedResponse.status == "success" ? 'succeeded' : 'failed'
126
132
  }, [], true);
127
133
  if (aiInteraction.isAutoApply) {
128
134
  this.aiInteractionService.applySolidAiInteraction(genAiInteraction.id);
@@ -1 +1 @@
1
- {"version":3,"file":"trigger-mcp-client-subscriber-database.service.js","sourceRoot":"","sources":["../../../src/jobs/database/trigger-mcp-client-subscriber-database.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\n\nimport { QueueMessage } from 'src/interfaces/mq';\nimport { MqMessageService } from '../../services/mq-message.service';\nimport { MqMessageQueueService } from '../../services/mq-message-queue.service';\nimport { McpResponse, QueuesModuleOptions, TriggerMcpClientOptions } from \"../../interfaces\";\nimport { DatabaseSubscriber } from 'src/services/queues/database-subscriber.service';\nimport triggerMcpClientQueueOptions from \"./trigger-mcp-client-queue-options\";\nimport { AiInteractionService } from 'src/services/ai-interaction.service';\nimport { PollerService } from 'src/services/poller.service';\n\n@Injectable()\nexport class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<TriggerMcpClientOptions> {\n private readonly triggerMcpClientSubscriberLogger = new Logger(TriggerMcpClientSubscriberDatabase.name);\n\n constructor(\n readonly mqMessageService: MqMessageService,\n readonly mqMessageQueueService: MqMessageQueueService,\n readonly poller: PollerService,\n readonly aiInteractionService: AiInteractionService,\n ) {\n super(mqMessageService, mqMessageQueueService, poller);\n }\n\n options(): QueuesModuleOptions {\n return {\n ...triggerMcpClientQueueOptions\n }\n }\n\n cleanNestedResponse(aiResponse: McpResponse) {\n let nestedResponse: any;\n\n try {\n let raw = aiResponse.response;\n\n if (typeof raw === \"string\") {\n raw = raw.trim();\n try {\n // Try to parse as JSON\n nestedResponse = JSON.parse(raw);\n } catch {\n // Not JSON, just keep as string\n nestedResponse = raw;\n }\n } else if (typeof raw === \"object\" && raw !== null) {\n // Already JSON\n nestedResponse = raw;\n } else {\n // Fallback\n nestedResponse = String(raw);\n }\n } catch (err) {\n this.triggerMcpClientSubscriberLogger.error(\"Error processing AI response:\", err);\n nestedResponse = `Error handling response: ${err?.message || String(err)}`;\n }\n\n return nestedResponse;\n }\n\n async subscribe(message: QueueMessage<TriggerMcpClientOptions>) {\n this.triggerMcpClientSubscriberLogger.debug(`Received message: ${JSON.stringify(message)}`);\n\n const codeGnerationOptions = message.payload;\n\n const aiInteraction = await this.aiInteractionService.findOne(codeGnerationOptions.aiInteractionId, {\n populate: ['user']\n });\n if (!aiInteraction) {\n const m = `Unable to identified the aiInteraction entry that triggered this job... using id: ${codeGnerationOptions.aiInteractionId}`\n this.triggerMcpClientSubscriberLogger.log(m);\n throw new Error(m);\n }\n\n // The message contains the users prompt.\n const prompt = aiInteraction.message;\n\n // Use this to invoke our mcp client\n // TODO: try / catch ... \n // Handle the rejection gracefully...\n\n // We create the aiInteraction entry first \n const genAiInteraction = await this.aiInteractionService.create({\n userId: aiInteraction.user.id,\n threadId: aiInteraction.threadId,\n parentInteractionId: aiInteraction.id,\n role: 'gen-ai',\n message: '...', // Updated in the tool\n contentType: '', // Updated in the tool\n errorMessage: '', // Updated after we receive the response\n modelUsed: '', // Updated after we receive the response\n responseTimeMs: 0, // Updated after we receive the response\n metadata: '', // Updated in the tool\n isApplied: false, // Updated after we receive the response\n status: '' // Updated after we receive the response\n });\n\n const finalPrompt = `\n # User Prompt: \n ${prompt}\n \n # System Instructions:\n - aiInteractionId: ${genAiInteraction.id}\n - moduleName:${message.payload.moduleName}\n - You will be invoking tools if needed.\n - If a tool is invoked, you must return **exactly** the raw output from the tool, without any additional formatting, commentary, or text.\n - Do not wrap the result in quotes, JSON, or markdown fences.\n - Do not explain what the result means.\n - Your final response must be identical to the tool output.\n `\n\n const aiResponse = await this.aiInteractionService.runMcpPrompt(finalPrompt);\n this.triggerMcpClientSubscriberLogger.log(`aiResponse: `);\n this.triggerMcpClientSubscriberLogger.log(JSON.stringify(aiResponse));\n\n if (!aiResponse.success) {\n this.triggerMcpClientSubscriberLogger.log(`Gen ai has returned with a false status code`);\n\n const errorsStr = aiResponse.errors.join('\\n ');\n const errorTrace = aiResponse.error_trace.join('\\n');\n\n // await this.aiInteractionService.create({\n // userId: aiInteraction.user.id,\n // threadId: aiInteraction.threadId,\n // parentInteractionId: aiInteraction.id,\n // role: 'gen-ai',\n // message: '-',\n // contentType: aiResponse.content_type,\n // errorMessage: errorsStr,\n // modelUsed: aiResponse.model,\n // responseTimeMs: aiResponse.duration_ms,\n // metadata: JSON.stringify(aiResponse, null, 2),\n // isApplied: aiInteraction.isApplied,\n // status: aiResponse.success ? 'succeeded' : 'failed'\n // });\n\n // TODO: Update the previously created genAiInteraction record with the respective error fields and save to DB\n await this.aiInteractionService.update(genAiInteraction.id, {\n // contentType: aiResponse.content_type,\n errorMessage: `${errorsStr}\\n\\n${errorTrace}`,\n modelUsed: aiResponse.model,\n responseTimeMs: aiResponse.duration_ms,\n isApplied: aiInteraction.isApplied,\n status: aiResponse.success ? 'succeeded' : 'failed'\n }, [], true);\n\n // update the job entry with failure... raising an error will lead the job to be marked as failed...\n throw new Error(errorsStr);\n }\n else {\n // let nestedResponse = this.cleanNestedResponse(aiResponse);\n\n // const genAiInteraction = await this.aiInteractionService.create({\n // userId: aiInteraction.user.id,\n // threadId: aiInteraction.threadId,\n // parentInteractionId: aiInteraction.id,\n // role: 'gen-ai',\n // message: nestedResponse,\n // contentType: aiResponse.content_type,\n // errorMessage: '',\n // modelUsed: aiResponse.model,\n // responseTimeMs: aiResponse.duration_ms,\n // metadata: JSON.stringify(aiResponse, null, 2),\n // isApplied: aiInteraction.isApplied,\n // status: aiResponse.success ? 'succeeded' : 'failed'\n // });\n\n // TODO: Update the previously created genAiInteraction record with the respective success fields and save to DB\n await this.aiInteractionService.update(genAiInteraction.id, {\n // contentType: aiResponse.content_type,\n errorMessage: '',\n // message: nestedResponse,\n modelUsed: aiResponse.model,\n responseTimeMs: aiResponse.duration_ms,\n isApplied: aiInteraction.isApplied,\n status: aiResponse.success ? 'succeeded' : 'failed'\n }, [], true);\n\n // If the human interaction was with isAutoApply=true, then we can go ahead and autoApply.\n if (aiInteraction.isAutoApply) {\n this.aiInteractionService.applySolidAiInteraction(genAiInteraction.id);\n }\n }\n\n return aiResponse;\n }\n}\n"]}
1
+ {"version":3,"file":"trigger-mcp-client-subscriber-database.service.js","sourceRoot":"","sources":["../../../src/jobs/database/trigger-mcp-client-subscriber-database.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\n\nimport { QueueMessage } from 'src/interfaces/mq';\nimport { MqMessageService } from '../../services/mq-message.service';\nimport { MqMessageQueueService } from '../../services/mq-message-queue.service';\nimport { McpResponse, QueuesModuleOptions, TriggerMcpClientOptions } from \"../../interfaces\";\nimport { DatabaseSubscriber } from 'src/services/queues/database-subscriber.service';\nimport triggerMcpClientQueueOptions from \"./trigger-mcp-client-queue-options\";\nimport { AiInteractionService } from 'src/services/ai-interaction.service';\nimport { PollerService } from 'src/services/poller.service';\n\n@Injectable()\nexport class TriggerMcpClientSubscriberDatabase extends DatabaseSubscriber<TriggerMcpClientOptions> {\n private readonly triggerMcpClientSubscriberLogger = new Logger(TriggerMcpClientSubscriberDatabase.name);\n\n constructor(\n readonly mqMessageService: MqMessageService,\n readonly mqMessageQueueService: MqMessageQueueService,\n readonly poller: PollerService,\n readonly aiInteractionService: AiInteractionService,\n ) {\n super(mqMessageService, mqMessageQueueService, poller);\n }\n\n options(): QueuesModuleOptions {\n return {\n ...triggerMcpClientQueueOptions\n }\n }\n\n cleanNestedResponse(aiResponse: McpResponse) {\n let nestedResponse: any;\n\n try {\n let raw = aiResponse.response;\n\n if (typeof raw === \"string\") {\n raw = raw.trim();\n try {\n // Try to parse as JSON\n nestedResponse = JSON.parse(raw);\n } catch {\n // Not JSON, just keep as string\n nestedResponse = raw;\n }\n } else if (typeof raw === \"object\" && raw !== null) {\n // Already JSON\n nestedResponse = raw;\n } else {\n // Fallback\n nestedResponse = String(raw);\n }\n } catch (err) {\n this.triggerMcpClientSubscriberLogger.error(\"Error processing AI response:\", err);\n nestedResponse = `Error handling response: ${err?.message || String(err)}`;\n }\n\n return nestedResponse;\n }\n\n async subscribe(message: QueueMessage<TriggerMcpClientOptions>) {\n this.triggerMcpClientSubscriberLogger.debug(`Received message: ${JSON.stringify(message)}`);\n\n const codeGnerationOptions = message.payload;\n\n const aiInteraction = await this.aiInteractionService.findOne(codeGnerationOptions.aiInteractionId, {\n populate: ['user']\n });\n if (!aiInteraction) {\n const m = `Unable to identified the aiInteraction entry that triggered this job... using id: ${codeGnerationOptions.aiInteractionId}`\n this.triggerMcpClientSubscriberLogger.log(m);\n throw new Error(m);\n }\n\n // The message contains the users prompt.\n const prompt = aiInteraction.message;\n\n // Use this to invoke our mcp client\n // TODO: try / catch ... \n // Handle the rejection gracefully...\n\n // We create the aiInteraction entry first \n const genAiInteraction = await this.aiInteractionService.create({\n userId: aiInteraction.user.id,\n threadId: aiInteraction.threadId,\n parentInteractionId: aiInteraction.id,\n role: 'gen-ai',\n message: '...', // Updated in the tool\n contentType: '', // Updated in the tool\n errorMessage: '', // Updated after we receive the response\n modelUsed: '', // Updated after we receive the response\n responseTimeMs: 0, // Updated after we receive the response\n metadata: '', // Updated in the tool\n isApplied: false, // Updated after we receive the response\n status: 'pending' // Updated after we receive the response\n });\n\n const finalPrompt = `\n# User Prompt: \n${prompt}\n\n# System Instructions:\n- aiInteractionId: ${genAiInteraction.id}\n- moduleName:${message.payload.moduleName}\n- You will be invoking tools if needed.\n- If a tool is invoked, you must return **exactly** the raw output from the tool, without any json envelopes, additional formatting, commentary, or text.\n- Do not wrap the result in quotes, JSON, or markdown fences.\n- Do not explain what the result means.\n\n# Past Interactions: \nThis section contains the last 10 interactions done between the human and LLM. These are sorted by oldest first. \nUse these interactions to further identify concerns based on the current User Prompt.\n\n`\n\n const aiResponse = await this.aiInteractionService.runMcpPrompt(finalPrompt);\n this.triggerMcpClientSubscriberLogger.log(`aiResponse: `);\n this.triggerMcpClientSubscriberLogger.log(JSON.stringify(aiResponse));\n\n if (!aiResponse.success) {\n this.triggerMcpClientSubscriberLogger.log(`Gen ai has returned with a false status code`);\n\n const errorsStr = aiResponse.errors?.join('\\n ');\n const errorTrace = aiResponse.error_trace?.join('\\n');\n\n // await this.aiInteractionService.create({\n // userId: aiInteraction.user.id,\n // threadId: aiInteraction.threadId,\n // parentInteractionId: aiInteraction.id,\n // role: 'gen-ai',\n // message: '-',\n // contentType: aiResponse.content_type,\n // errorMessage: errorsStr,\n // modelUsed: aiResponse.model,\n // responseTimeMs: aiResponse.duration_ms,\n // metadata: JSON.stringify(aiResponse, null, 2),\n // isApplied: aiInteraction.isApplied,\n // status: aiResponse.success ? 'succeeded' : 'failed'\n // });\n\n // TODO: Update the previously created genAiInteraction record with the respective error fields and save to DB\n await this.aiInteractionService.update(genAiInteraction.id, {\n // contentType: aiResponse.content_type,\n errorMessage: `${errorsStr}\\n\\n${errorTrace}`,\n modelUsed: aiResponse.model,\n responseTimeMs: aiResponse.duration_ms,\n isApplied: aiInteraction.isApplied,\n status: aiResponse.success ? 'succeeded' : 'failed'\n }, [], true);\n\n // update the job entry with failure... raising an error will lead the job to be marked as failed...\n throw new Error(errorsStr);\n }\n else {\n let nestedResponse = this.cleanNestedResponse(aiResponse);\n\n // const genAiInteraction = await this.aiInteractionService.create({\n // userId: aiInteraction.user.id,\n // threadId: aiInteraction.threadId,\n // parentInteractionId: aiInteraction.id,\n // role: 'gen-ai',\n // message: nestedResponse,\n // contentType: aiResponse.content_type,\n // errorMessage: '',\n // modelUsed: aiResponse.model,\n // responseTimeMs: aiResponse.duration_ms,\n // metadata: JSON.stringify(aiResponse, null, 2),\n // isApplied: aiInteraction.isApplied,\n // status: aiResponse.success ? 'succeeded' : 'failed'\n // });\n\n // TODO: Update the previously created genAiInteraction record with the respective success fields and save to DB\n const errorsStr = nestedResponse.status == \"error\" && nestedResponse.errors.join('\\n ');\n\n await this.aiInteractionService.update(genAiInteraction.id, {\n errorMessage: nestedResponse.status == \"error\" ? `${errorsStr}` : \"\",\n // errorMessage:\"\",\n // contentType: aiResponse.content_type,\n // message: nestedResponse,\n modelUsed: aiResponse.model,\n responseTimeMs: aiResponse.duration_ms,\n isApplied: aiInteraction.isApplied,\n\n // status: aiResponse.success ? 'succeeded' : 'failed'\n status: aiResponse.success && nestedResponse.status == \"success\" ? 'succeeded' : 'failed'\n }, [], true);\n\n // If the human interaction was with isAutoApply=true, then we can go ahead and autoApply.\n if (aiInteraction.isAutoApply) {\n this.aiInteractionService.applySolidAiInteraction(genAiInteraction.id);\n }\n }\n\n return aiResponse;\n }\n}\n"]}
@@ -12331,7 +12331,8 @@
12331
12331
  "type": "field",
12332
12332
  "attrs": {
12333
12333
  "name": "metadata",
12334
- "height": "80vh"
12334
+ "height": "80vh",
12335
+ "viewWidget": "SolidAiInteractionMetadataFieldFormWidget"
12335
12336
  }
12336
12337
  }
12337
12338
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"ai-interaction.service.d.ts","sourceRoot":"","sources":["../../src/services/ai-interaction.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,wEAAwE,CAAC;AAEvH,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,qBACa,oBAAqB,SAAQ,WAAW,CAAC,aAAa,CAAC;IAIhE,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IACnD,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW;IACjC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB;IAE7C,QAAQ,CAAC,aAAa,EAAE,aAAa;IAErC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAEpE,QAAQ,CAAC,6BAA6B,EAAE,6BAA6B;IAhBvE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;gBAGrD,oBAAoB,EAAE,oBAAoB,EAC1C,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,iBAAiB,EAAE,iBAAiB,EAEpC,aAAa,EAAE,aAAa,EAE5B,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC,EAC/B,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,EAE3D,6BAA6B,EAAE,6BAA6B;IAMjE,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,EAAE,QAAQ,GAAE,MAAa,GAAG,OAAO,CAAC,GAAG,CAAC;IAqChI,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA8FxD,aAAa,CAAC,QAAQ,EAAE,MAAM;IAexB,uBAAuB,CAAC,EAAE,EAAE,MAAM;CAiDzC"}
1
+ {"version":3,"file":"ai-interaction.service.d.ts","sourceRoot":"","sources":["../../src/services/ai-interaction.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEpD,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAC3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,6BAA6B,EAAE,MAAM,wEAAwE,CAAC;AAEvH,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,qBACa,oBAAqB,SAAQ,WAAW,CAAC,aAAa,CAAC;IAIhE,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB;IACnD,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB;IACrD,QAAQ,CAAC,aAAa,EAAE,aAAa;IACrC,QAAQ,CAAC,WAAW,EAAE,WAAW;IACjC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB;IAE7C,QAAQ,CAAC,aAAa,EAAE,aAAa;IAErC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC;IACxC,QAAQ,CAAC,SAAS,EAAE,SAAS;IAC7B,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC;IAEpE,QAAQ,CAAC,6BAA6B,EAAE,6BAA6B;IAhBvE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyC;gBAGrD,oBAAoB,EAAE,oBAAoB,EAC1C,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,gBAAgB,EAAE,gBAAgB,EAClC,iBAAiB,EAAE,iBAAiB,EAEpC,aAAa,EAAE,aAAa,EAE5B,IAAI,EAAE,UAAU,CAAC,aAAa,CAAC,EAC/B,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,EAE3D,6BAA6B,EAAE,6BAA6B;IAMjE,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAE,OAAe,EAAE,QAAQ,GAAE,MAAa,GAAG,OAAO,CAAC,GAAG,CAAC;IAqChI,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA+FxD,aAAa,CAAC,QAAQ,EAAE,MAAM;IAexB,uBAAuB,CAAC,EAAE,EAAE,MAAM;CAuDzC"}
@@ -188,12 +188,20 @@ let AiInteractionService = AiInteractionService_1 = class AiInteractionService e
188
188
  }
189
189
  let metadata = {};
190
190
  try {
191
- metadata = JSON.parse(aiInteraction.metadata);
191
+ if (typeof aiInteraction.metadata === "string") {
192
+ metadata = JSON.parse(aiInteraction.metadata);
193
+ }
194
+ else if (typeof aiInteraction.metadata === "object" && aiInteraction.metadata !== null) {
195
+ metadata = aiInteraction.metadata;
196
+ }
197
+ else {
198
+ metadata = {};
199
+ }
192
200
  }
193
201
  catch (e) {
194
- throw new Error(e);
202
+ throw new Error(`Invalid metadata JSON: ${e}`);
195
203
  }
196
- const toolsInvoked = metadata['tools_invoked'];
204
+ const toolsInvoked = metadata['toolsInvoked'];
197
205
  if (!toolsInvoked) {
198
206
  throw new Error(error_messages_1.ERROR_MESSAGES.UNABLE_TO_RESOLVE_SOLID_COMMAND);
199
207
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ai-interaction.service.js","sourceRoot":"","sources":["../../src/services/ai-interaction.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, Logger, Injectable } from '@nestjs/common';\nimport { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';\nimport { DiscoveryService, ModuleRef } from \"@nestjs/core\";\nimport { EntityManager, Repository } from 'typeorm';\n\nimport { CRUDService } from 'src/services/crud.service';\nimport { ModelMetadataService } from 'src/services/model-metadata.service';\nimport { ModuleMetadataService } from 'src/services/module-metadata.service';\nimport { ConfigService } from '@nestjs/config';\nimport { FileService } from 'src/services/file.service';\nimport { CrudHelperService } from 'src/services/crud-helper.service';\nimport { spawn } from 'child_process';\nimport { AiInteraction } from '../entities/ai-interaction.entity';\nimport * as fs from 'fs/promises';\nimport { McpResponse, TriggerMcpClientOptions } from 'src/interfaces';\nimport { PublisherFactory } from './queues/publisher-factory.service';\nimport { RequestContextService } from './request-context.service';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { McpToolResponseHandlerFactory } from './mcp-tool-response-handlers/mcp-tool-response-handler-factory.service';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { InvokeAiPromptDto } from 'src/dtos/invoke-ai-prompt.dto';\n\n@Injectable()\nexport class AiInteractionService extends CRUDService<AiInteraction> {\n private readonly logger = new Logger(AiInteractionService.name);\n\n constructor(\n readonly modelMetadataService: ModelMetadataService,\n readonly moduleMetadataService: ModuleMetadataService,\n readonly configService: ConfigService,\n readonly fileService: FileService,\n readonly discoveryService: DiscoveryService,\n readonly crudHelperService: CrudHelperService,\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n @InjectRepository(AiInteraction, 'default')\n readonly repo: Repository<AiInteraction>,\n readonly moduleRef: ModuleRef,\n readonly publisherFactory: PublisherFactory<TriggerMcpClientOptions>,\n // readonly requestContextService: RequestContextService,\n readonly mcpToolResponseHandlerFactory: McpToolResponseHandlerFactory,\n\n ) {\n super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);\n }\n\n async triggerMcpClientJob(dto: InvokeAiPromptDto, userId: number, isAutoApply: boolean = false, threadId: string = null): Promise<any> {\n // const activeUser: ActiveUserData = this.requestContextService.getActiveUser();\n\n const aiInteraction = await this.create({\n userId: userId,\n threadId: threadId ? threadId : `thread-${userId}`,\n role: 'human',\n message: dto.prompt,\n contentType: '',\n errorMessage: '',\n modelUsed: '',\n responseTimeMs: 0,\n metadata: '',\n isAutoApply: isAutoApply\n });\n const m = {\n payload: {\n aiInteractionId: aiInteraction.id,\n moduleName:dto.moduleName\n },\n parentEntity: 'aiInteraction',\n parentEntityId: aiInteraction.id,\n };\n\n const queueMessageId = await this.publisherFactory.publish(m, 'TriggerMcpClientPublisher');\n\n return {\n queueMessageId: queueMessageId,\n aiInteractionId: aiInteraction.id\n }\n }\n\n /**\n * Runs the Python MCP client with a prompt and returns the parsed JSON embedded in the 'response'.\n * @param prompt - The question or instruction to send to the MCP client.\n * @returns The parsed object inside the 'response' field of the JSON output.\n */\n async runMcpPrompt(prompt: string): Promise<McpResponse> {\n const pythonExecutable = process.env.MCP_PYTHON_EXECUTABLE;\n const mcpClient = process.env.MCP_CLIENT;\n\n // TODO: We can return an error if the above env variables are not properly setup...\n if (!pythonExecutable || !mcpClient) {\n throw new BadRequestException(ERROR_MESSAGES.PYTHON_EXECUTABLE_NOT_CONFIGURED);\n }\n\n // Check if both paths are valid and accessible\n try {\n const [pyStat, clientStat] = await Promise.all([\n fs.stat(pythonExecutable),\n fs.stat(mcpClient),\n ]);\n\n if (!pyStat.isFile()) {\n throw new BadRequestException(`MCP_PYTHON_EXECUTABLE path is not a file: ${pythonExecutable}`);\n }\n\n if (!clientStat.isFile()) {\n throw new BadRequestException(`MCP_CLIENT path is not a file: ${mcpClient}`);\n }\n\n } catch (err: any) {\n throw new BadRequestException(`Invalid MCP executable or client path: ${err.message}`);\n }\n\n // TODO: Refactor to use the command.service.ts instead...\n return new Promise((resolve, reject) => {\n this.logger.log(`Attempting to run command:`)\n this.logger.log(`${pythonExecutable} ${mcpClient} \"${prompt}\"`);\n\n const python = spawn(pythonExecutable, [mcpClient, `\"${prompt}\"`]);\n\n let stdout = '';\n let stderr = '';\n\n python.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n python.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n python.on('close', (code) => {\n this.logger.log(`Python script exited with code ${code}`);\n\n if (code !== 0) {\n this.logger.error(`Python script exited with a non-zero exit code: ${stderr}`);\n return reject(new Error(`Python script exited with a non-zero exit code: ${stderr}`));\n }\n\n try {\n this.logger.log(`Python script exited with zero exit code: ${stdout}`);\n const raw: McpResponse = JSON.parse(stdout);\n\n // Sometimes the raw.response might not be a valid json\n // TODO: examine the content type of the raw response..\n // if (raw.content_type==='json') {\n // }\n let parsedResponse = raw.response;\n try {\n parsedResponse = JSON.parse(raw.response);\n }\n catch (ex) {\n this.logger.warn(`Attempting to parse mcp client response assuming it is JSON, however it is not: ${parsedResponse}`);\n }\n // Parse the response string into an object\n // const parsedResponse = JSON.parse(raw.response);\n\n // Replace the string with the parsed object\n const enrichedRaw = {\n ...raw,\n response: parsedResponse,\n };\n // if (!raw.success) {\n // return reject(new Error(`MCP error: ${raw.errors?.join(', ')}`));\n // }\n // let cleaned = raw.response.trim();\n\n // Don't need to re-parse this...\n // const parsed = JSON.parse(cleaned);\n // resolve(cleaned);\n\n resolve(enrichedRaw);\n } catch (err: any) {\n reject(new Error(`Mcp Invocation Failed: ${err.message}`));\n }\n });\n });\n }\n\n cleanResponse(response: string) {\n this.logger.log(`mcp server response is: ${response}`);\n\n // Remove markdown-style code block wrapper\n if (response.startsWith('```json')) {\n response = response.replace(/^```json/, '').trim();\n }\n if (response.endsWith('```')) {\n response = response.replace(/```$/, '').trim();\n }\n this.logger.log(`mcp server response after removing doc tags is: ${response}`);\n\n return response;\n }\n\n async applySolidAiInteraction(id: number) {\n // Fetch the aiInteraction\n const aiInteraction = await this.findOne(id, {\n populate: ['user']\n });\n if (!aiInteraction) {\n const m = `Unable to identified the aiInteraction entry that triggered this job... using id: ${id}`\n\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(m);\n }\n\n // TODO: Validation: Check if JSON.parse(metadata).tools_invoked starts with solid_\n let metadata = {};\n try {\n metadata = JSON.parse(aiInteraction.metadata);\n }\n catch (e) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(e);\n }\n\n const toolsInvoked = metadata['tools_invoked'];\n if (!toolsInvoked) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_SOLID_COMMAND);\n }\n\n // TODO: OPTIMISATION for chained tool invocation, for now we are assuming only 1 tool was used.\n const toolInvoked = toolsInvoked[0];\n\n // TODO: use the toolInvoked to identify a service using some convention.\n // TODO: Eg. if toolInvoked is solid_create_module <> SolidCreateModuleMcpToolHandler ... create a factory class to do this mapping and identify the relevant provider. \n const mcpToolHandler = this.mcpToolResponseHandlerFactory.getInstance(toolInvoked);\n if (!mcpToolHandler) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_MCP_HANDLER);\n }\n\n const handlerApplicationResponse = await mcpToolHandler.apply(aiInteraction);\n\n // TODO: This provider to implement an interface - IMcpToolResponseHandler ... apply(aiInteraction: AiInteraction)\n // throw new Error('Method not implemented.');\n\n // Mark the interaction as applied\n await this.update(aiInteraction.id, { isApplied: true }, [], true);\n\n return handlerApplicationResponse;\n }\n}\n"]}
1
+ {"version":3,"file":"ai-interaction.service.js","sourceRoot":"","sources":["../../src/services/ai-interaction.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { BadRequestException, Logger, Injectable } from '@nestjs/common';\nimport { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';\nimport { DiscoveryService, ModuleRef } from \"@nestjs/core\";\nimport { EntityManager, Repository } from 'typeorm';\n\nimport { CRUDService } from 'src/services/crud.service';\nimport { ModelMetadataService } from 'src/services/model-metadata.service';\nimport { ModuleMetadataService } from 'src/services/module-metadata.service';\nimport { ConfigService } from '@nestjs/config';\nimport { FileService } from 'src/services/file.service';\nimport { CrudHelperService } from 'src/services/crud-helper.service';\nimport { spawn } from 'child_process';\nimport { AiInteraction } from '../entities/ai-interaction.entity';\nimport * as fs from 'fs/promises';\nimport { McpResponse, TriggerMcpClientOptions } from 'src/interfaces';\nimport { PublisherFactory } from './queues/publisher-factory.service';\nimport { RequestContextService } from './request-context.service';\nimport { ActiveUserData } from 'src/interfaces/active-user-data.interface';\nimport { McpToolResponseHandlerFactory } from './mcp-tool-response-handlers/mcp-tool-response-handler-factory.service';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { InvokeAiPromptDto } from 'src/dtos/invoke-ai-prompt.dto';\n\n@Injectable()\nexport class AiInteractionService extends CRUDService<AiInteraction> {\n private readonly logger = new Logger(AiInteractionService.name);\n\n constructor(\n readonly modelMetadataService: ModelMetadataService,\n readonly moduleMetadataService: ModuleMetadataService,\n readonly configService: ConfigService,\n readonly fileService: FileService,\n readonly discoveryService: DiscoveryService,\n readonly crudHelperService: CrudHelperService,\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n @InjectRepository(AiInteraction, 'default')\n readonly repo: Repository<AiInteraction>,\n readonly moduleRef: ModuleRef,\n readonly publisherFactory: PublisherFactory<TriggerMcpClientOptions>,\n // readonly requestContextService: RequestContextService,\n readonly mcpToolResponseHandlerFactory: McpToolResponseHandlerFactory,\n\n ) {\n super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);\n }\n\n async triggerMcpClientJob(dto: InvokeAiPromptDto, userId: number, isAutoApply: boolean = false, threadId: string = null): Promise<any> {\n // const activeUser: ActiveUserData = this.requestContextService.getActiveUser();\n\n const aiInteraction = await this.create({\n userId: userId,\n threadId: threadId ? threadId : `thread-${userId}`,\n role: 'human',\n message: dto.prompt,\n contentType: '',\n errorMessage: '',\n modelUsed: '',\n responseTimeMs: 0,\n metadata: '',\n isAutoApply: isAutoApply\n });\n const m = {\n payload: {\n aiInteractionId: aiInteraction.id,\n moduleName: dto.moduleName\n },\n parentEntity: 'aiInteraction',\n parentEntityId: aiInteraction.id,\n };\n\n const queueMessageId = await this.publisherFactory.publish(m, 'TriggerMcpClientPublisher');\n\n return {\n queueMessageId: queueMessageId,\n aiInteractionId: aiInteraction.id\n }\n }\n\n /**\n * Runs the Python MCP client with a prompt and returns the parsed JSON embedded in the 'response'.\n * @param prompt - The question or instruction to send to the MCP client.\n * @returns The parsed object inside the 'response' field of the JSON output.\n */\n async runMcpPrompt(prompt: string): Promise<McpResponse> {\n const pythonExecutable = process.env.MCP_PYTHON_EXECUTABLE;\n const mcpClient = process.env.MCP_CLIENT;\n\n // TODO: We can return an error if the above env variables are not properly setup...\n if (!pythonExecutable || !mcpClient) {\n throw new BadRequestException(ERROR_MESSAGES.PYTHON_EXECUTABLE_NOT_CONFIGURED);\n }\n\n // Check if both paths are valid and accessible\n try {\n const [pyStat, clientStat] = await Promise.all([\n fs.stat(pythonExecutable),\n fs.stat(mcpClient),\n ]);\n\n if (!pyStat.isFile()) {\n throw new BadRequestException(`MCP_PYTHON_EXECUTABLE path is not a file: ${pythonExecutable}`);\n }\n\n if (!clientStat.isFile()) {\n throw new BadRequestException(`MCP_CLIENT path is not a file: ${mcpClient}`);\n }\n\n } catch (err: any) {\n throw new BadRequestException(`Invalid MCP executable or client path: ${err.message}`);\n }\n\n // TODO: Refactor to use the command.service.ts instead...\n return new Promise((resolve, reject) => {\n this.logger.log(`Attempting to run command:`)\n this.logger.log(`${pythonExecutable} ${mcpClient} \"${prompt}\"`);\n\n const python = spawn(pythonExecutable, [mcpClient, `\"${prompt}\"`]);\n\n let stdout = '';\n let stderr = '';\n\n python.stdout.on('data', (data) => {\n stdout += data.toString();\n });\n\n python.stderr.on('data', (data) => {\n stderr += data.toString();\n });\n\n python.on('close', (code) => {\n this.logger.log(`Python script exited with code ${code}`);\n\n if (code !== 0) {\n this.logger.error(`Python script exited with a non-zero exit code: ${stderr}`);\n return reject(new Error(`Python script exited with a non-zero exit code: ${stderr}`));\n }\n\n try {\n this.logger.log(`Python script exited with zero exit code: ${stdout}`);\n const raw: McpResponse = JSON.parse(stdout);\n\n // Sometimes the raw.response might not be a valid json\n // TODO: examine the content type of the raw response..\n // if (raw.content_type==='json') {\n // }\n let parsedResponse = raw.response;\n try {\n parsedResponse = JSON.parse(raw.response);\n }\n catch (ex) {\n this.logger.warn(`Attempting to parse mcp client response assuming it is JSON, however it is not: ${parsedResponse}`);\n // raw.success = false\n }\n // Parse the response string into an object\n // const parsedResponse = JSON.parse(raw.response);\n\n // Replace the string with the parsed object\n const enrichedRaw = {\n ...raw,\n response: parsedResponse,\n };\n // if (!raw.success) {\n // return reject(new Error(`MCP error: ${raw.errors?.join(', ')}`));\n // }\n // let cleaned = raw.response.trim();\n\n // Don't need to re-parse this...\n // const parsed = JSON.parse(cleaned);\n // resolve(cleaned);\n\n resolve(enrichedRaw);\n } catch (err: any) {\n reject(new Error(`Mcp Invocation Failed: ${err.message}`));\n }\n });\n });\n }\n\n cleanResponse(response: string) {\n this.logger.log(`mcp server response is: ${response}`);\n\n // Remove markdown-style code block wrapper\n if (response.startsWith('```json')) {\n response = response.replace(/^```json/, '').trim();\n }\n if (response.endsWith('```')) {\n response = response.replace(/```$/, '').trim();\n }\n this.logger.log(`mcp server response after removing doc tags is: ${response}`);\n\n return response;\n }\n\n async applySolidAiInteraction(id: number) {\n // Fetch the aiInteraction\n const aiInteraction = await this.findOne(id, {\n populate: ['user']\n });\n if (!aiInteraction) {\n const m = `Unable to identified the aiInteraction entry that triggered this job... using id: ${id}`\n\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(m);\n }\n\n // TODO: Validation: Check if JSON.parse(metadata).tools_invoked starts with solid_\n let metadata: any = {};\n try {\n if (typeof aiInteraction.metadata === \"string\") {\n metadata = JSON.parse(aiInteraction.metadata);\n } else if (typeof aiInteraction.metadata === \"object\" && aiInteraction.metadata !== null) {\n metadata = aiInteraction.metadata;\n } else {\n // optional fallback\n metadata = {};\n }\n } catch (e) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(`Invalid metadata JSON: ${e}`);\n }\n\n const toolsInvoked = metadata['toolsInvoked'];\n if (!toolsInvoked) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_SOLID_COMMAND);\n }\n\n // TODO: OPTIMISATION for chained tool invocation, for now we are assuming only 1 tool was used.\n const toolInvoked = toolsInvoked[0];\n\n // TODO: use the toolInvoked to identify a service using some convention.\n // TODO: Eg. if toolInvoked is solid_create_module <> SolidCreateModuleMcpToolHandler ... create a factory class to do this mapping and identify the relevant provider. \n const mcpToolHandler = this.mcpToolResponseHandlerFactory.getInstance(toolInvoked);\n if (!mcpToolHandler) {\n // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....\n throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_MCP_HANDLER);\n }\n\n const handlerApplicationResponse = await mcpToolHandler.apply(aiInteraction);\n\n // TODO: This provider to implement an interface - IMcpToolResponseHandler ... apply(aiInteraction: AiInteraction)\n // throw new Error('Method not implemented.');\n\n // Mark the interaction as applied\n await this.update(aiInteraction.id, { isApplied: true }, [], true);\n\n return handlerApplicationResponse;\n }\n}\n"]}
@@ -71,7 +71,7 @@ let ExcelService = ExcelService_1 = class ExcelService {
71
71
  isHeaderWritten = true;
72
72
  }
73
73
  if (typeof getDataRecords !== 'function') {
74
- await workbook.commit();
74
+ workbook.commit();
75
75
  return passThrough;
76
76
  }
77
77
  let chunkIndex = 0;
@@ -93,7 +93,7 @@ let ExcelService = ExcelService_1 = class ExcelService {
93
93
  chunkIndex++;
94
94
  this.logger.debug(`✅ Chunk ${chunkIndex} written to Excel`);
95
95
  }
96
- await workbook.commit();
96
+ workbook.commit();
97
97
  }
98
98
  catch (error) {
99
99
  this.logger.error(`❌ Error writing Excel: ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"excel.service.js","sourceRoot":"","sources":["../../src/services/excel.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport * as ExcelJS from 'exceljs';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PassThrough, Readable } from 'stream';\n\n\nexport interface ExcelReadOptions {\n pageSize?: number; // Number of records per page\n hasHeaderRow?: boolean; // Whether the first row contains headers\n providedHeaders?: string[]; // Custom headers if hasHeaderRow is false\n}\n\nconst DEFAULT_PAGE_SIZE = 100; // Default page size if not provided\n\nexport interface ExcelReadResult {\n headers: string[]; // Headers of the Excel file\n data: Record<string, any>[]; // Data records in the current page\n}\n\n@Injectable()\nexport class ExcelService {\n private logger = new Logger(ExcelService.name);\n\n public async createExcelStream(\n getDataRecords: (chunkIndex: number, chunkSize: number) => Promise<any[]>,\n chunkSize: number = 100,\n headers: string[] = []\n ): Promise<Readable> {\n // Validations\n // If neither headers nor data records function is provided, throw an error\n if (headers.length === 0 && typeof getDataRecords !== 'function') {\n throw new Error(ERROR_MESSAGES.MISSING_HEADERS_OR_FUNCTION);\n }\n\n // If data records function is provided, chunkSize must be greater than 0\n if (getDataRecords && chunkSize <= 0) {\n throw new Error(ERROR_MESSAGES.INVALID_CHUNK_SIZE);\n }\n\n const passThrough = new PassThrough(); // Create streaming pipe\n try {\n const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ stream: passThrough });\n const worksheet = workbook.addWorksheet('Data');\n\n // If headers are provided, use them;\n let isHeaderWritten = false;\n if (headers.length > 0) {\n worksheet.columns = headers.map((header) => ({\n header: header, // Convert header names to uppercase\n key: header,\n width: 20, // Set column width\n }));\n isHeaderWritten = true; // Mark headers as written\n }\n\n // ✅ If no data loader provided, write only headers and finish\n if (typeof getDataRecords !== 'function') {\n // worksheet.addRow(\n // headers.reduce((acc, header) => ({ ...acc, [header]: '' }), {})\n // ).commit(); // Write a dummy record with headers\n\n await workbook.commit();\n return passThrough;\n }\n\n // Write the data records in chunks\n let chunkIndex = 0;\n while (true) {\n const records = await getDataRecords(chunkIndex, chunkSize); // Fetch chunked data\n if (records.length === 0) break; // Stop if no more records\n\n if (!isHeaderWritten) { // Falback because without columns being set, ExcelJS won't write data correctly\n worksheet.columns = Object.keys(records[0]).map((key) => ({\n header: key.toUpperCase(),\n key: key,\n width: 20,\n }));\n isHeaderWritten = true;\n }\n\n records.forEach((item) => {\n worksheet.addRow(item).commit(); // Commit each row immediately\n });\n\n chunkIndex++; // Fetch next chunk\n this.logger.debug(`✅ Chunk ${chunkIndex} written to Excel`);\n }\n\n await workbook.commit();\n // passThrough.end(); // ✅ Properly close the stream\n } catch (error) {\n this.logger.error(`❌ Error writing Excel: ${error.message}`);\n passThrough.destroy(error); // Destroy stream\n throw error;\n }\n return passThrough; // Return streaming response\n }\n\n public async *readExcelInPagesFromStream(\n stream: Readable,\n options?: ExcelReadOptions\n ): AsyncGenerator<ExcelReadResult> {\n const { pageSize = DEFAULT_PAGE_SIZE, hasHeaderRow = true, providedHeaders = [] } = options || {};\n const workbookReader = new ExcelJS.stream.xlsx.WorkbookReader(stream, {});\n\n let headers: string[] = [];\n let page: Record<string, any>[] = [];\n let isFirstRow = true;\n let hasYieldedData = false;\n\n for await (const worksheet of workbookReader) {\n for await (const row of worksheet) {\n const values = Array.isArray(row.values) ? row.values.slice(1) : [];\n\n if (isFirstRow) {\n isFirstRow = false;\n\n if (hasHeaderRow) {\n headers = values.map(v => v?.toString().trim() || '');\n continue;\n } else if (providedHeaders.length) {\n headers = providedHeaders;\n } else {\n headers = values.map((_, idx) => `${idx}`);\n }\n }\n\n while (values.length < headers.length) values.push(null);\n if (values.length > headers.length) values.length = headers.length;\n\n const record = headers.reduce((acc, key, i) => {\n acc[key] = values[i] ?? null;\n return acc;\n }, {} as Record<string, any>);\n\n if (Object.values(record).every(v => v === null || v === '')) continue;\n\n page.push(record);\n\n if (page.length === pageSize) {\n yield { headers, data: page };\n hasYieldedData = true;\n page = [];\n }\n }\n\n // Optional: break if only processing first worksheet\n // break;\n }\n\n if (page.length > 0) {\n yield { headers, data: page };\n hasYieldedData = true;\n }\n\n // ✅ Yield headers with empty data if only headers were found\n if (!hasYieldedData && headers.length > 0) {\n yield { headers, data: [] };\n }\n }\n\n}"]}
1
+ {"version":3,"file":"excel.service.js","sourceRoot":"","sources":["../../src/services/excel.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\nimport * as ExcelJS from 'exceljs';\nimport { ERROR_MESSAGES } from 'src/constants/error-messages';\nimport { PassThrough, Readable } from 'stream';\n\n\nexport interface ExcelReadOptions {\n pageSize?: number; // Number of records per page\n hasHeaderRow?: boolean; // Whether the first row contains headers\n providedHeaders?: string[]; // Custom headers if hasHeaderRow is false\n}\n\nconst DEFAULT_PAGE_SIZE = 100; // Default page size if not provided\n\nexport interface ExcelReadResult {\n headers: string[]; // Headers of the Excel file\n data: Record<string, any>[]; // Data records in the current page\n}\n\n@Injectable()\nexport class ExcelService {\n private logger = new Logger(ExcelService.name);\n\n public async createExcelStream(\n getDataRecords: (chunkIndex: number, chunkSize: number) => Promise<any[]>,\n chunkSize: number = 100,\n headers: string[] = []\n ): Promise<Readable> {\n // Validations\n // If neither headers nor data records function is provided, throw an error\n if (headers.length === 0 && typeof getDataRecords !== 'function') {\n throw new Error(ERROR_MESSAGES.MISSING_HEADERS_OR_FUNCTION);\n }\n\n // If data records function is provided, chunkSize must be greater than 0\n if (getDataRecords && chunkSize <= 0) {\n throw new Error(ERROR_MESSAGES.INVALID_CHUNK_SIZE);\n }\n\n const passThrough = new PassThrough(); // Create streaming pipe\n try {\n const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ stream: passThrough });\n const worksheet = workbook.addWorksheet('Data');\n\n // If headers are provided, use them;\n let isHeaderWritten = false;\n if (headers.length > 0) {\n worksheet.columns = headers.map((header) => ({\n header: header, // Convert header names to uppercase\n key: header,\n width: 20, // Set column width\n }));\n isHeaderWritten = true; // Mark headers as written\n }\n\n // ✅ If no data loader provided, write only headers and finish\n if (typeof getDataRecords !== 'function') {\n // worksheet.addRow(\n // headers.reduce((acc, header) => ({ ...acc, [header]: '' }), {})\n // ).commit(); // Write a dummy record with headers\n\n workbook.commit();\n return passThrough;\n }\n\n // Write the data records in chunks\n let chunkIndex = 0;\n while (true) {\n const records = await getDataRecords(chunkIndex, chunkSize); // Fetch chunked data\n if (records.length === 0) break; // Stop if no more records\n\n if (!isHeaderWritten) { // Falback because without columns being set, ExcelJS won't write data correctly\n worksheet.columns = Object.keys(records[0]).map((key) => ({\n header: key.toUpperCase(),\n key: key,\n width: 20,\n }));\n isHeaderWritten = true;\n }\n\n records.forEach((item) => {\n worksheet.addRow(item).commit(); // Commit each row immediately\n });\n\n chunkIndex++; // Fetch next chunk\n this.logger.debug(`✅ Chunk ${chunkIndex} written to Excel`);\n }\n\n workbook.commit();\n // passThrough.end(); // ✅ Properly close the stream\n } catch (error) {\n this.logger.error(`❌ Error writing Excel: ${error.message}`);\n passThrough.destroy(error); // Destroy stream\n throw error;\n }\n return passThrough; // Return streaming response\n }\n\n public async *readExcelInPagesFromStream(\n stream: Readable,\n options?: ExcelReadOptions\n ): AsyncGenerator<ExcelReadResult> {\n const { pageSize = DEFAULT_PAGE_SIZE, hasHeaderRow = true, providedHeaders = [] } = options || {};\n const workbookReader = new ExcelJS.stream.xlsx.WorkbookReader(stream, {});\n\n let headers: string[] = [];\n let page: Record<string, any>[] = [];\n let isFirstRow = true;\n let hasYieldedData = false;\n\n for await (const worksheet of workbookReader) {\n for await (const row of worksheet) {\n const values = Array.isArray(row.values) ? row.values.slice(1) : [];\n\n if (isFirstRow) {\n isFirstRow = false;\n\n if (hasHeaderRow) {\n headers = values.map(v => v?.toString().trim() || '');\n continue;\n } else if (providedHeaders.length) {\n headers = providedHeaders;\n } else {\n headers = values.map((_, idx) => `${idx}`);\n }\n }\n\n while (values.length < headers.length) values.push(null);\n if (values.length > headers.length) values.length = headers.length;\n\n const record = headers.reduce((acc, key, i) => {\n acc[key] = values[i] ?? null;\n return acc;\n }, {} as Record<string, any>);\n\n if (Object.values(record).every(v => v === null || v === '')) continue;\n\n page.push(record);\n\n if (page.length === pageSize) {\n yield { headers, data: page };\n hasYieldedData = true;\n page = [];\n }\n }\n\n // Optional: break if only processing first worksheet\n // break;\n }\n\n if (page.length > 0) {\n yield { headers, data: page };\n hasYieldedData = true;\n }\n\n // ✅ Yield headers with empty data if only headers were found\n if (!hasYieldedData && headers.length > 0) {\n yield { headers, data: [] };\n }\n }\n\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ingest-metadata.service.d.ts","sourceRoot":"","sources":["../../../src/services/genai/ingest-metadata.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKxD,MAAM,MAAM,kBAAkB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAAC;AAEF,qBACa,qBAAqB;IAK1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,SAAS,CAAY;gBAGR,UAAU,EAAE,gBAAgB;IAajD,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAMZ,MAAM;YAuDE,6BAA6B;YAoC7B,gDAAgD;YAqDhD,6BAA6B;YA8E7B,4BAA4B;IAwG1C,OAAO,CAAC,0BAA0B;YA+NpB,4BAA4B;CA2D7C"}
1
+ {"version":3,"file":"ingest-metadata.service.d.ts","sourceRoot":"","sources":["../../../src/services/genai/ingest-metadata.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAKxD,MAAM,MAAM,kBAAkB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IAGtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAChC,CAAC;AAEF,qBACa,qBAAqB;IAK1B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAJ/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,SAAS,CAAY;gBAGR,UAAU,EAAE,gBAAgB;IAajD,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,UAAU;IAMZ,MAAM;YAyEE,6BAA6B;YAoC7B,gDAAgD;YAqDhD,6BAA6B;YAgF7B,4BAA4B;IA6G1C,OAAO,CAAC,0BAA0B;YA+NpB,4BAA4B;CA4D7C"}