@nexus-ai-nexoralabs/cli 0.1.0

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 (411) hide show
  1. package/.env.example +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +106 -0
  4. package/dist/api/index.d.ts +81 -0
  5. package/dist/api/index.d.ts.map +1 -0
  6. package/dist/api/index.js +224 -0
  7. package/dist/api/index.js.map +1 -0
  8. package/dist/chat/chatService.d.ts +49 -0
  9. package/dist/chat/chatService.d.ts.map +1 -0
  10. package/dist/chat/chatService.js +163 -0
  11. package/dist/chat/chatService.js.map +1 -0
  12. package/dist/chat/contextBuilder.d.ts +19 -0
  13. package/dist/chat/contextBuilder.d.ts.map +1 -0
  14. package/dist/chat/contextBuilder.js +43 -0
  15. package/dist/chat/contextBuilder.js.map +1 -0
  16. package/dist/chat/conversationService.d.ts +25 -0
  17. package/dist/chat/conversationService.d.ts.map +1 -0
  18. package/dist/chat/conversationService.js +55 -0
  19. package/dist/chat/conversationService.js.map +1 -0
  20. package/dist/chat/index.d.ts +6 -0
  21. package/dist/chat/index.d.ts.map +1 -0
  22. package/dist/chat/index.js +6 -0
  23. package/dist/chat/index.js.map +1 -0
  24. package/dist/chat/messageService.d.ts +18 -0
  25. package/dist/chat/messageService.d.ts.map +1 -0
  26. package/dist/chat/messageService.js +26 -0
  27. package/dist/chat/messageService.js.map +1 -0
  28. package/dist/chat/promptTemplates.d.ts +19 -0
  29. package/dist/chat/promptTemplates.d.ts.map +1 -0
  30. package/dist/chat/promptTemplates.js +32 -0
  31. package/dist/chat/promptTemplates.js.map +1 -0
  32. package/dist/cli/agentRunner.d.ts +126 -0
  33. package/dist/cli/agentRunner.d.ts.map +1 -0
  34. package/dist/cli/agentRunner.js +892 -0
  35. package/dist/cli/agentRunner.js.map +1 -0
  36. package/dist/cli/bin.d.ts +14 -0
  37. package/dist/cli/bin.d.ts.map +1 -0
  38. package/dist/cli/bin.js +20 -0
  39. package/dist/cli/bin.js.map +1 -0
  40. package/dist/cli/index.d.ts +3 -0
  41. package/dist/cli/index.d.ts.map +1 -0
  42. package/dist/cli/index.js +2 -0
  43. package/dist/cli/index.js.map +1 -0
  44. package/dist/cli/inputEngine.d.ts +76 -0
  45. package/dist/cli/inputEngine.d.ts.map +1 -0
  46. package/dist/cli/inputEngine.js +281 -0
  47. package/dist/cli/inputEngine.js.map +1 -0
  48. package/dist/cli/main.d.ts +9 -0
  49. package/dist/cli/main.d.ts.map +1 -0
  50. package/dist/cli/main.js +144 -0
  51. package/dist/cli/main.js.map +1 -0
  52. package/dist/cli/uiFormatters.d.ts +108 -0
  53. package/dist/cli/uiFormatters.d.ts.map +1 -0
  54. package/dist/cli/uiFormatters.js +925 -0
  55. package/dist/cli/uiFormatters.js.map +1 -0
  56. package/dist/common/logger.d.ts +13 -0
  57. package/dist/common/logger.d.ts.map +1 -0
  58. package/dist/common/logger.js +43 -0
  59. package/dist/common/logger.js.map +1 -0
  60. package/dist/config/firstRunHealthCheck.d.ts +50 -0
  61. package/dist/config/firstRunHealthCheck.d.ts.map +1 -0
  62. package/dist/config/firstRunHealthCheck.js +196 -0
  63. package/dist/config/firstRunHealthCheck.js.map +1 -0
  64. package/dist/config/firstRunService.d.ts +53 -0
  65. package/dist/config/firstRunService.d.ts.map +1 -0
  66. package/dist/config/firstRunService.js +93 -0
  67. package/dist/config/firstRunService.js.map +1 -0
  68. package/dist/config/index.d.ts +30 -0
  69. package/dist/config/index.d.ts.map +1 -0
  70. package/dist/config/index.js +65 -0
  71. package/dist/config/index.js.map +1 -0
  72. package/dist/config/productionPaths.d.ts +34 -0
  73. package/dist/config/productionPaths.d.ts.map +1 -0
  74. package/dist/config/productionPaths.js +95 -0
  75. package/dist/config/productionPaths.js.map +1 -0
  76. package/dist/config/workspaceService.d.ts +42 -0
  77. package/dist/config/workspaceService.d.ts.map +1 -0
  78. package/dist/config/workspaceService.js +218 -0
  79. package/dist/config/workspaceService.js.map +1 -0
  80. package/dist/desktop/appWindow.d.ts +21 -0
  81. package/dist/desktop/appWindow.d.ts.map +1 -0
  82. package/dist/desktop/appWindow.js +77 -0
  83. package/dist/desktop/appWindow.js.map +1 -0
  84. package/dist/desktop/main.d.ts +14 -0
  85. package/dist/desktop/main.d.ts.map +1 -0
  86. package/dist/desktop/main.js +90 -0
  87. package/dist/desktop/main.js.map +1 -0
  88. package/dist/desktop/preload.d.ts +14 -0
  89. package/dist/desktop/preload.d.ts.map +1 -0
  90. package/dist/desktop/preload.js +20 -0
  91. package/dist/desktop/preload.js.map +1 -0
  92. package/dist/intelligence/index.d.ts +33 -0
  93. package/dist/intelligence/index.d.ts.map +1 -0
  94. package/dist/intelligence/index.js +82 -0
  95. package/dist/intelligence/index.js.map +1 -0
  96. package/dist/intelligence/modelGateway.d.ts +35 -0
  97. package/dist/intelligence/modelGateway.d.ts.map +1 -0
  98. package/dist/intelligence/modelGateway.js +123 -0
  99. package/dist/intelligence/modelGateway.js.map +1 -0
  100. package/dist/intelligence/modelRegistry.d.ts +17 -0
  101. package/dist/intelligence/modelRegistry.d.ts.map +1 -0
  102. package/dist/intelligence/modelRegistry.js +87 -0
  103. package/dist/intelligence/modelRegistry.js.map +1 -0
  104. package/dist/intelligence/modelRouter.d.ts +76 -0
  105. package/dist/intelligence/modelRouter.d.ts.map +1 -0
  106. package/dist/intelligence/modelRouter.js +256 -0
  107. package/dist/intelligence/modelRouter.js.map +1 -0
  108. package/dist/intelligence/ollamaAdapter.d.ts +49 -0
  109. package/dist/intelligence/ollamaAdapter.d.ts.map +1 -0
  110. package/dist/intelligence/ollamaAdapter.js +197 -0
  111. package/dist/intelligence/ollamaAdapter.js.map +1 -0
  112. package/dist/intelligence/prototype/runPrototype.d.ts +14 -0
  113. package/dist/intelligence/prototype/runPrototype.d.ts.map +1 -0
  114. package/dist/intelligence/prototype/runPrototype.js +87 -0
  115. package/dist/intelligence/prototype/runPrototype.js.map +1 -0
  116. package/dist/intelligence/providers/embeddedInferenceProvider.d.ts +29 -0
  117. package/dist/intelligence/providers/embeddedInferenceProvider.d.ts.map +1 -0
  118. package/dist/intelligence/providers/embeddedInferenceProvider.js +162 -0
  119. package/dist/intelligence/providers/embeddedInferenceProvider.js.map +1 -0
  120. package/dist/intelligence/providers/index.d.ts +4 -0
  121. package/dist/intelligence/providers/index.d.ts.map +1 -0
  122. package/dist/intelligence/providers/index.js +4 -0
  123. package/dist/intelligence/providers/index.js.map +1 -0
  124. package/dist/intelligence/providers/inferenceProvider.d.ts +98 -0
  125. package/dist/intelligence/providers/inferenceProvider.d.ts.map +1 -0
  126. package/dist/intelligence/providers/inferenceProvider.js +9 -0
  127. package/dist/intelligence/providers/inferenceProvider.js.map +1 -0
  128. package/dist/intelligence/providers/ollamaInferenceProvider.d.ts +17 -0
  129. package/dist/intelligence/providers/ollamaInferenceProvider.d.ts.map +1 -0
  130. package/dist/intelligence/providers/ollamaInferenceProvider.js +103 -0
  131. package/dist/intelligence/providers/ollamaInferenceProvider.js.map +1 -0
  132. package/dist/intelligence/provisioning/hardwareDetector.d.ts +5 -0
  133. package/dist/intelligence/provisioning/hardwareDetector.d.ts.map +1 -0
  134. package/dist/intelligence/provisioning/hardwareDetector.js +48 -0
  135. package/dist/intelligence/provisioning/hardwareDetector.js.map +1 -0
  136. package/dist/intelligence/provisioning/index.d.ts +12 -0
  137. package/dist/intelligence/provisioning/index.d.ts.map +1 -0
  138. package/dist/intelligence/provisioning/index.js +12 -0
  139. package/dist/intelligence/provisioning/index.js.map +1 -0
  140. package/dist/intelligence/provisioning/modelDownloader.d.ts +22 -0
  141. package/dist/intelligence/provisioning/modelDownloader.d.ts.map +1 -0
  142. package/dist/intelligence/provisioning/modelDownloader.js +134 -0
  143. package/dist/intelligence/provisioning/modelDownloader.js.map +1 -0
  144. package/dist/intelligence/provisioning/modelManifest.d.ts +10 -0
  145. package/dist/intelligence/provisioning/modelManifest.d.ts.map +1 -0
  146. package/dist/intelligence/provisioning/modelManifest.js +72 -0
  147. package/dist/intelligence/provisioning/modelManifest.js.map +1 -0
  148. package/dist/intelligence/provisioning/modelSelector.d.ts +14 -0
  149. package/dist/intelligence/provisioning/modelSelector.d.ts.map +1 -0
  150. package/dist/intelligence/provisioning/modelSelector.js +40 -0
  151. package/dist/intelligence/provisioning/modelSelector.js.map +1 -0
  152. package/dist/intelligence/provisioning/modelStorage.d.ts +12 -0
  153. package/dist/intelligence/provisioning/modelStorage.d.ts.map +1 -0
  154. package/dist/intelligence/provisioning/modelStorage.js +66 -0
  155. package/dist/intelligence/provisioning/modelStorage.js.map +1 -0
  156. package/dist/intelligence/provisioning/modelUpdater.d.ts +29 -0
  157. package/dist/intelligence/provisioning/modelUpdater.d.ts.map +1 -0
  158. package/dist/intelligence/provisioning/modelUpdater.js +89 -0
  159. package/dist/intelligence/provisioning/modelUpdater.js.map +1 -0
  160. package/dist/intelligence/provisioning/modelVerifier.d.ts +16 -0
  161. package/dist/intelligence/provisioning/modelVerifier.d.ts.map +1 -0
  162. package/dist/intelligence/provisioning/modelVerifier.js +108 -0
  163. package/dist/intelligence/provisioning/modelVerifier.js.map +1 -0
  164. package/dist/intelligence/provisioning/nativeRuntime.d.ts +18 -0
  165. package/dist/intelligence/provisioning/nativeRuntime.d.ts.map +1 -0
  166. package/dist/intelligence/provisioning/nativeRuntime.js +78 -0
  167. package/dist/intelligence/provisioning/nativeRuntime.js.map +1 -0
  168. package/dist/intelligence/provisioning/platformDetector.d.ts +15 -0
  169. package/dist/intelligence/provisioning/platformDetector.d.ts.map +1 -0
  170. package/dist/intelligence/provisioning/platformDetector.js +40 -0
  171. package/dist/intelligence/provisioning/platformDetector.js.map +1 -0
  172. package/dist/intelligence/provisioning/setupState.d.ts +10 -0
  173. package/dist/intelligence/provisioning/setupState.d.ts.map +1 -0
  174. package/dist/intelligence/provisioning/setupState.js +59 -0
  175. package/dist/intelligence/provisioning/setupState.js.map +1 -0
  176. package/dist/intelligence/provisioning/types.d.ts +51 -0
  177. package/dist/intelligence/provisioning/types.d.ts.map +1 -0
  178. package/dist/intelligence/provisioning/types.js +2 -0
  179. package/dist/intelligence/provisioning/types.js.map +1 -0
  180. package/dist/intelligence/runtime/embeddedRuntimeAdapter.d.ts +26 -0
  181. package/dist/intelligence/runtime/embeddedRuntimeAdapter.d.ts.map +1 -0
  182. package/dist/intelligence/runtime/embeddedRuntimeAdapter.js +119 -0
  183. package/dist/intelligence/runtime/embeddedRuntimeAdapter.js.map +1 -0
  184. package/dist/intelligence/runtime/ollamaRuntimeAdapter.d.ts +28 -0
  185. package/dist/intelligence/runtime/ollamaRuntimeAdapter.d.ts.map +1 -0
  186. package/dist/intelligence/runtime/ollamaRuntimeAdapter.js +131 -0
  187. package/dist/intelligence/runtime/ollamaRuntimeAdapter.js.map +1 -0
  188. package/dist/intelligence/runtime/runtimeManager.d.ts +37 -0
  189. package/dist/intelligence/runtime/runtimeManager.d.ts.map +1 -0
  190. package/dist/intelligence/runtime/runtimeManager.js +168 -0
  191. package/dist/intelligence/runtime/runtimeManager.js.map +1 -0
  192. package/dist/intelligence/runtime/types.d.ts +56 -0
  193. package/dist/intelligence/runtime/types.d.ts.map +1 -0
  194. package/dist/intelligence/runtime/types.js +7 -0
  195. package/dist/intelligence/runtime/types.js.map +1 -0
  196. package/dist/knowledge/chunker.d.ts +18 -0
  197. package/dist/knowledge/chunker.d.ts.map +1 -0
  198. package/dist/knowledge/chunker.js +55 -0
  199. package/dist/knowledge/chunker.js.map +1 -0
  200. package/dist/knowledge/citationService.d.ts +26 -0
  201. package/dist/knowledge/citationService.d.ts.map +1 -0
  202. package/dist/knowledge/citationService.js +47 -0
  203. package/dist/knowledge/citationService.js.map +1 -0
  204. package/dist/knowledge/embeddings.d.ts +11 -0
  205. package/dist/knowledge/embeddings.d.ts.map +1 -0
  206. package/dist/knowledge/embeddings.js +28 -0
  207. package/dist/knowledge/embeddings.js.map +1 -0
  208. package/dist/knowledge/hybridSearch.d.ts +13 -0
  209. package/dist/knowledge/hybridSearch.d.ts.map +1 -0
  210. package/dist/knowledge/hybridSearch.js +38 -0
  211. package/dist/knowledge/hybridSearch.js.map +1 -0
  212. package/dist/knowledge/index.d.ts +25 -0
  213. package/dist/knowledge/index.d.ts.map +1 -0
  214. package/dist/knowledge/index.js +37 -0
  215. package/dist/knowledge/index.js.map +1 -0
  216. package/dist/knowledge/parsers.d.ts +20 -0
  217. package/dist/knowledge/parsers.d.ts.map +1 -0
  218. package/dist/knowledge/parsers.js +94 -0
  219. package/dist/knowledge/parsers.js.map +1 -0
  220. package/dist/knowledge/ragEngine.d.ts +24 -0
  221. package/dist/knowledge/ragEngine.d.ts.map +1 -0
  222. package/dist/knowledge/ragEngine.js +121 -0
  223. package/dist/knowledge/ragEngine.js.map +1 -0
  224. package/dist/knowledge/reranker.d.ts +10 -0
  225. package/dist/knowledge/reranker.d.ts.map +1 -0
  226. package/dist/knowledge/reranker.js +11 -0
  227. package/dist/knowledge/reranker.js.map +1 -0
  228. package/dist/knowledge/vectorStore.d.ts +22 -0
  229. package/dist/knowledge/vectorStore.d.ts.map +1 -0
  230. package/dist/knowledge/vectorStore.js +74 -0
  231. package/dist/knowledge/vectorStore.js.map +1 -0
  232. package/dist/main.d.ts +2 -0
  233. package/dist/main.d.ts.map +1 -0
  234. package/dist/main.js +113 -0
  235. package/dist/main.js.map +1 -0
  236. package/dist/orchestration/agentExecutionService.d.ts +29 -0
  237. package/dist/orchestration/agentExecutionService.d.ts.map +1 -0
  238. package/dist/orchestration/agentExecutionService.js +306 -0
  239. package/dist/orchestration/agentExecutionService.js.map +1 -0
  240. package/dist/orchestration/agentStateMachine.d.ts +29 -0
  241. package/dist/orchestration/agentStateMachine.d.ts.map +1 -0
  242. package/dist/orchestration/agentStateMachine.js +153 -0
  243. package/dist/orchestration/agentStateMachine.js.map +1 -0
  244. package/dist/orchestration/agentTaskService.d.ts +44 -0
  245. package/dist/orchestration/agentTaskService.d.ts.map +1 -0
  246. package/dist/orchestration/agentTaskService.js +168 -0
  247. package/dist/orchestration/agentTaskService.js.map +1 -0
  248. package/dist/orchestration/codingAgentDiscovery.d.ts +32 -0
  249. package/dist/orchestration/codingAgentDiscovery.d.ts.map +1 -0
  250. package/dist/orchestration/codingAgentDiscovery.js +148 -0
  251. package/dist/orchestration/codingAgentDiscovery.js.map +1 -0
  252. package/dist/orchestration/codingAgentService.d.ts +40 -0
  253. package/dist/orchestration/codingAgentService.d.ts.map +1 -0
  254. package/dist/orchestration/codingAgentService.js +319 -0
  255. package/dist/orchestration/codingAgentService.js.map +1 -0
  256. package/dist/orchestration/codingAgentTypes.d.ts +111 -0
  257. package/dist/orchestration/codingAgentTypes.d.ts.map +1 -0
  258. package/dist/orchestration/codingAgentTypes.js +32 -0
  259. package/dist/orchestration/codingAgentTypes.js.map +1 -0
  260. package/dist/orchestration/codingAgentVerifier.d.ts +34 -0
  261. package/dist/orchestration/codingAgentVerifier.d.ts.map +1 -0
  262. package/dist/orchestration/codingAgentVerifier.js +109 -0
  263. package/dist/orchestration/codingAgentVerifier.js.map +1 -0
  264. package/dist/orchestration/codingRepairService.d.ts +34 -0
  265. package/dist/orchestration/codingRepairService.d.ts.map +1 -0
  266. package/dist/orchestration/codingRepairService.js +120 -0
  267. package/dist/orchestration/codingRepairService.js.map +1 -0
  268. package/dist/orchestration/goalCompletionVerifier.d.ts +36 -0
  269. package/dist/orchestration/goalCompletionVerifier.d.ts.map +1 -0
  270. package/dist/orchestration/goalCompletionVerifier.js +165 -0
  271. package/dist/orchestration/goalCompletionVerifier.js.map +1 -0
  272. package/dist/orchestration/humanApprovalService.d.ts +89 -0
  273. package/dist/orchestration/humanApprovalService.d.ts.map +1 -0
  274. package/dist/orchestration/humanApprovalService.js +346 -0
  275. package/dist/orchestration/humanApprovalService.js.map +1 -0
  276. package/dist/orchestration/index.d.ts +47 -0
  277. package/dist/orchestration/index.d.ts.map +1 -0
  278. package/dist/orchestration/index.js +67 -0
  279. package/dist/orchestration/index.js.map +1 -0
  280. package/dist/orchestration/planner.d.ts +105 -0
  281. package/dist/orchestration/planner.d.ts.map +1 -0
  282. package/dist/orchestration/planner.js +692 -0
  283. package/dist/orchestration/planner.js.map +1 -0
  284. package/dist/orchestration/types.d.ts +109 -0
  285. package/dist/orchestration/types.d.ts.map +1 -0
  286. package/dist/orchestration/types.js +20 -0
  287. package/dist/orchestration/types.js.map +1 -0
  288. package/dist/preview/previewServer.d.ts +39 -0
  289. package/dist/preview/previewServer.d.ts.map +1 -0
  290. package/dist/preview/previewServer.js +228 -0
  291. package/dist/preview/previewServer.js.map +1 -0
  292. package/dist/preview/previewService.d.ts +43 -0
  293. package/dist/preview/previewService.d.ts.map +1 -0
  294. package/dist/preview/previewService.js +289 -0
  295. package/dist/preview/previewService.js.map +1 -0
  296. package/dist/preview/previewTypes.d.ts +35 -0
  297. package/dist/preview/previewTypes.d.ts.map +1 -0
  298. package/dist/preview/previewTypes.js +5 -0
  299. package/dist/preview/previewTypes.js.map +1 -0
  300. package/dist/storage/database.d.ts +12 -0
  301. package/dist/storage/database.d.ts.map +1 -0
  302. package/dist/storage/database.js +46 -0
  303. package/dist/storage/database.js.map +1 -0
  304. package/dist/storage/health.d.ts +17 -0
  305. package/dist/storage/health.d.ts.map +1 -0
  306. package/dist/storage/health.js +48 -0
  307. package/dist/storage/health.js.map +1 -0
  308. package/dist/storage/index.d.ts +45 -0
  309. package/dist/storage/index.d.ts.map +1 -0
  310. package/dist/storage/index.js +96 -0
  311. package/dist/storage/index.js.map +1 -0
  312. package/dist/storage/migration.d.ts +17 -0
  313. package/dist/storage/migration.d.ts.map +1 -0
  314. package/dist/storage/migration.js +354 -0
  315. package/dist/storage/migration.js.map +1 -0
  316. package/dist/storage/projectService.d.ts +19 -0
  317. package/dist/storage/projectService.d.ts.map +1 -0
  318. package/dist/storage/projectService.js +29 -0
  319. package/dist/storage/projectService.js.map +1 -0
  320. package/dist/storage/repositories/agentTaskRepository.d.ts +34 -0
  321. package/dist/storage/repositories/agentTaskRepository.d.ts.map +1 -0
  322. package/dist/storage/repositories/agentTaskRepository.js +128 -0
  323. package/dist/storage/repositories/agentTaskRepository.js.map +1 -0
  324. package/dist/storage/repositories/approvalRepository.d.ts +20 -0
  325. package/dist/storage/repositories/approvalRepository.d.ts.map +1 -0
  326. package/dist/storage/repositories/approvalRepository.js +116 -0
  327. package/dist/storage/repositories/approvalRepository.js.map +1 -0
  328. package/dist/storage/repositories/conversationRepository.d.ts +16 -0
  329. package/dist/storage/repositories/conversationRepository.d.ts.map +1 -0
  330. package/dist/storage/repositories/conversationRepository.js +50 -0
  331. package/dist/storage/repositories/conversationRepository.js.map +1 -0
  332. package/dist/storage/repositories/knowledgeRepository.d.ts +109 -0
  333. package/dist/storage/repositories/knowledgeRepository.d.ts.map +1 -0
  334. package/dist/storage/repositories/knowledgeRepository.js +177 -0
  335. package/dist/storage/repositories/knowledgeRepository.js.map +1 -0
  336. package/dist/storage/repositories/messageRepository.d.ts +13 -0
  337. package/dist/storage/repositories/messageRepository.d.ts.map +1 -0
  338. package/dist/storage/repositories/messageRepository.js +39 -0
  339. package/dist/storage/repositories/messageRepository.js.map +1 -0
  340. package/dist/storage/repositories/modelsRepository.d.ts +39 -0
  341. package/dist/storage/repositories/modelsRepository.d.ts.map +1 -0
  342. package/dist/storage/repositories/modelsRepository.js +92 -0
  343. package/dist/storage/repositories/modelsRepository.js.map +1 -0
  344. package/dist/storage/repositories/projectRepository.d.ts +14 -0
  345. package/dist/storage/repositories/projectRepository.d.ts.map +1 -0
  346. package/dist/storage/repositories/projectRepository.js +44 -0
  347. package/dist/storage/repositories/projectRepository.js.map +1 -0
  348. package/dist/storage/repositories/settingsRepository.d.ts +10 -0
  349. package/dist/storage/repositories/settingsRepository.d.ts.map +1 -0
  350. package/dist/storage/repositories/settingsRepository.js +27 -0
  351. package/dist/storage/repositories/settingsRepository.js.map +1 -0
  352. package/dist/storage/repositories/types.d.ts +56 -0
  353. package/dist/storage/repositories/types.d.ts.map +1 -0
  354. package/dist/storage/repositories/types.js +2 -0
  355. package/dist/storage/repositories/types.js.map +1 -0
  356. package/dist/tools/adapters/filesystemAdapter.d.ts +121 -0
  357. package/dist/tools/adapters/filesystemAdapter.d.ts.map +1 -0
  358. package/dist/tools/adapters/filesystemAdapter.js +808 -0
  359. package/dist/tools/adapters/filesystemAdapter.js.map +1 -0
  360. package/dist/tools/adapters/terminalAdapter.d.ts +67 -0
  361. package/dist/tools/adapters/terminalAdapter.d.ts.map +1 -0
  362. package/dist/tools/adapters/terminalAdapter.js +487 -0
  363. package/dist/tools/adapters/terminalAdapter.js.map +1 -0
  364. package/dist/tools/adapters/terminalCommandPolicy.d.ts +44 -0
  365. package/dist/tools/adapters/terminalCommandPolicy.d.ts.map +1 -0
  366. package/dist/tools/adapters/terminalCommandPolicy.js +422 -0
  367. package/dist/tools/adapters/terminalCommandPolicy.js.map +1 -0
  368. package/dist/tools/adapters/terminalTypes.d.ts +111 -0
  369. package/dist/tools/adapters/terminalTypes.d.ts.map +1 -0
  370. package/dist/tools/adapters/terminalTypes.js +26 -0
  371. package/dist/tools/adapters/terminalTypes.js.map +1 -0
  372. package/dist/tools/approvalGate.d.ts +24 -0
  373. package/dist/tools/approvalGate.d.ts.map +1 -0
  374. package/dist/tools/approvalGate.js +137 -0
  375. package/dist/tools/approvalGate.js.map +1 -0
  376. package/dist/tools/approvalPolicyEngine.d.ts +32 -0
  377. package/dist/tools/approvalPolicyEngine.d.ts.map +1 -0
  378. package/dist/tools/approvalPolicyEngine.js +141 -0
  379. package/dist/tools/approvalPolicyEngine.js.map +1 -0
  380. package/dist/tools/approvalTypes.d.ts +67 -0
  381. package/dist/tools/approvalTypes.d.ts.map +1 -0
  382. package/dist/tools/approvalTypes.js +23 -0
  383. package/dist/tools/approvalTypes.js.map +1 -0
  384. package/dist/tools/index.d.ts +72 -0
  385. package/dist/tools/index.d.ts.map +1 -0
  386. package/dist/tools/index.js +353 -0
  387. package/dist/tools/index.js.map +1 -0
  388. package/dist/tools/permissionEngine.d.ts +27 -0
  389. package/dist/tools/permissionEngine.d.ts.map +1 -0
  390. package/dist/tools/permissionEngine.js +130 -0
  391. package/dist/tools/permissionEngine.js.map +1 -0
  392. package/dist/tools/toolExecutor.d.ts +37 -0
  393. package/dist/tools/toolExecutor.d.ts.map +1 -0
  394. package/dist/tools/toolExecutor.js +440 -0
  395. package/dist/tools/toolExecutor.js.map +1 -0
  396. package/dist/tools/toolRegistry.d.ts +34 -0
  397. package/dist/tools/toolRegistry.d.ts.map +1 -0
  398. package/dist/tools/toolRegistry.js +92 -0
  399. package/dist/tools/toolRegistry.js.map +1 -0
  400. package/dist/tools/types.d.ts +82 -0
  401. package/dist/tools/types.d.ts.map +1 -0
  402. package/dist/tools/types.js +33 -0
  403. package/dist/tools/types.js.map +1 -0
  404. package/dist/ui/public/app.js +777 -0
  405. package/dist/ui/public/index.html +117 -0
  406. package/dist/ui/public/styles.css +413 -0
  407. package/dist/ui/server.d.ts +27 -0
  408. package/dist/ui/server.d.ts.map +1 -0
  409. package/dist/ui/server.js +373 -0
  410. package/dist/ui/server.js.map +1 -0
  411. package/package.json +63 -0
