@solidstarters/solid-core 1.2.179 → 1.2.183

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 (166) hide show
  1. package/dev-grooming-docs/ozzy-prompts.txt +28 -3
  2. package/dist/config/iam.config.d.ts.map +1 -1
  3. package/dist/config/iam.config.js +2 -1
  4. package/dist/config/iam.config.js.map +1 -1
  5. package/dist/controllers/service.controller.d.ts +8 -1
  6. package/dist/controllers/service.controller.d.ts.map +1 -1
  7. package/dist/controllers/service.controller.js +38 -2
  8. package/dist/controllers/service.controller.js.map +1 -1
  9. package/dist/decorators/active-user.decorator.d.ts +1 -1
  10. package/dist/dtos/create-menu-item-metadata.dto.d.ts +3 -0
  11. package/dist/dtos/create-menu-item-metadata.dto.d.ts.map +1 -1
  12. package/dist/dtos/create-menu-item-metadata.dto.js +4 -1
  13. package/dist/dtos/create-menu-item-metadata.dto.js.map +1 -1
  14. package/dist/dtos/create-role-metadata.dto.d.ts +4 -0
  15. package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
  16. package/dist/dtos/create-role-metadata.dto.js +45 -1
  17. package/dist/dtos/create-role-metadata.dto.js.map +1 -1
  18. package/dist/helpers/date.helper.d.ts +2 -0
  19. package/dist/helpers/date.helper.d.ts.map +1 -0
  20. package/dist/helpers/date.helper.js +18 -0
  21. package/dist/helpers/date.helper.js.map +1 -0
  22. package/dist/interfaces.d.ts +20 -0
  23. package/dist/interfaces.d.ts.map +1 -1
  24. package/dist/interfaces.js.map +1 -1
  25. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +7 -1
  26. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -1
  27. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +82 -17
  28. package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -1
  29. package/dist/repository/view-metadata.repository.d.ts +1 -0
  30. package/dist/repository/view-metadata.repository.d.ts.map +1 -1
  31. package/dist/repository/view-metadata.repository.js +14 -0
  32. package/dist/repository/view-metadata.repository.js.map +1 -1
  33. package/dist/seeders/module-metadata-seeder.service.d.ts +52 -42
  34. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  35. package/dist/seeders/module-metadata-seeder.service.js +259 -202
  36. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  37. package/dist/seeders/permission-metadata-seeder.service.js +0 -1
  38. package/dist/seeders/permission-metadata-seeder.service.js.map +1 -1
  39. package/dist/seeders/seed-data/solid-core-metadata.json +2 -3
  40. package/dist/services/ai-interaction.service.d.ts +3 -3
  41. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  42. package/dist/services/ai-interaction.service.js +16 -9
  43. package/dist/services/ai-interaction.service.js.map +1 -1
  44. package/dist/services/excel.service.js +2 -2
  45. package/dist/services/excel.service.js.map +1 -1
  46. package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -1
  47. package/dist/services/genai/ingest-metadata.service.js +46 -35
  48. package/dist/services/genai/ingest-metadata.service.js.map +1 -1
  49. package/dist/services/{mcp-tool-response-handlers/mcp-tool-response-handler-factory.service.d.ts → genai/mcp-handlers/mcp-handler-factory.service.d.ts} +3 -3
  50. package/dist/services/genai/mcp-handlers/mcp-handler-factory.service.d.ts.map +1 -0
  51. package/dist/services/{mcp-tool-response-handlers/mcp-tool-response-handler-factory.service.js → genai/mcp-handlers/mcp-handler-factory.service.js} +10 -10
  52. package/dist/services/genai/mcp-handlers/mcp-handler-factory.service.js.map +1 -0
  53. package/dist/services/genai/mcp-handlers/solid-add-fields-to-model-mcp-handler.service.d.ts +12 -0
  54. package/dist/services/genai/mcp-handlers/solid-add-fields-to-model-mcp-handler.service.d.ts.map +1 -0
  55. package/dist/services/{mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-add-fields-to-model-mcp-handler.service.js} +19 -20
  56. package/dist/services/genai/mcp-handlers/solid-add-fields-to-model-mcp-handler.service.js.map +1 -0
  57. package/dist/services/genai/mcp-handlers/solid-create-computed-provider-mcp-handler.service.d.ts +16 -0
  58. package/dist/services/genai/mcp-handlers/solid-create-computed-provider-mcp-handler.service.d.ts.map +1 -0
  59. package/dist/services/genai/mcp-handlers/solid-create-computed-provider-mcp-handler.service.js +75 -0
  60. package/dist/services/genai/mcp-handlers/solid-create-computed-provider-mcp-handler.service.js.map +1 -0
  61. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts → genai/mcp-handlers/solid-create-dashboard-mcp-handler.service.d.ts} +9 -9
  62. package/dist/services/genai/mcp-handlers/solid-create-dashboard-mcp-handler.service.d.ts.map +1 -0
  63. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-dashboard-mcp-handler.service.js} +13 -13
  64. package/dist/services/genai/mcp-handlers/solid-create-dashboard-mcp-handler.service.js.map +1 -0
  65. package/dist/services/genai/mcp-handlers/solid-create-dashboard-question-mcp-handler.service.d.ts +12 -0
  66. package/dist/services/genai/mcp-handlers/solid-create-dashboard-question-mcp-handler.service.d.ts.map +1 -0
  67. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-question-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-dashboard-question-mcp-handler.service.js} +8 -8
  68. package/dist/services/genai/mcp-handlers/solid-create-dashboard-question-mcp-handler.service.js.map +1 -0
  69. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-tool-response-handler.service.d.ts → genai/mcp-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-handler.service.d.ts} +4 -4
  70. package/dist/services/genai/mcp-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-handler.service.d.ts.map +1 -0
  71. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-handler.service.js} +8 -8
  72. package/dist/services/genai/mcp-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-handler.service.js.map +1 -0
  73. package/dist/services/genai/mcp-handlers/solid-create-dashboard-widget-mcp-handler.service.d.ts +12 -0
  74. package/dist/services/genai/mcp-handlers/solid-create-dashboard-widget-mcp-handler.service.d.ts.map +1 -0
  75. package/dist/services/{mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-dashboard-widget-mcp-handler.service.js} +8 -8
  76. package/dist/services/genai/mcp-handlers/solid-create-dashboard-widget-mcp-handler.service.js.map +1 -0
  77. package/dist/services/genai/mcp-handlers/solid-create-model-with-fields-mcp-handler.service.d.ts +14 -0
  78. package/dist/services/genai/mcp-handlers/solid-create-model-with-fields-mcp-handler.service.d.ts.map +1 -0
  79. package/dist/services/{mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-model-with-fields-mcp-handler.service.js} +15 -17
  80. package/dist/services/genai/mcp-handlers/solid-create-model-with-fields-mcp-handler.service.js.map +1 -0
  81. package/dist/services/{mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.d.ts → genai/mcp-handlers/solid-create-module-mcp-handler.service.d.ts} +4 -4
  82. package/dist/services/genai/mcp-handlers/solid-create-module-mcp-handler.service.d.ts.map +1 -0
  83. package/dist/services/{mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-create-module-mcp-handler.service.js} +13 -10
  84. package/dist/services/genai/mcp-handlers/solid-create-module-mcp-handler.service.js.map +1 -0
  85. package/dist/services/{mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts → genai/mcp-handlers/solid-update-layout-mcp-handler.service.d.ts} +3 -3
  86. package/dist/services/genai/mcp-handlers/solid-update-layout-mcp-handler.service.d.ts.map +1 -0
  87. package/dist/services/{mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js → genai/mcp-handlers/solid-update-layout-mcp-handler.service.js} +12 -10
  88. package/dist/services/genai/mcp-handlers/solid-update-layout-mcp-handler.service.js.map +1 -0
  89. package/dist/services/import-transaction.service.d.ts.map +1 -1
  90. package/dist/services/import-transaction.service.js +6 -3
  91. package/dist/services/import-transaction.service.js.map +1 -1
  92. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  93. package/dist/services/menu-item-metadata.service.js +0 -2
  94. package/dist/services/menu-item-metadata.service.js.map +1 -1
  95. package/dist/services/model-metadata.service.d.ts.map +1 -1
  96. package/dist/services/model-metadata.service.js.map +1 -1
  97. package/dist/services/module-metadata.service.d.ts.map +1 -1
  98. package/dist/services/module-metadata.service.js +1 -1
  99. package/dist/services/module-metadata.service.js.map +1 -1
  100. package/dist/services/role-metadata.service.d.ts.map +1 -1
  101. package/dist/services/role-metadata.service.js +1 -7
  102. package/dist/services/role-metadata.service.js.map +1 -1
  103. package/dist/services/solid-ts-morph.service.d.ts +28 -0
  104. package/dist/services/solid-ts-morph.service.d.ts.map +1 -0
  105. package/dist/services/solid-ts-morph.service.js +222 -0
  106. package/dist/services/solid-ts-morph.service.js.map +1 -0
  107. package/dist/solid-core.module.d.ts.map +1 -1
  108. package/dist/solid-core.module.js +22 -18
  109. package/dist/solid-core.module.js.map +1 -1
  110. package/dist/tsconfig.tsbuildinfo +1 -1
  111. package/package.json +7 -4
  112. package/solid_seed_fixes.ts.txt +93 -0
  113. package/src/config/iam.config.ts +2 -1
  114. package/src/controllers/service.controller.ts +43 -2
  115. package/src/dtos/create-menu-item-metadata.dto.ts +5 -1
  116. package/src/dtos/create-role-metadata.dto.ts +60 -1
  117. package/src/helpers/date.helper.ts +13 -0
  118. package/src/interfaces.ts +29 -2
  119. package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +86 -16
  120. package/src/repository/view-metadata.repository.ts +15 -0
  121. package/src/seeders/module-metadata-seeder.service.ts +355 -282
  122. package/src/seeders/permission-metadata-seeder.service.ts +1 -1
  123. package/src/seeders/seed-data/solid-core-metadata.json +3 -5
  124. package/src/services/ai-interaction.service.ts +17 -13
  125. package/src/services/excel.service.ts +2 -2
  126. package/src/services/genai/ingest-metadata.service.ts +115 -39
  127. package/src/services/{mcp-tool-response-handlers/mcp-tool-response-handler-factory.service.ts → genai/mcp-handlers/mcp-handler-factory.service.ts} +5 -5
  128. package/src/services/genai/mcp-handlers/solid-add-fields-to-model-mcp-handler.service.ts +68 -0
  129. package/src/services/genai/mcp-handlers/solid-create-computed-provider-mcp-handler.service.ts +71 -0
  130. package/src/services/{mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-dashboard-mcp-handler.service.ts} +8 -8
  131. package/src/services/{mcp-tool-response-handlers/solid-create-dashboard-question-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-dashboard-question-mcp-handler.service.ts} +3 -3
  132. package/src/services/{mcp-tool-response-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-handler.service.ts} +3 -3
  133. package/src/services/{mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-dashboard-widget-mcp-handler.service.ts} +3 -3
  134. package/src/services/{mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-model-with-fields-mcp-handler.service.ts} +9 -10
  135. package/src/services/{mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-create-module-mcp-handler.service.ts} +8 -5
  136. package/src/services/{mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.ts → genai/mcp-handlers/solid-update-layout-mcp-handler.service.ts} +11 -5
  137. package/src/services/import-transaction.service.ts +12 -4
  138. package/src/services/menu-item-metadata.service.ts +3 -7
  139. package/src/services/model-metadata.service.ts +0 -3
  140. package/src/services/module-metadata.service.ts +2 -3
  141. package/src/services/role-metadata.service.ts +22 -8
  142. package/src/services/solid-ts-morph.service.ts +263 -0
  143. package/src/solid-core.module.ts +25 -19
  144. package/dist/services/mcp-tool-response-handlers/mcp-tool-response-handler-factory.service.d.ts.map +0 -1
  145. package/dist/services/mcp-tool-response-handlers/mcp-tool-response-handler-factory.service.js.map +0 -1
  146. package/dist/services/mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service.d.ts +0 -16
  147. package/dist/services/mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service.d.ts.map +0 -1
  148. package/dist/services/mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service.js.map +0 -1
  149. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts.map +0 -1
  150. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js.map +0 -1
  151. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-question-mcp-tool-response-handler.service.d.ts +0 -12
  152. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-question-mcp-tool-response-handler.service.d.ts.map +0 -1
  153. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-question-mcp-tool-response-handler.service.js.map +0 -1
  154. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-tool-response-handler.service.d.ts.map +0 -1
  155. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-question-sql-dataset-config-mcp-tool-response-handler.service.js.map +0 -1
  156. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service.d.ts +0 -12
  157. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service.d.ts.map +0 -1
  158. package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service.js.map +0 -1
  159. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.d.ts +0 -16
  160. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.d.ts.map +0 -1
  161. package/dist/services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service.js.map +0 -1
  162. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.d.ts.map +0 -1
  163. package/dist/services/mcp-tool-response-handlers/solid-create-module-mcp-tool-response-handler.service.js.map +0 -1
  164. package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts.map +0 -1
  165. package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js.map +0 -1
  166. package/src/services/mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service.ts +0 -56
