@exellix/ai-tasks 7.8.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 (524) hide show
  1. package/.env.example +3 -0
  2. package/.metadata/instructions-builders/create-expected-output-instructions.md +195 -0
  3. package/.metadata/readme.md +48 -0
  4. package/.metadata/shared/audit.md +29 -0
  5. package/.metadata/skills/professional-answer +32 -0
  6. package/.metadata/skills/professional-answer.compressed.md +11 -0
  7. package/.metadata/skills/professional-answer.instructions +33 -0
  8. package/.metadata/skills/professional-answer.instructions.md +33 -0
  9. package/.metadata/skills/professional-answer.l2.md +28 -0
  10. package/.metadata/skills/professional-answer.md +32 -0
  11. package/.metadata/skills/professional-answer.prompt +1 -0
  12. package/.metadata/skills/professional-answer.prompt.md +1 -0
  13. package/.metadata/skills/professional-decision.md +26 -0
  14. package/BREAKING-CHANGES.md +43 -0
  15. package/CHANGELOG.md +147 -0
  16. package/README.md +2497 -0
  17. package/RUNTASK_REQUEST.md +369 -0
  18. package/dist/activix/activixClient.d.ts +6 -0
  19. package/dist/activix/activixClient.d.ts.map +1 -0
  20. package/dist/activix/activixClient.js +131 -0
  21. package/dist/activix/activixClient.js.map +1 -0
  22. package/dist/activix/getTaskActivities.d.ts +10 -0
  23. package/dist/activix/getTaskActivities.d.ts.map +1 -0
  24. package/dist/activix/getTaskActivities.js +17 -0
  25. package/dist/activix/getTaskActivities.js.map +1 -0
  26. package/dist/activix/phaseTracking.d.ts +17 -0
  27. package/dist/activix/phaseTracking.d.ts.map +1 -0
  28. package/dist/activix/phaseTracking.js +85 -0
  29. package/dist/activix/phaseTracking.js.map +1 -0
  30. package/dist/aiScoping/index.d.ts +6 -0
  31. package/dist/aiScoping/index.d.ts.map +1 -0
  32. package/dist/aiScoping/index.js +4 -0
  33. package/dist/aiScoping/index.js.map +1 -0
  34. package/dist/aiScoping/runAiScoping.d.ts +36 -0
  35. package/dist/aiScoping/runAiScoping.d.ts.map +1 -0
  36. package/dist/aiScoping/runAiScoping.js +100 -0
  37. package/dist/aiScoping/runAiScoping.js.map +1 -0
  38. package/dist/aiScoping/runScopingCall.d.ts +23 -0
  39. package/dist/aiScoping/runScopingCall.d.ts.map +1 -0
  40. package/dist/aiScoping/runScopingCall.js +50 -0
  41. package/dist/aiScoping/runScopingCall.js.map +1 -0
  42. package/dist/aiScoping/validateAiScoping.d.ts +7 -0
  43. package/dist/aiScoping/validateAiScoping.d.ts.map +1 -0
  44. package/dist/aiScoping/validateAiScoping.js +33 -0
  45. package/dist/aiScoping/validateAiScoping.js.map +1 -0
  46. package/dist/aiSkillsUpstreamExports.d.ts +13 -0
  47. package/dist/aiSkillsUpstreamExports.d.ts.map +1 -0
  48. package/dist/aiSkillsUpstreamExports.js +12 -0
  49. package/dist/aiSkillsUpstreamExports.js.map +1 -0
  50. package/dist/analysis/analyzeRunTaskRequest.d.ts +29 -0
  51. package/dist/analysis/analyzeRunTaskRequest.d.ts.map +1 -0
  52. package/dist/analysis/analyzeRunTaskRequest.js +85 -0
  53. package/dist/analysis/analyzeRunTaskRequest.js.map +1 -0
  54. package/dist/analysis/index.d.ts +3 -0
  55. package/dist/analysis/index.d.ts.map +1 -0
  56. package/dist/analysis/index.js +2 -0
  57. package/dist/analysis/index.js.map +1 -0
  58. package/dist/builders/task-request-builder.d.ts +310 -0
  59. package/dist/builders/task-request-builder.d.ts.map +1 -0
  60. package/dist/builders/task-request-builder.js +581 -0
  61. package/dist/builders/task-request-builder.js.map +1 -0
  62. package/dist/compile/compileTaskConfiguration.d.ts +15 -0
  63. package/dist/compile/compileTaskConfiguration.d.ts.map +1 -0
  64. package/dist/compile/compileTaskConfiguration.js +184 -0
  65. package/dist/compile/compileTaskConfiguration.js.map +1 -0
  66. package/dist/compile/index.d.ts +2 -0
  67. package/dist/compile/index.d.ts.map +1 -0
  68. package/dist/compile/index.js +2 -0
  69. package/dist/compile/index.js.map +1 -0
  70. package/dist/core/task-sdk.d.ts +36 -0
  71. package/dist/core/task-sdk.d.ts.map +1 -0
  72. package/dist/core/task-sdk.js +2432 -0
  73. package/dist/core/task-sdk.js.map +1 -0
  74. package/dist/errors/smartInputValidationError.d.ts +39 -0
  75. package/dist/errors/smartInputValidationError.d.ts.map +1 -0
  76. package/dist/errors/smartInputValidationError.js +97 -0
  77. package/dist/errors/smartInputValidationError.js.map +1 -0
  78. package/dist/errors/taskConfigurationCompileError.d.ts +16 -0
  79. package/dist/errors/taskConfigurationCompileError.d.ts.map +1 -0
  80. package/dist/errors/taskConfigurationCompileError.js +20 -0
  81. package/dist/errors/taskConfigurationCompileError.js.map +1 -0
  82. package/dist/execution-strategies/applyExecutionStrategyOutputs.d.ts +17 -0
  83. package/dist/execution-strategies/applyExecutionStrategyOutputs.d.ts.map +1 -0
  84. package/dist/execution-strategies/applyExecutionStrategyOutputs.js +63 -0
  85. package/dist/execution-strategies/applyExecutionStrategyOutputs.js.map +1 -0
  86. package/dist/execution-strategies/constants.d.ts +14 -0
  87. package/dist/execution-strategies/constants.d.ts.map +1 -0
  88. package/dist/execution-strategies/constants.js +13 -0
  89. package/dist/execution-strategies/constants.js.map +1 -0
  90. package/dist/execution-strategies/executionStrategyCatalogMetadata.d.ts +9 -0
  91. package/dist/execution-strategies/executionStrategyCatalogMetadata.d.ts.map +1 -0
  92. package/dist/execution-strategies/executionStrategyCatalogMetadata.js +37 -0
  93. package/dist/execution-strategies/executionStrategyCatalogMetadata.js.map +1 -0
  94. package/dist/execution-strategies/genericExecutionFuncxEnvelope.d.ts +94 -0
  95. package/dist/execution-strategies/genericExecutionFuncxEnvelope.d.ts.map +1 -0
  96. package/dist/execution-strategies/genericExecutionFuncxEnvelope.js +306 -0
  97. package/dist/execution-strategies/genericExecutionFuncxEnvelope.js.map +1 -0
  98. package/dist/execution-strategies/resolveExecutionStrategies.d.ts +14 -0
  99. package/dist/execution-strategies/resolveExecutionStrategies.d.ts.map +1 -0
  100. package/dist/execution-strategies/resolveExecutionStrategies.js +108 -0
  101. package/dist/execution-strategies/resolveExecutionStrategies.js.map +1 -0
  102. package/dist/execution-strategies/runFuncxExecutionStrategy.d.ts +37 -0
  103. package/dist/execution-strategies/runFuncxExecutionStrategy.d.ts.map +1 -0
  104. package/dist/execution-strategies/runFuncxExecutionStrategy.js +72 -0
  105. package/dist/execution-strategies/runFuncxExecutionStrategy.js.map +1 -0
  106. package/dist/index.d.ts +99 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +106 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/internal/resolveLlmCallForXynthesis.d.ts +52 -0
  111. package/dist/internal/resolveLlmCallForXynthesis.d.ts.map +1 -0
  112. package/dist/internal/resolveLlmCallForXynthesis.js +81 -0
  113. package/dist/internal/resolveLlmCallForXynthesis.js.map +1 -0
  114. package/dist/internal/resolveRunTaskRuntimeKnobs.d.ts +19 -0
  115. package/dist/internal/resolveRunTaskRuntimeKnobs.d.ts.map +1 -0
  116. package/dist/internal/resolveRunTaskRuntimeKnobs.js +52 -0
  117. package/dist/internal/resolveRunTaskRuntimeKnobs.js.map +1 -0
  118. package/dist/internal/runPostStepLlmCall.d.ts +52 -0
  119. package/dist/internal/runPostStepLlmCall.d.ts.map +1 -0
  120. package/dist/internal/runPostStepLlmCall.js +170 -0
  121. package/dist/internal/runPostStepLlmCall.js.map +1 -0
  122. package/dist/localTasks/collectEvidence.d.ts +3 -0
  123. package/dist/localTasks/collectEvidence.d.ts.map +1 -0
  124. package/dist/localTasks/collectEvidence.js +364 -0
  125. package/dist/localTasks/collectEvidence.js.map +1 -0
  126. package/dist/localTasks/decideWebScope.d.ts +3 -0
  127. package/dist/localTasks/decideWebScope.d.ts.map +1 -0
  128. package/dist/localTasks/decideWebScope.js +56 -0
  129. package/dist/localTasks/decideWebScope.js.map +1 -0
  130. package/dist/localTasks/index.d.ts +5 -0
  131. package/dist/localTasks/index.d.ts.map +1 -0
  132. package/dist/localTasks/index.js +19 -0
  133. package/dist/localTasks/index.js.map +1 -0
  134. package/dist/localTasks/narrixAssetPlayground.d.ts +13 -0
  135. package/dist/localTasks/narrixAssetPlayground.d.ts.map +1 -0
  136. package/dist/localTasks/narrixAssetPlayground.js +161 -0
  137. package/dist/localTasks/narrixAssetPlayground.js.map +1 -0
  138. package/dist/localTasks/narrixSubnetPlayground.d.ts +14 -0
  139. package/dist/localTasks/narrixSubnetPlayground.d.ts.map +1 -0
  140. package/dist/localTasks/narrixSubnetPlayground.js +168 -0
  141. package/dist/localTasks/narrixSubnetPlayground.js.map +1 -0
  142. package/dist/localTasks/narrixVulnGroupPlayground.d.ts +13 -0
  143. package/dist/localTasks/narrixVulnGroupPlayground.d.ts.map +1 -0
  144. package/dist/localTasks/narrixVulnGroupPlayground.js +161 -0
  145. package/dist/localTasks/narrixVulnGroupPlayground.js.map +1 -0
  146. package/dist/localTasks/narrixVulnInstancePlayground.d.ts +13 -0
  147. package/dist/localTasks/narrixVulnInstancePlayground.d.ts.map +1 -0
  148. package/dist/localTasks/narrixVulnInstancePlayground.js +165 -0
  149. package/dist/localTasks/narrixVulnInstancePlayground.js.map +1 -0
  150. package/dist/localTasks/nodeCallExport.d.ts +6 -0
  151. package/dist/localTasks/nodeCallExport.d.ts.map +1 -0
  152. package/dist/localTasks/nodeCallExport.js +99 -0
  153. package/dist/localTasks/nodeCallExport.js.map +1 -0
  154. package/dist/localTasks/nodeCallExportBatch.d.ts +3 -0
  155. package/dist/localTasks/nodeCallExportBatch.d.ts.map +1 -0
  156. package/dist/localTasks/nodeCallExportBatch.js +52 -0
  157. package/dist/localTasks/nodeCallExportBatch.js.map +1 -0
  158. package/dist/localTasks/normalizeNarrixResult.d.ts +3 -0
  159. package/dist/localTasks/normalizeNarrixResult.d.ts.map +1 -0
  160. package/dist/localTasks/normalizeNarrixResult.js +106 -0
  161. package/dist/localTasks/normalizeNarrixResult.js.map +1 -0
  162. package/dist/localTasks/registry.d.ts +4 -0
  163. package/dist/localTasks/registry.d.ts.map +1 -0
  164. package/dist/localTasks/registry.js +8 -0
  165. package/dist/localTasks/registry.js.map +1 -0
  166. package/dist/localTasks/types.d.ts +28 -0
  167. package/dist/localTasks/types.d.ts.map +1 -0
  168. package/dist/localTasks/types.js +2 -0
  169. package/dist/localTasks/types.js.map +1 -0
  170. package/dist/localTasks/validateInput.d.ts +3 -0
  171. package/dist/localTasks/validateInput.d.ts.map +1 -0
  172. package/dist/localTasks/validateInput.js +66 -0
  173. package/dist/localTasks/validateInput.js.map +1 -0
  174. package/dist/methods/convenience-methods.d.ts +45 -0
  175. package/dist/methods/convenience-methods.d.ts.map +1 -0
  176. package/dist/methods/convenience-methods.js +39 -0
  177. package/dist/methods/convenience-methods.js.map +1 -0
  178. package/dist/narrix/applyNarrixScope.d.ts +10 -0
  179. package/dist/narrix/applyNarrixScope.d.ts.map +1 -0
  180. package/dist/narrix/applyNarrixScope.js +69 -0
  181. package/dist/narrix/applyNarrixScope.js.map +1 -0
  182. package/dist/narrix/buildNarrixAttachment.d.ts +9 -0
  183. package/dist/narrix/buildNarrixAttachment.d.ts.map +1 -0
  184. package/dist/narrix/buildNarrixAttachment.js +29 -0
  185. package/dist/narrix/buildNarrixAttachment.js.map +1 -0
  186. package/dist/narrix/buildWebScopeScopeInput.d.ts +39 -0
  187. package/dist/narrix/buildWebScopeScopeInput.d.ts.map +1 -0
  188. package/dist/narrix/buildWebScopeScopeInput.js +193 -0
  189. package/dist/narrix/buildWebScopeScopeInput.js.map +1 -0
  190. package/dist/narrix/flags.d.ts +4 -0
  191. package/dist/narrix/flags.d.ts.map +1 -0
  192. package/dist/narrix/flags.js +4 -0
  193. package/dist/narrix/flags.js.map +1 -0
  194. package/dist/narrix/index.d.ts +11 -0
  195. package/dist/narrix/index.d.ts.map +1 -0
  196. package/dist/narrix/index.js +14 -0
  197. package/dist/narrix/index.js.map +1 -0
  198. package/dist/narrix/narrixClient.d.ts +9 -0
  199. package/dist/narrix/narrixClient.d.ts.map +1 -0
  200. package/dist/narrix/narrixClient.js +46 -0
  201. package/dist/narrix/narrixClient.js.map +1 -0
  202. package/dist/narrix/narrixContextMarkdown.d.ts +15 -0
  203. package/dist/narrix/narrixContextMarkdown.d.ts.map +1 -0
  204. package/dist/narrix/narrixContextMarkdown.js +98 -0
  205. package/dist/narrix/narrixContextMarkdown.js.map +1 -0
  206. package/dist/narrix/narrixRunnerModule.d.ts +11 -0
  207. package/dist/narrix/narrixRunnerModule.d.ts.map +1 -0
  208. package/dist/narrix/narrixRunnerModule.js +17 -0
  209. package/dist/narrix/narrixRunnerModule.js.map +1 -0
  210. package/dist/narrix/runNarrixForChat.d.ts +3 -0
  211. package/dist/narrix/runNarrixForChat.d.ts.map +1 -0
  212. package/dist/narrix/runNarrixForChat.js +51 -0
  213. package/dist/narrix/runNarrixForChat.js.map +1 -0
  214. package/dist/narrix/runNarrixForDocs.d.ts +3 -0
  215. package/dist/narrix/runNarrixForDocs.d.ts.map +1 -0
  216. package/dist/narrix/runNarrixForDocs.js +50 -0
  217. package/dist/narrix/runNarrixForDocs.js.map +1 -0
  218. package/dist/narrix/runNarrixForRecord.d.ts +3 -0
  219. package/dist/narrix/runNarrixForRecord.d.ts.map +1 -0
  220. package/dist/narrix/runNarrixForRecord.js +47 -0
  221. package/dist/narrix/runNarrixForRecord.js.map +1 -0
  222. package/dist/narrix/runNarrixForText.d.ts +3 -0
  223. package/dist/narrix/runNarrixForText.d.ts.map +1 -0
  224. package/dist/narrix/runNarrixForText.js +49 -0
  225. package/dist/narrix/runNarrixForText.js.map +1 -0
  226. package/dist/narrix/runnerDispatch.d.ts +12 -0
  227. package/dist/narrix/runnerDispatch.d.ts.map +1 -0
  228. package/dist/narrix/runnerDispatch.js +19 -0
  229. package/dist/narrix/runnerDispatch.js.map +1 -0
  230. package/dist/narrix/seedBundleRouting.d.ts +15 -0
  231. package/dist/narrix/seedBundleRouting.d.ts.map +1 -0
  232. package/dist/narrix/seedBundleRouting.js +46 -0
  233. package/dist/narrix/seedBundleRouting.js.map +1 -0
  234. package/dist/narrix/task.d.ts +4 -0
  235. package/dist/narrix/task.d.ts.map +1 -0
  236. package/dist/narrix/task.js +143 -0
  237. package/dist/narrix/task.js.map +1 -0
  238. package/dist/narrix/types.d.ts +104 -0
  239. package/dist/narrix/types.d.ts.map +1 -0
  240. package/dist/narrix/types.js +3 -0
  241. package/dist/narrix/types.js.map +1 -0
  242. package/dist/narrix/webContextMarkdown.d.ts +54 -0
  243. package/dist/narrix/webContextMarkdown.d.ts.map +1 -0
  244. package/dist/narrix/webContextMarkdown.js +206 -0
  245. package/dist/narrix/webContextMarkdown.js.map +1 -0
  246. package/dist/narrix/webScoper.d.ts +43 -0
  247. package/dist/narrix/webScoper.d.ts.map +1 -0
  248. package/dist/narrix/webScoper.js +144 -0
  249. package/dist/narrix/webScoper.js.map +1 -0
  250. package/dist/observability/debugTrace.d.ts +31 -0
  251. package/dist/observability/debugTrace.d.ts.map +1 -0
  252. package/dist/observability/debugTrace.js +117 -0
  253. package/dist/observability/debugTrace.js.map +1 -0
  254. package/dist/observability/extractAiTasksObservability.d.ts +7 -0
  255. package/dist/observability/extractAiTasksObservability.d.ts.map +1 -0
  256. package/dist/observability/extractAiTasksObservability.js +98 -0
  257. package/dist/observability/extractAiTasksObservability.js.map +1 -0
  258. package/dist/observability/graphExecutionRunLogContract.d.ts +19 -0
  259. package/dist/observability/graphExecutionRunLogContract.d.ts.map +1 -0
  260. package/dist/observability/graphExecutionRunLogContract.js +11 -0
  261. package/dist/observability/graphExecutionRunLogContract.js.map +1 -0
  262. package/dist/packaged-tasks-client.d.ts +66 -0
  263. package/dist/packaged-tasks-client.d.ts.map +1 -0
  264. package/dist/packaged-tasks-client.js +100 -0
  265. package/dist/packaged-tasks-client.js.map +1 -0
  266. package/dist/planWebScopeQuestions/index.d.ts +78 -0
  267. package/dist/planWebScopeQuestions/index.d.ts.map +1 -0
  268. package/dist/planWebScopeQuestions/index.js +282 -0
  269. package/dist/planWebScopeQuestions/index.js.map +1 -0
  270. package/dist/planWebScopeQuestions/runResearchPlanQuestionsFuncx.d.ts +18 -0
  271. package/dist/planWebScopeQuestions/runResearchPlanQuestionsFuncx.d.ts.map +1 -0
  272. package/dist/planWebScopeQuestions/runResearchPlanQuestionsFuncx.js +42 -0
  273. package/dist/planWebScopeQuestions/runResearchPlanQuestionsFuncx.js.map +1 -0
  274. package/dist/post-steps/audit/loadAuditTemplates.d.ts +72 -0
  275. package/dist/post-steps/audit/loadAuditTemplates.d.ts.map +1 -0
  276. package/dist/post-steps/audit/loadAuditTemplates.js +62 -0
  277. package/dist/post-steps/audit/loadAuditTemplates.js.map +1 -0
  278. package/dist/post-steps/audit/parseAuditOutput.d.ts +11 -0
  279. package/dist/post-steps/audit/parseAuditOutput.d.ts.map +1 -0
  280. package/dist/post-steps/audit/parseAuditOutput.js +50 -0
  281. package/dist/post-steps/audit/parseAuditOutput.js.map +1 -0
  282. package/dist/post-steps/audit/runAudit.d.ts +22 -0
  283. package/dist/post-steps/audit/runAudit.d.ts.map +1 -0
  284. package/dist/post-steps/audit/runAudit.js +406 -0
  285. package/dist/post-steps/audit/runAudit.js.map +1 -0
  286. package/dist/post-steps/audit/runAuditCall.d.ts +23 -0
  287. package/dist/post-steps/audit/runAuditCall.d.ts.map +1 -0
  288. package/dist/post-steps/audit/runAuditCall.js +32 -0
  289. package/dist/post-steps/audit/runAuditCall.js.map +1 -0
  290. package/dist/post-steps/polish/loadPolishTemplates.d.ts +35 -0
  291. package/dist/post-steps/polish/loadPolishTemplates.d.ts.map +1 -0
  292. package/dist/post-steps/polish/loadPolishTemplates.js +38 -0
  293. package/dist/post-steps/polish/loadPolishTemplates.js.map +1 -0
  294. package/dist/post-steps/polish/parsePolishOutput.d.ts +6 -0
  295. package/dist/post-steps/polish/parsePolishOutput.d.ts.map +1 -0
  296. package/dist/post-steps/polish/parsePolishOutput.js +47 -0
  297. package/dist/post-steps/polish/parsePolishOutput.js.map +1 -0
  298. package/dist/post-steps/polish/runPolish.d.ts +24 -0
  299. package/dist/post-steps/polish/runPolish.d.ts.map +1 -0
  300. package/dist/post-steps/polish/runPolish.js +147 -0
  301. package/dist/post-steps/polish/runPolish.js.map +1 -0
  302. package/dist/post-steps/polish/runPolishCall.d.ts +22 -0
  303. package/dist/post-steps/polish/runPolishCall.d.ts.map +1 -0
  304. package/dist/post-steps/polish/runPolishCall.js +32 -0
  305. package/dist/post-steps/polish/runPolishCall.js.map +1 -0
  306. package/dist/post-steps/resolvePostStepConfig.d.ts +58 -0
  307. package/dist/post-steps/resolvePostStepConfig.d.ts.map +1 -0
  308. package/dist/post-steps/resolvePostStepConfig.js +105 -0
  309. package/dist/post-steps/resolvePostStepConfig.js.map +1 -0
  310. package/dist/rendrixUpstreamExports.d.ts +7 -0
  311. package/dist/rendrixUpstreamExports.d.ts.map +1 -0
  312. package/dist/rendrixUpstreamExports.js +6 -0
  313. package/dist/rendrixUpstreamExports.js.map +1 -0
  314. package/dist/skillCatalogExports.d.ts +8 -0
  315. package/dist/skillCatalogExports.d.ts.map +1 -0
  316. package/dist/skillCatalogExports.js +8 -0
  317. package/dist/skillCatalogExports.js.map +1 -0
  318. package/dist/strategies/direct-execution-strategy.d.ts +31 -0
  319. package/dist/strategies/direct-execution-strategy.d.ts.map +1 -0
  320. package/dist/strategies/direct-execution-strategy.js +107 -0
  321. package/dist/strategies/direct-execution-strategy.js.map +1 -0
  322. package/dist/strategies/execution-strategy.interface.d.ts +31 -0
  323. package/dist/strategies/execution-strategy.interface.d.ts.map +1 -0
  324. package/dist/strategies/execution-strategy.interface.js +2 -0
  325. package/dist/strategies/execution-strategy.interface.js.map +1 -0
  326. package/dist/strategies/index.d.ts +9 -0
  327. package/dist/strategies/index.d.ts.map +1 -0
  328. package/dist/strategies/index.js +8 -0
  329. package/dist/strategies/index.js.map +1 -0
  330. package/dist/strategies/strategy-factory.d.ts +45 -0
  331. package/dist/strategies/strategy-factory.d.ts.map +1 -0
  332. package/dist/strategies/strategy-factory.js +59 -0
  333. package/dist/strategies/strategy-factory.js.map +1 -0
  334. package/dist/synthesis/index.d.ts +9 -0
  335. package/dist/synthesis/index.d.ts.map +1 -0
  336. package/dist/synthesis/index.js +8 -0
  337. package/dist/synthesis/index.js.map +1 -0
  338. package/dist/synthesis/resolveSourceMaterial.d.ts +35 -0
  339. package/dist/synthesis/resolveSourceMaterial.d.ts.map +1 -0
  340. package/dist/synthesis/resolveSourceMaterial.js +152 -0
  341. package/dist/synthesis/resolveSourceMaterial.js.map +1 -0
  342. package/dist/synthesis/runStructuredSynthesisRobust.d.ts +42 -0
  343. package/dist/synthesis/runStructuredSynthesisRobust.d.ts.map +1 -0
  344. package/dist/synthesis/runStructuredSynthesisRobust.js +303 -0
  345. package/dist/synthesis/runStructuredSynthesisRobust.js.map +1 -0
  346. package/dist/task-strategies/buildTaskStrategyCatalogDescriptor.d.ts +19 -0
  347. package/dist/task-strategies/buildTaskStrategyCatalogDescriptor.d.ts.map +1 -0
  348. package/dist/task-strategies/buildTaskStrategyCatalogDescriptor.js +242 -0
  349. package/dist/task-strategies/buildTaskStrategyCatalogDescriptor.js.map +1 -0
  350. package/dist/task-strategies/canonicalInputExecutionStrategies.d.ts +171 -0
  351. package/dist/task-strategies/canonicalInputExecutionStrategies.d.ts.map +1 -0
  352. package/dist/task-strategies/canonicalInputExecutionStrategies.js +117 -0
  353. package/dist/task-strategies/canonicalInputExecutionStrategies.js.map +1 -0
  354. package/dist/task-strategies/canonicalNarrixModes.d.ts +31 -0
  355. package/dist/task-strategies/canonicalNarrixModes.d.ts.map +1 -0
  356. package/dist/task-strategies/canonicalNarrixModes.js +35 -0
  357. package/dist/task-strategies/canonicalNarrixModes.js.map +1 -0
  358. package/dist/task-strategies/canonicalTaskStrategies.d.ts +104 -0
  359. package/dist/task-strategies/canonicalTaskStrategies.d.ts.map +1 -0
  360. package/dist/task-strategies/canonicalTaskStrategies.js +77 -0
  361. package/dist/task-strategies/canonicalTaskStrategies.js.map +1 -0
  362. package/dist/task-strategies/cataloxCatalogViews.d.ts +55 -0
  363. package/dist/task-strategies/cataloxCatalogViews.d.ts.map +1 -0
  364. package/dist/task-strategies/cataloxCatalogViews.js +65 -0
  365. package/dist/task-strategies/cataloxCatalogViews.js.map +1 -0
  366. package/dist/task-strategies/constants.d.ts +49 -0
  367. package/dist/task-strategies/constants.d.ts.map +1 -0
  368. package/dist/task-strategies/constants.js +49 -0
  369. package/dist/task-strategies/constants.js.map +1 -0
  370. package/dist/task-strategies/index.d.ts +22 -0
  371. package/dist/task-strategies/index.d.ts.map +1 -0
  372. package/dist/task-strategies/index.js +13 -0
  373. package/dist/task-strategies/index.js.map +1 -0
  374. package/dist/task-strategies/listAiTaskStrategies.d.ts +43 -0
  375. package/dist/task-strategies/listAiTaskStrategies.d.ts.map +1 -0
  376. package/dist/task-strategies/listAiTaskStrategies.js +74 -0
  377. package/dist/task-strategies/listAiTaskStrategies.js.map +1 -0
  378. package/dist/task-strategies/normalize.d.ts +7 -0
  379. package/dist/task-strategies/normalize.d.ts.map +1 -0
  380. package/dist/task-strategies/normalize.js +44 -0
  381. package/dist/task-strategies/normalize.js.map +1 -0
  382. package/dist/task-strategies/types.d.ts +37 -0
  383. package/dist/task-strategies/types.d.ts.map +1 -0
  384. package/dist/task-strategies/types.js +2 -0
  385. package/dist/task-strategies/types.js.map +1 -0
  386. package/dist/types/decision-contracts.d.ts +31 -0
  387. package/dist/types/decision-contracts.d.ts.map +1 -0
  388. package/dist/types/decision-contracts.js +23 -0
  389. package/dist/types/decision-contracts.js.map +1 -0
  390. package/dist/types/evidence-types.d.ts +108 -0
  391. package/dist/types/evidence-types.d.ts.map +1 -0
  392. package/dist/types/evidence-types.js +9 -0
  393. package/dist/types/evidence-types.js.map +1 -0
  394. package/dist/types/executionType.d.ts +9 -0
  395. package/dist/types/executionType.d.ts.map +1 -0
  396. package/dist/types/executionType.js +8 -0
  397. package/dist/types/executionType.js.map +1 -0
  398. package/dist/types/index.d.ts +28 -0
  399. package/dist/types/index.d.ts.map +1 -0
  400. package/dist/types/index.js +12 -0
  401. package/dist/types/index.js.map +1 -0
  402. package/dist/types/llmCall.d.ts +121 -0
  403. package/dist/types/llmCall.d.ts.map +1 -0
  404. package/dist/types/llmCall.js +39 -0
  405. package/dist/types/llmCall.js.map +1 -0
  406. package/dist/types/task-configuration.d.ts +60 -0
  407. package/dist/types/task-configuration.d.ts.map +1 -0
  408. package/dist/types/task-configuration.js +3 -0
  409. package/dist/types/task-configuration.js.map +1 -0
  410. package/dist/types/task-types.d.ts +887 -0
  411. package/dist/types/task-types.d.ts.map +1 -0
  412. package/dist/types/task-types.js +21 -0
  413. package/dist/types/task-types.js.map +1 -0
  414. package/dist/utilities/runUtility.d.ts +3 -0
  415. package/dist/utilities/runUtility.d.ts.map +1 -0
  416. package/dist/utilities/runUtility.js +204 -0
  417. package/dist/utilities/runUtility.js.map +1 -0
  418. package/dist/utils/assertRequiredRunSkillCorrelation.d.ts +7 -0
  419. package/dist/utils/assertRequiredRunSkillCorrelation.d.ts.map +1 -0
  420. package/dist/utils/assertRequiredRunSkillCorrelation.js +17 -0
  421. package/dist/utils/assertRequiredRunSkillCorrelation.js.map +1 -0
  422. package/dist/utils/assertValidSmartInputConfig.d.ts +5 -0
  423. package/dist/utils/assertValidSmartInputConfig.d.ts.map +1 -0
  424. package/dist/utils/assertValidSmartInputConfig.js +71 -0
  425. package/dist/utils/assertValidSmartInputConfig.js.map +1 -0
  426. package/dist/utils/bridgeRunSkillGatewayMemory.d.ts +13 -0
  427. package/dist/utils/bridgeRunSkillGatewayMemory.d.ts.map +1 -0
  428. package/dist/utils/bridgeRunSkillGatewayMemory.js +65 -0
  429. package/dist/utils/bridgeRunSkillGatewayMemory.js.map +1 -0
  430. package/dist/utils/extractSmartInputRenderResult.d.ts +7 -0
  431. package/dist/utils/extractSmartInputRenderResult.d.ts.map +1 -0
  432. package/dist/utils/extractSmartInputRenderResult.js +30 -0
  433. package/dist/utils/extractSmartInputRenderResult.js.map +1 -0
  434. package/dist/utils/jsonPaths.d.ts +6 -0
  435. package/dist/utils/jsonPaths.d.ts.map +1 -0
  436. package/dist/utils/jsonPaths.js +32 -0
  437. package/dist/utils/jsonPaths.js.map +1 -0
  438. package/dist/utils/normalizeSmartInputConfig.d.ts +5 -0
  439. package/dist/utils/normalizeSmartInputConfig.d.ts.map +1 -0
  440. package/dist/utils/normalizeSmartInputConfig.js +30 -0
  441. package/dist/utils/normalizeSmartInputConfig.js.map +1 -0
  442. package/dist/utils/outputValidation.d.ts +19 -0
  443. package/dist/utils/outputValidation.d.ts.map +1 -0
  444. package/dist/utils/outputValidation.js +75 -0
  445. package/dist/utils/outputValidation.js.map +1 -0
  446. package/dist/utils/runTaskRequestShape.d.ts +16 -0
  447. package/dist/utils/runTaskRequestShape.d.ts.map +1 -0
  448. package/dist/utils/runTaskRequestShape.js +80 -0
  449. package/dist/utils/runTaskRequestShape.js.map +1 -0
  450. package/dist/utils/skillTemplateVariables.d.ts +20 -0
  451. package/dist/utils/skillTemplateVariables.d.ts.map +1 -0
  452. package/dist/utils/skillTemplateVariables.js +63 -0
  453. package/dist/utils/skillTemplateVariables.js.map +1 -0
  454. package/dist/utils/xynthesizedSmartInputPaths.d.ts +16 -0
  455. package/dist/utils/xynthesizedSmartInputPaths.d.ts.map +1 -0
  456. package/dist/utils/xynthesizedSmartInputPaths.js +56 -0
  457. package/dist/utils/xynthesizedSmartInputPaths.js.map +1 -0
  458. package/dist/utils/xynthesizedWrite.d.ts +10 -0
  459. package/dist/utils/xynthesizedWrite.d.ts.map +1 -0
  460. package/dist/utils/xynthesizedWrite.js +61 -0
  461. package/dist/utils/xynthesizedWrite.js.map +1 -0
  462. package/dist/validation/analyzeExpectedRunTaskInput.d.ts +41 -0
  463. package/dist/validation/analyzeExpectedRunTaskInput.d.ts.map +1 -0
  464. package/dist/validation/analyzeExpectedRunTaskInput.js +133 -0
  465. package/dist/validation/analyzeExpectedRunTaskInput.js.map +1 -0
  466. package/dist/validation/collectSmartInputValidationIssues.d.ts +6 -0
  467. package/dist/validation/collectSmartInputValidationIssues.d.ts.map +1 -0
  468. package/dist/validation/collectSmartInputValidationIssues.js +38 -0
  469. package/dist/validation/collectSmartInputValidationIssues.js.map +1 -0
  470. package/dist/validation/helpers.d.ts +15 -0
  471. package/dist/validation/helpers.d.ts.map +1 -0
  472. package/dist/validation/helpers.js +184 -0
  473. package/dist/validation/helpers.js.map +1 -0
  474. package/dist/validation/index.d.ts +9 -0
  475. package/dist/validation/index.d.ts.map +1 -0
  476. package/dist/validation/index.js +6 -0
  477. package/dist/validation/index.js.map +1 -0
  478. package/dist/validation/types.d.ts +51 -0
  479. package/dist/validation/types.d.ts.map +1 -0
  480. package/dist/validation/types.js +5 -0
  481. package/dist/validation/types.js.map +1 -0
  482. package/dist/validation/validateRunTaskConfig.d.ts +8 -0
  483. package/dist/validation/validateRunTaskConfig.d.ts.map +1 -0
  484. package/dist/validation/validateRunTaskConfig.js +158 -0
  485. package/dist/validation/validateRunTaskConfig.js.map +1 -0
  486. package/dist/validation/validateRunTaskInvoke.d.ts +30 -0
  487. package/dist/validation/validateRunTaskInvoke.d.ts.map +1 -0
  488. package/dist/validation/validateRunTaskInvoke.js +108 -0
  489. package/dist/validation/validateRunTaskInvoke.js.map +1 -0
  490. package/documenations/activix-feature-request-identity.md +123 -0
  491. package/documenations/activix.md +175 -0
  492. package/documenations/bug-report-xynthesis-and-synthesis-call.md +217 -0
  493. package/documenations/core-runtime-tokens-and-strategies.md +123 -0
  494. package/documenations/downstream-environment.md +48 -0
  495. package/documenations/downstream-test-runtime-teardown-cleanup.md +73 -0
  496. package/documenations/examples/xynthesis-run-task-request.example.json +170 -0
  497. package/documenations/feature-request-ai-skills-raw-template-access.md +82 -0
  498. package/documenations/feature-request-athenix-core-directive.md +145 -0
  499. package/documenations/feature-request-athenix-token-extraction.md +124 -0
  500. package/documenations/funcx-catalog-hosting-checklist.md +107 -0
  501. package/documenations/funcx-scoping-integration-gaps.md +120 -0
  502. package/documenations/funcx-upstream-github-issues-draft.md +153 -0
  503. package/documenations/identity-metadata-contract.md +165 -0
  504. package/documenations/intermediate-steps.md +33 -0
  505. package/documenations/record-and-template-variables.md +32 -0
  506. package/documenations/run-task-execution-flow.md +153 -0
  507. package/documenations/run-task-single-run-checklist.md +109 -0
  508. package/documenations/schemas/README.md +40 -0
  509. package/documenations/schemas/openapi-3.1-components.yaml +24 -0
  510. package/documenations/schemas/v1/output-schema.json +55 -0
  511. package/documenations/schemas/v1/output-validation-result.json +41 -0
  512. package/documenations/schemas/v1/run-task-request.json +219 -0
  513. package/documenations/schemas/v1/synthesized-artifacts.json +133 -0
  514. package/documenations/synthesis-invocation-notes.md +26 -0
  515. package/documenations/synthesized-context-guide.md +84 -0
  516. package/documenations/task-core-and-core-aware-synthesis.md +58 -0
  517. package/documenations/upstream-feature-requests/ai-skills-llm-observability.md +129 -0
  518. package/documenations/upstream-feature-requests/xynthesis-llm-observability.md +125 -0
  519. package/documenations/upstream-feedback-request-shape-clarification.md +101 -0
  520. package/documenations/web-context-precedence.md +33 -0
  521. package/documenations/web-scoping-in-ai-tasks.md +503 -0
  522. package/documenations/xynthesis-activix-telemetry.md +28 -0
  523. package/documenations/xynthesis-upstream-fixes-checklist.md +71 -0
  524. package/package.json +92 -0