@@ -0,0 +1,692 @@
1
+ /**
2
+ * NEXUS AI — P5-E: Agent Plan Synthesis & Controlled Task Orchestration
3
+ *
4
+ * Security invariant:
5
+ * PlanSynthesisService is an UNTRUSTED PLAN GENERATOR.
6
+ * It has NO execution authority — it cannot call tools, modify task state,
7
+ * or interact with the PermissionEngine.
8
+ * The AgentExecutionService (P5-D) remains the sole execution authority.
9
+ *
10
+ * Data flow:
11
+ * PlanSynthesisService
12
+ * → ModelGateway (plain-text inference only)
13
+ * → PlanValidator (deterministic, stateless, no side effects)
14
+ * → PlanSynthesisResult (validated AgentPlan or typed error)
15
+ * → caller passes AgentPlan.steps to AgentExecutionService.runExecutionLoop()
16
+ */
17
+ import { VALID_CAPABILITIES } from '../tools/types.js';
18
+ import { Logger } from '../common/logger.js';
19
+ // ---------------------------------------------------------------------------
20
+ // Constants
21
+ // ---------------------------------------------------------------------------
22
+ /** Default maximum steps a plan may contain. */
23
+ const DEFAULT_MAX_STEPS = 10;
24
+ /** Low temperature for deterministic planner output. */
25
+ const PLANNER_DEFAULT_TEMPERATURE = 0.2;
26
+ /** Default inference timeout for the planning call. */
27
+ const PLANNER_DEFAULT_TIMEOUT_MS = 30_000;
28
+ /**
29
+ * System prompt injected for the planner role.
30
+ * Instructs the model to output ONLY a well-formed JSON plan and nothing else.
31
+ */
32
+ const PLANNER_SYSTEM_PROMPT = `You are a deterministic task planner for the NEXUS AI Agent Runtime.
33
+
34
+ Your ONLY job is to produce a valid JSON plan for the given goal.
35
+ You do NOT execute tools. You do NOT make decisions at runtime.
36
+ You ONLY output a plan in the exact JSON format specified.
37
+
38
+ TOOL CONTRACT & CAPABILITY RULES:
39
+ 1. workspace_tree: READ-ONLY workspace/directory structure inspection. MUST NEVER be used to create directories, create files, or modify files.
40
+ 2. code_search: READ-ONLY source code search. MUST NEVER be used to create or modify files.
41
+ 3. filesystem_read: READ-ONLY file content inspection. MUST NEVER be used to create or modify files.
42
+ 4. filesystem_write: Used ONLY to CREATE new files or REPLACE full file contents. Requires filesystem.write.
43
+ 5. filesystem_edit: Used ONLY to MODIFY existing files. Requires filesystem.write.
44
+ 6. terminal_execute: Used ONLY for executing allowed terminal/build/test commands. Requires terminal.execute. High risk, approval-controlled.
45
+
46
+ STRICT PLAN & JSON ESCAPING RULES:
47
+ 1. Output ONLY valid JSON — no markdown wrapper, no conversational text, no explanation outside JSON.
48
+ 2. The plan must have a "reasoning" string and a "steps" array containing at least 1 step.
49
+ 3. Each step must have: stepId (string), toolId (string), requestedCapabilities (array), params (object).
50
+ 4. Only use tool IDs that are explicitly listed in the AVAILABLE TOOLS section.
51
+ 5. Only request capabilities that match the selected tool's contract.
52
+ 6. stepId values must be unique within the plan (e.g., "step-1", "step-2").
53
+ 7. Use read-only tools (workspace_tree, code_search, filesystem_read) for inspection/discovery of files that ALREADY EXIST. filesystem_read MUST ONLY be used on files confirmed to exist.
54
+ 8. Use filesystem_write to create new files or filesystem_edit to modify existing files.
55
+ 9. Keep reasoning concise and steps minimal.
56
+ 10. JSON STRING ESCAPING: Inside all JSON string values (especially "content" or "path"), write newlines as \\n and escape double quotes as \\". DO NOT include unescaped raw newlines or unescaped raw double quotes inside string values.
57
+
58
+ FILE CREATION / AUTHORING RULES:
59
+ 11. MANDATORY MULTI-STEP CREATION: If the task asks to build/create a project, webpage, website, or multi-file artifact (e.g. calculator webpage with HTML, CSS, and JS), you MUST include a filesystem_write step for EACH required file (e.g. index.html, style.css, script.js).
60
+ 12. NEVER output ONLY workspace_tree or read-only tools for a creation/authoring goal. A plan for an authoring task MUST contain actual filesystem_write or filesystem_edit steps.
61
+ 13. NO PREMATURE READS: NEVER issue filesystem_read on the target file path that you are about to create — it does not exist yet. filesystem_read is RESERVED for reading files that are KNOWN TO EXIST. Use filesystem_write to author each file with complete, valid code contents.
62
+
63
+ REQUIRED OUTPUT FORMAT EXAMPLE (strict JSON, no other text):
64
+ {
65
+ "reasoning": "Create project directory and author HTML, CSS, and JS files for calculator webpage.",
66
+ "steps": [
67
+ {
68
+ "stepId": "step-1",
69
+ "toolId": "filesystem_write",
70
+ "requestedCapabilities": ["filesystem.write"],
71
+ "params": {
72
+ "path": "final-calculator-test/index.html",
73
+ "content": "<!DOCTYPE html>\\n<html>\\n<head>\\n<link rel=\\\"stylesheet\\\" href=\\\"style.css\\\">\\n</head>\\n<body>\\n<div id=\\\"calc\\\"></div>\\n<script src=\\\"script.js\\\"></script>\\n</body>\\n</html>"
74
+ }
75
+ }
76
+ ]
77
+ }`;
78
+ /**
79
+ * Utility to determine if a task goal represents an authoring/creation request.
80
+ *
81
+ * Uses word-boundary regex matching to prevent substring false-positives
82
+ * (e.g. 'typescript' must not match keyword 'script').
83
+ */
84
+ export function isAuthoringGoal(goalText) {
85
+ if (!goalText || !goalText.trim())
86
+ return false;
87
+ const lower = goalText.toLowerCase();
88
+ // Action verbs that signal file creation/authoring intent.
89
+ // Use word-boundary anchors (\b) to avoid substring matches.
90
+ const authoringVerbs = [
91
+ 'create', 'build', 'write', 'generate', 'make', 'author', 'develop',
92
+ 'draft', 'implement', 'scaffold', 'initialise', 'initialize',
93
+ ];
94
+ // Multi-word phrases or specific artifact noun patterns that confirm authoring
95
+ // even without an explicit verb (e.g. "new file", "a webpage", "PRD document").
96
+ const authoringPhrases = [
97
+ 'new file', 'add file', 'webpage', 'website', 'prd', 'readme',
98
+ 'calculator', 'landing page',
99
+ ];
100
+ const inspectionOnlyPhrases = [
101
+ 'show workspace', 'list workspace', 'workspace tree', 'inspect workspace',
102
+ 'search code', 'find in code', 'read file', 'view file', 'check status',
103
+ 'list directory', 'explore workspace',
104
+ ];
105
+ // Word-boundary match for single verbs
106
+ const hasAuthoringVerb = authoringVerbs.some((verb) => new RegExp(`\\b${verb}\\b`).test(lower));
107
+ // Simple substring match is fine for multi-word phrases / proper nouns
108
+ const hasAuthoringPhrase = authoringPhrases.some((phrase) => lower.includes(phrase));
109
+ const hasAuthoring = hasAuthoringVerb || hasAuthoringPhrase;
110
+ const isPureInspection = inspectionOnlyPhrases.some((phrase) => lower.includes(phrase)) && !hasAuthoring;
111
+ return hasAuthoring && !isPureInspection;
112
+ }
113
+ // ---------------------------------------------------------------------------
114
+ // PlanValidator
115
+ // ---------------------------------------------------------------------------
116
+ /**
117
+ * Deterministic, stateless plan validator.
118
+ *
119
+ * Validates a raw model-generated plan proposal against the tool registry.
120
+ * No side effects. No execution. Returns a typed validation result.
121
+ *
122
+ * Security note: model-generated params are treated as untrusted strings.
123
+ * The validator does NOT evaluate or execute any param values.
124
+ */
125
+ export class PlanValidator {
126
+ toolGateway;
127
+ constructor(toolGateway) {
128
+ this.toolGateway = toolGateway;
129
+ }
130
+ /**
131
+ * Validate a raw parsed plan proposal.
132
+ * Returns a deterministic result with all errors (does not short-circuit on first error).
133
+ */
134
+ validate(proposal, taskId, maxSteps = DEFAULT_MAX_STEPS, taskGoal) {
135
+ const errors = [];
136
+ // 1. Top-level structure check
137
+ if (typeof proposal !== 'object' ||
138
+ proposal === null ||
139
+ Array.isArray(proposal)) {
140
+ errors.push({
141
+ code: 'MALFORMED_OUTPUT',
142
+ message: 'Plan proposal is not a JSON object.',
143
+ });
144
+ return { valid: false, errors };
145
+ }
146
+ const raw = proposal;
147
+ // 2. Reasoning field
148
+ if (typeof raw['reasoning'] !== 'string' || raw['reasoning'].trim() === '') {
149
+ errors.push({
150
+ code: 'INVALID_STEP_STRUCTURE',
151
+ message: 'Plan must contain a non-empty "reasoning" string.',
152
+ });
153
+ }
154
+ // 3. Steps array
155
+ if (!Array.isArray(raw['steps'])) {
156
+ errors.push({
157
+ code: 'MALFORMED_OUTPUT',
158
+ message: 'Plan must contain a "steps" array.',
159
+ });
160
+ return { valid: false, errors };
161
+ }
162
+ const rawSteps = raw['steps'];
163
+ // 4. Empty plan check
164
+ if (rawSteps.length === 0) {
165
+ errors.push({
166
+ code: 'EMPTY_PLAN',
167
+ message: 'Plan must contain at least one step.',
168
+ });
169
+ return { valid: false, errors };
170
+ }
171
+ // 5. Step limit check
172
+ if (rawSteps.length > maxSteps) {
173
+ errors.push({
174
+ code: 'STEP_LIMIT_EXCEEDED',
175
+ message: `Plan contains ${rawSteps.length} steps but maximum allowed is ${maxSteps}.`,
176
+ });
177
+ }
178
+ // 5b. Authoring goal validation — authoring goals MUST NOT consist ONLY of workspace_tree steps.
179
+ // This prevents the specific false-completion bug where a "build" task runs only workspace_tree
180
+ // and is marked COMPLETED without creating any files.
181
+ // Note: filesystem_read-only plans are allowed at this stage; GoalCompletionVerifier enforces
182
+ // artifact existence at completion time.
183
+ if (taskGoal && isAuthoringGoal(taskGoal)) {
184
+ const allStepsAreWorkspaceTree = rawSteps.every((step) => {
185
+ if (typeof step === 'object' && step !== null && !Array.isArray(step)) {
186
+ const toolId = String(step['toolId'] || '');
187
+ return toolId === 'workspace_tree';
188
+ }
189
+ return true;
190
+ });
191
+ if (allStepsAreWorkspaceTree) {
192
+ errors.push({
193
+ code: 'UNSUPPORTED_ACTION',
194
+ message: 'Task goal requires file creation/authoring, but the plan contains no file creation or execution steps (only read-only inspection tools were planned).',
195
+ });
196
+ }
197
+ }
198
+ // 6. Per-step validation
199
+ const seenStepIds = new Set();
200
+ for (let i = 0; i < rawSteps.length; i++) {
201
+ const rawStep = rawSteps[i];
202
+ if (typeof rawStep !== 'object' || rawStep === null || Array.isArray(rawStep)) {
203
+ errors.push({
204
+ code: 'INVALID_STEP_STRUCTURE',
205
+ message: `Step at index ${i} is not a valid object.`,
206
+ });
207
+ continue;
208
+ }
209
+ const s = rawStep;
210
+ const stepId = typeof s['stepId'] === 'string' ? s['stepId'].trim() : '';
211
+ // 6a. stepId must be a non-empty unique string
212
+ if (!stepId) {
213
+ errors.push({
214
+ code: 'INVALID_STEP_STRUCTURE',
215
+ message: `Step at index ${i} is missing a valid "stepId".`,
216
+ });
217
+ }
218
+ else if (seenStepIds.has(stepId)) {
219
+ errors.push({
220
+ code: 'INVALID_STEP_STRUCTURE',
221
+ message: `Duplicate stepId "${stepId}" at index ${i}.`,
222
+ stepId,
223
+ });
224
+ }
225
+ else {
226
+ seenStepIds.add(stepId);
227
+ }
228
+ // 6b. toolId must reference a registered, enabled tool
229
+ const toolId = typeof s['toolId'] === 'string' ? s['toolId'].trim() : '';
230
+ let toolDef = null;
231
+ if (!toolId) {
232
+ errors.push({
233
+ code: 'INVALID_STEP_STRUCTURE',
234
+ message: `Step "${stepId || i}" is missing a valid "toolId".`,
235
+ stepId: stepId || undefined,
236
+ });
237
+ }
238
+ else {
239
+ toolDef = this.toolGateway.getTool(toolId);
240
+ if (!toolDef) {
241
+ errors.push({
242
+ code: 'UNKNOWN_TOOL',
243
+ message: `Step "${stepId}" references unknown tool "${toolId}". Only registered tools may be planned.`,
244
+ stepId: stepId || undefined,
245
+ });
246
+ }
247
+ else if (!toolDef.enabled) {
248
+ errors.push({
249
+ code: 'UNSUPPORTED_ACTION',
250
+ message: `Step "${stepId}" references disabled tool "${toolId}".`,
251
+ stepId: stepId || undefined,
252
+ });
253
+ }
254
+ }
255
+ // 6c. requestedCapabilities must be a non-empty array of known values matching tool definition permissions
256
+ const reqCaps = s['requestedCapabilities'];
257
+ if (!Array.isArray(reqCaps) || reqCaps.length === 0) {
258
+ errors.push({
259
+ code: 'INVALID_STEP_STRUCTURE',
260
+ message: `Step "${stepId || i}" must specify at least one requestedCapability.`,
261
+ stepId: stepId || undefined,
262
+ });
263
+ }
264
+ else {
265
+ for (const cap of reqCaps) {
266
+ if (typeof cap !== 'string' || !VALID_CAPABILITIES.has(cap)) {
267
+ errors.push({
268
+ code: 'UNSUPPORTED_ACTION',
269
+ message: `Step "${stepId}" requests unknown capability "${String(cap)}".`,
270
+ stepId: stepId || undefined,
271
+ });
272
+ }
273
+ else if (toolDef) {
274
+ // Check capability is permitted for the tool definition
275
+ if (!toolDef.requiredPermissions.includes(cap)) {
276
+ errors.push({
277
+ code: 'UNSUPPORTED_ACTION',
278
+ message: `Step "${stepId}" requests capability "${String(cap)}" which is not permitted for tool "${toolId}".`,
279
+ stepId: stepId || undefined,
280
+ });
281
+ }
282
+ }
283
+ }
284
+ }
285
+ // 6d. Tool contract & action compatibility validation
286
+ if (toolDef && toolId) {
287
+ const writeMutationRegex = /\b(create|mkdir|write|edit|modify|delete|remove|add-dir|make-dir|create-structure|build-structure)\b/i;
288
+ const stepTextToTest = `${stepId} ${JSON.stringify(s['params'] || {})}`;
289
+ if (toolId === 'workspace_tree') {
290
+ if (writeMutationRegex.test(stepTextToTest) || (Array.isArray(reqCaps) && reqCaps.includes('filesystem.write'))) {
291
+ errors.push({
292
+ code: 'UNSUPPORTED_ACTION',
293
+ message: `Step "${stepId}" claims a write/create/modify operation but 'workspace_tree' is strictly READ-ONLY.`,
294
+ stepId: stepId || undefined,
295
+ });
296
+ }
297
+ }
298
+ else if (toolId === 'code_search') {
299
+ if (writeMutationRegex.test(stepTextToTest) || (Array.isArray(reqCaps) && reqCaps.includes('filesystem.write'))) {
300
+ errors.push({
301
+ code: 'UNSUPPORTED_ACTION',
302
+ message: `Step "${stepId}" claims a write/modify operation but 'code_search' is strictly READ-ONLY.`,
303
+ stepId: stepId || undefined,
304
+ });
305
+ }
306
+ }
307
+ else if (toolId === 'filesystem_read') {
308
+ if (writeMutationRegex.test(stepTextToTest) || (Array.isArray(reqCaps) && reqCaps.includes('filesystem.write'))) {
309
+ errors.push({
310
+ code: 'UNSUPPORTED_ACTION',
311
+ message: `Step "${stepId}" claims a write/modify operation but 'filesystem_read' is strictly READ-ONLY.`,
312
+ stepId: stepId || undefined,
313
+ });
314
+ }
315
+ }
316
+ else if (toolId === 'filesystem_write' || toolId === 'filesystem_edit') {
317
+ if (Array.isArray(reqCaps) && !reqCaps.includes('filesystem.write')) {
318
+ errors.push({
319
+ code: 'UNSUPPORTED_ACTION',
320
+ message: `Step "${stepId}" uses tool '${toolId}' but missing required capability 'filesystem.write'.`,
321
+ stepId: stepId || undefined,
322
+ });
323
+ }
324
+ }
325
+ else if (toolId === 'terminal_execute') {
326
+ if (Array.isArray(reqCaps) && !reqCaps.includes('terminal.execute')) {
327
+ errors.push({
328
+ code: 'UNSUPPORTED_ACTION',
329
+ message: `Step "${stepId}" uses tool 'terminal_execute' but missing required capability 'terminal.execute'.`,
330
+ stepId: stepId || undefined,
331
+ });
332
+ }
333
+ }
334
+ }
335
+ // 6e. params must be an object (content treated as untrusted — not evaluated)
336
+ if (typeof s['params'] !== 'object' ||
337
+ s['params'] === null ||
338
+ Array.isArray(s['params'])) {
339
+ errors.push({
340
+ code: 'INVALID_STEP_STRUCTURE',
341
+ message: `Step "${stepId || i}" must have a "params" object (may be empty: {}).`,
342
+ stepId: stepId || undefined,
343
+ });
344
+ }
345
+ else {
346
+ const params = s['params'];
347
+ for (const [key, val] of Object.entries(params)) {
348
+ if (typeof val === 'function') {
349
+ errors.push({
350
+ code: 'UNTRUSTED_PARAM',
351
+ message: `Step "${stepId}" param "${key}" must not be a function.`,
352
+ stepId: stepId || undefined,
353
+ });
354
+ }
355
+ }
356
+ }
357
+ }
358
+ void taskId;
359
+ return { valid: errors.length === 0, errors };
360
+ }
361
+ }
362
+ // ---------------------------------------------------------------------------
363
+ // PlanSynthesisService
364
+ // ---------------------------------------------------------------------------
365
+ /**
366
+ * PlanSynthesisService — generates structured, validated agent plans using
367
+ * the ModelGateway.
368
+ *
369
+ * SECURITY CONTRACT:
370
+ * - This service is an UNTRUSTED PLAN GENERATOR.
371
+ * - It has NO access to ToolExecutor, PermissionEngine, or AgentExecutionService.
372
+ * - It passes only plain-text prompts to the model and returns structured data.
373
+ * - The resulting AgentPlan carries zero execution authority.
374
+ * - Callers must pass plan.steps to AgentExecutionService.runExecutionLoop()
375
+ * for execution, which enforces all authorization and sandbox boundaries.
376
+ */
377
+ export class PlanSynthesisService {
378
+ modelGateway;
379
+ toolGateway;
380
+ logger;
381
+ validator;
382
+ planVersion = 0;
383
+ constructor(modelGateway, toolGateway, logLevel = 'info') {
384
+ this.modelGateway = modelGateway;
385
+ this.toolGateway = toolGateway;
386
+ this.logger = new Logger('PlanSynthesisService', logLevel);
387
+ this.validator = new PlanValidator(toolGateway);
388
+ }
389
+ /**
390
+ * Synthesize a validated agent plan for the given task.
391
+ *
392
+ * Flow:
393
+ * 1. Build a structured prompt listing available tools + constraints.
394
+ * 2. Invoke ModelGateway with a low-temperature generation call.
395
+ * 3. Extract the JSON plan block from the raw model output.
396
+ * 4. Parse the JSON.
397
+ * 5. Run PlanValidator (deterministic, no side effects).
398
+ * 6. If valid → assemble and return AgentPlan.
399
+ * If invalid → return PlanSynthesisResult with typed errors.
400
+ */
401
+ async synthesize(taskId, options) {
402
+ const maxSteps = options.maxSteps ?? DEFAULT_MAX_STEPS;
403
+ const timeoutMs = options.timeoutMs ?? PLANNER_DEFAULT_TIMEOUT_MS;
404
+ const temperature = options.temperature ?? PLANNER_DEFAULT_TEMPERATURE;
405
+ this.logger.info('Starting plan synthesis', { taskId, maxSteps, temperature });
406
+ const maxAttempts = 2; // Bounded retry: 1 initial attempt + 1 retry attempt
407
+ let lastErrorCategory = 'PLAN_PARSE_FAILED';
408
+ let lastErrorMessage = 'Unknown synthesis failure';
409
+ let lastValidationErrors;
410
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
411
+ const isRetry = attempt > 1;
412
+ this.logger.info(`Plan synthesis attempt ${attempt}/${maxAttempts}`, { taskId, isRetry });
413
+ // 1. Build prompt (standard or targeted retry prompt)
414
+ const prompt = isRetry
415
+ ? this.buildRetryPlannerPrompt(options.taskGoal, maxSteps, lastErrorMessage)
416
+ : this.buildPlannerPrompt(options.taskGoal, maxSteps);
417
+ // 2. Model inference
418
+ let rawModelText;
419
+ let usedModelId;
420
+ try {
421
+ const response = await this.modelGateway.generate({
422
+ prompt,
423
+ system: PLANNER_SYSTEM_PROMPT,
424
+ modelId: options.modelId,
425
+ taskCapability: 'planning',
426
+ temperature,
427
+ timeoutMs,
428
+ allowFallback: true,
429
+ });
430
+ rawModelText = response.text;
431
+ usedModelId = response.modelId;
432
+ this.logger.info('Model inference completed', {
433
+ taskId,
434
+ attempt,
435
+ modelId: usedModelId,
436
+ latencyMs: response.latencyMs,
437
+ textLength: rawModelText.length,
438
+ });
439
+ }
440
+ catch (err) {
441
+ const msg = err instanceof Error ? err.message : String(err);
442
+ this.logger.error(`Model inference failed during plan synthesis (attempt ${attempt}): ${msg}`, { taskId });
443
+ return {
444
+ success: false,
445
+ errorCategory: (msg.toLowerCase().includes('timeout') || msg.toLowerCase().includes('timed out')) ? 'SYNTHESIS_TIMEOUT' : 'MODEL_UNAVAILABLE',
446
+ errorMessage: msg,
447
+ };
448
+ }
449
+ // 3. Extract JSON from raw model output
450
+ let parsed;
451
+ try {
452
+ parsed = this.extractJsonFromModelOutput(rawModelText);
453
+ }
454
+ catch (parseErr) {
455
+ const msg = parseErr instanceof Error ? parseErr.message : String(parseErr);
456
+ lastErrorCategory = 'PLAN_PARSE_FAILED';
457
+ lastErrorMessage = `Could not extract valid JSON from model output: ${msg}`;
458
+ this.logger.warn(`JSON extraction failed (attempt ${attempt}/${maxAttempts})`, { taskId, error: msg });
459
+ if (attempt < maxAttempts) {
460
+ continue; // Trigger bounded retry
461
+ }
462
+ return {
463
+ success: false,
464
+ errorCategory: 'PLAN_PARSE_FAILED',
465
+ errorMessage: lastErrorMessage,
466
+ };
467
+ }
468
+ // 4. Validate the parsed proposal
469
+ const validation = this.validator.validate(parsed, taskId, maxSteps, options.taskGoal);
470
+ if (!validation.valid) {
471
+ lastErrorCategory = 'PLAN_VALIDATION_FAILED';
472
+ lastValidationErrors = validation.errors;
473
+ lastErrorMessage = `Plan rejected: ${validation.errors.map((e) => e.message).join('; ')}`;
474
+ this.logger.warn(`Plan validation failed (attempt ${attempt}/${maxAttempts})`, {
475
+ taskId,
476
+ errorCount: validation.errors.length,
477
+ errors: validation.errors.map((e) => e.code),
478
+ });
479
+ if (attempt < maxAttempts) {
480
+ continue; // Trigger bounded retry
481
+ }
482
+ return {
483
+ success: false,
484
+ errorCategory: 'PLAN_VALIDATION_FAILED',
485
+ validationErrors: validation.errors,
486
+ errorMessage: lastErrorMessage,
487
+ };
488
+ }
489
+ // 5. Assemble the validated AgentPlan
490
+ const planVersion = ++this.planVersion;
491
+ const planId = `plan-${taskId}-v${planVersion}-${Date.now()}`;
492
+ const raw = parsed;
493
+ const rawSteps = raw['steps'];
494
+ const steps = rawSteps.map((s, idx) => {
495
+ const now = new Date().toISOString();
496
+ return {
497
+ stepId: String(s['stepId']),
498
+ taskId,
499
+ sequence: idx + 1,
500
+ stepType: 'tool_execution',
501
+ status: 'pending',
502
+ toolId: String(s['toolId']),
503
+ requestedCapabilities: s['requestedCapabilities'].slice(),
504
+ params: { ...s['params'] },
505
+ attemptCount: 0,
506
+ maxAttempts: 3,
507
+ createdAt: now,
508
+ updatedAt: now,
509
+ };
510
+ });
511
+ const plan = {
512
+ planId,
513
+ taskId,
514
+ version: planVersion,
515
+ steps,
516
+ reasoning: String(raw['reasoning']),
517
+ modelId: usedModelId,
518
+ synthesizedAt: new Date().toISOString(),
519
+ };
520
+ this.logger.info('Plan synthesis succeeded', {
521
+ taskId,
522
+ planId,
523
+ version: planVersion,
524
+ stepCount: steps.length,
525
+ modelId: usedModelId,
526
+ attempt,
527
+ });
528
+ return { success: true, plan };
529
+ }
530
+ return {
531
+ success: false,
532
+ errorCategory: lastErrorCategory,
533
+ validationErrors: lastValidationErrors,
534
+ errorMessage: lastErrorMessage,
535
+ };
536
+ }
537
+ // ---------------------------------------------------------------------------
538
+ // Private helpers
539
+ // ---------------------------------------------------------------------------
540
+ /**
541
+ * Build the structured planner prompt.
542
+ * Lists available registered tools with their IDs and required capabilities
543
+ * so the model can only reference tools that exist in the registry.
544
+ */
545
+ buildPlannerPrompt(taskGoal, maxSteps) {
546
+ const tools = this.toolGateway.listTools();
547
+ const toolLines = tools.length > 0
548
+ ? tools
549
+ .filter((t) => t.enabled)
550
+ .map((t) => {
551
+ const schemaKeys = t.inputSchema ? Object.keys(t.inputSchema).map((k) => `"${k}"`).join(', ') : '';
552
+ return ` - id: "${t.id}" | capabilities: [${t.requiredPermissions.map((p) => `"${p}"`).join(', ')}] | params: {${schemaKeys}} | risk: ${t.riskLevel} | description: ${t.description}`;
553
+ })
554
+ .join('\n')
555
+ : ' (none — no tools are registered)';
556
+ return [
557
+ `TASK GOAL: ${taskGoal}`,
558
+ '',
559
+ 'CONSTRAINTS:',
560
+ ` - Maximum steps: ${maxSteps}`,
561
+ ` - You may ONLY use the tools listed below.`,
562
+ ` - You MUST include at least 1 step to inspect, explore, or execute the goal.`,
563
+ ` - Do NOT output an empty steps array.`,
564
+ ` - Do NOT invent tool IDs or capabilities.`,
565
+ '',
566
+ 'AVAILABLE TOOLS:',
567
+ toolLines,
568
+ '',
569
+ 'Produce a minimal, valid JSON plan containing at least 1 step using the available tools to accomplish or inspect the goal.',
570
+ ].join('\n');
571
+ }
572
+ /**
573
+ * Build targeted retry prompt requesting JSON correction.
574
+ */
575
+ buildRetryPlannerPrompt(taskGoal, maxSteps, failureReason) {
576
+ const basePrompt = this.buildPlannerPrompt(taskGoal, maxSteps);
577
+ return [
578
+ basePrompt,
579
+ '',
580
+ 'CRITICAL REPAIR REQUIRED FOR THIS RETRY:',
581
+ `Your previous response failed validation/parsing with error:`,
582
+ `"${failureReason}"`,
583
+ '',
584
+ 'RETRY INSTRUCTIONS:',
585
+ '1. You MUST output ONLY valid JSON matching the exact REQUIRED OUTPUT FORMAT.',
586
+ '2. Escape all newlines in string literals as \\n and double quotes as \\".',
587
+ '3. Ensure all steps include stepId, toolId, requestedCapabilities, and params.',
588
+ '4. Do NOT output markdown code fences or conversational text.',
589
+ ].join('\n');
590
+ }
591
+ /**
592
+ * Extract a JSON object from raw model output.
593
+ *
594
+ * Handles:
595
+ * - Pure JSON responses (ideal)
596
+ * - JSON wrapped in markdown code fences (```json ... ```)
597
+ * - Leading/trailing conversational text
598
+ * - Sanitization of unescaped raw control characters (newlines/tabs) inside JSON strings
599
+ *
600
+ * Throws if no valid JSON object can be extracted.
601
+ */
602
+ extractJsonFromModelOutput(raw) {
603
+ const trimmed = raw.trim();
604
+ if (!trimmed) {
605
+ throw new Error('Model returned empty response');
606
+ }
607
+ const candidates = [];
608
+ // Candidate 1: markdown code fence content
609
+ const fenceMatch = trimmed.match(/```(?:json)?\s*([\s\S]*?)```/i);
610
+ if (fenceMatch && fenceMatch[1].trim()) {
611
+ candidates.push(fenceMatch[1].trim());
612
+ }
613
+ // Candidate 2: pure trimmed response
614
+ candidates.push(trimmed);
615
+ // Candidate 3: first '{' to last '}' block
616
+ const braceStart = trimmed.indexOf('{');
617
+ const braceEnd = trimmed.lastIndexOf('}');
618
+ if (braceStart !== -1 && braceEnd > braceStart) {
619
+ const slice = trimmed.slice(braceStart, braceEnd + 1).trim();
620
+ if (!candidates.includes(slice)) {
621
+ candidates.push(slice);
622
+ }
623
+ }
624
+ // Try parsing candidates: first raw JSON.parse, then sanitized JSON.parse
625
+ for (const cand of candidates) {
626
+ try {
627
+ return JSON.parse(cand);
628
+ }
629
+ catch {
630
+ try {
631
+ const sanitized = this.sanitizeJsonString(cand);
632
+ return JSON.parse(sanitized);
633
+ }
634
+ catch {
635
+ // continue
636
+ }
637
+ }
638
+ }
639
+ // Check for truncated JSON indicators
640
+ if (braceStart !== -1 && braceEnd <= braceStart) {
641
+ throw new Error('Truncated or incomplete JSON output (missing closing brace)');
642
+ }
643
+ throw new Error('No valid JSON object could be extracted from model output');
644
+ }
645
+ /**
646
+ * Repair unescaped raw newlines, tabs, and trailing commas inside JSON string candidate.
647
+ */
648
+ sanitizeJsonString(jsonStr) {
649
+ // Remove trailing commas in objects and arrays
650
+ const clean = jsonStr.replace(/,\s*([}\]])/g, '$1');
651
+ let inString = false;
652
+ let escaped = false;
653
+ let result = '';
654
+ for (let i = 0; i < clean.length; i++) {
655
+ const ch = clean[i];
656
+ if (inString) {
657
+ if (escaped) {
658
+ result += ch;
659
+ escaped = false;
660
+ }
661
+ else if (ch === '\\') {
662
+ result += ch;
663
+ escaped = true;
664
+ }
665
+ else if (ch === '"') {
666
+ result += ch;
667
+ inString = false;
668
+ }
669
+ else if (ch === '\n') {
670
+ result += '\\n';
671
+ }
672
+ else if (ch === '\r') {
673
+ // drop CR
674
+ }
675
+ else if (ch === '\t') {
676
+ result += '\\t';
677
+ }
678
+ else {
679
+ result += ch;
680
+ }
681
+ }
682
+ else {
683
+ if (ch === '"') {
684
+ inString = true;
685
+ }
686
+ result += ch;
687
+ }
688
+ }
689
+ return result;
690
+ }
691
+ }
692
+ //# sourceMappingURL=planner.js.map