@@ -25,7 +25,7 @@ export class PermissionMetadataSeederService {
25
25
  for (let id = 0; id < controllers.length; id++) {
26
26
  try {
27
27
  const controller = controllers[id];
28
- this.logger.log(`Resolving controller: ${controller.name}`);
28
+ // this.logger.log(`Resolving controller: ${controller.name}`);
29
29
 
30
30
  const methods = controller.methods;
31
31
  for (let mId = 0; mId < methods.length; mId++) {
@@ -12136,6 +12136,7 @@
12136
12136
  "modelUserKey": "aiInteraction",
12137
12137
  "layout": {
12138
12138
  "type": "form",
12139
+ "edit": false,
12139
12140
  "attrs": {
12140
12141
  "name": "form-1",
12141
12142
  "label": "AI Interaction",
@@ -12203,8 +12204,7 @@
12203
12204
  "type": "field",
12204
12205
  "attrs": {
12205
12206
  "name": "message",
12206
- "editWidget": "textarea",
12207
- "rows": 6
12207
+ "viewWidget": "SolidAiInteractionMessageFieldFormWidget"
12208
12208
  }
12209
12209
  }
12210
12210
  ]
@@ -12296,7 +12296,6 @@
12296
12296
  "type": "field",
12297
12297
  "attrs": {
12298
12298
  "name": "errorMessage",
12299
- "editWidget": "textarea",
12300
12299
  "rows": 5
12301
12300
  }
12302
12301
  }
@@ -12332,8 +12331,7 @@
12332
12331
  "attrs": {
12333
12332
  "name": "metadata",
12334
12333
  "height": "80vh",
12335
- "viewWidget":"SolidAiInteractionMetadataFieldFormWidget"
12336
-
12334
+ "viewWidget": "SolidAiInteractionMetadataFieldFormWidget"
12337
12335
  }
12338
12336
  }
12339
12337
  ]
@@ -14,11 +14,9 @@ import { AiInteraction } from '../entities/ai-interaction.entity';
14
14
  import * as fs from 'fs/promises';
15
15
  import { McpResponse, TriggerMcpClientOptions } from 'src/interfaces';
16
16
  import { PublisherFactory } from './queues/publisher-factory.service';
17
- import { RequestContextService } from './request-context.service';
18
- import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
19
- import { McpToolResponseHandlerFactory } from './mcp-tool-response-handlers/mcp-tool-response-handler-factory.service';
20
17
  import { ERROR_MESSAGES } from 'src/constants/error-messages';
21
18
  import { InvokeAiPromptDto } from 'src/dtos/invoke-ai-prompt.dto';
19
+ import { McpHandlerFactory } from './genai/mcp-handlers/mcp-handler-factory.service';
22
20
 
23
21
  @Injectable()
24
22
  export class AiInteractionService extends CRUDService<AiInteraction> {
@@ -38,7 +36,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
38
36
  readonly moduleRef: ModuleRef,
39
37
  readonly publisherFactory: PublisherFactory<TriggerMcpClientOptions>,
40
38
  // readonly requestContextService: RequestContextService,
41
- readonly mcpToolResponseHandlerFactory: McpToolResponseHandlerFactory,
39
+ readonly mcpHandlerFactory: McpHandlerFactory,
42
40
 
43
41
  ) {
44
42
  super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);
@@ -62,7 +60,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
62
60
  const m = {
63
61
  payload: {
64
62
  aiInteractionId: aiInteraction.id,
65
- moduleName:dto.moduleName
63
+ moduleName: dto.moduleName
66
64
  },
67
65
  parentEntity: 'aiInteraction',
68
66
  parentEntityId: aiInteraction.id,
@@ -149,7 +147,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
149
147
  }
150
148
  catch (ex) {
151
149
  this.logger.warn(`Attempting to parse mcp client response assuming it is JSON, however it is not: ${parsedResponse}`);
152
- raw.success = false
150
+ // raw.success = false
153
151
  }
154
152
  // Parse the response string into an object
155
153
  // const parsedResponse = JSON.parse(raw.response);
@@ -204,16 +202,22 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
204
202
  }