@@ -0,0 +1,2432 @@
1
+ // @exellix/ai-tasks
2
+ import { randomUUID } from "crypto";
3
+ import { resolveRunTaskRuntimeKnobs, } from "../internal/resolveRunTaskRuntimeKnobs.js";
4
+ import { applyOptimizerFeedbackToRequest, applyPlannerOutputToRequest } from "../execution-strategies/applyExecutionStrategyOutputs.js";
5
+ import { buildExecutionStrategyRequestPayload, runOptimizerFuncx, runPlannerFuncx, } from "../execution-strategies/runFuncxExecutionStrategy.js";
6
+ import { resolveSafeExecutionStrategyCatalogDefaultFunctionId } from "../execution-strategies/executionStrategyCatalogMetadata.js";
7
+ import { SYNTHESIZED_CONTEXT } from "../types/index.js";
8
+ import { runAuditPostStep } from "../post-steps/audit/runAudit.js";
9
+ import { runPolishPostStep } from "../post-steps/polish/runPolish.js";
10
+ import { getLocalTask } from "../localTasks/registry.js";
11
+ import { registerBuiltInLocalTasks } from "../localTasks/index.js";
12
+ import { getByPath } from "../utils/jsonPaths.js";
13
+ import { passthroughJobTemplateVariables } from "../utils/skillTemplateVariables.js";
14
+ import { emitRunTaskRequestWarnings } from "../utils/runTaskRequestShape.js";
15
+ import { assertRequiredRunSkillCorrelation } from "../utils/assertRequiredRunSkillCorrelation.js";
16
+ import { compileTaskConfigurationOnRunTaskRequest } from "../compile/compileTaskConfiguration.js";
17
+ import { assertValidSmartInputConfig } from "../utils/assertValidSmartInputConfig.js";
18
+ import { extractSmartInputRenderResult } from "../utils/extractSmartInputRenderResult.js";
19
+ import { normalizeSmartInputConfig } from "../utils/normalizeSmartInputConfig.js";
20
+ import { applyXynthesizedOutputWrite, mergeXynthesizedPatchSlices, } from "../utils/xynthesizedWrite.js";
21
+ import { validateParsedOutput } from "../utils/outputValidation.js";
22
+ import { narrixRunHandler } from "../narrix/task.js";
23
+ import { buildNarrixContextMarkdown, buildNarrixPreProcessorContextMarkdown } from "../narrix/narrixContextMarkdown.js";
24
+ import { buildWebContextEvidenceMarkdown } from "../narrix/webContextMarkdown.js";
25
+ import { applyNarrixScope } from "../narrix/applyNarrixScope.js";
26
+ import { adaptMemoryToNarrixInput } from "@exellix/xmemory-narrix-adapter";
27
+ import { buildNarrixAttachment } from "../narrix/buildNarrixAttachment.js";
28
+ import { runWebScope, runWebScopeQuestionPack, webScopeActivixCorrelationPatch } from "../narrix/webScoper.js";
29
+ import { resolveWebScopeQuestionAndTemplates } from "../narrix/buildWebScopeScopeInput.js";
30
+ import { runAiScoping } from "../aiScoping/runAiScoping.js";
31
+ import { getActivixClient } from "../activix/activixClient.js";
32
+ import { withPhaseRecord } from "../activix/phaseTracking.js";
33
+ import { activixOuterTier } from "@x12i/activix";
34
+ import { createDebugTraceCollector, traceWrap } from "../observability/debugTrace.js";
35
+ import { loadSynthesisTemplates, buildSynthesisSystemPrompt, buildSynthesisUserPrompt, resolveSourceMaterial, resolveSourceMaterialParts, getRenderedTemplates, buildSynthesizedContextMarkdown, resolveSynthesisQuestion, runStructuredSynthesisGatewayCallRobust, getContextSynthesizer, normalizeAndValidateSynthesizedPayload, discoverTemplateCores, } from "../synthesis/index.js";
36
+ import { resolveOutputExpectation as resolveOutputExpectationXynthesis } from "@exellix/xynthesis/ai-actions";
37
+ import { llmCallEnvPrefix, resolveLlmCall } from "../post-steps/resolvePostStepConfig.js";
38
+ import { runPostStepLlmCall } from "../internal/runPostStepLlmCall.js";
39
+ registerBuiltInLocalTasks();
40
+ const DEFAULT_SYNTH_INPUT_MAX_CHARS = 200_000;
41
+ function synthesizedResultForXynthesizedPatch(artifact, contextMarkdown) {
42
+ if (artifact !== undefined)
43
+ return artifact;
44
+ return { contextMarkdown };
45
+ }
46
+ function maxSynthesizedInputChars() {
47
+ const raw = process.env.SYNTHESIZED_INPUT_MAX_CHARS;
48
+ if (!raw)
49
+ return DEFAULT_SYNTH_INPUT_MAX_CHARS;
50
+ const n = parseInt(raw, 10);
51
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_SYNTH_INPUT_MAX_CHARS;
52
+ }
53
+ function buildSynthesizedInputArtifact(synthesisMode, sourceMaterial, parts, extras) {
54
+ const max = maxSynthesizedInputChars();
55
+ let truncated = false;
56
+ let sm = sourceMaterial;
57
+ if (sm.length > max) {
58
+ sm = sm.slice(0, Math.max(0, max - 80)) + "\n\n[truncated synthesizedInput.sourceMaterial]\n";
59
+ truncated = true;
60
+ }
61
+ const clip = (s) => (s.length <= max ? s : s.slice(0, max) + "…[truncated]");
62
+ return {
63
+ synthesisMode,
64
+ sourceMaterial: sm,
65
+ localMarkdown: clip(parts.localMarkdown),
66
+ supportingMarkdown: clip(parts.supportingMarkdown),
67
+ ...extras,
68
+ truncated,
69
+ };
70
+ }
71
+ function reuseableSynthesizedArtifact(artifact) {
72
+ if (!artifact || typeof artifact !== "object")
73
+ return false;
74
+ const a = artifact;
75
+ const mode = a.mode;
76
+ if (mode === "questionDriven") {
77
+ return typeof a.contextMarkdown === "string" && a.contextMarkdown.trim().length > 0;
78
+ }
79
+ if (mode === "markdown" || mode === "structured") {
80
+ return typeof a.contextMarkdown === "string";
81
+ }
82
+ return false;
83
+ }
84
+ function contextMarkdownFromArtifact(artifact) {
85
+ const a = artifact;
86
+ return typeof a.contextMarkdown === "string" ? a.contextMarkdown : "";
87
+ }
88
+ function appendExternalWebContextMarkdown(contextMarkdown, execMem, allowAppend) {
89
+ if (!allowAppend)
90
+ return contextMarkdown;
91
+ const raw = execMem?.webContextMarkdown;
92
+ if (typeof raw !== "string")
93
+ return contextMarkdown;
94
+ const trimmed = raw.trim();
95
+ if (!trimmed)
96
+ return contextMarkdown;
97
+ const base = contextMarkdown.length > 0 && !contextMarkdown.endsWith("\n") ? `${contextMarkdown}\n\n` : contextMarkdown;
98
+ return `${base}## Supplementary web context (caller-provided)\n\n${trimmed}\n`;
99
+ }
100
+ function isStrictDecisionTask(request) {
101
+ return request?.taskKind === "decision";
102
+ }
103
+ function defaultDecisionOutputSchema() {
104
+ return {
105
+ type: "object",
106
+ required: ["contractVersion", "shouldUseWeb", "reasonCodes", "missingSignals"],
107
+ properties: {
108
+ contractVersion: { type: "string" },
109
+ shouldUseWeb: { type: "boolean" },
110
+ reasonCodes: { type: "array", items: { type: "string" } },
111
+ missingSignals: { type: "array", items: { type: "string" } },
112
+ },
113
+ additionalProperties: false,
114
+ };
115
+ }
116
+ function withDefaultDecisionValidation(request) {
117
+ if (!isStrictDecisionTask(request))
118
+ return request;
119
+ const autoValidate = request.autoValidateDecisionOutput !== false;
120
+ if (!autoValidate)
121
+ return request;
122
+ if (request.outputValidation)
123
+ return request;
124
+ return {
125
+ ...request,
126
+ outputValidation: {
127
+ schema: defaultDecisionOutputSchema(),
128
+ mode: "fail",
129
+ validateWhenMissing: true,
130
+ },
131
+ };
132
+ }
133
+ /** Runtime `request.identity` forwarded to xynthesis synthesis calls (not from step config). */
134
+ function synthesisIdentityFromRequest(request) {
135
+ const id = request.identity;
136
+ if (id == null || typeof id !== "object")
137
+ return undefined;
138
+ return id;
139
+ }
140
+ /** When the skills client has no `enrichMemoriesWithScoping` (semver drift), pass memory through unchanged. */
141
+ async function passthroughEnrichMemories(_id, _level, bundle) {
142
+ return {
143
+ jobMemory: bundle.jobMemory ?? {},
144
+ taskMemory: bundle.taskMemory ?? {},
145
+ executionMemory: bundle.executionMemory ?? {},
146
+ };
147
+ }
148
+ /** When the skills client has no `generateContextMarkdown`, return empty context (callers that need context should use a client that implements it). */
149
+ async function noopGenerateContextMarkdown() {
150
+ return "";
151
+ }
152
+ function bindEnrichMemoriesWithScoping(client) {
153
+ const c = client;
154
+ if (typeof c.enrichMemoriesWithScoping === "function") {
155
+ return c.enrichMemoriesWithScoping.bind(client);
156
+ }
157
+ return passthroughEnrichMemories;
158
+ }
159
+ function bindGenerateContextMarkdown(client) {
160
+ const c = client;
161
+ if (typeof c.generateContextMarkdown === "function") {
162
+ return c.generateContextMarkdown.bind(client);
163
+ }
164
+ return async (_id, _level, _bundle) => noopGenerateContextMarkdown();
165
+ }
166
+ function hasNonEmptyWebScoping(s) {
167
+ return s != null && Object.keys(s).length > 0;
168
+ }
169
+ /** Resolve narrixInput from request; if it has $path (e.g. jobMemory.currentRecord), resolve from jobMemory. */
170
+ function resolveNarrixInput(narrixInput, jobMemory) {
171
+ if (!narrixInput || typeof narrixInput !== "object")
172
+ return null;
173
+ const o = narrixInput;
174
+ if (typeof o.$path === "string") {
175
+ const path = o.$path;
176
+ if (!path.startsWith("jobMemory."))
177
+ return null;
178
+ const rel = path.replace(/^jobMemory\./, "");
179
+ const resolved = getByPath(jobMemory ?? {}, rel);
180
+ if (!resolved || typeof resolved !== "object")
181
+ return null;
182
+ const r = resolved;
183
+ if (typeof r.medium !== "string" || typeof r.datasetId !== "string")
184
+ return null;
185
+ return resolved;
186
+ }
187
+ if (typeof o.medium === "string" && typeof o.datasetId === "string") {
188
+ return narrixInput;
189
+ }
190
+ return null;
191
+ }
192
+ /**
193
+ * Deep merge utility for execution objects.
194
+ * Merges source into target, with source taking precedence for conflicts.
195
+ * Arrays are concatenated, objects are deep merged.
196
+ */
197
+ function deepMergeExecution(target, source) {
198
+ if (source === null || source === undefined) {
199
+ return target;
200
+ }
201
+ if (target === null || target === undefined) {
202
+ return source;
203
+ }
204
+ // If both are arrays, concatenate (source items appended)
205
+ if (Array.isArray(target) && Array.isArray(source)) {
206
+ return [...target, ...source];
207
+ }
208
+ // If both are objects, deep merge
209
+ if (typeof target === 'object' && typeof source === 'object' &&
210
+ !Array.isArray(target) && !Array.isArray(source)) {
211
+ const result = { ...target };
212
+ for (const key in source) {
213
+ if (source.hasOwnProperty(key)) {
214
+ if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key]) &&
215
+ typeof target[key] === 'object' && target[key] !== null && !Array.isArray(target[key])) {
216
+ // Recursively merge nested objects
217
+ result[key] = deepMergeExecution(target[key], source[key]);
218
+ }
219
+ else if (Array.isArray(target[key]) && Array.isArray(source[key])) {
220
+ // Concatenate arrays
221
+ result[key] = [...target[key], ...source[key]];
222
+ }
223
+ else {
224
+ // Source takes precedence
225
+ result[key] = source[key];
226
+ }
227
+ }
228
+ }
229
+ return result;
230
+ }
231
+ // Otherwise, source replaces target
232
+ return source;
233
+ }
234
+ /**
235
+ * Filter system/internal fields from execution object to prevent leakage into model context.
236
+ * Currently filters: bindingDefaultsDb
237
+ */
238
+ function cleanseExecution(execution) {
239
+ if (!execution || typeof execution !== 'object' || Array.isArray(execution)) {
240
+ return execution;
241
+ }
242
+ const { bindingDefaultsDb, ...clean } = execution;
243
+ return clean;
244
+ }
245
+ function hasNarrixAttachmentShape(value) {
246
+ return !!(value &&
247
+ typeof value === "object" &&
248
+ "scoping" in value &&
249
+ "discovery" in value);
250
+ }
251
+ function coerceTaskMemoryNarrixToAttachment(taskMemoryNarrix) {
252
+ if (!Array.isArray(taskMemoryNarrix) || taskMemoryNarrix.length === 0)
253
+ return null;
254
+ const scopedEntries = taskMemoryNarrix.filter((entry) => !!entry && typeof entry === "object");
255
+ if (scopedEntries.length === 0)
256
+ return null;
257
+ const signals = scopedEntries.flatMap((entry) => Array.isArray(entry.signals) ? entry.signals : []);
258
+ const stories = scopedEntries.flatMap((entry) => Array.isArray(entry.stories) ? entry.stories : []);
259
+ if (signals.length === 0 && stories.length === 0)
260
+ return null;
261
+ return {
262
+ scoping: { signals, stories },
263
+ discovery: { signals: [], stories: [] },
264
+ meta: {
265
+ source: "taskMemory.narrix",
266
+ runCount: scopedEntries.length,
267
+ },
268
+ };
269
+ }
270
+ function resolveSynthesisMode(config) {
271
+ if (config.synthesisMode === "structured" || config.synthesisMode === "markdown") {
272
+ return config.synthesisMode;
273
+ }
274
+ return "markdown";
275
+ }
276
+ /**
277
+ * If parsed is an object with intermediateSteps, lift them to the response and remove from parsed
278
+ * so that response.intermediateSteps is the canonical place and parsed holds only task output.
279
+ */
280
+ function liftIntermediateSteps(result) {
281
+ const parsed = result?.parsed;
282
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
283
+ return;
284
+ const steps = parsed.intermediateSteps;
285
+ if (!Array.isArray(steps) || steps.length === 0)
286
+ return;
287
+ const valid = steps.every((s) => typeof s === 'object' && s !== null && 'step' in s && 'id' in s && 'ok' in s);
288
+ if (!valid)
289
+ return;
290
+ result.intermediateSteps = steps;
291
+ const { intermediateSteps: _removed, ...rest } = parsed;
292
+ result.parsed = Object.keys(rest).length > 0 ? rest : undefined;
293
+ }
294
+ function extractExecutionMemoryFromResponse(result) {
295
+ if (result && typeof result === "object") {
296
+ if (result.executionMemory && typeof result.executionMemory === "object") {
297
+ return result.executionMemory;
298
+ }
299
+ if (result.parsed && typeof result.parsed === "object") {
300
+ const parsed = result.parsed;
301
+ if (parsed.executionMemory && typeof parsed.executionMemory === "object") {
302
+ return parsed.executionMemory;
303
+ }
304
+ }
305
+ }
306
+ return undefined;
307
+ }
308
+ function executionStrategiesSummaryFromKnobs(knobs) {
309
+ const r = knobs.resolvedExecutionStrategies;
310
+ return {
311
+ beforeKeys: r.orderedBefore.map((x) => x.strategyKey),
312
+ afterKeys: r.orderedAfter.map((x) => x.strategyKey),
313
+ ...(r.primaryOptimizer
314
+ ? { primaryOptimizerMaxIterations: r.effectivePrimaryOptimizerMaxIterations }
315
+ : {}),
316
+ };
317
+ }
318
+ function attachExecutionStateAndObservability(result, request, observability, runtimeKnobs) {
319
+ const responseExecution = extractExecutionMemoryFromResponse(result);
320
+ const finalExecutionMemory = {
321
+ ...(request.executionMemory ?? {}),
322
+ ...(responseExecution ?? {}),
323
+ };
324
+ result.executionMemory = finalExecutionMemory;
325
+ result.executionState = { executionMemory: finalExecutionMemory };
326
+ result.metadata = {
327
+ ...(result.metadata ?? {}),
328
+ synthesisEnabled: observability.synthesisEnabled,
329
+ effectiveExecutionPipeline: observability.effectiveExecutionPipeline,
330
+ synthesizedContextPresent: observability.synthesizedContextPresent,
331
+ mainContextSource: observability.mainContextSource,
332
+ detectedTemplateCores: observability.detectedTemplateCores ?? [],
333
+ synthesisMode: observability.synthesisMode,
334
+ ...(runtimeKnobs
335
+ ? {
336
+ narrixMode: runtimeKnobs.narrixMode,
337
+ inputStrategyKey: runtimeKnobs.inputStrategyKey,
338
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(runtimeKnobs),
339
+ }
340
+ : {}),
341
+ };
342
+ // Alias for callers/docs that expect a `meta` block (same object as `metadata`).
343
+ result.meta = result.metadata;
344
+ }
345
+ function safeJson(value) {
346
+ return JSON.stringify(value ?? {}, null, 2);
347
+ }
348
+ function summarizeForOuter(value, maxChars) {
349
+ if (value === null || value === undefined)
350
+ return value;
351
+ if (typeof value === "string") {
352
+ return value.length > maxChars ? value.slice(0, maxChars) + "…[truncated]" : value;
353
+ }
354
+ if (typeof value === "number" || typeof value === "boolean")
355
+ return value;
356
+ try {
357
+ const json = JSON.stringify(value);
358
+ if (typeof json !== "string")
359
+ return "[unserializable]";
360
+ if (json.length <= maxChars)
361
+ return value;
362
+ return json.slice(0, maxChars) + "…[truncated]";
363
+ }
364
+ catch {
365
+ return "[unserializable]";
366
+ }
367
+ }
368
+ function isRecord(value) {
369
+ return !!value && typeof value === "object" && !Array.isArray(value);
370
+ }
371
+ function extractDownstreamIdentity(result) {
372
+ if (!isRecord(result))
373
+ return undefined;
374
+ if (isRecord(result.identity))
375
+ return result.identity;
376
+ if (isRecord(result.metadata?.identity))
377
+ return result.metadata.identity;
378
+ if (isRecord(result.gatewayResponse?.identity))
379
+ return result.gatewayResponse.identity;
380
+ if (isRecord(result.enhancedResponse?.identity))
381
+ return result.enhancedResponse.identity;
382
+ return undefined;
383
+ }
384
+ function buildSynthesizerInputMaterial(strategy, resolveOpts) {
385
+ const selected = strategy ?? "policy";
386
+ if (selected === "execution-memory-only") {
387
+ const localMarkdown = safeJson({ executionMemory: resolveOpts.enrichedMemoryBundle.executionMemory ?? {} });
388
+ return { sourceMaterial: localMarkdown, parts: { localMarkdown, supportingMarkdown: "" } };
389
+ }
390
+ if (selected === "job-memory-only") {
391
+ const localMarkdown = safeJson({ jobMemory: resolveOpts.enrichedMemoryBundle.jobMemory ?? {} });
392
+ return { sourceMaterial: localMarkdown, parts: { localMarkdown, supportingMarkdown: "" } };
393
+ }
394
+ if (selected === "task-memory-only") {
395
+ const localMarkdown = safeJson({ taskMemory: resolveOpts.enrichedMemoryBundle.taskMemory ?? {} });
396
+ return { sourceMaterial: localMarkdown, parts: { localMarkdown, supportingMarkdown: "" } };
397
+ }
398
+ if (selected === "full-memory-bundle") {
399
+ const localMarkdown = safeJson({
400
+ jobMemory: resolveOpts.enrichedMemoryBundle.jobMemory ?? {},
401
+ taskMemory: resolveOpts.enrichedMemoryBundle.taskMemory ?? {},
402
+ executionMemory: resolveOpts.enrichedMemoryBundle.executionMemory ?? {},
403
+ });
404
+ return { sourceMaterial: localMarkdown, parts: { localMarkdown, supportingMarkdown: "" } };
405
+ }
406
+ const sourceMaterial = resolveSourceMaterial(resolveOpts);
407
+ const parts = resolveSourceMaterialParts(resolveOpts);
408
+ return { sourceMaterial, parts };
409
+ }
410
+ function safeResolveSynthesisQuestion(synthesisRequest, config, renderedPrompt) {
411
+ try {
412
+ const q = resolveSynthesisQuestion(synthesisRequest, config, renderedPrompt);
413
+ if (typeof q === "string")
414
+ return q;
415
+ return String(q ?? "");
416
+ }
417
+ catch {
418
+ // Utility tasks should not fail solely due to missing/invalid question resolution.
419
+ // If a template truly requires `question`, that will surface as a template resolution error elsewhere.
420
+ return "";
421
+ }
422
+ }
423
+ /**
424
+ * Task execution client for @exellix/ai-tasks.
425
+ *
426
+ * This class implements the canonical runTask algorithm:
427
+ * 1) Look up local handler by skillKey; if found, run it and return
428
+ * 2) Enrich memories at TASK level (using skillKey)
429
+ * 3) Generate TASK-level context markdown (using skillKey)
430
+ * 4) Execute via executor (no-enrichment primitive)
431
+ *
432
+ * This is a private package. We intentionally reuse @exellix/ai-skills directly,
433
+ * including its types and helpers. Naming leakage is acceptable.
434
+ */
435
+ export class WorexClientTasks {
436
+ skillsClient;
437
+ executor;
438
+ constructor(skillsClient, executor) {
439
+ this.skillsClient = skillsClient;
440
+ this.executor = executor;
441
+ }
442
+ async runTask(input) {
443
+ const compiled = compileTaskConfigurationOnRunTaskRequest(input);
444
+ input = compiled.request;
445
+ emitRunTaskRequestWarnings(input);
446
+ assertRequiredRunSkillCorrelation(input);
447
+ assertValidSmartInputConfig(input.smartInput, input.skillKey);
448
+ const traceCollector = input.executionMode === "trace" ? createDebugTraceCollector() : null;
449
+ const withTrace = (result) => {
450
+ if (!traceCollector)
451
+ return result;
452
+ return {
453
+ ...result,
454
+ debugTrace: { tasks: traceCollector.tasks() },
455
+ };
456
+ };
457
+ // `@exellix/ai-skills` requires stable ids on each gateway request; callers may omit for simple runs.
458
+ const taskId = input.taskId?.trim() ? input.taskId : randomUUID();
459
+ const jobId = input.jobId?.trim() ? input.jobId : randomUUID();
460
+ input.taskId = taskId;
461
+ input.jobId = jobId;
462
+ // Optional activix tracking (non-fatal).
463
+ const ax = await getActivixClient().catch(() => null);
464
+ const correlationId = ax ? taskId : undefined;
465
+ const coreSkillId = input.coreSkillId;
466
+ const upstreamIdentity = isRecord(input.identity) ? input.identity : undefined;
467
+ const executingSkillId = coreSkillId ?? input.skillKey;
468
+ const effectiveIdentity = {
469
+ ...(upstreamIdentity ?? {}),
470
+ ...(upstreamIdentity?.taskId ? {} : { taskId }),
471
+ ...(upstreamIdentity?.skillId ? {} : { skillId: executingSkillId }),
472
+ };
473
+ const normalizedSmartInput = input.smartInput !== undefined && input.smartInput !== null
474
+ ? normalizeSmartInputConfig(input.smartInput)
475
+ : undefined;
476
+ let request = withDefaultDecisionValidation({
477
+ ...input,
478
+ identity: effectiveIdentity,
479
+ ...(normalizedSmartInput !== undefined ? { smartInput: normalizedSmartInput } : {}),
480
+ });
481
+ let xynthesizedPatchAccumulator;
482
+ const knobs = resolveRunTaskRuntimeKnobs(request);
483
+ const baseTraceMeta = () => ({
484
+ jobId,
485
+ taskId,
486
+ skillKey: input.skillKey,
487
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(knobs),
488
+ narrixMode: knobs.narrixMode,
489
+ agentId: input.agentId,
490
+ graphId: input.graphId,
491
+ nodeId: input.nodeId,
492
+ prevNodeId: input.prevNodeId,
493
+ masterSkillId: input.masterSkillId,
494
+ masterSkillActivityId: input.masterSkillActivityId,
495
+ hasPipeline: Array.isArray(input.executionPipeline) && input.executionPipeline.length > 0,
496
+ hasNarrix: !!input.narrix,
497
+ hasNarrixInput: !!input.narrixInput,
498
+ });
499
+ const modelUsedFromResult = (result) => {
500
+ if (!result || typeof result !== "object")
501
+ return undefined;
502
+ const r = result;
503
+ const candidates = [
504
+ r?.metadata?.modelUsed,
505
+ r?.metadata?.model,
506
+ r?.gatewayResponse?.model,
507
+ r?.enhancedResponse?.model,
508
+ r?.model,
509
+ ];
510
+ const found = candidates.find((x) => typeof x === "string" && x.trim().length > 0);
511
+ return typeof found === "string" ? found : undefined;
512
+ };
513
+ const finalize = (result) => {
514
+ const downstreamIdentity = extractDownstreamIdentity(result);
515
+ const identityToReturn = downstreamIdentity ??
516
+ (upstreamIdentity ? effectiveIdentity : undefined);
517
+ if (identityToReturn) {
518
+ result.identity = identityToReturn;
519
+ result.metadata = { ...(result.metadata ?? {}), identity: identityToReturn };
520
+ }
521
+ const smartInputRenderResult = extractSmartInputRenderResult(result);
522
+ if (smartInputRenderResult) {
523
+ result.smartInputRenderResult = smartInputRenderResult;
524
+ }
525
+ result.metadata = {
526
+ ...result.metadata,
527
+ taskId,
528
+ ...(coreSkillId ? { skillId: coreSkillId } : {}),
529
+ identityPresent: (input.identity !== undefined),
530
+ ...(smartInputRenderResult ? { smartInputRenderResult } : {}),
531
+ };
532
+ const patchJob = xynthesizedPatchAccumulator?.job && Object.keys(xynthesizedPatchAccumulator.job).length > 0;
533
+ const patchTask = xynthesizedPatchAccumulator?.task && Object.keys(xynthesizedPatchAccumulator.task).length > 0;
534
+ const patchExecution = xynthesizedPatchAccumulator?.execution &&
535
+ Object.keys(xynthesizedPatchAccumulator.execution).length > 0;
536
+ if (patchJob || patchTask || patchExecution) {
537
+ result.xynthesizedPatch = xynthesizedPatchAccumulator;
538
+ }
539
+ return result;
540
+ };
541
+ const hasPipeline = Array.isArray(input.executionPipeline) && input.executionPipeline.length > 0;
542
+ const hasNarrix = !!input.narrix;
543
+ const hasNarrixInput = !!input.narrixInput;
544
+ // Activix 6+: correlation + task identity belong in `runContext`, not a parallel top-level `identity` field.
545
+ const runContext = {
546
+ ...effectiveIdentity,
547
+ sessionId: taskId,
548
+ };
549
+ const baseMeta = {
550
+ skillKey: input.skillKey,
551
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(knobs),
552
+ narrixMode: knobs.narrixMode,
553
+ jobId: input.jobId,
554
+ agentId: input.agentId,
555
+ graphId: input.graphId,
556
+ nodeId: input.nodeId,
557
+ prevNodeId: input.prevNodeId,
558
+ masterSkillId: input.masterSkillId,
559
+ masterSkillActivityId: input.masterSkillActivityId,
560
+ runContext,
561
+ hasPipeline,
562
+ hasNarrix,
563
+ hasNarrixInput,
564
+ };
565
+ const runDirect = async (req, options) => {
566
+ const traceTask = {
567
+ taskType: "ai-task",
568
+ details: "direct execution (skills/gateway)",
569
+ metadata: {
570
+ ...baseTraceMeta(),
571
+ phase: "direct",
572
+ overrideContextProvided: options?.overrideContext !== undefined,
573
+ captureContextProvided: options?.captureContext !== undefined,
574
+ synthesisContextAuthoritative: options?.synthesisContextAuthoritative === true,
575
+ ...(traceCollector
576
+ ? {
577
+ smartInput: {
578
+ paths: req.smartInput?.paths ?? [],
579
+ },
580
+ }
581
+ : {}),
582
+ },
583
+ };
584
+ return traceWrap(traceCollector, traceTask, async () => withPhaseRecord({
585
+ ax,
586
+ correlationId,
587
+ phase: "direct",
588
+ meta: {
589
+ ...baseMeta,
590
+ outer: activixOuterTier({
591
+ kind: "runTask.request",
592
+ skillKey: req.skillKey,
593
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(knobs),
594
+ jobId: req.jobId,
595
+ agentId: req.agentId,
596
+ graphId: req.graphId,
597
+ nodeId: req.nodeId,
598
+ masterSkillId: req.masterSkillId,
599
+ masterSkillActivityId: req.masterSkillActivityId,
600
+ includeContextInPrompt: req.includeContextInPrompt === true,
601
+ hasPipeline: Array.isArray(req.executionPipeline) && req.executionPipeline.length > 0,
602
+ hasNarrix: !!req.narrix,
603
+ hasNarrixInput: !!req.narrixInput,
604
+ input: summarizeForOuter(req.input, 4_000),
605
+ }, null, { phase: "direct" }),
606
+ // pipeline MAIN vs DIRECT is still tracked as the same phase label ("direct")
607
+ hasPipeline: !!req.executionPipeline,
608
+ hasNarrix: !!req.narrix,
609
+ hasNarrixInput: !!req.narrixInput,
610
+ overrideContextProvided: options?.overrideContext !== undefined,
611
+ captureContextProvided: options?.captureContext !== undefined,
612
+ synthesisContextAuthoritative: options?.synthesisContextAuthoritative === true,
613
+ },
614
+ fn: async () => this._executeDirect(req, {
615
+ ...options,
616
+ validationCorrelationId: taskId,
617
+ traceCollector,
618
+ }),
619
+ onSuccessUpdates: (result) => {
620
+ const steps = result?.intermediateSteps;
621
+ return {
622
+ instructionVersion: result?.metadata?.instructionVersion,
623
+ activityId: result?.metadata?.activityId,
624
+ durationMs: result?.metadata?.durationMs,
625
+ hasIntermediateSteps: Array.isArray(steps) && steps.length > 0,
626
+ stepCount: Array.isArray(steps) ? steps.length : undefined,
627
+ outer: activixOuterTier({
628
+ kind: "runTask.request",
629
+ skillKey: req.skillKey,
630
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(knobs),
631
+ jobId: req.jobId,
632
+ agentId: req.agentId,
633
+ graphId: req.graphId,
634
+ nodeId: req.nodeId,
635
+ masterSkillId: req.masterSkillId,
636
+ masterSkillActivityId: req.masterSkillActivityId,
637
+ includeContextInPrompt: req.includeContextInPrompt === true,
638
+ hasPipeline: Array.isArray(req.executionPipeline) && req.executionPipeline.length > 0,
639
+ hasNarrix: !!req.narrix,
640
+ hasNarrixInput: !!req.narrixInput,
641
+ input: summarizeForOuter(req.input, 4_000),
642
+ }, {
643
+ kind: "runTask.response",
644
+ skillKey: result?.skillKey,
645
+ // Keep this intentionally small; rawText / flexMd payloads can be huge.
646
+ metadata: summarizeForOuter(result?.metadata, 4_000),
647
+ parsed: summarizeForOuter(result?.parsed, 8_000),
648
+ }, { phase: "direct" }),
649
+ };
650
+ },
651
+ }), (result) => {
652
+ const modelUsed = modelUsedFromResult(result);
653
+ const r = result;
654
+ return {
655
+ modelUsed: modelUsed ?? null,
656
+ metadata: {
657
+ activityId: r?.metadata?.activityId,
658
+ instructionVersion: r?.metadata?.instructionVersion,
659
+ durationMs: r?.metadata?.durationMs,
660
+ outputValidation: r?.metadata?.outputValidation,
661
+ },
662
+ };
663
+ });
664
+ };
665
+ const runMainWithExecutionStrategies = async (req, options) => {
666
+ const strat = knobs.resolvedExecutionStrategies;
667
+ let working = { ...req };
668
+ const prefixSteps = [];
669
+ for (let pi = 0; pi < strat.orderedBefore.length; pi++) {
670
+ const spec = strat.orderedBefore[pi];
671
+ if (spec.strategyKey !== "planner")
672
+ continue;
673
+ const payload = buildExecutionStrategyRequestPayload({
674
+ skillKey: working.skillKey,
675
+ input: working.input,
676
+ variables: working.variables,
677
+ jobContext: working.jobContext,
678
+ jobMemory: working.jobMemory,
679
+ taskMemory: working.taskMemory,
680
+ executionMemory: working.executionMemory,
681
+ jobId: working.jobId,
682
+ taskId: working.taskId,
683
+ agentId: working.agentId,
684
+ graphId: working.graphId,
685
+ nodeId: working.nodeId,
686
+ prevNodeId: working.prevNodeId,
687
+ coreSkillId: working.coreSkillId,
688
+ includeContextInPrompt: working.includeContextInPrompt,
689
+ });
690
+ const catalogDefaultFunctionId = resolveSafeExecutionStrategyCatalogDefaultFunctionId(req.executionStrategyCatalogItems, spec);
691
+ const plannerOut = await runPlannerFuncx({
692
+ args: spec.args,
693
+ requestPayload: payload,
694
+ defaultFunctionId: catalogDefaultFunctionId,
695
+ });
696
+ working = applyPlannerOutputToRequest(working, plannerOut, pi);
697
+ prefixSteps.push({
698
+ step: prefixSteps.length + 1,
699
+ id: `executionStrategy.planner.${pi}`,
700
+ ok: true,
701
+ summary: "FuncX planner (execution/plan)",
702
+ outputExcerpt: {
703
+ hasInstructions: typeof plannerOut.instructions === "string",
704
+ hasPrompt: typeof plannerOut.prompt === "string",
705
+ variableKeys: plannerOut.variables ? Object.keys(plannerOut.variables).slice(0, 20) : [],
706
+ functionIdSource: typeof spec.args?.functionId === "string"
707
+ ? "invocation"
708
+ : catalogDefaultFunctionId
709
+ ? "catalog"
710
+ : "code-default",
711
+ },
712
+ });
713
+ if (traceCollector) {
714
+ traceCollector.push({
715
+ taskType: "pre-execution",
716
+ details: "execution strategy planner (FuncX)",
717
+ metadata: {
718
+ ...baseTraceMeta(),
719
+ phase: "execution_strategy_planner",
720
+ plannerIndex: pi,
721
+ },
722
+ modelUsed: null,
723
+ });
724
+ }
725
+ }
726
+ const mergePrefixSteps = (result) => {
727
+ if (prefixSteps.length === 0)
728
+ return result;
729
+ const existing = (result.intermediateSteps ?? []);
730
+ const shifted = existing.map((s, i) => ({ ...s, step: prefixSteps.length + i + 1 }));
731
+ result.intermediateSteps = [...prefixSteps, ...shifted];
732
+ return result;
733
+ };
734
+ const primary = strat.primaryOptimizer;
735
+ const maxIter = strat.effectivePrimaryOptimizerMaxIterations;
736
+ if (!primary) {
737
+ return mergePrefixSteps(await runDirect(working, options));
738
+ }
739
+ let last;
740
+ for (let iter = 0; iter < maxIter; iter++) {
741
+ last = await runDirect(working, options);
742
+ const mainSummary = {
743
+ rawText: typeof last.rawText === "string" ? String(last.rawText).slice(0, 12_000) : undefined,
744
+ parsed: last.parsed,
745
+ skillKey: last.skillKey,
746
+ metadata: last.metadata ? summarizeForOuter(last.metadata, 6_000) : undefined,
747
+ };
748
+ const evalOut = await runOptimizerFuncx({
749
+ args: primary.args,
750
+ defaultFunctionId: resolveSafeExecutionStrategyCatalogDefaultFunctionId(req.executionStrategyCatalogItems, primary),
751
+ requestPayload: buildExecutionStrategyRequestPayload({
752
+ skillKey: working.skillKey,
753
+ input: working.input,
754
+ variables: working.variables,
755
+ jobContext: working.jobContext,
756
+ jobMemory: working.jobMemory,
757
+ taskMemory: working.taskMemory,
758
+ executionMemory: working.executionMemory,
759
+ jobId: working.jobId,
760
+ taskId: working.taskId,
761
+ agentId: working.agentId,
762
+ graphId: working.graphId,
763
+ nodeId: working.nodeId,
764
+ prevNodeId: working.prevNodeId,
765
+ coreSkillId: working.coreSkillId,
766
+ includeContextInPrompt: working.includeContextInPrompt,
767
+ }),
768
+ mainResultSummary: mainSummary,
769
+ iterationIndex: iter,
770
+ });
771
+ if (traceCollector) {
772
+ traceCollector.push({
773
+ taskType: "ai-task",
774
+ details: "execution strategy optimizer (FuncX)",
775
+ metadata: {
776
+ ...baseTraceMeta(),
777
+ phase: "execution_strategy_optimizer",
778
+ iterationIndex: iter,
779
+ satisfied: evalOut.satisfied === true,
780
+ },
781
+ modelUsed: modelUsedFromResult(last) ?? null,
782
+ });
783
+ }
784
+ if (evalOut.satisfied) {
785
+ return mergePrefixSteps(last);
786
+ }
787
+ if (iter === maxIter - 1) {
788
+ return mergePrefixSteps(last);
789
+ }
790
+ working = applyOptimizerFeedbackToRequest(working, evalOut, iter + 1);
791
+ }
792
+ return mergePrefixSteps(last);
793
+ };
794
+ // NARRIX task-level pre-processor + structured handler: `narrixMode` (+ inference) via `resolveRunTaskRuntimeKnobs`.
795
+ if (knobs.narrixMode === "preprocessor" && request.narrix) {
796
+ const narrixCfg = request.narrix;
797
+ await traceWrap(traceCollector, {
798
+ taskType: "pre-execution",
799
+ details: "narrix preprocessor",
800
+ metadata: {
801
+ ...baseTraceMeta(),
802
+ phase: "narrix",
803
+ datasetId: narrixCfg.datasetId,
804
+ attachToField: narrixCfg.attachToField ?? "_narrix",
805
+ enableWebScope: narrixCfg.enableWebScope === true,
806
+ },
807
+ }, async () => withPhaseRecord({
808
+ ax,
809
+ correlationId,
810
+ phase: "narrix",
811
+ meta: {
812
+ ...baseMeta,
813
+ narrixAttachToField: narrixCfg.attachToField ?? "_narrix",
814
+ outer: activixOuterTier({
815
+ kind: "narrix.preProcessor.request",
816
+ datasetId: narrixCfg.datasetId,
817
+ attachToField: narrixCfg.attachToField ?? "_narrix",
818
+ enableWebScope: narrixCfg.enableWebScope === true,
819
+ webScoping: narrixCfg.webScoping ? summarizeForOuter(narrixCfg.webScoping, 2_000) : undefined,
820
+ requestInput: summarizeForOuter(request.input, 4_000),
821
+ }, null, { phase: "narrix" }),
822
+ },
823
+ fn: async () => {
824
+ const adaptResult = adaptMemoryToNarrixInput({
825
+ datasetId: narrixCfg.datasetId,
826
+ mediumHint: "record",
827
+ memory: {
828
+ jobMemory: request.jobMemory,
829
+ executionMemory: request.executionMemory,
830
+ input: request.input,
831
+ },
832
+ }, {
833
+ record: {
834
+ minKeys: 1,
835
+ preferPaths: [
836
+ "executionMemory.input.raw",
837
+ "executionMemory.inputs.*.raw",
838
+ "jobMemory.record",
839
+ "jobMemory.currentRecord",
840
+ "executionMemory.input.record",
841
+ "executionMemory.record",
842
+ "taskMemory.currentRecord",
843
+ "*.currentRecord",
844
+ "*.record",
845
+ ],
846
+ },
847
+ });
848
+ if (!adaptResult.ok) {
849
+ const attempted = adaptResult.attempted?.length ? ` Attempted: ${adaptResult.attempted.join(", ")}.` : "";
850
+ const summary = adaptResult.foundSummary ? ` Seen: ${adaptResult.foundSummary}` : "";
851
+ throw new Error(`NARRIX pre-processor: no usable input. ${adaptResult.message}.${attempted}${summary}`);
852
+ }
853
+ const ctx = {
854
+ skillKey: request.skillKey,
855
+ jobMemory: request.jobMemory,
856
+ taskMemory: request.taskMemory,
857
+ executionMemory: request.executionMemory,
858
+ variables: input.variables,
859
+ xynthesized: request.xynthesized,
860
+ smartInput: request.smartInput,
861
+ jobId: input.jobId,
862
+ taskId: request.taskId,
863
+ agentId: input.agentId,
864
+ graphId: input.graphId,
865
+ nodeId: input.nodeId,
866
+ prevNodeId: input.prevNodeId,
867
+ coreSkillId: input.coreSkillId,
868
+ masterSkillId: request.masterSkillId,
869
+ masterSkillActivityId: request.masterSkillActivityId,
870
+ };
871
+ const narrixResult = await narrixRunHandler({ input: adaptResult.narrixInput, ctx });
872
+ if (!narrixResult.ok) {
873
+ const fail = narrixResult;
874
+ throw new Error(`NARRIX pre-processor failed: ${fail.error}${fail.message ? ` - ${fail.message}` : ""}`);
875
+ }
876
+ const attachment = buildNarrixAttachment(narrixResult);
877
+ const attachToField = narrixCfg.attachToField ?? "_narrix";
878
+ let webContextEntry = undefined;
879
+ let webContextAvailable;
880
+ let webContextReason;
881
+ const externalWebMdPreNarrix = typeof request.executionMemory?.webContextMarkdown === "string" &&
882
+ request.executionMemory.webContextMarkdown.trim().length > 0;
883
+ const skipWebScopeForExternalMd = narrixCfg.skipWebScopeWhenExternalWebMarkdownPresent === true && externalWebMdPreNarrix;
884
+ if (narrixCfg.enableWebScope === true && !skipWebScopeForExternalMd) {
885
+ const successResult = narrixResult;
886
+ const entity = adaptResult.narrixInput.medium === "record"
887
+ ? adaptResult.narrixInput.record
888
+ : undefined;
889
+ const scopeFields = resolveWebScopeQuestionAndTemplates({
890
+ narrix: narrixCfg,
891
+ requestInput: request.input,
892
+ successResult,
893
+ entity,
894
+ });
895
+ const webScopeOpts = hasNonEmptyWebScoping(narrixCfg.webScoping)
896
+ ? { scoping: narrixCfg.webScoping }
897
+ : undefined;
898
+ const activixPatch = webScopeActivixCorrelationPatch({
899
+ jobId: request.jobId,
900
+ taskId: request.taskId,
901
+ sessionId: request.taskId,
902
+ });
903
+ const packQs = scopeFields.packQuestions;
904
+ if (Array.isArray(packQs) && packQs.length > 0) {
905
+ webContextEntry = await runWebScopeQuestionPack({
906
+ datasetId: narrixCfg.datasetId,
907
+ subjectId: successResult.entity.entityKey,
908
+ entityKind: successResult.entity.entityKind,
909
+ entity,
910
+ cni: successResult.cni,
911
+ ...activixPatch,
912
+ questions: packQs,
913
+ }, webScopeOpts);
914
+ }
915
+ else {
916
+ const { packQuestions: _pq, ...genericScope } = scopeFields;
917
+ void _pq;
918
+ webContextEntry = await runWebScope({
919
+ datasetId: narrixCfg.datasetId,
920
+ subjectId: successResult.entity.entityKey,
921
+ entityKind: successResult.entity.entityKind,
922
+ entity,
923
+ cni: successResult.cni,
924
+ ...activixPatch,
925
+ ...genericScope,
926
+ }, webScopeOpts);
927
+ }
928
+ if (webContextEntry && typeof webContextEntry === "object") {
929
+ const wc = webContextEntry;
930
+ webContextAvailable = typeof wc.available === "boolean" ? wc.available : undefined;
931
+ webContextReason = typeof wc.reason === "string" ? wc.reason : undefined;
932
+ }
933
+ if (webContextEntry &&
934
+ typeof webContextEntry === "object" &&
935
+ webContextEntry.available === false) {
936
+ const miss = webContextEntry;
937
+ if (process.env.NARRIX_DEBUG === "1") {
938
+ // eslint-disable-next-line no-console
939
+ console.warn("[NARRIX_WEB_SCOPE] miss:", miss.reason, miss.error ?? "");
940
+ }
941
+ if (traceCollector) {
942
+ traceCollector.push({
943
+ taskType: "pre-execution",
944
+ details: "narrix web scope miss",
945
+ metadata: {
946
+ ...baseTraceMeta(),
947
+ phase: "narrix",
948
+ webContext: { available: false, reason: miss.reason, error: miss.error },
949
+ },
950
+ modelUsed: null,
951
+ });
952
+ }
953
+ }
954
+ }
955
+ request = {
956
+ ...request,
957
+ executionMemory: {
958
+ ...(request.executionMemory || {}),
959
+ [attachToField]: attachment,
960
+ ...(webContextEntry !== undefined ? { webContext: webContextEntry } : {}),
961
+ },
962
+ jobMemory: request.jobMemory ? { ...request.jobMemory, _narrix: attachment } : { _narrix: attachment },
963
+ };
964
+ const scopingSignalsCount = Array.isArray(attachment?.scoping?.signals) ? attachment.scoping.signals.length : undefined;
965
+ const scopingStoriesCount = Array.isArray(attachment?.scoping?.stories) ? attachment.scoping.stories.length : undefined;
966
+ const discoverySignalsCount = Array.isArray(attachment?.discovery?.signals) ? attachment.discovery.signals.length : undefined;
967
+ const discoveryStoriesCount = Array.isArray(attachment?.discovery?.stories) ? attachment.discovery.stories.length : undefined;
968
+ const entityKey = narrixResult?.entity?.entityKey;
969
+ const entityKind = narrixResult?.entity?.entityKind;
970
+ return {
971
+ datasetId: narrixCfg.datasetId,
972
+ attachToField,
973
+ enableWebScope: narrixCfg.enableWebScope === true,
974
+ webContextAvailable,
975
+ webContextReason,
976
+ attachmentMeta: isRecord(attachment?.meta) ? attachment.meta : undefined,
977
+ scopingSignalsCount,
978
+ scopingStoriesCount,
979
+ discoverySignalsCount,
980
+ discoveryStoriesCount,
981
+ entityKey: typeof entityKey === "string" ? entityKey : undefined,
982
+ entityKind: typeof entityKind === "string" ? entityKind : undefined,
983
+ medium: typeof adaptResult.narrixInput?.medium === "string" ? adaptResult.narrixInput.medium : undefined,
984
+ };
985
+ },
986
+ onSuccessUpdates: (r) => ({
987
+ outer: activixOuterTier({
988
+ kind: "narrix.preProcessor.request",
989
+ datasetId: narrixCfg.datasetId,
990
+ attachToField: narrixCfg.attachToField ?? "_narrix",
991
+ enableWebScope: narrixCfg.enableWebScope === true,
992
+ webScoping: narrixCfg.webScoping ? summarizeForOuter(narrixCfg.webScoping, 2_000) : undefined,
993
+ requestInput: summarizeForOuter(request.input, 4_000),
994
+ }, {
995
+ kind: "narrix.preProcessor.result",
996
+ datasetId: r.datasetId,
997
+ attachToField: r.attachToField,
998
+ enableWebScope: r.enableWebScope,
999
+ entity: r.entityKey ? { entityKey: r.entityKey, entityKind: r.entityKind } : undefined,
1000
+ counts: {
1001
+ scopingSignals: r.scopingSignalsCount,
1002
+ scopingStories: r.scopingStoriesCount,
1003
+ discoverySignals: r.discoverySignalsCount,
1004
+ discoveryStories: r.discoveryStoriesCount,
1005
+ },
1006
+ webContext: r.enableWebScope
1007
+ ? { available: r.webContextAvailable, reason: r.webContextReason }
1008
+ : undefined,
1009
+ attachmentMeta: r.attachmentMeta,
1010
+ }, { phase: "narrix" }),
1011
+ }),
1012
+ }));
1013
+ }
1014
+ // Structured Narrix (`narrixInput`): same enrichment as legacy `narrix-then-direct`, but runs before local tasks / pipeline PRE.
1015
+ if (knobs.narrixMode === "handler") {
1016
+ if (!request.narrixInput) {
1017
+ throw new Error(`narrixMode "handler" requires narrixInput. ` +
1018
+ `Provide { medium, datasetId, ... } or { $path: "jobMemory.currentRecord" } on the request.`);
1019
+ }
1020
+ const resolvedNarrixInput = resolveNarrixInput(request.narrixInput, request.jobMemory);
1021
+ if (!resolvedNarrixInput) {
1022
+ throw new Error(`narrixMode "handler": narrixInput could not be resolved. ` +
1023
+ `Ensure it has medium and datasetId, or that $path points to a valid object in jobMemory.`);
1024
+ }
1025
+ let narrixThenDirectPhaseRecordId = null;
1026
+ if (ax && correlationId) {
1027
+ try {
1028
+ narrixThenDirectPhaseRecordId = (await ax.startRecord({
1029
+ correlationId,
1030
+ phase: "narrix_then_direct",
1031
+ ...baseMeta,
1032
+ narrixDatasetId: resolvedNarrixInput.datasetId,
1033
+ narrixMedium: resolvedNarrixInput.medium,
1034
+ outer: activixOuterTier({
1035
+ kind: "narrixThenDirect.request",
1036
+ skillKey: request.skillKey,
1037
+ jobId: request.jobId,
1038
+ agentId: request.agentId,
1039
+ narrixInput: summarizeForOuter(resolvedNarrixInput, 6_000),
1040
+ }, null, { phase: "narrix_then_direct" }),
1041
+ })).recordId;
1042
+ }
1043
+ catch {
1044
+ narrixThenDirectPhaseRecordId = null;
1045
+ }
1046
+ }
1047
+ try {
1048
+ const narrixStarted = Date.now();
1049
+ const narrixHandlerCtx = {
1050
+ skillKey: request.skillKey,
1051
+ jobMemory: request.jobMemory,
1052
+ taskMemory: request.taskMemory,
1053
+ executionMemory: request.executionMemory,
1054
+ variables: request.variables,
1055
+ xynthesized: request.xynthesized,
1056
+ smartInput: request.smartInput,
1057
+ jobId: request.jobId,
1058
+ taskId: request.taskId,
1059
+ agentId: request.agentId,
1060
+ graphId: request.graphId,
1061
+ nodeId: request.nodeId,
1062
+ prevNodeId: request.prevNodeId,
1063
+ coreSkillId: request.coreSkillId,
1064
+ masterSkillId: request.masterSkillId,
1065
+ masterSkillActivityId: request.masterSkillActivityId,
1066
+ };
1067
+ const narrixResult = await traceWrap(traceCollector, {
1068
+ taskType: "pre-execution",
1069
+ details: "narrix structured handler (narrixInput)",
1070
+ metadata: {
1071
+ ...baseTraceMeta(),
1072
+ phase: "narrix_then_direct",
1073
+ datasetId: resolvedNarrixInput.datasetId,
1074
+ medium: resolvedNarrixInput.medium,
1075
+ },
1076
+ }, async () => narrixRunHandler({ input: resolvedNarrixInput, ctx: narrixHandlerCtx }), (r) => ({
1077
+ metadata: { ok: r?.ok === true },
1078
+ modelUsed: null,
1079
+ }));
1080
+ const narrixDurationMs = Date.now() - narrixStarted;
1081
+ if (!narrixResult.ok) {
1082
+ const fail = narrixResult;
1083
+ if (ax && correlationId && narrixThenDirectPhaseRecordId) {
1084
+ await ax
1085
+ .failRecord(narrixThenDirectPhaseRecordId, new Error(`Narrix handler failed: ${fail.error}${fail.message ? ` - ${fail.message}` : ""}`), {
1086
+ errorMessage: fail.message ? `${fail.error} - ${fail.message}` : fail.error,
1087
+ errorCode: fail.code,
1088
+ narrixDurationMs,
1089
+ })
1090
+ .catch(() => undefined);
1091
+ }
1092
+ return withTrace({
1093
+ skillKey: request.skillKey,
1094
+ rawText: JSON.stringify(narrixResult, null, 2),
1095
+ flexMd: { frame: "narrixThenDirect.v1", payloads: { narrix: JSON.stringify(narrixResult) } },
1096
+ parsed: {
1097
+ ok: false,
1098
+ error: narrixResult.error,
1099
+ phase: "narrix",
1100
+ message: narrixResult.message,
1101
+ },
1102
+ metadata: {
1103
+ instructionVersion: "narrix-then-direct",
1104
+ narrix: { ...narrixResult, durationMs: narrixDurationMs },
1105
+ narrixMode: knobs.narrixMode,
1106
+ inputStrategyKey: knobs.inputStrategyKey,
1107
+ executionStrategiesSummary: executionStrategiesSummaryFromKnobs(knobs),
1108
+ },
1109
+ });
1110
+ }
1111
+ const filteredEntry = applyNarrixScope(narrixResult, request.narrixScope);
1112
+ const existingNarrix = Array.isArray(request.taskMemory?.narrix)
1113
+ ? request.taskMemory.narrix
1114
+ : [];
1115
+ const updatedTaskMemory = {
1116
+ ...(request.taskMemory ?? {}),
1117
+ narrix: [...existingNarrix, filteredEntry],
1118
+ };
1119
+ const skillInput = typeof request.input === "object" && request.input !== null
1120
+ ? { ...request.input, narrixContext: filteredEntry }
1121
+ : { narrixContext: filteredEntry };
1122
+ request = {
1123
+ ...request,
1124
+ taskMemory: updatedTaskMemory,
1125
+ input: skillInput,
1126
+ };
1127
+ if (ax && correlationId && narrixThenDirectPhaseRecordId) {
1128
+ await ax
1129
+ .completeRecord(narrixThenDirectPhaseRecordId, {
1130
+ narrixDurationMs,
1131
+ outer: activixOuterTier({
1132
+ kind: "narrixThenDirect.request",
1133
+ skillKey: request.skillKey,
1134
+ jobId: request.jobId,
1135
+ agentId: request.agentId,
1136
+ narrixInput: summarizeForOuter(resolvedNarrixInput, 6_000),
1137
+ }, {
1138
+ kind: "narrixThenDirect.result",
1139
+ ok: true,
1140
+ durationMs: narrixDurationMs,
1141
+ }, { phase: "narrix_then_direct" }),
1142
+ })
1143
+ .catch(() => undefined);
1144
+ }
1145
+ }
1146
+ catch (error) {
1147
+ if (ax && correlationId && narrixThenDirectPhaseRecordId) {
1148
+ await ax
1149
+ .failRecord(narrixThenDirectPhaseRecordId, error instanceof Error ? error : new Error(String(error)), {
1150
+ errorMessage: error instanceof Error ? error.message : String(error),
1151
+ errorCode: error?.code,
1152
+ outer: activixOuterTier({
1153
+ kind: "narrixThenDirect.request",
1154
+ skillKey: request.skillKey,
1155
+ jobId: request.jobId,
1156
+ agentId: request.agentId,
1157
+ narrixInput: summarizeForOuter(resolvedNarrixInput, 6_000),
1158
+ }, {
1159
+ kind: "narrixThenDirect.error",
1160
+ message: error instanceof Error ? error.message : String(error),
1161
+ }, { phase: "narrix_then_direct" }),
1162
+ })
1163
+ .catch(() => undefined);
1164
+ }
1165
+ throw error;
1166
+ }
1167
+ }
1168
+ // Local task dispatch: if a handler is registered, run it and return (no enrichment)
1169
+ const handler = getLocalTask(request.skillKey);
1170
+ if (handler) {
1171
+ const result = await traceWrap(traceCollector, {
1172
+ taskType: "pre-execution",
1173
+ details: "local task handler",
1174
+ metadata: {
1175
+ ...baseTraceMeta(),
1176
+ phase: "local",
1177
+ localSkillKey: request.skillKey,
1178
+ },
1179
+ modelUsed: null,
1180
+ }, async () => withPhaseRecord({
1181
+ ax,
1182
+ correlationId,
1183
+ phase: "local",
1184
+ meta: {
1185
+ ...baseMeta,
1186
+ localSkillKey: request.skillKey,
1187
+ outer: activixOuterTier({
1188
+ kind: "localTask.request",
1189
+ skillKey: request.skillKey,
1190
+ jobId: request.jobId,
1191
+ agentId: request.agentId,
1192
+ input: summarizeForOuter(request.input, 4_000),
1193
+ }, null, { phase: "local" }),
1194
+ },
1195
+ fn: async () => {
1196
+ const started = Date.now();
1197
+ const ctx = {
1198
+ skillKey: request.skillKey,
1199
+ jobMemory: request.jobMemory,
1200
+ taskMemory: request.taskMemory,
1201
+ executionMemory: request.executionMemory,
1202
+ variables: input.variables,
1203
+ xynthesized: request.xynthesized,
1204
+ smartInput: request.smartInput,
1205
+ jobId: input.jobId,
1206
+ taskId: input.taskId,
1207
+ agentId: input.agentId,
1208
+ graphId: input.graphId,
1209
+ nodeId: input.nodeId,
1210
+ prevNodeId: input.prevNodeId,
1211
+ coreSkillId: input.coreSkillId,
1212
+ masterSkillId: request.masterSkillId,
1213
+ masterSkillActivityId: request.masterSkillActivityId,
1214
+ };
1215
+ const value = await handler({ input: request.input, ctx });
1216
+ const durationMs = Date.now() - started;
1217
+ let parsed = value;
1218
+ let intermediateSteps;
1219
+ if (value !== null &&
1220
+ typeof value === "object" &&
1221
+ !Array.isArray(value) &&
1222
+ "intermediateSteps" in value) {
1223
+ const steps = value.intermediateSteps;
1224
+ if (Array.isArray(steps) &&
1225
+ steps.length > 0 &&
1226
+ steps.every((s) => typeof s === "object" && s !== null && "step" in s && "id" in s && "ok" in s)) {
1227
+ intermediateSteps = steps;
1228
+ const { intermediateSteps: _removed, ...rest } = value;
1229
+ parsed = (Object.keys(rest).length > 0 ? rest : undefined);
1230
+ }
1231
+ }
1232
+ const response = {
1233
+ skillKey: request.skillKey,
1234
+ rawText: JSON.stringify(value, null, 2),
1235
+ flexMd: {
1236
+ frame: "localTask.v1",
1237
+ payloads: { value: JSON.stringify(value, null, 2) },
1238
+ },
1239
+ parsed,
1240
+ metadata: {
1241
+ instructionVersion: "local",
1242
+ activityId: undefined,
1243
+ durationMs,
1244
+ localSkillKey: request.skillKey,
1245
+ },
1246
+ };
1247
+ if (intermediateSteps)
1248
+ response.intermediateSteps = intermediateSteps;
1249
+ if (isStrictDecisionTask(request)) {
1250
+ const parsedMissing = response.parsed === undefined || response.parsed === null;
1251
+ if (parsedMissing) {
1252
+ throw new Error(`Decision task "${request.skillKey}" did not return response.parsed`);
1253
+ }
1254
+ }
1255
+ const outputValidation = request.outputValidation;
1256
+ if (outputValidation?.schema) {
1257
+ const validateWhenMissing = outputValidation.validateWhenMissing !== false;
1258
+ if (validateWhenMissing || response.parsed !== undefined) {
1259
+ const vr = validateParsedOutput(response.parsed, outputValidation.schema);
1260
+ vr.correlationId = taskId;
1261
+ response.metadata = { ...response.metadata, outputValidation: vr };
1262
+ if (!vr.ok && (outputValidation.mode ?? "fail") === "fail") {
1263
+ throw new Error(`outputValidation failed for skillKey ${request.skillKey}: ` +
1264
+ vr.errors.map((e) => `${e.path} ${e.message}`).join("; "));
1265
+ }
1266
+ if (!vr.ok && (outputValidation.mode ?? "fail") === "warn") {
1267
+ }
1268
+ }
1269
+ }
1270
+ return response;
1271
+ },
1272
+ onSuccessUpdates: (result) => {
1273
+ const steps = result?.intermediateSteps;
1274
+ return {
1275
+ localSkillKey: result?.metadata?.localSkillKey,
1276
+ durationMs: result?.metadata?.durationMs,
1277
+ hasIntermediateSteps: Array.isArray(steps) && steps.length > 0,
1278
+ stepCount: Array.isArray(steps) ? steps.length : undefined,
1279
+ outer: activixOuterTier({
1280
+ kind: "localTask.request",
1281
+ skillKey: request.skillKey,
1282
+ jobId: request.jobId,
1283
+ agentId: request.agentId,
1284
+ input: summarizeForOuter(request.input, 4_000),
1285
+ }, {
1286
+ kind: "localTask.response",
1287
+ skillKey: result?.skillKey,
1288
+ metadata: summarizeForOuter(result?.metadata, 4_000),
1289
+ parsed: summarizeForOuter(result?.parsed, 8_000),
1290
+ }, { phase: "local" }),
1291
+ };
1292
+ },
1293
+ }), (r) => ({
1294
+ metadata: {
1295
+ durationMs: r?.metadata?.durationMs,
1296
+ },
1297
+ modelUsed: null,
1298
+ }));
1299
+ return withTrace(finalize(result));
1300
+ }
1301
+ // Execution pipeline: when request.executionPipeline is set, run PRE steps then main then POST
1302
+ const pipeline = request.executionPipeline;
1303
+ if (pipeline && Array.isArray(pipeline) && pipeline.length > 0) {
1304
+ const mainSteps = pipeline.filter((s) => s.phase === "main");
1305
+ if (mainSteps.length !== 1) {
1306
+ throw new Error(`executionPipeline must have exactly one step with phase "main"; got ${mainSteps.length}. skillKey: ${request.skillKey}`);
1307
+ }
1308
+ const preSteps = pipeline.filter((s) => s.phase === "pre");
1309
+ let overrideContext;
1310
+ let synthesizedArtifact;
1311
+ let detectedTemplateCores = [];
1312
+ // Aggregated trace-mode-only LlmCallObservations from PRE synthesis (markdown/structured/questionDriven).
1313
+ // Lifted into `result.metadata.synthesizedContextLlmCalls` once the pipeline finishes.
1314
+ const aggregatedSynthLlmCalls = [];
1315
+ for (const step of preSteps) {
1316
+ if (step.type !== SYNTHESIZED_CONTEXT) {
1317
+ throw new Error(`executionPipeline: unsupported PRE step type "${String(step.type)}". Only "${SYNTHESIZED_CONTEXT}" (Xynthesis synthesized-context) is supported.`);
1318
+ }
1319
+ {
1320
+ const config = (step.config ?? {});
1321
+ if (request.includeContextInPrompt !== true && config.autoEnableContext !== true) {
1322
+ throw new Error("synthesized-context PRE step requires includeContextInPrompt: true or synthesisConfig.autoEnableContext: true");
1323
+ }
1324
+ const reqWithContext = { ...request, includeContextInPrompt: true };
1325
+ const cachedSynth = request.executionMemory?.synthesizedContext;
1326
+ const preStepResult = config.reuseCachedSynthesizedContext === true &&
1327
+ cachedSynth &&
1328
+ reuseableSynthesizedArtifact(cachedSynth)
1329
+ ? {
1330
+ contextMarkdown: contextMarkdownFromArtifact(cachedSynth),
1331
+ artifact: cachedSynth,
1332
+ synthesizedInput: request.executionMemory?.synthesizedInput,
1333
+ }
1334
+ : await traceWrap(traceCollector, {
1335
+ taskType: "pre-execution",
1336
+ details: "synthesized-context pre step",
1337
+ metadata: {
1338
+ ...baseTraceMeta(),
1339
+ phase: "pipeline_pre",
1340
+ preStepType: "synthesized-context",
1341
+ synthesisMode: resolveSynthesisMode(config),
1342
+ reusedCache: false,
1343
+ ...(config.xynthesizedOutput && traceCollector
1344
+ ? {
1345
+ xynthesized: {
1346
+ inputPathsUsed: [...(config.memoryPaths ?? [])],
1347
+ outputDestination: config.xynthesizedOutput.destination,
1348
+ outputKey: config.xynthesizedOutput.outputKey,
1349
+ patchKeys: [config.xynthesizedOutput.outputKey],
1350
+ },
1351
+ smartInput: {
1352
+ paths: reqWithContext.smartInput?.paths ?? [],
1353
+ },
1354
+ }
1355
+ : traceCollector
1356
+ ? {
1357
+ smartInput: {
1358
+ paths: reqWithContext.smartInput?.paths ?? [],
1359
+ },
1360
+ }
1361
+ : {}),
1362
+ },
1363
+ }, async () => withPhaseRecord({
1364
+ ax,
1365
+ correlationId,
1366
+ phase: "pipeline_pre",
1367
+ meta: {
1368
+ ...baseMeta,
1369
+ preStepType: "synthesized-context",
1370
+ outer: activixOuterTier({
1371
+ kind: "pipelinePre.synthesizedContext.request",
1372
+ skillKey: reqWithContext.skillKey,
1373
+ jobId: reqWithContext.jobId,
1374
+ agentId: reqWithContext.agentId,
1375
+ contextSourcePolicy: config?.contextSourcePolicy,
1376
+ synthesisMode: resolveSynthesisMode(config),
1377
+ input: summarizeForOuter(reqWithContext.input, 4_000),
1378
+ }, null, { phase: "pipeline_pre" }),
1379
+ },
1380
+ fn: async () => this._runSynthesizedContextPreStep(reqWithContext, config, traceCollector),
1381
+ onSuccessUpdates: (r) => ({
1382
+ outer: activixOuterTier({
1383
+ kind: "pipelinePre.synthesizedContext.request",
1384
+ skillKey: reqWithContext.skillKey,
1385
+ jobId: reqWithContext.jobId,
1386
+ agentId: reqWithContext.agentId,
1387
+ contextSourcePolicy: config?.contextSourcePolicy,
1388
+ synthesisMode: resolveSynthesisMode(config),
1389
+ input: summarizeForOuter(reqWithContext.input, 4_000),
1390
+ }, {
1391
+ kind: "pipelinePre.synthesizedContext.result",
1392
+ contextMarkdown: summarizeForOuter(r.contextMarkdown, 8_000),
1393
+ artifact: r.artifact
1394
+ ? {
1395
+ mode: r.artifact.mode,
1396
+ templateCores: r.artifact?.templateCores ?? [],
1397
+ question: typeof r.artifact?.question === "string"
1398
+ ? summarizeForOuter(r.artifact.question, 2_000)
1399
+ : undefined,
1400
+ }
1401
+ : undefined,
1402
+ }, { phase: "pipeline_pre" }),
1403
+ }),
1404
+ }), (r) => ({
1405
+ metadata: {
1406
+ synthesizedContextChars: typeof r.contextMarkdown === "string" ? r.contextMarkdown.length : 0,
1407
+ ...(config.xynthesizedOutput && traceCollector
1408
+ ? {
1409
+ xynthesized: {
1410
+ inputPathsUsed: [...(config.memoryPaths ?? [])],
1411
+ outputDestination: config.xynthesizedOutput.destination,
1412
+ outputKey: config.xynthesizedOutput.outputKey,
1413
+ patchKeys: [config.xynthesizedOutput.outputKey],
1414
+ },
1415
+ }
1416
+ : {}),
1417
+ },
1418
+ }));
1419
+ overrideContext = preStepResult.contextMarkdown;
1420
+ synthesizedArtifact = preStepResult.artifact;
1421
+ if (traceCollector && preStepResult.synthesizedContextLlmCalls) {
1422
+ aggregatedSynthLlmCalls.push(...preStepResult.synthesizedContextLlmCalls);
1423
+ }
1424
+ if (synthesizedArtifact) {
1425
+ detectedTemplateCores = synthesizedArtifact?.templateCores ?? [];
1426
+ }
1427
+ const xynthOut = config.xynthesizedOutput;
1428
+ const writeLegacyToExecutionMemory = !xynthOut || xynthOut.alsoWriteLegacySynthesizedContext !== false;
1429
+ if (synthesizedArtifact && writeLegacyToExecutionMemory) {
1430
+ request = {
1431
+ ...request,
1432
+ executionMemory: {
1433
+ ...(request.executionMemory ?? {}),
1434
+ synthesizedContext: synthesizedArtifact,
1435
+ ...(preStepResult.synthesizedInput ? { synthesizedInput: preStepResult.synthesizedInput } : {}),
1436
+ },
1437
+ };
1438
+ }
1439
+ if (xynthOut) {
1440
+ const synthesizedResult = synthesizedResultForXynthesizedPatch(synthesizedArtifact, preStepResult.contextMarkdown);
1441
+ const { nextXynthesized, patchSlice } = applyXynthesizedOutputWrite(request.xynthesized, xynthOut, synthesizedResult);
1442
+ request = { ...request, xynthesized: nextXynthesized };
1443
+ xynthesizedPatchAccumulator = mergeXynthesizedPatchSlices(xynthesizedPatchAccumulator, patchSlice);
1444
+ }
1445
+ if (traceCollector &&
1446
+ config.reuseCachedSynthesizedContext === true &&
1447
+ cachedSynth &&
1448
+ reuseableSynthesizedArtifact(cachedSynth)) {
1449
+ traceCollector.push({
1450
+ taskType: "pre-execution",
1451
+ details: "synthesized-context pre step (reused cached artifact)",
1452
+ metadata: {
1453
+ ...baseTraceMeta(),
1454
+ phase: "pipeline_pre",
1455
+ preStepType: "synthesized-context",
1456
+ synthesisMode: resolveSynthesisMode(config),
1457
+ reusedCache: true,
1458
+ ...(config.xynthesizedOutput
1459
+ ? {
1460
+ xynthesized: {
1461
+ inputPathsUsed: [...(config.memoryPaths ?? [])],
1462
+ outputDestination: config.xynthesizedOutput.destination,
1463
+ outputKey: config.xynthesizedOutput.outputKey,
1464
+ patchKeys: [config.xynthesizedOutput.outputKey],
1465
+ },
1466
+ smartInput: {
1467
+ paths: request.smartInput?.paths ?? [],
1468
+ },
1469
+ }
1470
+ : {
1471
+ smartInput: {
1472
+ paths: request.smartInput?.paths ?? [],
1473
+ },
1474
+ }),
1475
+ },
1476
+ modelUsed: null,
1477
+ });
1478
+ }
1479
+ break;
1480
+ }
1481
+ }
1482
+ const synthesizedFromExecution = request.executionMemory?.synthesizedContext &&
1483
+ typeof request.executionMemory.synthesizedContext === "object";
1484
+ const mainContextSource = synthesizedFromExecution ? "synthesizedContext" : "unsynthesized";
1485
+ if (mainContextSource === "synthesizedContext") {
1486
+ const artifact = request.executionMemory?.synthesizedContext;
1487
+ if (artifact && typeof artifact === "object" && typeof artifact.contextMarkdown === "string") {
1488
+ overrideContext = artifact.contextMarkdown;
1489
+ }
1490
+ }
1491
+ const postSteps = pipeline.filter((s) => s.phase === "post");
1492
+ const observability = {
1493
+ synthesisEnabled: preSteps.some((s) => s.type === SYNTHESIZED_CONTEXT),
1494
+ effectiveExecutionPipeline: pipeline,
1495
+ synthesizedContextPresent: synthesizedFromExecution,
1496
+ mainContextSource,
1497
+ detectedTemplateCores,
1498
+ synthesisMode: synthesizedArtifact?.mode === "markdown" || synthesizedArtifact?.mode === "structured"
1499
+ ? synthesizedArtifact.mode
1500
+ : undefined,
1501
+ };
1502
+ const directOpts = {
1503
+ overrideContext,
1504
+ synthesisContextAuthoritative: mainContextSource === "synthesizedContext",
1505
+ };
1506
+ if (postSteps.length === 0) {
1507
+ const result = finalize(await runMainWithExecutionStrategies(request, directOpts));
1508
+ if (overrideContext !== undefined) {
1509
+ const synthesisStep = {
1510
+ step: 1,
1511
+ id: "synthesis",
1512
+ ok: true,
1513
+ summary: "context synthesized",
1514
+ outputExcerpt: {
1515
+ mainContextSource,
1516
+ synthesizedContextPresent: observability.synthesizedContextPresent,
1517
+ detectedTemplateCores: observability.detectedTemplateCores ?? [],
1518
+ },
1519
+ };
1520
+ const existingSteps = result.intermediateSteps ?? [];
1521
+ result.intermediateSteps = [
1522
+ synthesisStep,
1523
+ ...existingSteps.map((s, i) => ({ ...s, step: i + 2 })),
1524
+ ];
1525
+ }
1526
+ attachExecutionStateAndObservability(result, request, observability);
1527
+ if (traceCollector && aggregatedSynthLlmCalls.length > 0) {
1528
+ result.metadata = {
1529
+ ...(result.metadata ?? {}),
1530
+ synthesizedContextLlmCalls: aggregatedSynthLlmCalls,
1531
+ };
1532
+ }
1533
+ return withTrace(result);
1534
+ }
1535
+ const capture = { contextMarkdown: "" };
1536
+ let result = finalize(await runMainWithExecutionStrategies(request, { ...directOpts, captureContext: capture }));
1537
+ if (overrideContext !== undefined) {
1538
+ const synthesisStep = {
1539
+ step: 1,
1540
+ id: "synthesis",
1541
+ ok: true,
1542
+ summary: "context synthesized",
1543
+ outputExcerpt: {
1544
+ mainContextSource,
1545
+ synthesizedContextPresent: observability.synthesizedContextPresent,
1546
+ detectedTemplateCores: observability.detectedTemplateCores ?? [],
1547
+ },
1548
+ };
1549
+ const existingSteps = result.intermediateSteps ?? [];
1550
+ result.intermediateSteps = [
1551
+ synthesisStep,
1552
+ ...existingSteps.map((s, i) => ({ ...s, step: i + 2 })),
1553
+ ];
1554
+ }
1555
+ let currentOutput = typeof result.rawText === "string"
1556
+ ? result.rawText
1557
+ : JSON.stringify(result.parsed ?? result.rawText ?? "", null, 2);
1558
+ const postStepsMeta = {};
1559
+ let nextStepNumber = (result.intermediateSteps?.length ?? 0) + 1;
1560
+ const reRunMain = (overrideContextWithFeedback) => runDirect(request, { overrideContext: overrideContextWithFeedback });
1561
+ for (const step of postSteps) {
1562
+ if (step.type === "audit") {
1563
+ const auditResult = await traceWrap(traceCollector, {
1564
+ taskType: "post-execution",
1565
+ details: "audit post step",
1566
+ metadata: {
1567
+ ...baseTraceMeta(),
1568
+ phase: "audit",
1569
+ postStepType: "audit",
1570
+ },
1571
+ }, async () => withPhaseRecord({
1572
+ ax,
1573
+ correlationId,
1574
+ phase: "audit",
1575
+ meta: {
1576
+ ...baseMeta,
1577
+ postStepType: "audit",
1578
+ outer: activixOuterTier({
1579
+ kind: "postStep.audit.request",
1580
+ skillKey: request.skillKey,
1581
+ jobId: request.jobId,
1582
+ agentId: request.agentId,
1583
+ input: summarizeForOuter({
1584
+ currentOutput,
1585
+ hasContextMarkdown: !!capture.contextMarkdown,
1586
+ }, 8_000),
1587
+ }, null, { phase: "audit" }),
1588
+ },
1589
+ fn: async () => runAuditPostStep({
1590
+ request,
1591
+ mainResult: result,
1592
+ contextMarkdown: capture.contextMarkdown,
1593
+ config: (step.config ?? {}),
1594
+ reRunMain,
1595
+ traceCollector,
1596
+ }),
1597
+ onSuccessUpdates: (auditResult) => ({
1598
+ totalCycles: auditResult.metadata?.totalCycles,
1599
+ allMustPassed: auditResult.metadata?.allMustPassed,
1600
+ synthesisUsed: auditResult.metadata?.synthesisUsed,
1601
+ durationMs: auditResult.metadata?.durationMs,
1602
+ outer: activixOuterTier({
1603
+ kind: "postStep.audit.request",
1604
+ skillKey: request.skillKey,
1605
+ jobId: request.jobId,
1606
+ agentId: request.agentId,
1607
+ input: summarizeForOuter({
1608
+ currentOutput,
1609
+ hasContextMarkdown: !!capture.contextMarkdown,
1610
+ }, 8_000),
1611
+ }, {
1612
+ kind: "postStep.audit.result",
1613
+ outputText: summarizeForOuter(auditResult.outputText, 8_000),
1614
+ metadata: summarizeForOuter(auditResult.metadata, 6_000),
1615
+ }, { phase: "audit" }),
1616
+ }),
1617
+ }), (r) => ({
1618
+ metadata: {
1619
+ durationMs: r?.metadata?.durationMs,
1620
+ totalCycles: r?.metadata?.totalCycles,
1621
+ allMustPassed: r?.metadata?.allMustPassed,
1622
+ },
1623
+ modelUsed: r?.metadata?.modelUsed ?? null,
1624
+ }));
1625
+ currentOutput = auditResult.outputText;
1626
+ postStepsMeta.audit = auditResult.metadata;
1627
+ const stepsWithNumbers = auditResult.intermediateSteps.map((s) => ({
1628
+ ...s,
1629
+ step: nextStepNumber++,
1630
+ }));
1631
+ result.intermediateSteps = [
1632
+ ...(result.intermediateSteps ?? []),
1633
+ ...stepsWithNumbers,
1634
+ ];
1635
+ }
1636
+ else if (step.type === "polish") {
1637
+ const polishResult = await traceWrap(traceCollector, {
1638
+ taskType: "post-execution",
1639
+ details: "polish post step",
1640
+ metadata: {
1641
+ ...baseTraceMeta(),
1642
+ phase: "polish",
1643
+ postStepType: "polish",
1644
+ },
1645
+ }, async () => withPhaseRecord({
1646
+ ax,
1647
+ correlationId,
1648
+ phase: "polish",
1649
+ meta: {
1650
+ ...baseMeta,
1651
+ postStepType: "polish",
1652
+ outer: activixOuterTier({
1653
+ kind: "postStep.polish.request",
1654
+ skillKey: request.skillKey,
1655
+ jobId: request.jobId,
1656
+ agentId: request.agentId,
1657
+ input: summarizeForOuter({ currentOutput }, 8_000),
1658
+ }, null, { phase: "polish" }),
1659
+ },
1660
+ fn: async () => runPolishPostStep({
1661
+ currentOutput,
1662
+ config: (step.config ?? {}),
1663
+ originalInput: step.config?.includeOriginalContext ? request.input : undefined,
1664
+ promptContext: step.config?.includeOriginalContext ? capture.contextMarkdown : undefined,
1665
+ traceCollector,
1666
+ jobId: request.jobId,
1667
+ taskId: request.taskId,
1668
+ skillKey: request.skillKey,
1669
+ }),
1670
+ onSuccessUpdates: (polishResult) => ({
1671
+ totalPasses: polishResult.metadata?.totalPasses,
1672
+ durationMs: polishResult.metadata?.durationMs,
1673
+ outer: activixOuterTier({
1674
+ kind: "postStep.polish.request",
1675
+ skillKey: request.skillKey,
1676
+ jobId: request.jobId,
1677
+ agentId: request.agentId,
1678
+ input: summarizeForOuter({ currentOutput }, 8_000),
1679
+ }, {
1680
+ kind: "postStep.polish.result",
1681
+ outputText: summarizeForOuter(polishResult.outputText, 8_000),
1682
+ metadata: summarizeForOuter(polishResult.metadata, 6_000),
1683
+ }, { phase: "polish" }),
1684
+ }),
1685
+ }), (r) => ({
1686
+ metadata: {
1687
+ durationMs: r?.metadata?.durationMs,
1688
+ totalPasses: r?.metadata?.totalPasses,
1689
+ },
1690
+ modelUsed: r?.metadata?.modelUsed ?? null,
1691
+ }));
1692
+ currentOutput = polishResult.outputText;
1693
+ postStepsMeta.polish = polishResult.metadata;
1694
+ const stepsWithNumbers = polishResult.intermediateSteps.map((s) => ({
1695
+ ...s,
1696
+ step: nextStepNumber++,
1697
+ }));
1698
+ result.intermediateSteps = [
1699
+ ...(result.intermediateSteps ?? []),
1700
+ ...stepsWithNumbers,
1701
+ ];
1702
+ }
1703
+ }
1704
+ result.rawText = currentOutput;
1705
+ result.parsed = currentOutput;
1706
+ result.metadata = {
1707
+ ...(result.metadata ?? {}),
1708
+ postSteps: postStepsMeta,
1709
+ ...(traceCollector && aggregatedSynthLlmCalls.length > 0
1710
+ ? { synthesizedContextLlmCalls: aggregatedSynthLlmCalls }
1711
+ : {}),
1712
+ };
1713
+ attachExecutionStateAndObservability(result, request, observability, knobs);
1714
+ return withTrace(result);
1715
+ }
1716
+ // MAIN path (direct / gateway skill). Narrix handler runs earlier when `narrixMode === "handler"`.
1717
+ {
1718
+ const result = finalize(await runMainWithExecutionStrategies(request));
1719
+ attachExecutionStateAndObservability(result, request, {
1720
+ synthesisEnabled: false,
1721
+ synthesizedContextPresent: !!request.executionMemory?.synthesizedContext,
1722
+ mainContextSource: "unsynthesized",
1723
+ }, knobs);
1724
+ return withTrace(result);
1725
+ }
1726
+ }
1727
+ /**
1728
+ * Run the synthesized-context PRE step: enrich memory, resolve source material, render templates, call synthesis model, return synthesized context.
1729
+ */
1730
+ async _runSynthesizedContextPreStep(request, config, traceCollector) {
1731
+ const input = request;
1732
+ let jobMemoryWithExecution = input.jobMemory || {};
1733
+ if (input.executionMemory) {
1734
+ const executionWithDefaults = {
1735
+ bindingDefaultsDb: process.env.MONGO_LOGS_DB || "logs-db",
1736
+ ...input.executionMemory,
1737
+ };
1738
+ if (jobMemoryWithExecution.execution) {
1739
+ jobMemoryWithExecution = {
1740
+ ...jobMemoryWithExecution,
1741
+ execution: deepMergeExecution(jobMemoryWithExecution.execution, executionWithDefaults),
1742
+ };
1743
+ }
1744
+ else {
1745
+ jobMemoryWithExecution = { ...jobMemoryWithExecution, execution: executionWithDefaults };
1746
+ }
1747
+ }
1748
+ else if (!jobMemoryWithExecution.execution?.bindingDefaultsDb) {
1749
+ jobMemoryWithExecution = {
1750
+ ...jobMemoryWithExecution,
1751
+ execution: { ...jobMemoryWithExecution.execution, bindingDefaultsDb: process.env.MONGO_LOGS_DB || "logs-db" },
1752
+ };
1753
+ }
1754
+ const memoryBundle = {
1755
+ jobMemory: jobMemoryWithExecution,
1756
+ taskMemory: input.taskMemory,
1757
+ executionMemory: {
1758
+ bindingDefaultsDb: process.env.MONGO_LOGS_DB || "logs-db",
1759
+ ...(input.executionMemory || {}),
1760
+ },
1761
+ };
1762
+ const enrichMemories = bindEnrichMemoriesWithScoping(this.skillsClient);
1763
+ const enrichedBundle = await enrichMemories(request.skillKey, "task", memoryBundle);
1764
+ const cleanExecution = cleanseExecution(enrichedBundle.jobMemory?.execution);
1765
+ const bundleForRendering = {
1766
+ ...enrichedBundle,
1767
+ jobMemory: { ...enrichedBundle.jobMemory, execution: cleanExecution },
1768
+ xynthesized: input.xynthesized,
1769
+ smartInput: input.smartInput,
1770
+ };
1771
+ const attachToField = input.narrix?.attachToField ?? "_narrix";
1772
+ const preProcessorAttachment = input.executionMemory?.[attachToField];
1773
+ const narrixAttachment = hasNarrixAttachmentShape(preProcessorAttachment)
1774
+ ? preProcessorAttachment
1775
+ : coerceTaskMemoryNarrixToAttachment(input.taskMemory?.narrix);
1776
+ const contextSourcePolicy = config.contextSourcePolicy ?? "auto";
1777
+ const resolveOpts = {
1778
+ contextSourcePolicy,
1779
+ narrixAttachment,
1780
+ enrichedMemoryBundle: enrichedBundle,
1781
+ memoryPaths: config.memoryPaths,
1782
+ webEvidence: config.webEvidence,
1783
+ narrixAttachToField: input.narrix?.attachToField ?? "_narrix",
1784
+ };
1785
+ let sourceMaterial;
1786
+ let sourceMaterialParts;
1787
+ try {
1788
+ const material = buildSynthesizerInputMaterial(config.synthesisInputStrategy, resolveOpts);
1789
+ sourceMaterial = material.sourceMaterial;
1790
+ sourceMaterialParts = material.parts;
1791
+ }
1792
+ catch (e) {
1793
+ if (config.fallbackToDirect)
1794
+ return { contextMarkdown: "" };
1795
+ throw e;
1796
+ }
1797
+ const resolveRawTemplate = async (key) => {
1798
+ const section = key.endsWith(".instructions") || key.endsWith(".instructions.md")
1799
+ ? "instructions"
1800
+ : key.endsWith(".prompt") || key.endsWith(".prompt.md")
1801
+ ? "prompt"
1802
+ : null;
1803
+ const baseSkillKey = request.skillKey;
1804
+ const skillsClient = this.skillsClient;
1805
+ if (section && typeof skillsClient.resolveRawTemplate === "function") {
1806
+ try {
1807
+ const result = await skillsClient.resolveRawTemplate(baseSkillKey, section);
1808
+ if (result?.found && typeof result.content === "string" && result.content.length > 0) {
1809
+ return result.content;
1810
+ }
1811
+ }
1812
+ catch {
1813
+ // Keep hard failure behavior in structured mode via empty token discovery.
1814
+ }
1815
+ }
1816
+ return undefined;
1817
+ };
1818
+ const synthesisRequest = request;
1819
+ const { rawInstructions, rawPrompt, renderedInstructions, renderedPrompt } = await getRenderedTemplates({
1820
+ skillKey: request.skillKey,
1821
+ bundle: bundleForRendering,
1822
+ request: synthesisRequest,
1823
+ resolveRawTemplate,
1824
+ });
1825
+ // Resolve effective LlmCallConfig for the PRE synthesis call. `config.llmCall` overrides
1826
+ // `modelConfig.model` / `timeoutMs` / `maxOutputLength`. Default `outputExpectation` from
1827
+ // `resolveOutputExpectation("synthesis")` (per xynthesis routing JSON).
1828
+ const synthLlmCallInput = {
1829
+ ...(config.llmCall ?? {}),
1830
+ model: config.llmCall?.model ??
1831
+ config.modelConfig?.model,
1832
+ timeoutMs: config.llmCall?.timeoutMs ?? config.timeoutMs,
1833
+ maxOutputLength: config.llmCall?.maxOutputLength ?? config.maxOutputLength,
1834
+ };
1835
+ const synthLlmCall = resolveLlmCall(synthLlmCallInput, llmCallEnvPrefix("SYNTHESIS"), {}, {
1836
+ outputExpectation: resolveOutputExpectationXynthesis("synthesis"),
1837
+ model: "gpt-5-nano",
1838
+ timeoutMs: 30_000,
1839
+ });
1840
+ const model = synthLlmCall.model;
1841
+ const timeoutMs = synthLlmCall.timeoutMs;
1842
+ const maxOutputLength = synthLlmCall.maxOutputLength;
1843
+ // Trace-mode-only sink for PRE synthesis observations. Surfaced to the caller via the return value's
1844
+ // `synthesizedContextLlmCalls` field (lifted into result.metadata higher up the call stack).
1845
+ const synthLlmCalls = [];
1846
+ const synthObservationSink = traceCollector
1847
+ ? (obs) => {
1848
+ synthLlmCalls.push(obs);
1849
+ }
1850
+ : undefined;
1851
+ if (config.questionDriven === true) {
1852
+ const isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
1853
+ const nonEmptyString = (v) => {
1854
+ if (typeof v !== "string")
1855
+ return undefined;
1856
+ const t = v.trim();
1857
+ return t ? t : undefined;
1858
+ };
1859
+ const truncate = (s, maxChars) => {
1860
+ if (!maxChars || maxChars <= 0)
1861
+ return s;
1862
+ if (s.length <= maxChars)
1863
+ return s;
1864
+ return s.slice(0, Math.max(0, maxChars - 20)) + "\n\n[truncated]";
1865
+ };
1866
+ const questions = Array.isArray(config.questions) ? config.questions : [];
1867
+ if (questions.length === 0) {
1868
+ const artifact = {
1869
+ mode: "questionDriven",
1870
+ answers: {},
1871
+ contextMarkdown: "",
1872
+ };
1873
+ return {
1874
+ contextMarkdown: "",
1875
+ artifact,
1876
+ synthesizedInput: buildSynthesizedInputArtifact("questionDriven", "", {
1877
+ localMarkdown: "",
1878
+ supportingMarkdown: "",
1879
+ }),
1880
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
1881
+ };
1882
+ }
1883
+ const execMem = (enrichedBundle.executionMemory ?? memoryBundle.executionMemory);
1884
+ const recordRaw = isRecord(execMem?.input) ? execMem.input.raw : undefined;
1885
+ const recordMd = recordRaw !== undefined
1886
+ ? `## Record (executionMemory.input.raw)\n\n\`\`\`json\n${truncate(JSON.stringify(recordRaw, null, 2), maxOutputLength ? Math.min(maxOutputLength, 60_000) : 60_000)}\n\`\`\`\n`
1887
+ : "";
1888
+ const webContextEntry = execMem?.webContext;
1889
+ const webMd = buildWebContextEvidenceMarkdown(webContextEntry, config.webEvidence);
1890
+ const { system: systemTemplate, user: userTemplate } = await loadSynthesisTemplates();
1891
+ const systemPrompt = buildSynthesisSystemPrompt(systemTemplate, config.synthesisPromptOverride, config.customSynthesizingGuidelines);
1892
+ const extractWebEvidence = () => {
1893
+ if (!isRecord(webContextEntry))
1894
+ return { webUnavailableReason: "webContext missing" };
1895
+ if (webContextEntry.available !== true) {
1896
+ const reason = nonEmptyString(webContextEntry.reason) ?? "unavailable";
1897
+ const err = nonEmptyString(webContextEntry.error);
1898
+ return { webUnavailableReason: err ? `${reason}: ${err}` : reason };
1899
+ }
1900
+ const ctx = webContextEntry.context;
1901
+ if (!isRecord(ctx))
1902
+ return {};
1903
+ const sourcesRaw = Array.isArray(ctx.sources) ? ctx.sources : [];
1904
+ const sources = sourcesRaw
1905
+ .filter((s) => isRecord(s))
1906
+ .map((s) => ({
1907
+ url: nonEmptyString(s.url) ?? nonEmptyString(s.link),
1908
+ title: nonEmptyString(s.title) ?? nonEmptyString(s.name),
1909
+ }))
1910
+ .filter((s) => s.url || s.title);
1911
+ const scopesRaw = Array.isArray(ctx.scopes) ? ctx.scopes : [];
1912
+ const webScopeIds = scopesRaw
1913
+ .filter((s) => isRecord(s))
1914
+ .map((s) => nonEmptyString(s.id) ?? nonEmptyString(s.scopeId))
1915
+ .filter((x) => !!x);
1916
+ return {
1917
+ sources: sources.length > 0 ? sources : undefined,
1918
+ webScopeIds: webScopeIds.length > 0 ? webScopeIds : undefined,
1919
+ };
1920
+ };
1921
+ const webEvidence = extractWebEvidence();
1922
+ const answers = {};
1923
+ for (const q of questions) {
1924
+ if (!q || typeof q !== "object")
1925
+ continue;
1926
+ const id = q.id;
1927
+ const question = q.question;
1928
+ if (typeof id !== "string" || !id.trim())
1929
+ continue;
1930
+ if (typeof question !== "string" || !question.trim())
1931
+ continue;
1932
+ const source = q.source === "record" || q.source === "web" || q.source === "both"
1933
+ ? q.source
1934
+ : "both";
1935
+ const allowRecord = source === "record" || source === "both";
1936
+ const allowWeb = source === "web" || source === "both";
1937
+ const hasRecord = !!recordMd;
1938
+ const hasWeb = !!webMd;
1939
+ const materialParts = [
1940
+ "## Target question",
1941
+ "",
1942
+ question.trim(),
1943
+ "",
1944
+ "## Allowed sources",
1945
+ "",
1946
+ `- source: ${source}`,
1947
+ "",
1948
+ ];
1949
+ if (allowRecord)
1950
+ materialParts.push(recordMd || "## Record\n\n[missing]");
1951
+ if (allowWeb)
1952
+ materialParts.push(webMd || "## Web sources (primary evidence)\n\n[unavailable]");
1953
+ const perQuestionMaterial = materialParts.join("\n");
1954
+ const userPrompt = buildSynthesisUserPrompt(renderedInstructions, renderedPrompt, perQuestionMaterial, userTemplate);
1955
+ let synthesisText;
1956
+ if (allowWeb && !hasWeb && !allowRecord) {
1957
+ const reason = webEvidence.webUnavailableReason ?? "web scoping unavailable";
1958
+ synthesisText = `Unknown — web-derived context unavailable (${reason}).`;
1959
+ }
1960
+ else if (allowRecord && !hasRecord && !allowWeb) {
1961
+ synthesisText = `Unknown — record-derived context unavailable (missing executionMemory.input.raw).`;
1962
+ }
1963
+ else if (allowRecord && allowWeb && !hasRecord && !hasWeb) {
1964
+ const reason = webEvidence.webUnavailableReason ?? "web scoping unavailable";
1965
+ synthesisText =
1966
+ `Unknown — no inputs available (missing executionMemory.input.raw; web unavailable: ${reason}).`;
1967
+ }
1968
+ else {
1969
+ const res = await runPostStepLlmCall({
1970
+ systemPrompt,
1971
+ userPrompt,
1972
+ llmCall: synthLlmCall,
1973
+ stage: "pre-synthesis-question",
1974
+ stepId: `questionDriven:${id}`,
1975
+ jobId: request.jobId,
1976
+ taskId: request.taskId,
1977
+ agentId: request.agentId,
1978
+ traceCollector,
1979
+ traceTask: traceCollector
1980
+ ? {
1981
+ taskType: "pre-execution",
1982
+ details: "synthesized-context question call",
1983
+ modelUsed: model ?? null,
1984
+ metadata: {
1985
+ jobId: request.jobId,
1986
+ taskId: request.taskId,
1987
+ skillKey: request.skillKey,
1988
+ phase: "pipeline_pre",
1989
+ preStepType: "synthesized-context",
1990
+ step: { phase: "pre", type: "synthesized-context", stepId: `questionDriven:${id}` },
1991
+ questionId: id,
1992
+ },
1993
+ }
1994
+ : undefined,
1995
+ observationSink: synthObservationSink,
1996
+ });
1997
+ synthesisText = res.text;
1998
+ }
1999
+ answers[id] = {
2000
+ question: question.trim(),
2001
+ source,
2002
+ synthesis: synthesisText,
2003
+ evidence: {
2004
+ recordPaths: allowRecord ? ["executionMemory.input.raw"] : undefined,
2005
+ webScopeIds: allowWeb ? webEvidence.webScopeIds : undefined,
2006
+ sources: allowWeb ? webEvidence.sources : undefined,
2007
+ },
2008
+ };
2009
+ }
2010
+ const contextMarkdown = "## Question-driven synthesized context\n\n" +
2011
+ Object.entries(answers)
2012
+ .map(([id, a]) => `### ${id}\n\n**Question:** ${a.question}\n\n${a.synthesis}\n`)
2013
+ .join("\n");
2014
+ const qdSource = [recordMd, webMd].filter(Boolean).join("\n\n");
2015
+ const artifact = {
2016
+ mode: "questionDriven",
2017
+ answers,
2018
+ contextMarkdown,
2019
+ };
2020
+ return {
2021
+ contextMarkdown,
2022
+ artifact,
2023
+ synthesizedInput: buildSynthesizedInputArtifact("questionDriven", qdSource, {
2024
+ localMarkdown: recordMd,
2025
+ supportingMarkdown: webMd,
2026
+ }),
2027
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
2028
+ };
2029
+ }
2030
+ const synthesisMode = resolveSynthesisMode(config);
2031
+ if (synthesisMode === "structured") {
2032
+ const parts = sourceMaterialParts;
2033
+ const question = safeResolveSynthesisQuestion(synthesisRequest, config, renderedPrompt);
2034
+ const { templateCores } = discoverTemplateCores({
2035
+ templates: [
2036
+ { name: "instructions", content: rawInstructions },
2037
+ { name: "prompt", content: rawPrompt },
2038
+ ],
2039
+ });
2040
+ if (templateCores.length === 0) {
2041
+ if (!rawInstructions.trim() && !rawPrompt.trim()) {
2042
+ throw new Error(`structured synthesized-context could not resolve raw instructions/prompt templates for skillKey: ${request.skillKey}. ` +
2043
+ `Ensure ai-skills content registry is available for resolveRawTemplate().`);
2044
+ }
2045
+ throw new Error(`structured synthesized-context requires at least one template core token in instructions or prompt. skillKey: ${request.skillKey}`);
2046
+ }
2047
+ const validateOpts = {
2048
+ expectedTemplateCores: templateCores,
2049
+ expectedQuestion: question,
2050
+ maxItemsPerSide: config.structuredMaxItemsPerSide,
2051
+ maxItemContentChars: config.structuredMaxItemContentChars,
2052
+ };
2053
+ try {
2054
+ const custom = getContextSynthesizer();
2055
+ let payload;
2056
+ if (custom) {
2057
+ payload = await custom.synthesize({
2058
+ templateCores,
2059
+ question,
2060
+ localRaw: parts.localMarkdown,
2061
+ supportingRaw: parts.supportingMarkdown,
2062
+ metadata: {
2063
+ renderedInstructions,
2064
+ renderedPrompt,
2065
+ templateCores,
2066
+ skillKey: request.skillKey,
2067
+ jobId: request.jobId,
2068
+ taskId: request.taskId,
2069
+ },
2070
+ });
2071
+ payload = normalizeAndValidateSynthesizedPayload(payload, validateOpts);
2072
+ }
2073
+ else {
2074
+ payload = await runStructuredSynthesisGatewayCallRobust({
2075
+ question,
2076
+ localMarkdown: parts.localMarkdown,
2077
+ supportingMarkdown: parts.supportingMarkdown,
2078
+ renderedInstructions,
2079
+ renderedPrompt,
2080
+ templatesBasePath: config.templatesBasePath,
2081
+ synthesisPromptOverride: config.synthesisPromptOverride,
2082
+ customSynthesizingGuidelines: config.customSynthesizingGuidelines,
2083
+ model: model,
2084
+ timeoutMs: timeoutMs,
2085
+ maxOutputLength: maxOutputLength,
2086
+ // Caller-supplied outputExpectation overrides the per-action default in the structured-repair path.
2087
+ outputExpectation: synthLlmCall.outputExpectation,
2088
+ // Hard ceiling for `resolveMaxTokens` in the AIGateway repair fallback.
2089
+ maxTokensCap: synthLlmCall.maxTokensCap,
2090
+ // Forward trace mode so the structured gateway returns a `debugTrace` (lifted into observations elsewhere).
2091
+ executionMode: traceCollector ? "trace" : undefined,
2092
+ jobId: request.jobId,
2093
+ taskId: request.taskId,
2094
+ agentId: request.agentId,
2095
+ });
2096
+ }
2097
+ const contextMarkdown = buildSynthesizedContextMarkdown(payload);
2098
+ return {
2099
+ contextMarkdown,
2100
+ artifact: {
2101
+ templateCores,
2102
+ question,
2103
+ mode: synthesisMode,
2104
+ payload,
2105
+ contextMarkdown,
2106
+ },
2107
+ synthesizedInput: buildSynthesizedInputArtifact(synthesisMode, sourceMaterial, parts, {
2108
+ question,
2109
+ templateCores,
2110
+ }),
2111
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
2112
+ };
2113
+ }
2114
+ catch (e) {
2115
+ if (config.fallbackToDirect === true)
2116
+ return {
2117
+ contextMarkdown: "",
2118
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
2119
+ };
2120
+ throw e;
2121
+ }
2122
+ }
2123
+ const { system: systemTemplate, user: userTemplate } = await loadSynthesisTemplates();
2124
+ const systemPrompt = buildSynthesisSystemPrompt(systemTemplate, config.synthesisPromptOverride, config.customSynthesizingGuidelines);
2125
+ const userPrompt = buildSynthesisUserPrompt(renderedInstructions, renderedPrompt, sourceMaterial, userTemplate);
2126
+ try {
2127
+ const { text: contextMarkdown } = await runPostStepLlmCall({
2128
+ systemPrompt,
2129
+ userPrompt,
2130
+ extraMaterial: sourceMaterial,
2131
+ llmCall: synthLlmCall,
2132
+ stage: "pre-synthesis-markdown",
2133
+ jobId: request.jobId,
2134
+ taskId: request.taskId,
2135
+ agentId: request.agentId,
2136
+ traceCollector,
2137
+ traceTask: traceCollector
2138
+ ? {
2139
+ taskType: "pre-execution",
2140
+ details: "synthesized-context markdown call",
2141
+ modelUsed: model ?? null,
2142
+ metadata: {
2143
+ jobId: request.jobId,
2144
+ taskId: request.taskId,
2145
+ skillKey: request.skillKey,
2146
+ phase: "pipeline_pre",
2147
+ preStepType: "synthesized-context",
2148
+ step: { phase: "pre", type: "synthesized-context", stepId: "markdown" },
2149
+ },
2150
+ }
2151
+ : undefined,
2152
+ observationSink: synthObservationSink,
2153
+ });
2154
+ const question = safeResolveSynthesisQuestion(synthesisRequest, config, renderedPrompt);
2155
+ const { templateCores } = discoverTemplateCores({
2156
+ templates: [
2157
+ { name: "instructions", content: rawInstructions },
2158
+ { name: "prompt", content: rawPrompt },
2159
+ ],
2160
+ });
2161
+ return {
2162
+ contextMarkdown,
2163
+ artifact: {
2164
+ templateCores,
2165
+ question,
2166
+ mode: "markdown",
2167
+ payload: { kind: "markdown-synthesis" },
2168
+ contextMarkdown,
2169
+ },
2170
+ synthesizedInput: buildSynthesizedInputArtifact("markdown", sourceMaterial, sourceMaterialParts, {
2171
+ question,
2172
+ templateCores,
2173
+ }),
2174
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
2175
+ };
2176
+ }
2177
+ catch (e) {
2178
+ if (config.fallbackToDirect === true)
2179
+ return {
2180
+ contextMarkdown: "",
2181
+ synthesizedContextLlmCalls: traceCollector ? synthLlmCalls : undefined,
2182
+ };
2183
+ throw e;
2184
+ }
2185
+ }
2186
+ /**
2187
+ * Execute the DIRECT path: build memory bundle, enrich, generate context (including Narrix section from taskMemory.narrix), then executor.
2188
+ * When options.overrideContext is set, that string is used as context markdown instead of generating it.
2189
+ * When options.captureContext is set, the context markdown sent to the MAIN step is written into it (for POST steps).
2190
+ * When options.synthesisContextAuthoritative is true, an empty override is not replaced by Narrix/web fallback.
2191
+ */
2192
+ async _executeDirect(request, options) {
2193
+ const input = request;
2194
+ const traceCollector = options?.traceCollector ?? null;
2195
+ const taskId = input.taskId;
2196
+ const jobId = input.jobId;
2197
+ // Merge executionMemory into jobMemory as "execution" before enrichment
2198
+ let jobMemoryWithExecution = input.jobMemory || {};
2199
+ if (input.executionMemory) {
2200
+ const executionWithDefaults = {
2201
+ bindingDefaultsDb: process.env.MONGO_LOGS_DB || 'logs-db',
2202
+ ...input.executionMemory
2203
+ };
2204
+ if (jobMemoryWithExecution.execution) {
2205
+ jobMemoryWithExecution = {
2206
+ ...jobMemoryWithExecution,
2207
+ execution: deepMergeExecution(jobMemoryWithExecution.execution, executionWithDefaults),
2208
+ };
2209
+ }
2210
+ else {
2211
+ jobMemoryWithExecution = {
2212
+ ...jobMemoryWithExecution,
2213
+ execution: executionWithDefaults,
2214
+ };
2215
+ }
2216
+ }
2217
+ else if (!jobMemoryWithExecution.execution || !jobMemoryWithExecution.execution.bindingDefaultsDb) {
2218
+ jobMemoryWithExecution = {
2219
+ ...jobMemoryWithExecution,
2220
+ execution: {
2221
+ ...jobMemoryWithExecution.execution,
2222
+ bindingDefaultsDb: process.env.MONGO_LOGS_DB || 'logs-db'
2223
+ }
2224
+ };
2225
+ }
2226
+ const memoryBundle = {
2227
+ jobMemory: jobMemoryWithExecution,
2228
+ taskMemory: input.taskMemory,
2229
+ executionMemory: {
2230
+ bindingDefaultsDb: process.env.MONGO_LOGS_DB || 'logs-db',
2231
+ ...(input.executionMemory || {}),
2232
+ },
2233
+ };
2234
+ const client = this.skillsClient;
2235
+ const enrichMemories = bindEnrichMemoriesWithScoping(this.skillsClient);
2236
+ const generateContext = bindGenerateContextMarkdown(this.skillsClient);
2237
+ let diagnose;
2238
+ if (typeof this.skillsClient.diagnoseSkillContent === 'function') {
2239
+ diagnose = this.skillsClient.diagnoseSkillContent.bind(this.skillsClient);
2240
+ }
2241
+ else if (typeof client.diagnoseSkillContent === 'function') {
2242
+ diagnose = client.diagnoseSkillContent.bind(client);
2243
+ }
2244
+ else {
2245
+ diagnose = async (key) => {
2246
+ const registry = this.skillsClient.registry;
2247
+ if (registry && typeof registry.diagnose === 'function') {
2248
+ await registry.diagnose(key);
2249
+ }
2250
+ };
2251
+ }
2252
+ const enrichedBundle = await enrichMemories(request.skillKey, "task", memoryBundle);
2253
+ const cleanExecution = cleanseExecution(enrichedBundle.jobMemory?.execution);
2254
+ const bundleForRendering = {
2255
+ ...enrichedBundle,
2256
+ jobMemory: {
2257
+ ...enrichedBundle.jobMemory,
2258
+ execution: cleanExecution,
2259
+ }
2260
+ };
2261
+ const attachToField = input.narrix?.attachToField ?? "_narrix";
2262
+ const preProcessorAttachment = input.executionMemory?.[attachToField];
2263
+ const narrixInPlay = hasNarrixAttachmentShape(preProcessorAttachment);
2264
+ const narrixInTaskMemory = Array.isArray(input.taskMemory?.narrix) && input.taskMemory.narrix.length > 0;
2265
+ const narrixRequested = !!input.narrix || narrixInTaskMemory;
2266
+ const contextRequested = input.includeContextInPrompt === true || narrixRequested;
2267
+ let contextMarkdown;
2268
+ if (options?.overrideContext !== undefined) {
2269
+ contextMarkdown = options.overrideContext;
2270
+ if (narrixRequested &&
2271
+ contextMarkdown.trim() === "" &&
2272
+ options?.synthesisContextAuthoritative !== true) {
2273
+ if (narrixInPlay) {
2274
+ contextMarkdown = buildNarrixPreProcessorContextMarkdown(preProcessorAttachment);
2275
+ const execMem = (enrichedBundle.executionMemory ?? memoryBundle.executionMemory);
2276
+ const webMd = buildWebContextEvidenceMarkdown(execMem?.webContext);
2277
+ if (webMd)
2278
+ contextMarkdown += webMd;
2279
+ }
2280
+ else {
2281
+ contextMarkdown = buildNarrixContextMarkdown(input.taskMemory?.narrix);
2282
+ }
2283
+ }
2284
+ }
2285
+ else if (!contextRequested) {
2286
+ contextMarkdown = "";
2287
+ }
2288
+ else if (narrixInPlay) {
2289
+ contextMarkdown = buildNarrixPreProcessorContextMarkdown(preProcessorAttachment);
2290
+ const execMem = (enrichedBundle.executionMemory ?? memoryBundle.executionMemory);
2291
+ const webMd = buildWebContextEvidenceMarkdown(execMem?.webContext);
2292
+ if (webMd)
2293
+ contextMarkdown += webMd;
2294
+ }
2295
+ else {
2296
+ contextMarkdown = await generateContext(request.skillKey, "task", bundleForRendering);
2297
+ const narrixSection = buildNarrixContextMarkdown(input.taskMemory?.narrix);
2298
+ if (narrixSection)
2299
+ contextMarkdown += narrixSection;
2300
+ }
2301
+ const execMemForCallerWeb = (enrichedBundle.executionMemory ?? memoryBundle.executionMemory);
2302
+ const allowCallerWebAppend = input.includeContextInPrompt === true ||
2303
+ narrixRequested ||
2304
+ options?.overrideContext !== undefined;
2305
+ contextMarkdown = appendExternalWebContextMarkdown(contextMarkdown, execMemForCallerWeb, allowCallerWebAppend);
2306
+ if (options?.captureContext) {
2307
+ options.captureContext.contextMarkdown = contextMarkdown;
2308
+ }
2309
+ let aiScoped;
2310
+ let aiScopingFailures;
2311
+ let aiScopingLlmCalls;
2312
+ if (input.aiScoping && input.aiScoping.length > 0) {
2313
+ const requestLevelLlmCall = input.aiScopingOptions?.llmCall;
2314
+ const fallbackModel = requestLevelLlmCall?.model ??
2315
+ input.modelConfig?.model ??
2316
+ process.env.AI_SCOPING_MODEL;
2317
+ const concurrency = input.aiScopingOptions?.concurrency ??
2318
+ (process.env.AI_SCOPING_CONCURRENCY
2319
+ ? parseInt(process.env.AI_SCOPING_CONCURRENCY, 10)
2320
+ : 5);
2321
+ const timeoutMsPerItem = input.aiScopingOptions?.timeoutMsPerItem ??
2322
+ (process.env.AI_SCOPING_TIMEOUT_MS
2323
+ ? parseInt(process.env.AI_SCOPING_TIMEOUT_MS, 10)
2324
+ : 30_000);
2325
+ const scopingLlmCall = {
2326
+ ...requestLevelLlmCall,
2327
+ model: requestLevelLlmCall?.model ?? fallbackModel,
2328
+ timeoutMs: requestLevelLlmCall?.timeoutMs ?? timeoutMsPerItem,
2329
+ };
2330
+ const scopingResult = await runAiScoping({
2331
+ bundle: enrichedBundle,
2332
+ instructions: input.aiScoping,
2333
+ llmCall: scopingLlmCall,
2334
+ concurrency,
2335
+ traceCollector,
2336
+ jobId,
2337
+ taskId,
2338
+ });
2339
+ aiScoped = scopingResult.scoped;
2340
+ aiScopingFailures = scopingResult.failures.length > 0 ? scopingResult.failures : undefined;
2341
+ aiScopingLlmCalls = traceCollector && scopingResult.llmCalls.length > 0 ? scopingResult.llmCalls : undefined;
2342
+ }
2343
+ let finalJobMemory = { ...enrichedBundle.jobMemory };
2344
+ const originalExecution = jobMemoryWithExecution?.execution;
2345
+ const executionFromEnrichment = enrichedBundle.jobMemory?.execution;
2346
+ const activeExecution = executionFromEnrichment || originalExecution;
2347
+ const cleanActiveExecution = cleanseExecution(activeExecution);
2348
+ finalJobMemory = {
2349
+ ...finalJobMemory,
2350
+ execution: cleanActiveExecution,
2351
+ };
2352
+ const { jobContext: _omitJobContextFromExecutor, ...inputForExecutor } = input;
2353
+ const mergedInput = aiScoped && aiScoped.length > 0
2354
+ ? {
2355
+ ...(input.input && typeof input.input === "object" && input.input !== null
2356
+ ? input.input
2357
+ : {}),
2358
+ aiScoped,
2359
+ }
2360
+ : input.input;
2361
+ const enrichedInput = {
2362
+ ...inputForExecutor,
2363
+ skillKey: request.skillKey,
2364
+ jobMemory: finalJobMemory,
2365
+ taskMemory: enrichedBundle.taskMemory,
2366
+ executionMemory: enrichedBundle.executionMemory || memoryBundle.executionMemory,
2367
+ context: contextMarkdown,
2368
+ input: mergedInput,
2369
+ xynthesized: input.xynthesized,
2370
+ smartInput: input.smartInput,
2371
+ variables: passthroughJobTemplateVariables(input.variables),
2372
+ };
2373
+ const result = await this.executor.execute(enrichedInput, async (key) => {
2374
+ await diagnose(key);
2375
+ });
2376
+ liftIntermediateSteps(result);
2377
+ const parsedIsEmpty = result.parsed === undefined ||
2378
+ result.parsed === null ||
2379
+ (typeof result.parsed === 'object' && Object.keys(result.parsed).length === 0);
2380
+ const strictDecision = isStrictDecisionTask(request);
2381
+ if (strictDecision && parsedIsEmpty) {
2382
+ throw new Error(`Decision task "${request.skillKey}" did not return response.parsed`);
2383
+ }
2384
+ if (!strictDecision && parsedIsEmpty && result) {
2385
+ if (result.flexMd && result.flexMd.payloads && Object.keys(result.flexMd.payloads).length > 0) {
2386
+ result.parsed = result.flexMd.payloads;
2387
+ }
2388
+ else {
2389
+ const resultAny = result;
2390
+ if (resultAny.parsedContent && typeof resultAny.parsedContent === 'object' && Object.keys(resultAny.parsedContent).length > 0) {
2391
+ result.parsed = resultAny.parsedContent;
2392
+ }
2393
+ else if (resultAny.metadata?.parsedContent && typeof resultAny.metadata.parsedContent === 'object' && Object.keys(resultAny.metadata.parsedContent).length > 0) {
2394
+ result.parsed = resultAny.metadata.parsedContent;
2395
+ }
2396
+ else if (resultAny.gatewayResponse?.parsedContent && typeof resultAny.gatewayResponse.parsedContent === 'object' && Object.keys(resultAny.gatewayResponse.parsedContent).length > 0) {
2397
+ result.parsed = resultAny.gatewayResponse.parsedContent;
2398
+ }
2399
+ else if (resultAny.enhancedResponse?.parsedContent && typeof resultAny.enhancedResponse.parsedContent === 'object' && Object.keys(resultAny.enhancedResponse.parsedContent).length > 0) {
2400
+ result.parsed = resultAny.enhancedResponse.parsedContent;
2401
+ }
2402
+ }
2403
+ }
2404
+ const outputValidation = request.outputValidation;
2405
+ if (outputValidation?.schema) {
2406
+ const validateWhenMissing = outputValidation.validateWhenMissing !== false;
2407
+ if (validateWhenMissing || result.parsed !== undefined) {
2408
+ const vr = validateParsedOutput(result.parsed, outputValidation.schema);
2409
+ if (options?.validationCorrelationId) {
2410
+ vr.correlationId = options.validationCorrelationId;
2411
+ }
2412
+ result.metadata = { ...result.metadata, outputValidation: vr };
2413
+ if (!vr.ok && (outputValidation.mode ?? "fail") === "fail") {
2414
+ throw new Error(`outputValidation failed for skillKey ${request.skillKey}: ` +
2415
+ vr.errors.map((e) => `${e.path} ${e.message}`).join("; "));
2416
+ }
2417
+ }
2418
+ }
2419
+ // Surface AI scoping per-item failures + per-item LlmCallObservations on result metadata.
2420
+ // `aiScopingFailures` is published whenever any item failed (regardless of mode); previously
2421
+ // failures were silently dropped. `aiScopingLlmCalls` is trace-mode-only.
2422
+ if (aiScopingFailures || aiScopingLlmCalls) {
2423
+ result.metadata = {
2424
+ ...(result.metadata ?? {}),
2425
+ ...(aiScopingFailures ? { aiScopingFailures } : {}),
2426
+ ...(aiScopingLlmCalls ? { aiScopingLlmCalls } : {}),
2427
+ };
2428
+ }
2429
+ return result;
2430
+ }
2431
+ }
2432
+ //# sourceMappingURL=task-sdk.js.map