205
203
 
206
204
  // TODO: Validation: Check if JSON.parse(metadata).tools_invoked starts with solid_
207
- let metadata = {};
205
+ let metadata: any = {};
208
206
  try {
209
- metadata = JSON.parse(aiInteraction.metadata);
210
- }
211
- catch (e) {
207
+ if (typeof aiInteraction.metadata === "string") {
208
+ metadata = JSON.parse(aiInteraction.metadata);
209
+ } else if (typeof aiInteraction.metadata === "object" && aiInteraction.metadata !== null) {
210
+ metadata = aiInteraction.metadata;
211
+ } else {
212
+ // optional fallback
213
+ metadata = {};
214
+ }
215
+ } catch (e) {
212
216
  // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....
213
- throw new Error(e);
217
+ throw new Error(`Invalid metadata JSON: ${e}`);
214
218
  }
215
219
 
216
- const toolsInvoked = metadata['tools_invoked'];
220
+ const toolsInvoked = metadata['toolsInvoked'];
217
221
  if (!toolsInvoked) {
218
222
  // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....
219
223
  throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_SOLID_COMMAND);
@@ -224,7 +228,7 @@ export class AiInteractionService extends CRUDService<AiInteraction> {
224
228
 
225
229
  // TODO: use the toolInvoked to identify a service using some convention.
226
230
  // TODO: Eg. if toolInvoked is solid_create_module <> SolidCreateModuleMcpToolHandler ... create a factory class to do this mapping and identify the relevant provider.
227
- const mcpToolHandler = this.mcpToolResponseHandlerFactory.getInstance(toolInvoked);
231
+ const mcpToolHandler = this.mcpHandlerFactory.getInstance(toolInvoked);
228
232
  if (!mcpToolHandler) {
229
233
  // TODO: RESPONSE SHAPE ALERT Check if we want to control the shape of the response....
230
234
  throw new Error(ERROR_MESSAGES.UNABLE_TO_RESOLVE_MCP_HANDLER);
@@ -59,7 +59,7 @@ export class ExcelService {
59
59
  // headers.reduce((acc, header) => ({ ...acc, [header]: '' }), {})
60
60
  // ).commit(); // Write a dummy record with headers
61
61
 
62
- await workbook.commit();
62
+ workbook.commit();
63
63
  return passThrough;
64
64
  }
65
65
 
@@ -86,7 +86,7 @@ export class ExcelService {
86
86
  this.logger.debug(`✅ Chunk ${chunkIndex} written to Excel`);
87
87
  }
88
88
 
89
- await workbook.commit();
89
+ workbook.commit();
90
90
  // passThrough.end(); // ✅ Properly close the stream
91
91
  } catch (error) {
92
92
  this.logger.error(`❌ Error writing Excel: ${error.message}`);
@@ -123,6 +123,20 @@ export class IngestMetadataService {
123
123
  // Delete and re-insert a document representing the full json...
124
124
  // await this.deleteInsertRagDocumentForModuleMetadataJsonFile(ingestionInfo, fullPath, fileName)
125
125
 
126
+ // Delete all metadata chunks.
127
+ // const collectionName = `${enabledModule}-rag-collection`;
128
+ // const deleteResult = await this.ragClient.documents.deleteByFilter({
129
+ // filters: {
130
+ // // AND semantics across fields:
131
+ // "$and": [
132
+ // { 'metadata.kind': { $eq: 'solidx-metadata' } },
133
+ // { 'metadata.collectionName': { $eq: collectionName } },
134
+ // { 'title': { $like: '%Ingested Chunks%' } },
135
+ // ]
136
+ // },
137
+ // });
138
+ // this.logger.log(`Deleted existing documents for collectionName: ${collectionName}. Got response:`, deleteResult);
139
+
126
140
  // Delete and re-insert a chunk representing the module.
127
141
  await this.deleteInsertRagChunkForModule(ingestionInfo, moduleMetadata);
128
142
 
@@ -160,37 +174,52 @@ export class IngestMetadataService {
160
174
  private async resolveRagCollectionForModule(ingestionInfo: ModuleRAGIngestionInfo, moduleName: string): Promise<string> {
161
175
  this.logger.debug(`Resolving RAG collection for module: ${moduleName}`);
162
176
 
163
- let existingCollection: CollectionResponse = null;
164
- if (ingestionInfo.collectionId) {
165
- // See if collection already exists...
166
- const r = await this.ragClient.collections.list({
167
- ids: [
168
- ingestionInfo.collectionId
169
- ]
170
- });
171
-
172
- if (r) {
173
- if (r.results.length === 1) {
174
- existingCollection = r.results[0];
175
- }
176
- if (r.results.length > 1) {
177
- // TODO: do something that will print a meaningful error on the console...
178
- }
179
- }
180
- }
181
-
182
- if (!existingCollection) {
183
- const r = await this.ragClient.collections.create({
184
- name: `${moduleName}-rag-collection`,
185
- description: `Collection created to group all documents, chunks related to module: ${moduleName}`
186
- });
177
+ const collectionName = `${moduleName}-rag-collection`;
187
178
 
188
- // TODO: for some reason if we are unable to create a collection then fail with a visible error message in the console...
179
+ // delete and recreate
180
+ // if (alwaysRecreate === true) {
181
+ const existingCollection = await this.ragClient.collections.retrieveByName({
182
+ name: collectionName
183
+ });
189
184
 
190
- return r.results.id;
185
+ if (existingCollection) {
186
+ try {
187
+ await this.ragClient.collections.delete({ id: existingCollection.results.id });
188
+ } catch (e) {
189
+ this.logger.warn(`[Warn] Failed deleteByFilter for collection': ${String(e)}`);
190
+ }
191
191
  }
192
+ // }
193
+
194
+ // let existingCollection: CollectionResponse = null;
195
+ // if (ingestionInfo.collectionId) {
196
+ // // See if collection already exists...
197
+ // const r = await this.ragClient.collections.list({
198
+ // ids: [
199
+ // ingestionInfo.collectionId
200
+ // ]
201
+ // });
202
+
203
+ // if (r) {
204
+ // if (r.results.length === 1) {
205
+ // existingCollection = r.results[0];
206
+ // }
207
+ // if (r.results.length > 1) {
208
+ // // TODO: do something that will print a meaningful error on the console...
209
+ // }
210
+ // }
211
+ // }
212
+
213
+ // if (!existingCollection) {
214
+ const r = await this.ragClient.collections.create({
215
+ name: collectionName,
216
+ description: `Collection created to group all documents, chunks related to module: ${moduleName}`
217
+ });
192
218
 
193
- return existingCollection.id;
219
+ // TODO: for some reason if we are unable to create a collection then fail with a visible error message in the console...
220
+ return r.results.id;
221
+ // }
222
+ // return existingCollection.id;
194
223
  }
195
224
 
196
225
  private async deleteInsertRagDocumentForModuleMetadataJsonFile(ingestionInfo: ModuleRAGIngestionInfo, fullPath: string, fileName: string): Promise<void> {
@@ -298,12 +327,35 @@ Usage: Use this chunk to choose the correct model/field chunks for code generati
298
327
  };
299
328
 
300
329
  // Delete previous chunk if we have one
301
- if (ingestionInfo.moduleChunkId) {
302
- try {
303
- await this.ragClient.documents.delete({ id: ingestionInfo.moduleChunkId });
304
- } catch (e) {
305
- this.logger.warn(`[Warn] Failed deleting old module chunk (${ingestionInfo.moduleChunkId}): ${String(e)}`);
306
- }
330
+ // if (ingestionInfo.moduleChunkId) {
331
+ // try {
332
+ // await this.ragClient.documents.delete({ id: ingestionInfo.moduleChunkId });
333
+ // } catch (e) {
334
+ // this.logger.warn(`[Warn] Failed deleting old module chunk (${ingestionInfo.moduleChunkId}): ${String(e)}`);
335
+ // }
336
+ // }
337
+
338
+ // We changed the approach to delete and re-create using metadata.
339
+ // delete any existing module records by metadata (idempotent)
340
+ try {
341
+ const deleteResult = await this.ragClient.documents.deleteByFilter({
342
+ filters: {
343
+ // AND semantics across fields:
344
+ "$and": [
345
+ { 'metadata.kind': { $eq: 'solidx-metadata' } },
346
+ { 'metadata.type': { $eq: 'module' } },
347
+ { 'metadata.moduleName': { $eq: moduleName } },
348
+ // (optional but nice to constrain tightly if you always set it)
349
+ { 'metadata.collectionName': { $eq: `${moduleName}-rag-collection` } },
350
+ ]
351
+ },
352
+ });
353
+
354
+ this.logger.log(`Deleted existing module document for moduleName: ${moduleName}. Got response:`, deleteResult);
355
+
356
+ } catch (e) {
357
+ this.logger.warn(`[Warn] Failed deleteByFilter for module '${moduleName}': ${String(e)}`);
358
+ // Non-fatal: we can still proceed to create; caller’s auth will limit scope anyway
307
359
  }
308
360
 
309
361
  const r = await this.ragClient.documents.create({
@@ -407,12 +459,36 @@ ${JSON.stringify(model)}
407
459
  };
408
460
 
409
461
  // 5) Delete previous chunk if present
410
- if (modelEntry.modelChunkId) {
411
- try {
412
- await this.ragClient.documents.delete({ id: modelEntry.modelChunkId });
413
- } catch (e) {
414
- this.logger.warn(`[Warn] Failed deleting old model chunk (${modelEntry.modelChunkId}): ${String(e)}`);
415
- }
462
+ // if (modelEntry.modelChunkId) {
463
+ // try {
464
+ // await this.ragClient.documents.delete({ id: modelEntry.modelChunkId });
465
+ // } catch (e) {
466
+ // this.logger.warn(`[Warn] Failed deleting old model chunk (${modelEntry.modelChunkId}): ${String(e)}`);
467
+ // }
468
+ // }
469
+
470
+ // We changed the approach to delete and re-create using metadata.
471
+ // delete any existing module records by metadata (idempotent)
472
+ try {
473
+ const deleteResult = await this.ragClient.documents.deleteByFilter({
474
+ filters: {
475
+ // AND semantics across fields:
476
+ "$and": [
477
+ { 'metadata.kind': { $eq: 'solidx-metadata' } },
478
+ { 'metadata.type': { $eq: 'model' } },
479
+ { 'metadata.moduleName': { $eq: moduleName } },
480
+ { 'metadata.modelName': { $eq: modelName } },
481
+ // (optional but nice to constrain tightly if you always set it)
482
+ { 'metadata.collectionName': { $eq: `${moduleName}-rag-collection` } },
483
+ ]
484
+ },
485
+ });
486
+
487
+ this.logger.log(`Deleted existing model document for modelName: ${modelName}. Got response:`, deleteResult);
488
+
489
+ } catch (e) {
490
+ this.logger.warn(`[Warn] Failed deleteByFilter for module '${moduleName}': ${String(e)}`);
491
+ // Non-fatal: we can still proceed to create; caller’s auth will limit scope anyway
416
492
  }
417
493
 
418
494
  // 6) Create new document (R2R auto-generates the ID)
@@ -2,12 +2,12 @@ import { Injectable, Logger } from '@nestjs/common';
2
2
 
3
3
  import { classify } from '@angular-devkit/core/src/utils/strings';
4
4
  import { IMcpToolResponseHandler } from 'src/interfaces';
5
- import { SolidIntrospectService } from '../solid-introspect.service';
5
+ import { SolidIntrospectService } from '../../solid-introspect.service';
6
6
 
7
7
 
8
8
  @Injectable()
9
- export class McpToolResponseHandlerFactory {
10
- private readonly logger = new Logger(McpToolResponseHandlerFactory.name);
9
+ export class McpHandlerFactory {
10
+ private readonly logger = new Logger(McpHandlerFactory.name);
11
11
 
12
12
  constructor(
13
13
  private readonly solidIntrospectionService: SolidIntrospectService
@@ -17,9 +17,9 @@ export class McpToolResponseHandlerFactory {
17
17
  getInstance(toolInvoked: string): IMcpToolResponseHandler {
18
18
  toolInvoked = classify(toolInvoked);
19
19
 
20
- let resolvedHandlerName = `${toolInvoked}McpToolResponseHandler`;
20
+ let resolvedHandlerName = `${toolInvoked}McpHandler`;
21
21
 
22
- // Register all ISolidDatabaseModules implementations
22
+ // Get hold of the tool response handler instance using the tool name used.
23
23
  let actualHandler = this.solidIntrospectionService.getProvider(resolvedHandlerName);
24
24
  if (!actualHandler) {
25
25
  throw new Error(`Unable to locate mcp tool handler with name ${resolvedHandlerName}`);
@@ -0,0 +1,68 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { UpdateModelMetaDataDto } from "src/dtos/update-model-metadata.dto";
3
+ import { AiInteraction } from "src/entities/ai-interaction.entity";
4
+ import { FieldMetadata } from "src/entities/field-metadata.entity";
5
+ import { IMcpToolResponseHandler } from "../../../interfaces";
6
+ import { ModelMetadataService } from "../../model-metadata.service";
7
+
8
+ @Injectable()
9
+ // solid_add_field
10
+ export class SolidAddFieldsToModelMcpHandler implements IMcpToolResponseHandler {
11
+
12
+ constructor(
13
+ private readonly modelMetadataService: ModelMetadataService,
14
+ ) {
15
+ }
16
+
17
+ async apply(aiInteraction: AiInteraction) {
18
+ // const aiResponse = JSON.parse(aiInteraction.message);
19
+ const escapedMessage = aiInteraction.message.replace(/\\'/g, "'");
20
+ const aiResponseMessage = JSON.parse(escapedMessage);
21
+
22
+ // {
23
+ // "generation_status": "success",
24
+ // "instructions": "<optional string>",
25
+ // "data": {
26
+ // "modelUserKey": "<existing model name>",
27
+ // "schemaPatch": {
28
+ // "fieldsToAdd": [
29
+ // <json representing each of the fields to be added>
30
+ // ]
31
+ // }
32
+ // }
33
+ // }
34
+ // const { modelUserKey, fieldSchema } = aiResponseMessage;
35
+ const { data } = aiResponseMessage;
36
+ const { modelUserKey, schemaPatch } = data;
37
+ const { fieldsToAdd } = schemaPatch;
38
+
39
+ // TODO: Validate if another field with same name exists, if it does then raise an error...
40
+
41
+ // TODO: load the model with the fields.
42
+ const modelMetadata = await this.modelMetadataService.findOneByUserKey(modelUserKey, ['fields']);
43
+ if (!modelMetadata) {
44
+ throw new Error(`Model with user key ${modelUserKey} not found.`);
45
+ }
46
+
47
+ for (let i = 0; i < fieldsToAdd.length; i++) {
48
+ const fieldSchema = fieldsToAdd[i];
49
+
50
+ // Add the fieldSchema to the model fields array
51
+ fieldSchema['modelId'] = modelMetadata.id;
52
+ modelMetadata.fields.push(fieldSchema as FieldMetadata);
53
+ }
54
+
55
+ // This adds the field to the respective model metadat...
56
+ await this.modelMetadataService.update(modelMetadata.id, modelMetadata as unknown as UpdateModelMetaDataDto);
57
+
58
+ // Now we need to run solid seed & then solid refresh-model --name <module-name>
59
+ await this.modelMetadataService.handleGenerateCode({ modelId: modelMetadata.id });
60
+
61
+ // TODO: decide on some shape to return hre...
62
+ return {
63
+ seedingRequired: true,
64
+ serverRebooting: true,
65
+ }
66
+ }
67
+
68
+ }
@@ -0,0 +1,71 @@
1
+ import { Injectable, Logger } from "@nestjs/common";
2
+ import { AiInteraction } from "src/entities/ai-interaction.entity";
3
+ import { IMcpToolResponseHandler, McpComputedProviderResponse, PlanStep } from "../../../interfaces";
4
+ import { SolidTsMorphService } from "src/services/solid-ts-morph.service";
5
+
6
+ const RESTART_TOUCH_FILE = process.env.MCP_RESTART_TOUCH_FILE || "tmp/restart.touch";
7
+
8
+ @Injectable()
9
+ export class SolidCreateComputedProviderMcpHandler implements IMcpToolResponseHandler {
10
+ private readonly logger = new Logger(SolidCreateComputedProviderMcpHandler.name);
11
+
12
+ constructor(private readonly tsMorph: SolidTsMorphService) { }
13
+
14
+ async apply(aiInteraction: AiInteraction) {
15
+ const raw = this.safeParse(aiInteraction.message);
16
+ const payload: McpComputedProviderResponse | undefined = (raw?.data?.plan ? raw.data : raw) as McpComputedProviderResponse;
17
+
18
+ if (!payload || !Array.isArray(payload.plan)) {
19
+ throw new Error("SolidCreateComputedProviderMcpHandler: invalid MCP response; missing plan[]");
20
+ }
21
+
22
+ // Batch all plan steps in a single txn so nodemon restarts only once.
23
+ this.tsMorph.begin();
24
+ try {
25
+ for (const step of payload.plan as PlanStep[]) {
26
+ switch (step.type) {
27
+ case "createNewFile": {
28
+ const overwrite = step.overwrite ?? false;
29
+ this.tsMorph.createNewFile(step.path, step.content, overwrite);
30
+ break;
31
+ }
32
+ case "registerNestProvider": {
33
+ const uniqueGuard = step.uniqueGuard ?? true;
34
+ this.tsMorph.registerNestProvider(
35
+ step.modulePath,
36
+ step.providerClassName,
37
+ step.importFrom,
38
+ step.registerIn,
39
+ uniqueGuard,
40
+ );
41
+ break;
42
+ }
43
+ default:
44
+ throw new Error(`Unsupported plan step type: ${(step as any).type}`);
45
+ }
46
+ }
47
+
48
+ const result = await this.tsMorph.commit();
49
+
50
+ return {
51
+ seedingRequired: false,
52
+ serverRebooting: false,
53
+ appliedSteps: payload.plan.length,
54
+ wroteFiles: result.wrote,
55
+ };
56
+ } catch (err) {
57
+ this.logger.error(`Apply failed; rolling back. ${String(err)}`);
58
+ this.tsMorph.rollback();
59
+ throw err;
60
+ }
61
+ }
62
+
63
+ private safeParse(str: string): any {
64
+ try {
65
+ return JSON.parse(str);
66
+ } catch {
67
+ const unescaped = str.replace(/\\'/g, "'");
68
+ return JSON.parse(unescaped);
69
+ }
70
+ }
71
+ }
@@ -4,16 +4,16 @@ import { CreateDashboardDto } from "src/dtos/create-dashboard.dto";
4
4
  import { UpdateMenuItemMetadataDto } from "src/dtos/update-menu-item-metadata.dto";
5
5
  import { AiInteraction } from "src/entities/ai-interaction.entity";
6
6
  import { Dashboard } from "src/entities/dashboard.entity";
7
- import { IMcpToolResponseHandler } from "../../interfaces";
8
- import { ActionMetadataService } from "../action-metadata.service";
9
- import { DashboardService } from "../dashboard.service";
10
- import { MenuItemMetadataService } from "../menu-item-metadata.service";
11
- import { ModelMetadataService } from "../model-metadata.service";
12
- import { ModuleMetadataService } from "../module-metadata.service";
13
- import { RoleMetadataService } from "../role-metadata.service";
7
+ import { IMcpToolResponseHandler } from "../../../interfaces";
8
+ import { ActionMetadataService } from "../../action-metadata.service";
9
+ import { DashboardService } from "../../dashboard.service";
10
+ import { MenuItemMetadataService } from "../../menu-item-metadata.service";
11
+ import { ModelMetadataService } from "../../model-metadata.service";
12
+ import { ModuleMetadataService } from "../../module-metadata.service";
13
+ import { RoleMetadataService } from "../../role-metadata.service";
14
14
 
15
15
  @Injectable()
16
- export class SolidCreateDashboardMcpToolResponseHandler implements IMcpToolResponseHandler {
16
+ export class SolidCreateDashboardMcpHandler implements IMcpToolResponseHandler {
17
17
 
18
18
  constructor(
19
19
  private readonly dashboardService: DashboardService,
@@ -2,11 +2,11 @@ import { Injectable } from "@nestjs/common";
2
2
  import { plainToInstance } from "class-transformer";
3
3
  import { CreateDashboardQuestionDto } from "src/dtos/create-dashboard-question.dto";
4
4
  import { AiInteraction } from "src/entities/ai-interaction.entity";
5
- import { IMcpToolResponseHandler } from "../../interfaces";
6
- import { DashboardQuestionService } from "../dashboard-question.service";
5
+ import { IMcpToolResponseHandler } from "../../../interfaces";
6
+ import { DashboardQuestionService } from "../../dashboard-question.service";
7
7
 
8
8
  @Injectable()
9
- export class SolidCreateDashboardQuestionMcpToolResponseHandler implements IMcpToolResponseHandler {
9
+ export class SolidCreateDashboardQuestionMcpHandler implements IMcpToolResponseHandler {
10
10
 
11
11
  constructor(
12
12
  private readonly dashboardQuestionService: DashboardQuestionService,
@@ -1,12 +1,12 @@
1
1
  import { Injectable } from "@nestjs/common";
2
2
  import { plainToInstance } from "class-transformer";
3
3
  import { AiInteraction } from "src/entities/ai-interaction.entity";
4
- import { IMcpToolResponseHandler } from "../../interfaces";
5
- import { DashboardQuestionSqlDatasetConfigService } from "../dashboard-question-sql-dataset-config.service";
4
+ import { IMcpToolResponseHandler } from "../../../interfaces";
5
+ import { DashboardQuestionSqlDatasetConfigService } from "../../dashboard-question-sql-dataset-config.service";
6
6
  import { CreateDashboardQuestionSqlDatasetConfigDto } from "src/dtos/create-dashboard-question-sql-dataset-config.dto";
7
7
 
8
8
  @Injectable()
9
- export class SolidCreateDashboardQuestionSqlDatasetConfigMcpToolResponseHandler implements IMcpToolResponseHandler {
9
+ export class SolidCreateDashboardQuestionSqlDatasetConfigMcpHandler implements IMcpToolResponseHandler {
10
10
 
11
11
  constructor(
12
12
  private readonly dashboardQuestionSqlDatasetConfigService: DashboardQuestionSqlDatasetConfigService,
@@ -2,11 +2,11 @@ import { Injectable } from "@nestjs/common";
2
2
  import { plainToInstance } from "class-transformer";
3
3
  import { CreateDashboardQuestionDto } from "src/dtos/create-dashboard-question.dto";
4
4
  import { AiInteraction } from "src/entities/ai-interaction.entity";
5
- import { IMcpToolResponseHandler } from "../../interfaces";
6
- import { DashboardQuestionService } from "../dashboard-question.service";
5
+ import { IMcpToolResponseHandler } from "../../../interfaces";
6
+ import { DashboardQuestionService } from "../../dashboard-question.service";
7
7
 
8
8
  @Injectable()
9
- export class SolidCreateDashboardWidgetMcpToolResponseHandler implements IMcpToolResponseHandler {
9
+ export class SolidCreateDashboardWidgetMcpHandler implements IMcpToolResponseHandler {
10
10
 
11
11
  constructor(
12
12
  private readonly dashboardQuestionService: DashboardQuestionService,
@@ -1,37 +1,36 @@
1
1
  import { Injectable } from "@nestjs/common";
2
- import { IMcpToolResponseHandler } from "../../interfaces";
2
+ import { IMcpToolResponseHandler } from "../../../interfaces";
3
3
  import { AiInteraction } from "src/entities/ai-interaction.entity";
4
- import { SolidRegistry } from "src/helpers/solid-registry";
5
- import { ModelMetadataService } from "../model-metadata.service";
4
+ import { ModelMetadataService } from "../../model-metadata.service";
6
5
  import { CreateModelMetadataDto } from "src/dtos/create-model-metadata.dto";
7
- import { ModuleMetadataService } from "../module-metadata.service";
6
+ import { ModuleMetadataService } from "../../module-metadata.service";
8
7
 
9
8
  @Injectable()
10
- export class SolidCreateModelWithFieldsMcpToolResponseHandler implements IMcpToolResponseHandler {
9
+ export class SolidCreateModelWithFieldsMcpHandler implements IMcpToolResponseHandler {
11
10
 
12
11
  constructor(
13
12
  private readonly moduleMetadataService: ModuleMetadataService,
14
13
  private readonly modelMetadataService: ModelMetadataService,
15
- private readonly solidRegistry: SolidRegistry,
16
14
  ) {
17
15
  }
18
16
 
19
17
  async apply(aiInteraction: AiInteraction) {
20
18
  // const aiResponse = JSON.parse(aiInteraction.message);
21
19
  const escapedMessage = aiInteraction.message.replace(/\\'/g, "'");
22
- const aiResponse = JSON.parse(escapedMessage);
20
+ const aiResponseMessage = JSON.parse(escapedMessage);
23
21
 
24
- const { moduleUserKey, modelSchema } = aiResponse;
22
+ const { generation_status, instructions, data } = aiResponseMessage;
23
+ const { moduleUserKey, schema } = data;
25
24
  const moduleMetadata = await this.moduleMetadataService.findOneByUserKey(moduleUserKey);
26
25
  if (!moduleMetadata) {
27
26
  throw new Error(`Module with user key ${moduleUserKey} not found.`);
28
27
  }
29
- modelSchema['moduleId'] = moduleMetadata.id;
28
+ schema['moduleId'] = moduleMetadata.id;
30
29
 
31
30
  // TODO: Validate if another model with same name exists, if it does then raise an error...
32
31
 
33
32
  // This creates the module-metadata.json file....
34
- const modelObj = await this.modelMetadataService.create(modelSchema as CreateModelMetadataDto);
33
+ const modelObj = await this.modelMetadataService.create(schema as CreateModelMetadataDto);
35
34
 
36
35
  // Now we need to run solid seed & then solid refresh-model --name <module-name>
37
36
  await this.modelMetadataService.handleGenerateCode({ modelId: modelObj.id });
@@ -1,12 +1,12 @@
1
1
  import { Injectable } from "@nestjs/common";
2
- import { IMcpToolResponseHandler } from "../../interfaces";
2
+ import { IMcpToolResponseHandler } from "../../../interfaces";
3
3
  import { AiInteraction } from "src/entities/ai-interaction.entity";
4
- import { ModuleMetadataService } from "../module-metadata.service";
4
+ import { ModuleMetadataService } from "../../module-metadata.service";
5
5
  import { CreateModuleMetadataDto } from "src/dtos/create-module-metadata.dto";
6
6
  import { SolidRegistry } from "src/helpers/solid-registry";
7
7
 
8
8
  @Injectable()
9
- export class SolidCreateModuleMcpToolResponseHandler implements IMcpToolResponseHandler {
9
+ export class SolidCreateModuleMcpHandler implements IMcpToolResponseHandler {
10
10
 
11
11
  constructor(
12
12
  private readonly moduleMetadataService: ModuleMetadataService,
@@ -16,9 +16,12 @@ export class SolidCreateModuleMcpToolResponseHandler implements IMcpToolResponse
16
16
  }
17
17
 
18
18
  async apply(aiInteraction: AiInteraction) {
19
- const aiResponse = JSON.parse(aiInteraction.message);
19
+ const escapedMessage = aiInteraction.message.replace(/\\'/g, "'");
20
+ const aiResponseMessage = JSON.parse(escapedMessage);
20
21
 
21
- const moduleMetadata = aiResponse?.data?.moduleMetadata ?? {};
22
+ const { generation_status, instructions, data } = aiResponseMessage;
23
+ const { schema } = data;
24
+ const { moduleMetadata } = schema;
22
25
 
23
26
  // TODO: Validate if another module with same name exists, if it does then raise an error...
24
27