@hotmeshio/long-tail 0.1.6 → 0.1.7

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 (335) hide show
  1. package/README.md +44 -4
  2. package/build/api/auth.d.ts +5 -0
  3. package/build/api/auth.js +42 -0
  4. package/build/api/bot-accounts.d.ts +50 -0
  5. package/build/api/bot-accounts.js +215 -0
  6. package/build/api/controlplane.d.ts +20 -0
  7. package/build/api/controlplane.js +110 -0
  8. package/build/api/dba.d.ts +15 -0
  9. package/build/api/dba.js +68 -0
  10. package/build/api/escalations.d.ts +70 -0
  11. package/build/api/escalations.js +656 -0
  12. package/build/api/exports.d.ts +32 -0
  13. package/build/api/exports.js +146 -0
  14. package/build/api/index.d.ts +18 -0
  15. package/build/api/index.js +54 -0
  16. package/build/api/insight.d.ts +29 -0
  17. package/build/api/insight.js +90 -0
  18. package/build/api/maintenance.d.ts +7 -0
  19. package/build/api/maintenance.js +28 -0
  20. package/build/api/mcp-runs.d.ts +16 -0
  21. package/build/api/mcp-runs.js +62 -0
  22. package/build/api/mcp.d.ts +52 -0
  23. package/build/api/mcp.js +212 -0
  24. package/build/api/namespaces.d.ts +7 -0
  25. package/build/{routes/escalations/helpers.js → api/namespaces.js} +24 -12
  26. package/build/api/roles.d.ts +25 -0
  27. package/build/api/roles.js +159 -0
  28. package/build/api/settings.d.ts +2 -0
  29. package/build/api/settings.js +35 -0
  30. package/build/api/tasks.d.ts +27 -0
  31. package/build/api/tasks.js +96 -0
  32. package/build/api/users.d.ts +44 -0
  33. package/build/api/users.js +162 -0
  34. package/build/api/workflow-sets.d.ts +26 -0
  35. package/build/api/workflow-sets.js +119 -0
  36. package/build/api/workflows.d.ts +48 -0
  37. package/build/api/workflows.js +298 -0
  38. package/build/api/yaml-workflows.d.ts +87 -0
  39. package/build/api/yaml-workflows.js +556 -0
  40. package/build/index.d.ts +4 -0
  41. package/build/index.js +6 -1
  42. package/build/lib/db/schemas/004_workflow_sets.sql +29 -0
  43. package/build/lib/db/schemas/005_unique_graph_topic.sql +7 -0
  44. package/build/lib/db/schemas/011_system_workflow_configs.sql +7 -0
  45. package/build/lib/events/callback.d.ts +41 -0
  46. package/build/lib/events/callback.js +98 -0
  47. package/build/modules/config.js +1 -1
  48. package/build/routes/auth.js +37 -36
  49. package/build/routes/bot-accounts.js +34 -164
  50. package/build/routes/controlplane.js +20 -60
  51. package/build/routes/dba.js +18 -28
  52. package/build/routes/escalations/bulk.js +17 -192
  53. package/build/routes/escalations/list.js +29 -75
  54. package/build/routes/escalations/resolve.js +3 -193
  55. package/build/routes/escalations/single.js +13 -122
  56. package/build/routes/exports.js +44 -95
  57. package/build/routes/index.js +2 -0
  58. package/build/routes/insight.js +46 -88
  59. package/build/routes/maintenance.js +41 -17
  60. package/build/routes/mcp-runs.js +52 -60
  61. package/build/routes/mcp.js +49 -177
  62. package/build/routes/namespaces.js +9 -20
  63. package/build/routes/roles.js +23 -97
  64. package/build/routes/settings.js +37 -25
  65. package/build/routes/tasks.js +28 -64
  66. package/build/routes/users.js +24 -113
  67. package/build/routes/workflow-sets.d.ts +2 -0
  68. package/build/routes/workflow-sets.js +98 -0
  69. package/build/routes/workflows/config.js +23 -57
  70. package/build/routes/workflows/discovery.js +11 -85
  71. package/build/routes/workflows/invocation.js +16 -84
  72. package/build/routes/yaml-workflows/cron.js +12 -61
  73. package/build/routes/yaml-workflows/crud.js +30 -223
  74. package/build/routes/yaml-workflows/deployment.js +15 -115
  75. package/build/routes/yaml-workflows/versions.js +20 -58
  76. package/build/sdk/index.d.ts +327 -0
  77. package/build/sdk/index.js +298 -0
  78. package/build/services/controlplane/index.d.ts +1 -2
  79. package/build/services/controlplane/index.js +3 -3
  80. package/build/services/controlplane/sql.d.ts +2 -2
  81. package/build/services/controlplane/sql.js +4 -5
  82. package/build/services/controlplane/types.d.ts +1 -0
  83. package/build/services/export/index.js +6 -1
  84. package/build/services/hotmesh-utils.js +2 -4
  85. package/build/services/insight/index.d.ts +7 -0
  86. package/build/services/insight/index.js +30 -0
  87. package/build/services/mcp/client/tools.js +13 -1
  88. package/build/services/mcp-runs/sql.js +1 -1
  89. package/build/services/workflow-sets/db.d.ts +16 -0
  90. package/build/services/workflow-sets/db.js +78 -0
  91. package/build/services/workflow-sets/index.d.ts +1 -0
  92. package/build/services/workflow-sets/index.js +11 -0
  93. package/build/services/workflow-sets/sql.d.ts +6 -0
  94. package/build/services/workflow-sets/sql.js +24 -0
  95. package/build/services/yaml-workflow/db-utils.d.ts +1 -0
  96. package/build/services/yaml-workflow/db-utils.js +4 -0
  97. package/build/services/yaml-workflow/db.d.ts +5 -0
  98. package/build/services/yaml-workflow/db.js +17 -0
  99. package/build/services/yaml-workflow/pipeline/build/wiring.js +14 -1
  100. package/build/services/yaml-workflow/pipeline/prompts.d.ts +1 -1
  101. package/build/services/yaml-workflow/pipeline/prompts.js +1 -1
  102. package/build/services/yaml-workflow/sql.d.ts +2 -1
  103. package/build/services/yaml-workflow/sql.js +8 -3
  104. package/build/services/yaml-workflow/types.d.ts +3 -0
  105. package/build/services/yaml-workflow/workers/callbacks.js +7 -1
  106. package/build/services/yaml-workflow/workers/register.js +7 -0
  107. package/build/start/adapters.js +4 -0
  108. package/build/system/index.js +6 -0
  109. package/build/system/mcp-servers/knowledge.js +1 -1
  110. package/build/system/seed/server-definitions.js +2 -1
  111. package/build/system/workflows/mcp-workflow-builder/activities/index.d.ts +1 -1
  112. package/build/system/workflows/mcp-workflow-builder/activities/index.js +2 -1
  113. package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.d.ts +6 -0
  114. package/build/system/workflows/mcp-workflow-builder/activities/tool-loader.js +26 -0
  115. package/build/system/workflows/mcp-workflow-builder/index.js +26 -2
  116. package/build/system/workflows/mcp-workflow-builder/prompts.js +104 -35
  117. package/build/system/workflows/mcp-workflow-planner/activities/analyze.d.ts +11 -0
  118. package/build/system/workflows/mcp-workflow-planner/activities/analyze.js +36 -0
  119. package/build/system/workflows/mcp-workflow-planner/activities/index.d.ts +3 -0
  120. package/build/system/workflows/mcp-workflow-planner/activities/index.js +12 -0
  121. package/build/system/workflows/mcp-workflow-planner/activities/persist.d.ts +19 -0
  122. package/build/system/workflows/mcp-workflow-planner/activities/persist.js +55 -0
  123. package/build/system/workflows/mcp-workflow-planner/activities/plan.d.ts +10 -0
  124. package/build/system/workflows/mcp-workflow-planner/activities/plan.js +43 -0
  125. package/build/system/workflows/mcp-workflow-planner/index.d.ts +7 -0
  126. package/build/system/workflows/mcp-workflow-planner/index.js +152 -0
  127. package/build/system/workflows/mcp-workflow-planner/prompts.d.ts +7 -0
  128. package/build/system/workflows/mcp-workflow-planner/prompts.js +77 -0
  129. package/build/tsconfig.tsbuildinfo +1 -1
  130. package/build/types/index.d.ts +1 -0
  131. package/build/types/sdk.d.ts +27 -0
  132. package/build/types/sdk.js +2 -0
  133. package/build/types/workflow-set.d.ts +44 -0
  134. package/build/types/workflow-set.js +5 -0
  135. package/dashboard/dist/assets/{AdminDashboard-BXkKGkb5.js → AdminDashboard-DRjkRSjJ.js} +2 -2
  136. package/dashboard/dist/assets/{AdminDashboard-BXkKGkb5.js.map → AdminDashboard-DRjkRSjJ.js.map} +1 -1
  137. package/dashboard/dist/assets/{AvailableEscalationsPage-DcH592mc.js → AvailableEscalationsPage-CnivX4Tz.js} +2 -2
  138. package/dashboard/dist/assets/{AvailableEscalationsPage-DcH592mc.js.map → AvailableEscalationsPage-CnivX4Tz.js.map} +1 -1
  139. package/dashboard/dist/assets/BotPicker-DwwaBhTH.js +2 -0
  140. package/dashboard/dist/assets/{BotPicker-A6LtzyuO.js.map → BotPicker-DwwaBhTH.js.map} +1 -1
  141. package/dashboard/dist/assets/{CollapsibleSection-C7nL2_mv.js → CollapsibleSection-DQpaVA0M.js} +2 -2
  142. package/dashboard/dist/assets/{CollapsibleSection-C7nL2_mv.js.map → CollapsibleSection-DQpaVA0M.js.map} +1 -1
  143. package/dashboard/dist/assets/{ConfirmDeleteModal-CWFwJrSl.js → ConfirmDeleteModal-B7JoDNvt.js} +2 -2
  144. package/dashboard/dist/assets/{ConfirmDeleteModal-CWFwJrSl.js.map → ConfirmDeleteModal-B7JoDNvt.js.map} +1 -1
  145. package/dashboard/dist/assets/{CopyableId-DbZ5c3jh.js → CopyableId-AqoZayBG.js} +2 -2
  146. package/dashboard/dist/assets/{CopyableId-DbZ5c3jh.js.map → CopyableId-AqoZayBG.js.map} +1 -1
  147. package/dashboard/dist/assets/{CredentialsPage-ClWkmLPu.js → CredentialsPage-qGw1kQzi.js} +2 -2
  148. package/dashboard/dist/assets/{CredentialsPage-ClWkmLPu.js.map → CredentialsPage-qGw1kQzi.js.map} +1 -1
  149. package/dashboard/dist/assets/{CustomDurationPicker-CtH2hReF.js → CustomDurationPicker-D1HUQcd0.js} +2 -2
  150. package/dashboard/dist/assets/{CustomDurationPicker-CtH2hReF.js.map → CustomDurationPicker-D1HUQcd0.js.map} +1 -1
  151. package/dashboard/dist/assets/{DataTable-CM5ZcpPi.js → DataTable-DKvSKoVG.js} +2 -2
  152. package/dashboard/dist/assets/{DataTable-CM5ZcpPi.js.map → DataTable-DKvSKoVG.js.map} +1 -1
  153. package/dashboard/dist/assets/{ElapsedCell-CwqavyeC.js → ElapsedCell-B0yrReGQ.js} +2 -2
  154. package/dashboard/dist/assets/{ElapsedCell-CwqavyeC.js.map → ElapsedCell-B0yrReGQ.js.map} +1 -1
  155. package/dashboard/dist/assets/{EmptyState-BBn78pmm.js → EmptyState-X0fIzYID.js} +2 -2
  156. package/dashboard/dist/assets/{EmptyState-BBn78pmm.js.map → EmptyState-X0fIzYID.js.map} +1 -1
  157. package/dashboard/dist/assets/{EscalationsOverview-BcJ2E3X7.js → EscalationsOverview-BQAT9W7r.js} +2 -2
  158. package/dashboard/dist/assets/{EscalationsOverview-BcJ2E3X7.js.map → EscalationsOverview-BQAT9W7r.js.map} +1 -1
  159. package/dashboard/dist/assets/{EventTable-C1en_KZ0.js → EventTable-CX1KNLhZ.js} +2 -2
  160. package/dashboard/dist/assets/{EventTable-C1en_KZ0.js.map → EventTable-CX1KNLhZ.js.map} +1 -1
  161. package/dashboard/dist/assets/{FilterBar-CZTlrLQT.js → FilterBar-DMTvuQy-.js} +2 -2
  162. package/dashboard/dist/assets/{FilterBar-CZTlrLQT.js.map → FilterBar-DMTvuQy-.js.map} +1 -1
  163. package/dashboard/dist/assets/{ListToolbar-Cdbsapig.js → ListToolbar-DTOSxoEy.js} +2 -2
  164. package/dashboard/dist/assets/{ListToolbar-Cdbsapig.js.map → ListToolbar-DTOSxoEy.js.map} +1 -1
  165. package/dashboard/dist/assets/{McpOverview-CSpEJxKa.js → McpOverview-BaKTIWrG.js} +2 -2
  166. package/dashboard/dist/assets/{McpOverview-CSpEJxKa.js.map → McpOverview-BaKTIWrG.js.map} +1 -1
  167. package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js +5 -0
  168. package/dashboard/dist/assets/McpQueryDetailPage-CC08T5k8.js.map +1 -0
  169. package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js +2 -0
  170. package/dashboard/dist/assets/McpQueryPage-CVfF9dYg.js.map +1 -0
  171. package/dashboard/dist/assets/{McpRunDetailPage-9xdxgG4d.js → McpRunDetailPage-CKs1RWeV.js} +2 -2
  172. package/dashboard/dist/assets/{McpRunDetailPage-9xdxgG4d.js.map → McpRunDetailPage-CKs1RWeV.js.map} +1 -1
  173. package/dashboard/dist/assets/{McpRunsPage-wWLqHsd4.js → McpRunsPage-CcPD_tY1.js} +2 -2
  174. package/dashboard/dist/assets/{McpRunsPage-wWLqHsd4.js.map → McpRunsPage-CcPD_tY1.js.map} +1 -1
  175. package/dashboard/dist/assets/{Modal-kB_P7ZOr.js → Modal-_2AbWxJT.js} +2 -2
  176. package/dashboard/dist/assets/{Modal-kB_P7ZOr.js.map → Modal-_2AbWxJT.js.map} +1 -1
  177. package/dashboard/dist/assets/OperatorDashboard-BGiRaRDr.js +2 -0
  178. package/dashboard/dist/assets/{OperatorDashboard-jc0vrgDI.js.map → OperatorDashboard-BGiRaRDr.js.map} +1 -1
  179. package/dashboard/dist/assets/{PageHeader-NkOeBR05.js → PageHeader-DVr5Qyzm.js} +2 -2
  180. package/dashboard/dist/assets/{PageHeader-NkOeBR05.js.map → PageHeader-DVr5Qyzm.js.map} +1 -1
  181. package/dashboard/dist/assets/{PageHeaderWithStats-ywNhrmFK.js → PageHeaderWithStats-D0KRASML.js} +2 -2
  182. package/dashboard/dist/assets/{PageHeaderWithStats-ywNhrmFK.js.map → PageHeaderWithStats-D0KRASML.js.map} +1 -1
  183. package/dashboard/dist/assets/{PriorityBadge-B2MQbSxy.js → PriorityBadge-Bx2559OU.js} +2 -2
  184. package/dashboard/dist/assets/{PriorityBadge-B2MQbSxy.js.map → PriorityBadge-Bx2559OU.js.map} +1 -1
  185. package/dashboard/dist/assets/{ProcessDetailPage-B7z7IdqE.js → ProcessDetailPage-69I--sry.js} +2 -2
  186. package/dashboard/dist/assets/{ProcessDetailPage-B7z7IdqE.js.map → ProcessDetailPage-69I--sry.js.map} +1 -1
  187. package/dashboard/dist/assets/{ProcessesListPage-C-uHadO6.js → ProcessesListPage-BDpUbua2.js} +2 -2
  188. package/dashboard/dist/assets/{ProcessesListPage-C-uHadO6.js.map → ProcessesListPage-BDpUbua2.js.map} +1 -1
  189. package/dashboard/dist/assets/{RolePill-C1dgC-fK.js → RolePill-CcAqEaSt.js} +2 -2
  190. package/dashboard/dist/assets/{RolePill-C1dgC-fK.js.map → RolePill-CcAqEaSt.js.map} +1 -1
  191. package/dashboard/dist/assets/{RolesPage-BSxrD1vm.js → RolesPage-Cl23Hjet.js} +2 -2
  192. package/dashboard/dist/assets/{RolesPage-BSxrD1vm.js.map → RolesPage-Cl23Hjet.js.map} +1 -1
  193. package/dashboard/dist/assets/{RowActions-lYaHGI-v.js → RowActions-B4mqIt3Z.js} +2 -2
  194. package/dashboard/dist/assets/{RowActions-lYaHGI-v.js.map → RowActions-B4mqIt3Z.js.map} +1 -1
  195. package/dashboard/dist/assets/{StatCard-v2TiITVr.js → StatCard-Cz_2OjAZ.js} +2 -2
  196. package/dashboard/dist/assets/{StatCard-v2TiITVr.js.map → StatCard-Cz_2OjAZ.js.map} +1 -1
  197. package/dashboard/dist/assets/{StatusBadge-DWlxevgG.js → StatusBadge-Wi2FJZsn.js} +2 -2
  198. package/dashboard/dist/assets/{StatusBadge-DWlxevgG.js.map → StatusBadge-Wi2FJZsn.js.map} +1 -1
  199. package/dashboard/dist/assets/{StepIndicator-CRM4ft28.js → StepIndicator-PW5NRDMb.js} +2 -2
  200. package/dashboard/dist/assets/{StepIndicator-CRM4ft28.js.map → StepIndicator-PW5NRDMb.js.map} +1 -1
  201. package/dashboard/dist/assets/{StickyPagination-CF0EToEU.js → StickyPagination-Bl2Uzz65.js} +2 -2
  202. package/dashboard/dist/assets/{StickyPagination-CF0EToEU.js.map → StickyPagination-Bl2Uzz65.js.map} +1 -1
  203. package/dashboard/dist/assets/{SwimlaneTimeline-CNlj7fgg.js → SwimlaneTimeline-CUPqMd0z.js} +2 -2
  204. package/dashboard/dist/assets/{SwimlaneTimeline-CNlj7fgg.js.map → SwimlaneTimeline-CUPqMd0z.js.map} +1 -1
  205. package/dashboard/dist/assets/{TagInput-CH8qMGhC.js → TagInput-BLtf86Ly.js} +2 -2
  206. package/dashboard/dist/assets/{TagInput-CH8qMGhC.js.map → TagInput-BLtf86Ly.js.map} +1 -1
  207. package/dashboard/dist/assets/{TaskDetailPage-CdWo-6mu.js → TaskDetailPage-BXJFX74D.js} +2 -2
  208. package/dashboard/dist/assets/{TaskDetailPage-CdWo-6mu.js.map → TaskDetailPage-BXJFX74D.js.map} +1 -1
  209. package/dashboard/dist/assets/{TaskQueuePill-BPj4ogVG.js → TaskQueuePill-CWYj3xKe.js} +2 -2
  210. package/dashboard/dist/assets/{TaskQueuePill-BPj4ogVG.js.map → TaskQueuePill-CWYj3xKe.js.map} +1 -1
  211. package/dashboard/dist/assets/{TasksListPage-CtRkMpKU.js → TasksListPage-C3cX94Mw.js} +2 -2
  212. package/dashboard/dist/assets/{TasksListPage-CtRkMpKU.js.map → TasksListPage-C3cX94Mw.js.map} +1 -1
  213. package/dashboard/dist/assets/{TimeAgo-Di1a3X5P.js → TimeAgo-B_5yDDHV.js} +2 -2
  214. package/dashboard/dist/assets/{TimeAgo-Di1a3X5P.js.map → TimeAgo-B_5yDDHV.js.map} +1 -1
  215. package/dashboard/dist/assets/{TimestampCell-CqrXql-S.js → TimestampCell-DRX724uU.js} +2 -2
  216. package/dashboard/dist/assets/{TimestampCell-CqrXql-S.js.map → TimestampCell-DRX724uU.js.map} +1 -1
  217. package/dashboard/dist/assets/{UserName-BUFYCnRa.js → UserName-Ca8FA469.js} +2 -2
  218. package/dashboard/dist/assets/{UserName-BUFYCnRa.js.map → UserName-Ca8FA469.js.map} +1 -1
  219. package/dashboard/dist/assets/{WorkflowExecutionPage-25iusMml.js → WorkflowExecutionPage-BBYWEV2P.js} +2 -2
  220. package/dashboard/dist/assets/{WorkflowExecutionPage-25iusMml.js.map → WorkflowExecutionPage-BBYWEV2P.js.map} +1 -1
  221. package/dashboard/dist/assets/WorkflowPill-BXifAuLi.js +2 -0
  222. package/dashboard/dist/assets/{WorkflowPill-DPKOcbf4.js.map → WorkflowPill-BXifAuLi.js.map} +1 -1
  223. package/dashboard/dist/assets/{WorkflowsDashboard-BgxslssH.js → WorkflowsDashboard-Drl3juz9.js} +2 -2
  224. package/dashboard/dist/assets/{WorkflowsDashboard-BgxslssH.js.map → WorkflowsDashboard-Drl3juz9.js.map} +1 -1
  225. package/dashboard/dist/assets/{WorkflowsOverview-Doe5L-Re.js → WorkflowsOverview-03IRrDLg.js} +2 -2
  226. package/dashboard/dist/assets/{WorkflowsOverview-Doe5L-Re.js.map → WorkflowsOverview-03IRrDLg.js.map} +1 -1
  227. package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js +2 -0
  228. package/dashboard/dist/assets/YamlWorkflowsPage-DC2cLxVi.js.map +1 -0
  229. package/dashboard/dist/assets/{bots-Bi2_O1Ts.js → bots-DZEXcgiJ.js} +2 -2
  230. package/dashboard/dist/assets/{bots-Bi2_O1Ts.js.map → bots-DZEXcgiJ.js.map} +1 -1
  231. package/dashboard/dist/assets/{escalation-Ck1KlLkT.js → escalation-Cw48lNaF.js} +2 -2
  232. package/dashboard/dist/assets/{escalation-Ck1KlLkT.js.map → escalation-Cw48lNaF.js.map} +1 -1
  233. package/dashboard/dist/assets/{escalation-columns-ohDsj2eJ.js → escalation-columns-NINpo3qf.js} +2 -2
  234. package/dashboard/dist/assets/{escalation-columns-ohDsj2eJ.js.map → escalation-columns-NINpo3qf.js.map} +1 -1
  235. package/dashboard/dist/assets/helpers-Cuu3xKfr.js +2 -0
  236. package/dashboard/dist/assets/helpers-Cuu3xKfr.js.map +1 -0
  237. package/dashboard/dist/assets/{helpers-BoD2SgUY.js → helpers-fk_qr729.js} +2 -2
  238. package/dashboard/dist/assets/{helpers-BoD2SgUY.js.map → helpers-fk_qr729.js.map} +1 -1
  239. package/dashboard/dist/assets/index-B98ipWxE.js +2 -0
  240. package/dashboard/dist/assets/{index-D7zYZOnH.js.map → index-B98ipWxE.js.map} +1 -1
  241. package/dashboard/dist/assets/{index-BEtLIsML.js → index-BIG3KooI.js} +2 -2
  242. package/dashboard/dist/assets/{index-BEtLIsML.js.map → index-BIG3KooI.js.map} +1 -1
  243. package/dashboard/dist/assets/{index-DYyLF-Qb.js → index-BwN3KP_L.js} +5 -5
  244. package/dashboard/dist/assets/{index-DYyLF-Qb.js.map → index-BwN3KP_L.js.map} +1 -1
  245. package/dashboard/dist/assets/index-Bxe8h1x4.js +17 -0
  246. package/dashboard/dist/assets/{index-DOkHXmyf.js.map → index-Bxe8h1x4.js.map} +1 -1
  247. package/dashboard/dist/assets/{index-FuohTtaM.js → index-CNI7k7oB.js} +3 -3
  248. package/dashboard/dist/assets/{index-FuohTtaM.js.map → index-CNI7k7oB.js.map} +1 -1
  249. package/dashboard/dist/assets/{index-CZrJ09p-.js → index-CORHB0WC.js} +2 -2
  250. package/dashboard/dist/assets/{index-CZrJ09p-.js.map → index-CORHB0WC.js.map} +1 -1
  251. package/dashboard/dist/assets/{index-PyCTS05D.css → index-DcIKW-cZ.css} +1 -1
  252. package/dashboard/dist/assets/{index-D3NyVADW.js → index-Dj-z-x8M.js} +2 -2
  253. package/dashboard/dist/assets/index-Dj-z-x8M.js.map +1 -0
  254. package/dashboard/dist/assets/{index-Bn2xHDr8.js → index-DwRytW9O.js} +3 -3
  255. package/dashboard/dist/assets/{index-Bn2xHDr8.js.map → index-DwRytW9O.js.map} +1 -1
  256. package/dashboard/dist/assets/index-aRvL-dXp.js +2 -0
  257. package/dashboard/dist/assets/{index-Dk2Q51o0.js.map → index-aRvL-dXp.js.map} +1 -1
  258. package/dashboard/dist/assets/index-b03HlbnH.js +2 -0
  259. package/dashboard/dist/assets/{index-BpT-6WgJ.js.map → index-b03HlbnH.js.map} +1 -1
  260. package/dashboard/dist/assets/{mcp-CJtYjA7A.js → mcp-BZoFryNc.js} +2 -2
  261. package/dashboard/dist/assets/{mcp-CJtYjA7A.js.map → mcp-BZoFryNc.js.map} +1 -1
  262. package/dashboard/dist/assets/mcp-query-wiw1kwm8.js +2 -0
  263. package/dashboard/dist/assets/mcp-query-wiw1kwm8.js.map +1 -0
  264. package/dashboard/dist/assets/{mcp-runs-DUWm9Z4V.js → mcp-runs-BaEKnf5v.js} +2 -2
  265. package/dashboard/dist/assets/{mcp-runs-DUWm9Z4V.js.map → mcp-runs-BaEKnf5v.js.map} +1 -1
  266. package/dashboard/dist/assets/{namespaces-BM5P2qmL.js → namespaces-BwnZI4_A.js} +2 -2
  267. package/dashboard/dist/assets/{namespaces-BM5P2qmL.js.map → namespaces-BwnZI4_A.js.map} +1 -1
  268. package/dashboard/dist/assets/{roles-lv0shpjJ.js → roles-Bgn1K8zU.js} +2 -2
  269. package/dashboard/dist/assets/{roles-lv0shpjJ.js.map → roles-Bgn1K8zU.js.map} +1 -1
  270. package/dashboard/dist/assets/{settings-Wlq92mRo.js → settings-CizYiutL.js} +2 -2
  271. package/dashboard/dist/assets/{settings-Wlq92mRo.js.map → settings-CizYiutL.js.map} +1 -1
  272. package/dashboard/dist/assets/{tasks-BFGm4PuE.js → tasks-Bmte_hc4.js} +2 -2
  273. package/dashboard/dist/assets/{tasks-BFGm4PuE.js.map → tasks-Bmte_hc4.js.map} +1 -1
  274. package/dashboard/dist/assets/{useEventHooks-DIE6ue4x.js → useEventHooks-CUCxpiI2.js} +2 -2
  275. package/dashboard/dist/assets/{useEventHooks-DIE6ue4x.js.map → useEventHooks-CUCxpiI2.js.map} +1 -1
  276. package/dashboard/dist/assets/{useYamlActivityEvents-DCwSO73t.js → useYamlActivityEvents-Cum02Ej9.js} +2 -2
  277. package/dashboard/dist/assets/{useYamlActivityEvents-DCwSO73t.js.map → useYamlActivityEvents-Cum02Ej9.js.map} +1 -1
  278. package/dashboard/dist/assets/{users-tA5-K0wA.js → users-NSDgTt-z.js} +2 -2
  279. package/dashboard/dist/assets/{users-tA5-K0wA.js.map → users-NSDgTt-z.js.map} +1 -1
  280. package/dashboard/dist/assets/{vendor-icons-BiIug1SK.js → vendor-icons-D1DdudfH.js} +93 -73
  281. package/dashboard/dist/assets/vendor-icons-D1DdudfH.js.map +1 -0
  282. package/dashboard/dist/assets/{workflows-CfLc15Wr.js → workflows-k0XRdGXx.js} +2 -2
  283. package/dashboard/dist/assets/{workflows-CfLc15Wr.js.map → workflows-k0XRdGXx.js.map} +1 -1
  284. package/dashboard/dist/assets/yaml-workflows-DAre8I78.js +2 -0
  285. package/dashboard/dist/assets/yaml-workflows-DAre8I78.js.map +1 -0
  286. package/dashboard/dist/index.html +3 -3
  287. package/docs/epic-integration.md +224 -0
  288. package/docs/events.md +28 -0
  289. package/docs/sdk.md +177 -0
  290. package/docs/story.md +157 -0
  291. package/docs/workflow-builder.md +371 -0
  292. package/package.json +3 -2
  293. package/build/routes/escalations/helpers.d.ts +0 -5
  294. package/build/routes/resolve.d.ts +0 -9
  295. package/build/routes/resolve.js +0 -19
  296. package/build/routes/yaml-workflows/helpers.d.ts +0 -2
  297. package/build/routes/yaml-workflows/helpers.js +0 -8
  298. package/dashboard/dist/assets/BotPicker-A6LtzyuO.js +0 -2
  299. package/dashboard/dist/assets/McpQueryDetailPage-DhqEI180.js +0 -5
  300. package/dashboard/dist/assets/McpQueryDetailPage-DhqEI180.js.map +0 -1
  301. package/dashboard/dist/assets/McpQueryPage-CIiVMlqo.js +0 -2
  302. package/dashboard/dist/assets/McpQueryPage-CIiVMlqo.js.map +0 -1
  303. package/dashboard/dist/assets/OperatorDashboard-jc0vrgDI.js +0 -2
  304. package/dashboard/dist/assets/RunAsSelector-CJDnyp93.js +0 -2
  305. package/dashboard/dist/assets/RunAsSelector-CJDnyp93.js.map +0 -1
  306. package/dashboard/dist/assets/WorkflowPill-DPKOcbf4.js +0 -2
  307. package/dashboard/dist/assets/YamlWorkflowsPage-BliAckJ6.js +0 -2
  308. package/dashboard/dist/assets/YamlWorkflowsPage-BliAckJ6.js.map +0 -1
  309. package/dashboard/dist/assets/index-BpT-6WgJ.js +0 -2
  310. package/dashboard/dist/assets/index-D3NyVADW.js.map +0 -1
  311. package/dashboard/dist/assets/index-D7zYZOnH.js +0 -2
  312. package/dashboard/dist/assets/index-DOkHXmyf.js +0 -17
  313. package/dashboard/dist/assets/index-Dk2Q51o0.js +0 -2
  314. package/dashboard/dist/assets/mcp-query-jQJQrs_7.js +0 -2
  315. package/dashboard/dist/assets/mcp-query-jQJQrs_7.js.map +0 -1
  316. package/dashboard/dist/assets/vendor-icons-BiIug1SK.js.map +0 -1
  317. package/dashboard/dist/assets/yaml-workflows-D7JXNqbM.js +0 -2
  318. package/dashboard/dist/assets/yaml-workflows-D7JXNqbM.js.map +0 -1
  319. package/docs/img/01-login.png +0 -0
  320. package/docs/img/02-dashboard-home.png +0 -0
  321. package/docs/img/03-processes-list.png +0 -0
  322. package/docs/img/04-escalations-list.png +0 -0
  323. package/docs/img/05-mcp-servers.png +0 -0
  324. package/docs/img/06-mcp-pipelines.png +0 -0
  325. package/docs/img/07-workflows-list.png +0 -0
  326. package/docs/img/compilation/01-query-submit.png +0 -0
  327. package/docs/img/compilation/02-mcp-servers.png +0 -0
  328. package/docs/img/compilation/03-query-completed.png +0 -0
  329. package/docs/img/compilation/04-wizard-original.png +0 -0
  330. package/docs/img/compilation/05-wizard-timeline.png +0 -0
  331. package/docs/img/compilation/06-wizard-profile.png +0 -0
  332. package/docs/img/compilation/07-wizard-deploy.png +0 -0
  333. package/docs/img/compilation/08-wizard-test-modal.png +0 -0
  334. package/docs/img/compilation/09-wizard-test-compare.png +0 -0
  335. package/docs/img/compilation/10-wizard-verify.png +0 -0
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ // ─── Workflow set CRUD ──────────────────────────────────────────────────────
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.LIST_WORKFLOW_SETS_BASE = exports.DELETE_WORKFLOW_SET = exports.UPDATE_WORKFLOW_SET_STATUS = exports.UPDATE_WORKFLOW_SET_PLAN = exports.GET_WORKFLOW_SET = exports.CREATE_WORKFLOW_SET = void 0;
5
+ exports.CREATE_WORKFLOW_SET = `
6
+ INSERT INTO lt_workflow_sets (name, description, specification, plan, namespaces, source_workflow_id)
7
+ VALUES ($1, $2, $3, $4, $5, $6)
8
+ RETURNING *`;
9
+ exports.GET_WORKFLOW_SET = `
10
+ SELECT * FROM lt_workflow_sets WHERE id = $1`;
11
+ exports.UPDATE_WORKFLOW_SET_PLAN = `
12
+ UPDATE lt_workflow_sets
13
+ SET plan = $2, namespaces = $3, status = 'planned', updated_at = NOW()
14
+ WHERE id = $1
15
+ RETURNING *`;
16
+ exports.UPDATE_WORKFLOW_SET_STATUS = `
17
+ UPDATE lt_workflow_sets
18
+ SET status = $2, updated_at = NOW()
19
+ WHERE id = $1
20
+ RETURNING *`;
21
+ exports.DELETE_WORKFLOW_SET = `
22
+ DELETE FROM lt_workflow_sets WHERE id = $1`;
23
+ exports.LIST_WORKFLOW_SETS_BASE = `
24
+ SELECT * FROM lt_workflow_sets`;
@@ -12,6 +12,7 @@ export declare function listYamlWorkflows(filters: {
12
12
  tags?: string[];
13
13
  search?: string;
14
14
  source_workflow_id?: string;
15
+ set_id?: string;
15
16
  limit?: number;
16
17
  offset?: number;
17
18
  }): Promise<{
@@ -69,6 +69,10 @@ async function listYamlWorkflows(filters) {
69
69
  conditions.push(`source_workflow_id = $${idx++}`);
70
70
  values.push(filters.source_workflow_id);
71
71
  }
72
+ if (filters.set_id) {
73
+ conditions.push(`set_id = $${idx++}`);
74
+ values.push(filters.set_id);
75
+ }
72
76
  const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
73
77
  const limit = filters.limit || defaults_1.YAML_LIST_LIMIT;
74
78
  const offset = filters.offset || 0;
@@ -1,6 +1,11 @@
1
1
  import type { LTYamlWorkflowRecord, LTYamlWorkflowVersionRecord, ActivityManifestEntry } from '../../types/yaml-workflow';
2
2
  import type { CreateYamlWorkflowInput } from './types';
3
3
  export { parseVersionFromYaml, updateYamlWorkflowStatus, listYamlWorkflows, findYamlWorkflowsByTags, } from './db-utils';
4
+ /**
5
+ * Check whether a graph_topic is already in use by a non-archived workflow
6
+ * in the same namespace. Returns the conflicting workflow name, or null.
7
+ */
8
+ export declare function checkTopicConflict(appId: string, graphTopic: string, excludeId?: string): Promise<string | null>;
4
9
  export declare function createYamlWorkflow(input: CreateYamlWorkflowInput): Promise<LTYamlWorkflowRecord>;
5
10
  export declare function getYamlWorkflow(id: string): Promise<LTYamlWorkflowRecord | null>;
6
11
  export declare function getYamlWorkflowByName(name: string): Promise<LTYamlWorkflowRecord | null>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findYamlWorkflowsByTags = exports.listYamlWorkflows = exports.updateYamlWorkflowStatus = exports.parseVersionFromYaml = void 0;
4
+ exports.checkTopicConflict = checkTopicConflict;
4
5
  exports.createYamlWorkflow = createYamlWorkflow;
5
6
  exports.getYamlWorkflow = getYamlWorkflow;
6
7
  exports.getYamlWorkflowByName = getYamlWorkflowByName;
@@ -29,6 +30,19 @@ Object.defineProperty(exports, "parseVersionFromYaml", { enumerable: true, get:
29
30
  Object.defineProperty(exports, "updateYamlWorkflowStatus", { enumerable: true, get: function () { return db_utils_2.updateYamlWorkflowStatus; } });
30
31
  Object.defineProperty(exports, "listYamlWorkflows", { enumerable: true, get: function () { return db_utils_2.listYamlWorkflows; } });
31
32
  Object.defineProperty(exports, "findYamlWorkflowsByTags", { enumerable: true, get: function () { return db_utils_2.findYamlWorkflowsByTags; } });
33
+ /**
34
+ * Check whether a graph_topic is already in use by a non-archived workflow
35
+ * in the same namespace. Returns the conflicting workflow name, or null.
36
+ */
37
+ async function checkTopicConflict(appId, graphTopic, excludeId) {
38
+ const pool = (0, db_1.getPool)();
39
+ const { rows } = await pool.query(sql_1.CHECK_TOPIC_UNIQUE, [appId, graphTopic]);
40
+ if (rows.length === 0)
41
+ return null;
42
+ if (excludeId && rows[0].id === excludeId)
43
+ return null;
44
+ return rows[0].name;
45
+ }
32
46
  async function createYamlWorkflow(input) {
33
47
  const pool = (0, db_1.getPool)();
34
48
  const { rows } = await pool.query(sql_1.CREATE_YAML_WORKFLOW, [
@@ -48,6 +62,9 @@ async function createYamlWorkflow(input) {
48
62
  input.category || null,
49
63
  input.tags || [],
50
64
  input.metadata ? JSON.stringify(input.metadata) : null,
65
+ input.set_id || null,
66
+ input.set_role || null,
67
+ input.set_build_order ?? null,
51
68
  ]);
52
69
  const record = rows[0];
53
70
  await createVersionSnapshot(record.id, 1, record.yaml_content, input.activity_manifest || [], input.input_schema || {}, input.output_schema || {}, input.input_field_meta || [], 'Initial version');
@@ -6,7 +6,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.wireStepInputs = wireStepInputs;
7
7
  /**
8
8
  * HotMesh @pipe sub-pipe for today's date as YYYY-MM-DD.
9
- * Must be used as a ROW-LEVEL entry in a parent @pipe, never inside an array row.
9
+ * Follows RPN convention: operands row, then operator row.
10
+ * Row 1: date.now() → epoch (operator, no extra operands)
11
+ * Row 2: [isoString, 0, 10] — three operands for substring
12
+ * Row 3: substring(isoString, 0, 10) → "YYYY-MM-DD"
10
13
  */
11
14
  const DATE_SUB_PIPE = {
12
15
  '@pipe': [
@@ -108,6 +111,16 @@ function wireStepInputs(stepIdx, step, plan, stepIndexToActivityId, triggerId, t
108
111
  : stepIdx;
109
112
  const edgesForStep = plan.dataFlow.filter(e => e.toStep === collapsedIdx);
110
113
  for (const edge of edgesForStep) {
114
+ // Skip edges that target a complex nested object argument — these are stored
115
+ // defaults in tool_arguments (e.g., a nested `login` object with selectors)
116
+ // and must not be overridden by a flat scalar from an upstream step.
117
+ if (step.kind === 'tool' && !edge.transform) {
118
+ const argValue = step.arguments[edge.toField];
119
+ if (argValue && typeof argValue === 'object' && !Array.isArray(argValue) &&
120
+ Object.keys(argValue).length > 2) {
121
+ continue;
122
+ }
123
+ }
111
124
  if (edge.transform && Object.keys(edge.transform.fieldMap).length > 0) {
112
125
  // This edge has a transform — the reshape activity was inserted before this step.
113
126
  // Wire from the transform activity's output (which uses toField as the output key).
@@ -4,7 +4,7 @@
4
4
  * Consolidates all system/user prompt strings used by compile, validate,
5
5
  * and extract stages so they can be reviewed and tuned in one place.
6
6
  */
7
- export declare const COMPILATION_PROMPT = "You are a workflow compiler. You analyze MCP tool execution traces and produce a COMPILATION PLAN \u2014 a complete specification for building a deterministic YAML DAG workflow.\n\nGiven:\n1. The user's ORIGINAL PROMPT \u2014 the single most important signal for understanding intent\n2. EXECUTION STEPS \u2014 tool calls with arguments, result structure samples, and server IDs\n3. PATTERN ANNOTATIONS \u2014 pre-detected iteration candidates from static analysis\n4. NAIVE INPUT CLASSIFICATION \u2014 initial argument classification\n\nYour job: produce a plan that makes the workflow truly reusable and deterministic.\n\n## Critical: Understand Intent\n\nThe original prompt describes what the user wanted. The execution trace shows HOW an LLM accomplished it, but may include exploratory detours. Your compilation captures INTENT, not a blind replay.\n\nFor example, if the prompt says \"login to site X and take screenshots of all pages\":\n- INTENT: login \u2192 discover pages \u2192 iterate and screenshot each one\n- Execution may have included probing steps \u2014 exclude those\n- Deterministic version: accept credentials \u2192 login \u2192 extract links \u2192 iterate taking screenshots\n\n## Critical: Preserve Discovery Steps\n\nMany workflows follow a \"discover then act\" pattern: one step DISCOVERS data (e.g., extract navigation links, query a database, list files) and a later step ACTS on that data (e.g., screenshot each page, process each record, transform each file).\n\n**NEVER collapse discovery + action into a single step with the discovered data as a user input.** If the execution trace shows:\n1. Step A: extract_content \u2192 produces `links: [{text, href}, ...]`\n2. Step B: capture_pages(pages=[...array built from step A's links...])\n\nThe compiled workflow MUST keep BOTH steps: A produces the array, B consumes it. Do NOT make the array a trigger input \u2014 it was runtime-discovered, not user-provided.\n\n**How to detect**: If a step's argument contains a large array of items that closely mirrors a prior step's output array (same URLs, same items, possibly reshaped), that array was DERIVED from the prior step. Keep both steps and wire them with a data_flow edge (with a transform if formats differ).\n\n## Rules\n\n### Step Dispositions\n- **core**: Directly serves the workflow intent. Produces data consumed by later steps. **Discovery steps that produce arrays consumed by later action steps are ALWAYS core.**\n- **exploratory**: Probing/debugging/discovery steps that don't produce data needed by the workflow. Exclude these:\n - Checking if compiled workflows exist (list_workflows, list_yaml_workflows)\n - Listing files to see what exists (list_files, read_file)\n - Initial tool calls that failed and were retried with different parameters\n - Any step whose result is not consumed by a subsequent core step\n - **NEVER mark a discovery step as exploratory if its output was used to build arguments for a later step**\n\n### Signal Steps (Human-in-the-Loop)\nSteps with kind \"signal\" represent a durable pause where the workflow waits for human input (e.g., credentials, approval). These are ALWAYS core \u2014 they are essential to the workflow's data flow. The signal step receives data from a human and makes it available to subsequent steps. Do NOT mark signal steps as exploratory. The escalation tool call (escalate_and_wait) that precedes a signal step is also always core.\n\n**Signal data flow**: The signal step result contains the human response fields (e.g., password). These MUST be wired via data_flow edges to every downstream step that needs them. Add a data_flow edge from the signal step index to the consuming step with the matching field name.\n\n**Credentials from signals**: When the signal provides a credential (format: password in the schema), downstream tools that need it should receive it as a separate named input argument. The runtime exchanges ephemeral credential tokens automatically. For tools with complex stored arguments (like run_script steps arrays), wire the credential as a top-level argument name \u2014 the runtime merges it with stored defaults.\n\n### Iteration Specifications\nWhen the execution shows repeated tool calls with varying arguments (the pattern detector may have already collapsed these):\n- Identify the SOURCE: which prior step's result contains the array being iterated. This is the step that PRODUCED the list of items \u2014 look for a step whose result contains an array field with items matching the iteration's varying values. For example, if the iteration visits multiple URLs, find the step that returned those URLs (e.g., extract_content with links).\n- The source is NEVER a step that doesn't have the array in its output. Double-check: does the source step's resultKeys include the source_field?\n- Specify the source_field: the dot-path to the array (e.g., \"links\", \"results.pages\")\n- List varying_keys (change per item) vs constant_args (shared)\n- **KEY MAPPINGS are critical**: array items often use different key names than the tool expects.\n E.g., extract_content returns `links: [{text, href}, ...]` but the screenshot tool wants `url`.\n Map: `{ \"url\": \"href\" }` \u2014 tool arg name \u2192 array item key name.\n Use null for keys that are COMPUTED at runtime, not sourced from the array.\n For example, screenshot_path is often derived from the link text or URL \u2014 it's not a field in the source array directly:\n `{ \"screenshot_path\": null }` \u2014 the value must be computed or provided by the trigger.\n\n### Tool Simplification for Iterations (CRITICAL)\nThe iteration pattern works by extracting individual values from array items and passing them as simple key=value arguments to the iterated tool. This means:\n\n**The iterated tool MUST accept simple, flat arguments** (url, path, page_id \u2014 not complex nested structures like a `steps` array).\n\nIf the execution used a complex multi-step scripting tool (e.g., `run_script` with a `steps: [{action, url}, {action, path}]` array) for each iteration, you MUST replace it with a simpler tool from the same server that accepts flat arguments. Check the server's tool inventory for a simpler alternative.\n\nFor example:\n- `run_script(steps=[navigate, wait, screenshot])` per page \u2192 replace with `capture_page(url, path, full_page, wait_ms)` (1 call, flat args)\n- `run_script(steps=[navigate, fill, click])` per item \u2192 replace with `submit_form(url, fields)` (1 call, flat args)\n\nWhen replacing: use the same server_id but the simpler tool_name. The varying_keys and key_mappings should map directly to the simple tool's argument names.\n\n**If no simpler tool alternative exists**, use a data_flow edge with a transform to feed the array into a batch/composite tool that accepts the full array (like `capture_authenticated_pages` which takes a `pages` array).\n\n### Data Flow Graph\nSpecify directed edges showing how data flows between steps:\n- from_step: \"trigger\" (user input) or step index number\n- from_field: the output field name (or trigger input key)\n- to_step: the consuming step index\n- to_field: the argument key name\n- is_session_wire: true for session handles (page_id, _handle, session_id)\n\nSession handles are critical \u2014 they maintain authenticated browser sessions, database connections, etc. They must be threaded from their producer through ALL subsequent steps that need them.\n\n### Chain Analysis to Downstream Steps\nWhen a step produces a meaningful result (analysis, extraction, description, computed value) and a later step consumes related data (saving, storing, forwarding, reporting), there MUST be a data_flow edge connecting them. Match by semantic intent, not just field name:\n- Step produces `description` \u2192 downstream step takes `value` \u2192 edge with from_field: \"description\", to_field: \"value\"\n- Step produces `analysis.summary` \u2192 downstream step takes `content` \u2192 edge with appropriate field mapping\n\nIf the original execution trace shows that a step's output was used (even indirectly) as input to a later step, the compiled version must preserve that data chain. A broken chain means the downstream step receives no data \u2014 the worst possible compilation error.\n\n### Data Flow Transforms (CRITICAL for array reshaping)\nWhen a source step produces an array of objects in one format but the consuming step expects a DIFFERENT format, add a `transform` to the data_flow edge. Compare the source step's result structure with the consuming step's actual arguments from the trace.\n\n**Choosing the correct source field**: When a step produces multiple output fields, check the result sample to determine which field actually contains an ARRAY OF OBJECTS suitable for iteration/reshaping. Prefer structured array fields over raw/unstructured fields. Check the Tool-Specific Compilation Hints section (if present) for guidance on which fields to use for specific tools.\n\nFor example: extract_content returns `links: [{text, href}]` but capture tool expects `pages: [{url, screenshot_path, wait_ms, full_page}]`.\nAdd a transform with:\n- `field_map`: maps target keys \u2192 source keys (e.g., `{\"url\": \"href\"}`). Use null for keys not in the source.\n- `defaults`: static values to inject (e.g., `{\"wait_ms\": 3000, \"full_page\": true}`)\n- `derivations`: for computed keys (null in field_map), how to derive them from source data\n - strategy: \"slugify\" (lowercase, replace spaces/special with hyphens), \"prefix\", \"template\", \"concat\"\n - source_key: which source field to derive from\n - prefix/suffix/template: string manipulation params\n\nAvailable derivation strategies:\n- **slugify**: Lowercase, replace spaces/special chars with hyphens. Optionally add prefix/suffix.\n- **prefix**: Prepend a static string.\n- **template**: Format string with `{value}` (source field) and `{date}` (today's ISO date, YYYY-MM-DD).\n- **concat**: Join multiple parts. Each part can use `{value}` and `{date}` placeholders.\n Example: `{ \"strategy\": \"concat\", \"parts\": [\"{value}\", \"-\", \"{date}\"] }` produces `my-slug-2026-04-17`.\n- **passthrough**: No transformation.\n\nUse these when the workflow needs runtime-computed values (date-stamped filenames, slugified URLs, templated paths).\n\nExample edge with transform:\n```\n{\n \"from_step\": 1, \"from_field\": \"links\", \"to_step\": 2, \"to_field\": \"pages\",\n \"is_session_wire\": false,\n \"transform\": {\n \"field_map\": { \"url\": \"href\", \"screenshot_path\": null },\n \"defaults\": { \"wait_ms\": 3000, \"full_page\": true },\n \"derivations\": {\n \"screenshot_path\": {\n \"source_key\": \"href\",\n \"strategy\": \"slugify\",\n \"prefix\": \"screenshots/\",\n \"suffix\": \".png\"\n }\n }\n }\n}\n```\n\nIMPORTANT: Check EVERY array-typed data_flow edge. Compare the source step's result item keys with the consuming step's argument item keys. If they differ, add a transform. Look at the actual tool_arguments in the execution trace to determine the correct field_map, defaults, and derivations.\n\n### Scalar Derivations on Data Flow Edges\nWhen a scalar value needs runtime transformation before reaching its consumer, add a `derivation` to the data_flow edge (NOT a `transform` \u2014 transforms are for array reshaping). Derivations generate runtime expressions for string manipulation.\n\nCommon use case: the user's prompt mentions a pattern like \"save with key slug-{date}\" or \"name it {something}-{today's date}\". The trigger provides the base value, and the derivation appends or formats it at runtime.\n\nAdd a `derivation` field to the data_flow edge:\n```\n{\n \"from_step\": \"trigger\", \"from_field\": \"key\", \"to_step\": 3, \"to_field\": \"key\",\n \"is_session_wire\": false,\n \"derivation\": { \"strategy\": \"concat\", \"parts\": [\"{value}\", \"-\", \"{date}\"] }\n}\n```\n\nThis produces a runtime-computed key like `my-slug-2026-04-17`. The `{value}` placeholder is the source field value; `{date}` is today's ISO date (YYYY-MM-DD).\n\nUse derivations when:\n- The user wants date-stamped keys, filenames, or identifiers\n- A value needs a prefix/suffix added at runtime\n- Two values need to be concatenated\n\n### Input Classification\n- **dynamic**: Simple values callers MUST provide: URLs, credentials, file paths, queries, search terms. These are always scalar strings, numbers, or booleans \u2014 NEVER complex objects or arrays.\n- **fixed**: Implementation details with sensible defaults: selectors, timeouts, boolean flags, AND complex structured arguments like `steps` arrays, `login` objects, or `pages` arrays. These are baked into stored tool_arguments.\n\n**Complex tool arguments (arrays of objects, nested structures) are ALWAYS fixed.** They represent the implementation recipe, not user input. For example:\n- A `steps` array describing browser actions (navigate, fill, click, screenshot) \u2192 **fixed**\n- A `login` object with selectors and credentials \u2192 flatten the credentials (username, password) as dynamic, but the selectors as fixed\n- A `pages` array of URLs to capture \u2192 **fixed** if hardcoded from the trace, or a data_flow edge if discovered at runtime\n\nFlatten nested objects containing dynamic values. E.g., `login: {url, username, password}` \u2192 separate `login_url`, `username`, `password` fields. But NEVER expose the full nested object or array as a trigger input.\n\n**Arrays that were DISCOVERED at runtime (by a prior step) are NOT inputs.** They flow between steps via data_flow edges. Only make an array a trigger input if the user explicitly provided it in their prompt. If the array was produced by a discovery step (extract_content, query, list), keep the discovery step as core and wire its output to the consuming step.\n\n### Prompt-Mentioned Values Are Dynamic\nIf a scalar value (URL, domain name, file path, key name, slug, query string) appears verbatim or closely paraphrased in the user's original prompt, classify it as **dynamic**. The user explicitly chose that value for this execution and will want to change it next time. Only classify a prompt-mentioned value as fixed if it is unambiguously an implementation constant (a CSS selector, a timeout, a boolean flag).\n\nThis is the most common compilation error: treating the user's specific request values as universal defaults. When in doubt, make it dynamic.\n\n### Data Flow Wiring Precision\n- **Only wire inputs that semantically match.** A directory name (e.g., `screenshot_dir = \"screenshots\"`) must NOT be wired to a file path argument (e.g., `screenshot_path` which expects `\"screenshots/home.png\"`). If a tool argument needs a specific file path but the trigger only provides a directory, leave that argument unwired \u2014 the stored tool_arguments default will provide the correct value.\n- **Trigger inputs should map to the EXACT tool argument they represent.** Don't reuse a trigger input for a different-purpose argument just because the names are vaguely related.\n- **When in doubt, don't wire.** An unwired argument falls back to the stored tool_arguments default from the original execution \u2014 this is always correct. An incorrectly wired argument overrides the correct default with a wrong value.\n\n### Session Fields and Threading Rules\nList all fields that represent session tokens/handles that must flow through the DAG (e.g., page_id, _handle, session_id).\n\n**Critical**: When a login/setup step produces a page_id or _handle, ALL subsequent browser/page steps must receive that session wire \u2014 including steps inside iterations. The data_flow graph must include session wire edges from the producing step to EVERY downstream step that operates on the same session, not just the immediately next one. For iterations: wire the session from the setup step directly to the iteration body step.\n\n**COMPLETENESS REQUIREMENT**: For EACH step that uses a session field (check the step's argumentKeys \u2014 if it includes page_id, _handle, or session_id), you MUST emit a data_flow edge wiring that field from its producer. If step 0 produces _handle and steps 1, 2, and 3 all use it, you need THREE edges: 0\u21921, 0\u21922, 0\u21923. Do NOT assume downstream steps will \"inherit\" session fields \u2014 each consumer needs an explicit edge.\n\n### Data Flow Completeness Check\nBefore finalizing the plan, verify:\n1. Every step that has a session field in its argumentKeys has a corresponding is_session_wire edge\n2. Every step that consumes data from a prior step has a data_flow edge for that field\n3. Every dynamic trigger input is wired to at least one step via a data_flow edge from \"trigger\"\n4. Transform edges include the source field AND the consuming step can access all fields it needs\n\n## Output Format\n\nReturn a JSON object (no markdown fences):\n{\n \"intent\": \"Brief generic description of what this workflow does\",\n \"description\": \"Suggested workflow description for discovery\",\n \"steps\": [\n { \"index\": 0, \"purpose\": \"Navigate to the target site\", \"disposition\": \"core\" },\n { \"index\": 1, \"purpose\": \"Extract navigation links from the page\", \"disposition\": \"core\" },\n { \"index\": 2, \"purpose\": \"List files to check directory structure\", \"disposition\": \"exploratory\" }\n ],\n \"core_step_indices\": [0, 1, 3],\n \"inputs\": [\n { \"key\": \"base_url\", \"type\": \"string\", \"classification\": \"dynamic\", \"description\": \"The base URL of the site\" },\n { \"key\": \"username\", \"type\": \"string\", \"classification\": \"dynamic\", \"description\": \"Login username\" },\n { \"key\": \"timeout\", \"type\": \"number\", \"classification\": \"fixed\", \"description\": \"Page load timeout\", \"default\": 30000 }\n ],\n \"iterations\": [\n {\n \"body_step_index\": 3,\n \"tool_name\": \"screenshot\",\n \"server_id\": \"playwright\",\n \"source_step_index\": 1,\n \"source_field\": \"links\",\n \"varying_keys\": [\"url\", \"screenshot_path\"],\n \"constant_args\": { \"full_page\": true },\n \"key_mappings\": { \"url\": \"href\", \"screenshot_path\": null }\n }\n ],\n \"data_flow\": [\n { \"from_step\": \"trigger\", \"from_field\": \"base_url\", \"to_step\": 0, \"to_field\": \"url\", \"is_session_wire\": false },\n { \"from_step\": 0, \"from_field\": \"page_id\", \"to_step\": 1, \"to_field\": \"page_id\", \"is_session_wire\": true },\n { \"from_step\": 0, \"from_field\": \"_handle\", \"to_step\": 1, \"to_field\": \"_handle\", \"is_session_wire\": true }\n ],\n \"session_fields\": [\"page_id\", \"_handle\"]\n}";
7
+ export declare const COMPILATION_PROMPT = "You are a workflow compiler. You analyze MCP tool execution traces and produce a COMPILATION PLAN \u2014 a complete specification for building a deterministic YAML DAG workflow.\n\nGiven:\n1. The user's ORIGINAL PROMPT \u2014 the single most important signal for understanding intent\n2. EXECUTION STEPS \u2014 tool calls with arguments, result structure samples, and server IDs\n3. PATTERN ANNOTATIONS \u2014 pre-detected iteration candidates from static analysis\n4. NAIVE INPUT CLASSIFICATION \u2014 initial argument classification\n\nYour job: produce a plan that makes the workflow truly reusable and deterministic.\n\n## Critical: Understand Intent\n\nThe original prompt describes what the user wanted. The execution trace shows HOW an LLM accomplished it, but may include exploratory detours. Your compilation captures INTENT, not a blind replay.\n\nFor example, if the prompt says \"login to site X and take screenshots of all pages\":\n- INTENT: login \u2192 discover pages \u2192 iterate and screenshot each one\n- Execution may have included probing steps \u2014 exclude those\n- Deterministic version: accept credentials \u2192 login \u2192 extract links \u2192 iterate taking screenshots\n\n## Critical: Preserve Discovery Steps\n\nMany workflows follow a \"discover then act\" pattern: one step DISCOVERS data (e.g., extract navigation links, query a database, list files) and a later step ACTS on that data (e.g., screenshot each page, process each record, transform each file).\n\n**NEVER collapse discovery + action into a single step with the discovered data as a user input.** If the execution trace shows:\n1. Step A: extract_content \u2192 produces `links: [{text, href}, ...]`\n2. Step B: capture_pages(pages=[...array built from step A's links...])\n\nThe compiled workflow MUST keep BOTH steps: A produces the array, B consumes it. Do NOT make the array a trigger input \u2014 it was runtime-discovered, not user-provided.\n\n**How to detect**: If a step's argument contains a large array of items that closely mirrors a prior step's output array (same URLs, same items, possibly reshaped), that array was DERIVED from the prior step. Keep both steps and wire them with a data_flow edge (with a transform if formats differ).\n\n## Rules\n\n### Step Dispositions\n- **core**: Directly serves the workflow intent. Produces data consumed by later steps. **Discovery steps that produce arrays consumed by later action steps are ALWAYS core.**\n- **exploratory**: Probing/debugging/discovery steps that don't produce data needed by the workflow. Exclude these:\n - Checking if compiled workflows exist (list_workflows, list_yaml_workflows)\n - Listing files to see what exists (list_files, read_file)\n - Initial tool calls that failed and were retried with different parameters\n - Any step whose result is not consumed by a subsequent core step\n - **NEVER mark a discovery step as exploratory if its output was used to build arguments for a later step**\n\n### Signal Steps (Human-in-the-Loop)\nSteps with kind \"signal\" represent a durable pause where the workflow waits for human input (e.g., credentials, approval). These are ALWAYS core \u2014 they are essential to the workflow's data flow. The signal step receives data from a human and makes it available to subsequent steps. Do NOT mark signal steps as exploratory. The escalation tool call (escalate_and_wait) that precedes a signal step is also always core.\n\n**Signal data flow**: The signal step result contains the human response fields (e.g., password). These MUST be wired via data_flow edges to every downstream step that needs them. Add a data_flow edge from the signal step index to the consuming step with the matching field name.\n\n**Credentials from signals**: When the signal provides a credential (format: password in the schema), downstream tools that need it should receive it as a separate named input argument. The runtime exchanges ephemeral credential tokens automatically. For tools with complex stored arguments (like run_script steps arrays), wire the credential as a top-level argument name \u2014 the runtime merges it with stored defaults.\n\n### Iteration Specifications\nWhen the execution shows repeated tool calls with varying arguments (the pattern detector may have already collapsed these):\n- Identify the SOURCE: which prior step's result contains the array being iterated. This is the step that PRODUCED the list of items \u2014 look for a step whose result contains an array field with items matching the iteration's varying values. For example, if the iteration visits multiple URLs, find the step that returned those URLs (e.g., extract_content with links).\n- The source is NEVER a step that doesn't have the array in its output. Double-check: does the source step's resultKeys include the source_field?\n- Specify the source_field: the dot-path to the array (e.g., \"links\", \"results.pages\")\n- List varying_keys (change per item) vs constant_args (shared)\n- **KEY MAPPINGS are critical**: array items often use different key names than the tool expects.\n E.g., extract_content returns `links: [{text, href}, ...]` but the screenshot tool wants `url`.\n Map: `{ \"url\": \"href\" }` \u2014 tool arg name \u2192 array item key name.\n Use null for keys that are COMPUTED at runtime, not sourced from the array.\n For example, screenshot_path is often derived from the link text or URL \u2014 it's not a field in the source array directly:\n `{ \"screenshot_path\": null }` \u2014 the value must be computed or provided by the trigger.\n\n### Tool Simplification for Iterations (CRITICAL)\nThe iteration pattern works by extracting individual values from array items and passing them as simple key=value arguments to the iterated tool. This means:\n\n**The iterated tool MUST accept simple, flat arguments** (url, path, page_id \u2014 not complex nested structures like a `steps` array).\n\nIf the execution used a complex multi-step scripting tool (e.g., `run_script` with a `steps: [{action, url}, {action, path}]` array) for each iteration, you MUST replace it with a simpler tool from the same server that accepts flat arguments. Check the server's tool inventory for a simpler alternative.\n\nFor example:\n- `run_script(steps=[navigate, wait, screenshot])` per page \u2192 replace with `capture_page(url, path, full_page, wait_ms)` (1 call, flat args)\n- `run_script(steps=[navigate, fill, click])` per item \u2192 replace with `submit_form(url, fields)` (1 call, flat args)\n\nWhen replacing: use the same server_id but the simpler tool_name. The varying_keys and key_mappings should map directly to the simple tool's argument names.\n\n**If no simpler tool alternative exists**, use a data_flow edge with a transform to feed the array into a batch/composite tool that accepts the full array (like `capture_authenticated_pages` which takes a `pages` array).\n\n### Data Flow Graph\nSpecify directed edges showing how data flows between steps:\n- from_step: \"trigger\" (user input) or step index number\n- from_field: the output field name (or trigger input key)\n- to_step: the consuming step index\n- to_field: the argument key name\n- is_session_wire: true for session handles (page_id, _handle, session_id)\n\nSession handles are critical \u2014 they maintain authenticated browser sessions, database connections, etc. They must be threaded from their producer through ALL subsequent steps that need them.\n\n### Chain Analysis to Downstream Steps\nWhen a step produces a meaningful result (analysis, extraction, description, computed value) and a later step consumes related data (saving, storing, forwarding, reporting), there MUST be a data_flow edge connecting them. Match by semantic intent, not just field name:\n- Step produces `description` \u2192 downstream step takes `value` \u2192 edge with from_field: \"description\", to_field: \"value\"\n- Step produces `analysis.summary` \u2192 downstream step takes `content` \u2192 edge with appropriate field mapping\n\nIf the original execution trace shows that a step's output was used (even indirectly) as input to a later step, the compiled version must preserve that data chain. A broken chain means the downstream step receives no data \u2014 the worst possible compilation error.\n\n### Data Flow Transforms (CRITICAL for array reshaping)\nWhen a source step produces an array of objects in one format but the consuming step expects a DIFFERENT format, add a `transform` to the data_flow edge. Compare the source step's result structure with the consuming step's actual arguments from the trace.\n\n**Choosing the correct source field**: When a step produces multiple output fields, check the result sample to determine which field actually contains an ARRAY OF OBJECTS suitable for iteration/reshaping. Prefer structured array fields over raw/unstructured fields. Check the Tool-Specific Compilation Hints section (if present) for guidance on which fields to use for specific tools.\n\nFor example: extract_content returns `links: [{text, href}]` but capture tool expects `pages: [{url, screenshot_path, wait_ms, full_page}]`.\nAdd a transform with:\n- `field_map`: maps target keys \u2192 source keys (e.g., `{\"url\": \"href\"}`). Use null for keys not in the source.\n- `defaults`: static values to inject (e.g., `{\"wait_ms\": 3000, \"full_page\": true}`)\n- `derivations`: for computed keys (null in field_map), how to derive them from source data\n - strategy: \"slugify\" (lowercase, replace spaces/special with hyphens), \"prefix\", \"template\", \"concat\"\n - source_key: which source field to derive from\n - prefix/suffix/template: string manipulation params\n\nAvailable derivation strategies:\n- **slugify**: Lowercase, replace spaces/special chars with hyphens. Optionally add prefix/suffix.\n- **prefix**: Prepend a static string.\n- **template**: Format string with `{value}` (source field) and `{date}` (today's date as YYYY-MM-DD via @date.yyyymmdd).\n- **concat**: Join multiple parts. Each part can use `{value}` and `{date}` placeholders.\n Example: `{ \"strategy\": \"concat\", \"parts\": [\"{value}\", \"-\", \"{date}\"] }` produces `my-slug-2026-04-17`.\n- **passthrough**: No transformation.\n\nUse these when the workflow needs runtime-computed values (date-stamped filenames, slugified URLs, templated paths).\n\nExample edge with transform:\n```\n{\n \"from_step\": 1, \"from_field\": \"links\", \"to_step\": 2, \"to_field\": \"pages\",\n \"is_session_wire\": false,\n \"transform\": {\n \"field_map\": { \"url\": \"href\", \"screenshot_path\": null },\n \"defaults\": { \"wait_ms\": 3000, \"full_page\": true },\n \"derivations\": {\n \"screenshot_path\": {\n \"source_key\": \"href\",\n \"strategy\": \"slugify\",\n \"prefix\": \"screenshots/\",\n \"suffix\": \".png\"\n }\n }\n }\n}\n```\n\nIMPORTANT: Check EVERY array-typed data_flow edge. Compare the source step's result item keys with the consuming step's argument item keys. If they differ, add a transform. Look at the actual tool_arguments in the execution trace to determine the correct field_map, defaults, and derivations.\n\n### Scalar Derivations on Data Flow Edges\nWhen a scalar value needs runtime transformation before reaching its consumer, add a `derivation` to the data_flow edge (NOT a `transform` \u2014 transforms are for array reshaping). Derivations generate runtime expressions for string manipulation.\n\nCommon use case: the user's prompt mentions a pattern like \"save with key slug-{date}\" or \"name it {something}-{today's date}\". The trigger provides the base value, and the derivation appends or formats it at runtime.\n\nAdd a `derivation` field to the data_flow edge:\n```\n{\n \"from_step\": \"trigger\", \"from_field\": \"key\", \"to_step\": 3, \"to_field\": \"key\",\n \"is_session_wire\": false,\n \"derivation\": { \"strategy\": \"concat\", \"parts\": [\"{value}\", \"-\", \"{date}\"] }\n}\n```\n\nThis produces a runtime-computed key like `my-slug-2026-04-17`. The `{value}` placeholder is the source field value; `{date}` is today's ISO date (YYYY-MM-DD).\n\nUse derivations when:\n- The user wants date-stamped keys, filenames, or identifiers\n- A value needs a prefix/suffix added at runtime\n- Two values need to be concatenated\n\n### Input Classification\n- **dynamic**: Simple values callers MUST provide: URLs, credentials, file paths, queries, search terms. These are always scalar strings, numbers, or booleans \u2014 NEVER complex objects or arrays.\n- **fixed**: Implementation details with sensible defaults: selectors, timeouts, boolean flags, AND complex structured arguments like `steps` arrays, `login` objects, or `pages` arrays. These are baked into stored tool_arguments.\n\n**Complex tool arguments (arrays of objects, nested structures) are ALWAYS fixed.** They represent the implementation recipe, not user input. For example:\n- A `steps` array describing browser actions (navigate, fill, click, screenshot) \u2192 **fixed**\n- A `login` object with selectors and credentials \u2192 flatten the credentials (username, password) as dynamic, but the selectors as fixed\n- A `pages` array of URLs to capture \u2192 **fixed** if hardcoded from the trace, or a data_flow edge if discovered at runtime\n\nFlatten nested objects containing dynamic values. E.g., `login: {url, username, password}` \u2192 separate `login_url`, `username`, `password` fields. But NEVER expose the full nested object or array as a trigger input.\n\n**Arrays that were DISCOVERED at runtime (by a prior step) are NOT inputs.** They flow between steps via data_flow edges. Only make an array a trigger input if the user explicitly provided it in their prompt. If the array was produced by a discovery step (extract_content, query, list), keep the discovery step as core and wire its output to the consuming step.\n\n### Prompt-Mentioned Values Are Dynamic\nIf a scalar value (URL, domain name, file path, key name, slug, query string) appears verbatim or closely paraphrased in the user's original prompt, classify it as **dynamic**. The user explicitly chose that value for this execution and will want to change it next time. Only classify a prompt-mentioned value as fixed if it is unambiguously an implementation constant (a CSS selector, a timeout, a boolean flag).\n\nThis is the most common compilation error: treating the user's specific request values as universal defaults. When in doubt, make it dynamic.\n\n### Data Flow Wiring Precision\n- **Only wire inputs that semantically match.** A directory name (e.g., `screenshot_dir = \"screenshots\"`) must NOT be wired to a file path argument (e.g., `screenshot_path` which expects `\"screenshots/home.png\"`). If a tool argument needs a specific file path but the trigger only provides a directory, leave that argument unwired \u2014 the stored tool_arguments default will provide the correct value.\n- **Trigger inputs should map to the EXACT tool argument they represent.** Don't reuse a trigger input for a different-purpose argument just because the names are vaguely related.\n- **When in doubt, don't wire.** An unwired argument falls back to the stored tool_arguments default from the original execution \u2014 this is always correct. An incorrectly wired argument overrides the correct default with a wrong value.\n\n### Session Fields and Threading Rules\nList all fields that represent session tokens/handles that must flow through the DAG (e.g., page_id, _handle, session_id).\n\n**Critical**: When a login/setup step produces a page_id or _handle, ALL subsequent browser/page steps must receive that session wire \u2014 including steps inside iterations. The data_flow graph must include session wire edges from the producing step to EVERY downstream step that operates on the same session, not just the immediately next one. For iterations: wire the session from the setup step directly to the iteration body step.\n\n**COMPLETENESS REQUIREMENT**: For EACH step that uses a session field (check the step's argumentKeys \u2014 if it includes page_id, _handle, or session_id), you MUST emit a data_flow edge wiring that field from its producer. If step 0 produces _handle and steps 1, 2, and 3 all use it, you need THREE edges: 0\u21921, 0\u21922, 0\u21923. Do NOT assume downstream steps will \"inherit\" session fields \u2014 each consumer needs an explicit edge.\n\n### Data Flow Completeness Check\nBefore finalizing the plan, verify:\n1. Every step that has a session field in its argumentKeys has a corresponding is_session_wire edge\n2. Every step that consumes data from a prior step has a data_flow edge for that field\n3. Every dynamic trigger input is wired to at least one step via a data_flow edge from \"trigger\"\n4. Transform edges include the source field AND the consuming step can access all fields it needs\n\n## Output Format\n\nReturn a JSON object (no markdown fences):\n{\n \"intent\": \"Brief generic description of what this workflow does\",\n \"description\": \"Suggested workflow description for discovery\",\n \"steps\": [\n { \"index\": 0, \"purpose\": \"Navigate to the target site\", \"disposition\": \"core\" },\n { \"index\": 1, \"purpose\": \"Extract navigation links from the page\", \"disposition\": \"core\" },\n { \"index\": 2, \"purpose\": \"List files to check directory structure\", \"disposition\": \"exploratory\" }\n ],\n \"core_step_indices\": [0, 1, 3],\n \"inputs\": [\n { \"key\": \"base_url\", \"type\": \"string\", \"classification\": \"dynamic\", \"description\": \"The base URL of the site\" },\n { \"key\": \"username\", \"type\": \"string\", \"classification\": \"dynamic\", \"description\": \"Login username\" },\n { \"key\": \"timeout\", \"type\": \"number\", \"classification\": \"fixed\", \"description\": \"Page load timeout\", \"default\": 30000 }\n ],\n \"iterations\": [\n {\n \"body_step_index\": 3,\n \"tool_name\": \"screenshot\",\n \"server_id\": \"playwright\",\n \"source_step_index\": 1,\n \"source_field\": \"links\",\n \"varying_keys\": [\"url\", \"screenshot_path\"],\n \"constant_args\": { \"full_page\": true },\n \"key_mappings\": { \"url\": \"href\", \"screenshot_path\": null }\n }\n ],\n \"data_flow\": [\n { \"from_step\": \"trigger\", \"from_field\": \"base_url\", \"to_step\": 0, \"to_field\": \"url\", \"is_session_wire\": false },\n { \"from_step\": 0, \"from_field\": \"page_id\", \"to_step\": 1, \"to_field\": \"page_id\", \"is_session_wire\": true },\n { \"from_step\": 0, \"from_field\": \"_handle\", \"to_step\": 1, \"to_field\": \"_handle\", \"is_session_wire\": true }\n ],\n \"session_fields\": [\"page_id\", \"_handle\"]\n}";
8
8
  /**
9
9
  * Build the retry hint injected into the compile stage when
10
10
  * user feedback or a prior deployment error triggers recompilation.
@@ -120,7 +120,7 @@ Add a transform with:
120
120
  Available derivation strategies:
121
121
  - **slugify**: Lowercase, replace spaces/special chars with hyphens. Optionally add prefix/suffix.
122
122
  - **prefix**: Prepend a static string.
123
- - **template**: Format string with \`{value}\` (source field) and \`{date}\` (today's ISO date, YYYY-MM-DD).
123
+ - **template**: Format string with \`{value}\` (source field) and \`{date}\` (today's date as YYYY-MM-DD via @date.yyyymmdd).
124
124
  - **concat**: Join multiple parts. Each part can use \`{value}\` and \`{date}\` placeholders.
125
125
  Example: \`{ "strategy": "concat", "parts": ["{value}", "-", "{date}"] }\` produces \`my-slug-2026-04-17\`.
126
126
  - **passthrough**: No transformation.
@@ -1,4 +1,5 @@
1
- export declare const CREATE_YAML_WORKFLOW = "\n INSERT INTO lt_yaml_workflows\n (name, description, app_id, app_version, source_workflow_id,\n source_workflow_type, yaml_content, graph_topic,\n input_schema, output_schema, activity_manifest, input_field_meta,\n original_prompt, category, tags, metadata, content_version)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, 1)\n RETURNING *";
1
+ export declare const CREATE_YAML_WORKFLOW = "\n INSERT INTO lt_yaml_workflows\n (name, description, app_id, app_version, source_workflow_id,\n source_workflow_type, yaml_content, graph_topic,\n input_schema, output_schema, activity_manifest, input_field_meta,\n original_prompt, category, tags, metadata, content_version,\n set_id, set_role, set_build_order)\n VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, 1, $17, $18, $19)\n RETURNING *";
2
+ export declare const CHECK_TOPIC_UNIQUE = "\n SELECT id, name FROM lt_yaml_workflows\n WHERE app_id = $1 AND graph_topic = $2 AND status != 'archived'\n LIMIT 1";
2
3
  export declare const GET_YAML_WORKFLOW = "\n SELECT * FROM lt_yaml_workflows WHERE id = $1";
3
4
  export declare const GET_YAML_WORKFLOW_BY_NAME = "\n SELECT * FROM lt_yaml_workflows WHERE name = $1";
4
5
  export declare const UPDATE_YAML_WORKFLOW_VERSION = "\n UPDATE lt_yaml_workflows SET app_version = $2 WHERE id = $1";
@@ -1,15 +1,20 @@
1
1
  "use strict";
2
2
  // ─── YAML workflow CRUD ─────────────────────────────────────────────────────
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.FIND_BY_TAGS_ALL = exports.FIND_BY_TAGS_ANY = exports.GET_CRON_SCHEDULED_WORKFLOWS = exports.CLEAR_CRON_SCHEDULE = exports.UPDATE_CRON_SCHEDULE = exports.UPDATE_STATUS_SUFFIX = exports.UPDATE_STATUS_BASE = exports.GET_VERSION_SNAPSHOT = exports.DISCOVER_WORKFLOWS = exports.LIST_VERSIONS = exports.COUNT_VERSIONS = exports.CREATE_VERSION_SNAPSHOT = exports.MARK_APP_ID_CONTENT_DEPLOYED = exports.MARK_CONTENT_DEPLOYED = exports.GET_DISTINCT_APP_IDS = exports.LIST_BY_APP_ID = exports.GET_ACTIVE_YAML_WORKFLOWS = exports.DELETE_YAML_WORKFLOW = exports.UPDATE_YAML_WORKFLOW_VERSION = exports.GET_YAML_WORKFLOW_BY_NAME = exports.GET_YAML_WORKFLOW = exports.CREATE_YAML_WORKFLOW = void 0;
4
+ exports.FIND_BY_TAGS_ALL = exports.FIND_BY_TAGS_ANY = exports.GET_CRON_SCHEDULED_WORKFLOWS = exports.CLEAR_CRON_SCHEDULE = exports.UPDATE_CRON_SCHEDULE = exports.UPDATE_STATUS_SUFFIX = exports.UPDATE_STATUS_BASE = exports.GET_VERSION_SNAPSHOT = exports.DISCOVER_WORKFLOWS = exports.LIST_VERSIONS = exports.COUNT_VERSIONS = exports.CREATE_VERSION_SNAPSHOT = exports.MARK_APP_ID_CONTENT_DEPLOYED = exports.MARK_CONTENT_DEPLOYED = exports.GET_DISTINCT_APP_IDS = exports.LIST_BY_APP_ID = exports.GET_ACTIVE_YAML_WORKFLOWS = exports.DELETE_YAML_WORKFLOW = exports.UPDATE_YAML_WORKFLOW_VERSION = exports.GET_YAML_WORKFLOW_BY_NAME = exports.GET_YAML_WORKFLOW = exports.CHECK_TOPIC_UNIQUE = exports.CREATE_YAML_WORKFLOW = void 0;
5
5
  exports.CREATE_YAML_WORKFLOW = `
6
6
  INSERT INTO lt_yaml_workflows
7
7
  (name, description, app_id, app_version, source_workflow_id,
8
8
  source_workflow_type, yaml_content, graph_topic,
9
9
  input_schema, output_schema, activity_manifest, input_field_meta,
10
- original_prompt, category, tags, metadata, content_version)
11
- VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, 1)
10
+ original_prompt, category, tags, metadata, content_version,
11
+ set_id, set_role, set_build_order)
12
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, 1, $17, $18, $19)
12
13
  RETURNING *`;
14
+ exports.CHECK_TOPIC_UNIQUE = `
15
+ SELECT id, name FROM lt_yaml_workflows
16
+ WHERE app_id = $1 AND graph_topic = $2 AND status != 'archived'
17
+ LIMIT 1`;
13
18
  exports.GET_YAML_WORKFLOW = `
14
19
  SELECT * FROM lt_yaml_workflows WHERE id = $1`;
15
20
  exports.GET_YAML_WORKFLOW_BY_NAME = `
@@ -24,6 +24,9 @@ export interface CreateYamlWorkflowInput {
24
24
  category?: string;
25
25
  tags?: string[];
26
26
  metadata?: Record<string, unknown>;
27
+ set_id?: string;
28
+ set_role?: 'leaf' | 'composition' | 'router';
29
+ set_build_order?: number;
27
30
  }
28
31
  /** Mutable state accumulated while building the YAML DAG. */
29
32
  export interface DagBuilder {
@@ -47,6 +47,8 @@ function compactForLlm(input) {
47
47
  */
48
48
  function buildLlmCallback(activity) {
49
49
  return async (data) => {
50
+ const wfName = data.data?.workflowName || activity.workflow_name || activity.activity_id;
51
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] entering llm wf=${wfName} argKeys=[${Object.keys(data.data || {}).join(',')}]`);
50
52
  const rawInput = (data.data || {});
51
53
  const input = compactForLlm(rawInput);
52
54
  const template = activity.prompt_template || '';
@@ -98,7 +100,7 @@ function buildLlmCallback(activity) {
98
100
  catch {
99
101
  result = { response: content };
100
102
  }
101
- logger_1.loggerRegistry.info(`[yaml-workflow] LLM step completed (model: ${model}, topic: ${activity.topic})`);
103
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] leaving llm wf=${wfName} resultType=${typeof result}`);
102
104
  return {
103
105
  metadata: { ...data.metadata },
104
106
  data: result,
@@ -154,9 +156,12 @@ function buildTransformCallback(activity) {
154
156
  if (!spec)
155
157
  throw new Error(`Transform activity ${activity.activity_id} missing transform_spec`);
156
158
  return async (data) => {
159
+ const wfName = data.data?.workflowName || activity.workflow_name || activity.activity_id;
160
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] entering transform wf=${wfName} source=${spec.sourceField} target=${spec.targetField} argKeys=[${Object.keys(data.data || {}).join(',')}]`);
157
161
  const input = (data.data || {});
158
162
  const sourceData = input[spec.sourceField];
159
163
  if (!Array.isArray(sourceData)) {
164
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] leaving transform wf=${wfName} passthrough (source not array)`);
160
165
  // Pass through non-array data unchanged
161
166
  return {
162
167
  metadata: { ...data.metadata },
@@ -194,6 +199,7 @@ function buildTransformCallback(activity) {
194
199
  });
195
200
  // Return reshaped data alongside any other input fields (session handles, etc.)
196
201
  const result = { ...input, [spec.targetField]: reshaped };
202
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] leaving transform wf=${wfName} reshapedCount=${reshaped.length} resultKeys=[${Object.keys(result).join(',')}]`);
197
203
  return {
198
204
  metadata: { ...data.metadata },
199
205
  data: result,
@@ -125,12 +125,15 @@ async function registerWorkersForWorkflow(workflow) {
125
125
  connection: (0, db_1.getConnection)(),
126
126
  retry: defaultRetry,
127
127
  callback: wrap(async (data) => {
128
+ const wfName = data.data?.workflowName || activity.workflow_name || toolName;
129
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] entering db/${toolName} wf=${wfName} argKeys=[${Object.keys(data.data || {}).join(',')}]`);
128
130
  const args = (data.data || {});
129
131
  let mergedArgs = toolArgs ? { ...toolArgs, ...args } : args;
130
132
  delete mergedArgs._scope;
131
133
  delete mergedArgs.workflowName;
132
134
  mergedArgs = await (0, ephemeral_1.exchangeTokensInArgs)(mergedArgs);
133
135
  const result = await mcpClient.callServerTool(dbServerId, toolName, mergedArgs);
136
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] leaving db/${toolName} wf=${wfName} resultKeys=[${Object.keys(result || {}).join(',')}]`);
134
137
  return { metadata: { ...data.metadata }, data: result };
135
138
  }),
136
139
  });
@@ -158,6 +161,8 @@ async function registerWorkersForWorkflow(workflow) {
158
161
  connection: (0, db_1.getConnection)(),
159
162
  retry: defaultRetry,
160
163
  callback: wrap(async (data) => {
164
+ const wfName = data.data?.workflowName || activity.workflow_name || toolName;
165
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] entering mcp/${toolName} wf=${wfName} server=${serverId} argKeys=[${Object.keys(data.data || {}).join(',')}]`);
161
166
  const args = (data.data || {});
162
167
  // Start from stored defaults, then strip any wired keys that
163
168
  // didn't arrive (upstream failure) so stale defaults don't leak.
@@ -173,6 +178,7 @@ async function registerWorkersForWorkflow(workflow) {
173
178
  mergedArgs[key] = value;
174
179
  }
175
180
  }
181
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] merged mcp/${toolName} wf=${wfName} mergedKeys=[${Object.keys(mergedArgs).join(',')}]`);
176
182
  // For escalate_and_wait: inject YAML signal routing so the MCP tool
177
183
  // stores engine:'yaml' + hookTopic + jobId in the escalation metadata
178
184
  if (yamlHookTopic) {
@@ -195,6 +201,7 @@ async function registerWorkersForWorkflow(workflow) {
195
201
  if (result == null) {
196
202
  logger_1.loggerRegistry.warn(`[yaml-workflow:worker] ${toolName} returned null/undefined`);
197
203
  }
204
+ logger_1.loggerRegistry.debug(`[yaml-workflow:worker] leaving mcp/${toolName} wf=${wfName} resultKeys=[${Object.keys(result || {}).join(',')}]`);
198
205
  return { metadata: { ...data.metadata }, data: result };
199
206
  }),
200
207
  });
@@ -8,6 +8,7 @@ const honeycomb_1 = require("../lib/telemetry/honeycomb");
8
8
  const events_1 = require("../lib/events");
9
9
  const nats_1 = require("../lib/events/nats");
10
10
  const socketio_1 = require("../lib/events/socketio");
11
+ const callback_1 = require("../lib/events/callback");
11
12
  const maintenance_1 = require("../services/maintenance");
12
13
  const maintenance_2 = require("../modules/maintenance");
13
14
  const mcp_1 = require("../services/mcp");
@@ -47,6 +48,9 @@ function registerAdapters(startConfig) {
47
48
  }
48
49
  events_1.eventRegistry.register(new socketio_1.SocketIOEventAdapter());
49
50
  }
51
+ // Always register the callback adapter for SDK event subscriptions.
52
+ // Zero-cost when no listeners are registered.
53
+ events_1.eventRegistry.register(new callback_1.CallbackEventAdapter());
50
54
  // Maintenance
51
55
  if (startConfig.maintenance === false) {
52
56
  // Disabled
@@ -83,6 +83,12 @@ function getSystemWorkers() {
83
83
  workers.push({ taskQueue: 'long-tail-system', workflow: mcpWorkflowBuilder });
84
84
  }
85
85
  catch { /* not available */ }
86
+ // ── Workflow planner (multi-workflow plan mode) ──
87
+ try {
88
+ const { mcpWorkflowPlanner } = require('./workflows/mcp-workflow-planner');
89
+ workers.push({ taskQueue: 'long-tail-system', workflow: mcpWorkflowPlanner });
90
+ }
91
+ catch { /* not available */ }
86
92
  }
87
93
  return workers;
88
94
  }
@@ -41,7 +41,7 @@ const knowledge = __importStar(require("../activities/knowledge"));
41
41
  const storeSchema = zod_1.z.object({
42
42
  domain: zod_1.z.string().describe('Knowledge domain (namespace)'),
43
43
  key: zod_1.z.string().describe('Unique key within domain'),
44
- data: zod_1.z.record(zod_1.z.any()).describe('JSONB payload to store'),
44
+ data: zod_1.z.record(zod_1.z.any()).describe('JSONB object payload to store (must be an object, not a string — wrap text as { "description": "..." })'),
45
45
  tags: zod_1.z.array(zod_1.z.string()).optional().describe('Categorization tags'),
46
46
  });
47
47
  const getSchema = zod_1.z.object({
@@ -183,7 +183,8 @@ exports.SEED_MCP_SERVERS = [
183
183
  tool_manifest: tool_manifests_knowledge_1.KNOWLEDGE_TOOLS,
184
184
  metadata: { builtin: true, category: 'knowledge' },
185
185
  tags: ['knowledge', 'memory', 'state', 'storage'],
186
- compile_hints: 'store_knowledge arguments: domain (string), key (string), data (the content to store NOT "content"), data_key (optional sub-key). ' +
186
+ compile_hints: 'store_knowledge arguments: domain (string), key (string), data (object MUST be a JSON object, never a string), tags (optional string[]). ' +
187
+ 'The data field is a JSONB object. When storing text content, wrap it: { "description": "the text" }. NEVER pass a bare string as data. ' +
187
188
  'store_knowledge upserts by domain+key — it merges data if the entry exists. ' +
188
189
  'Use a consistent domain name across related workflows to build shared context. ' +
189
190
  'search_knowledge uses JSONB containment (@>) — the query object must be a subset of the stored data. ' +
@@ -1,2 +1,2 @@
1
- export { loadBuilderTools } from './tool-loader';
1
+ export { loadBuilderTools, loadReferenceSection } from './tool-loader';
2
2
  export { callBuilderLLM } from './llm';
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.callBuilderLLM = exports.loadBuilderTools = void 0;
3
+ exports.callBuilderLLM = exports.loadReferenceSection = exports.loadBuilderTools = void 0;
4
4
  var tool_loader_1 = require("./tool-loader");
5
5
  Object.defineProperty(exports, "loadBuilderTools", { enumerable: true, get: function () { return tool_loader_1.loadBuilderTools; } });
6
+ Object.defineProperty(exports, "loadReferenceSection", { enumerable: true, get: function () { return tool_loader_1.loadReferenceSection; } });
6
7
  var llm_1 = require("./llm");
7
8
  Object.defineProperty(exports, "callBuilderLLM", { enumerable: true, get: function () { return llm_1.callBuilderLLM; } });
@@ -3,3 +3,9 @@ export declare function loadBuilderTools(tags?: string[]): Promise<{
3
3
  inventory: string;
4
4
  strategy: string;
5
5
  }>;
6
+ /**
7
+ * Load a specific section from the activity-types reference file.
8
+ * Returns the markdown for the requested activity type (await, signal, interrupt).
9
+ * Returns empty string if the section or file is not found.
10
+ */
11
+ export declare function loadReferenceSection(section: 'await' | 'signal' | 'interrupt'): Promise<string>;
@@ -1,8 +1,34 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadBuilderTools = loadBuilderTools;
4
+ exports.loadReferenceSection = loadReferenceSection;
5
+ const promises_1 = require("fs/promises");
6
+ const path_1 = require("path");
4
7
  const tool_loader_1 = require("../../shared/tool-loader");
5
8
  const caches_1 = require("./caches");
6
9
  async function loadBuilderTools(tags) {
7
10
  return (0, tool_loader_1.loadToolsFromServers)(tags, { toolServerMap: caches_1.toolServerMap, toolDefCache: caches_1.toolDefCache }, { logPrefix: 'workflowBuilder' });
8
11
  }
12
+ /**
13
+ * Load a specific section from the activity-types reference file.
14
+ * Returns the markdown for the requested activity type (await, signal, interrupt).
15
+ * Returns empty string if the section or file is not found.
16
+ */
17
+ async function loadReferenceSection(section) {
18
+ try {
19
+ const refPath = (0, path_1.join)(__dirname, '..', 'reference', 'activity-types.md');
20
+ const content = await (0, promises_1.readFile)(refPath, 'utf-8');
21
+ // Extract the section between ## <name> and the next ## or end of file
22
+ const sectionHeader = `## ${section}`;
23
+ const startIdx = content.indexOf(sectionHeader);
24
+ if (startIdx === -1)
25
+ return '';
26
+ const afterHeader = content.indexOf('\n', startIdx);
27
+ const nextSection = content.indexOf('\n## ', afterHeader + 1);
28
+ const endIdx = nextSection === -1 ? content.length : nextSection;
29
+ return content.slice(startIdx, endIdx).trim();
30
+ }
31
+ catch {
32
+ return '';
33
+ }
34
+ }
@@ -37,7 +37,7 @@ exports.mcpWorkflowBuilder = mcpWorkflowBuilder;
37
37
  const hotmesh_1 = require("@hotmeshio/hotmesh");
38
38
  const activities = __importStar(require("./activities"));
39
39
  const prompts_1 = require("./prompts");
40
- const { loadBuilderTools, callBuilderLLM, } = hotmesh_1.Durable.workflow.proxyActivities({
40
+ const { loadBuilderTools, loadReferenceSection, callBuilderLLM, } = hotmesh_1.Durable.workflow.proxyActivities({
41
41
  activities,
42
42
  retry: {
43
43
  maximumAttempts: 3,
@@ -94,6 +94,7 @@ async function mcpWorkflowBuilder(envelope) {
94
94
  const priorYaml = envelope.data?.prior_yaml;
95
95
  const answers = envelope.data?.answers;
96
96
  const priorQuestions = envelope.data?.prior_questions;
97
+ const compositionContext = envelope.data?.composition_context;
97
98
  if (!prompt) {
98
99
  return {
99
100
  type: 'return',
@@ -111,10 +112,33 @@ async function mcpWorkflowBuilder(envelope) {
111
112
  raw.strategy ? `${raw.strategy}\n` : '',
112
113
  `## Available MCP Servers & Tools\n\n${raw.inventory}`,
113
114
  ].filter(Boolean).join('\n');
115
+ // 3. Load composition references if this workflow is part of a plan
116
+ const compositionSections = [];
117
+ if (compositionContext) {
118
+ if (compositionContext.requires_await) {
119
+ const awaitRef = await loadReferenceSection('await');
120
+ if (awaitRef)
121
+ compositionSections.push(awaitRef);
122
+ }
123
+ if (compositionContext.requires_signal) {
124
+ const signalRef = await loadReferenceSection('signal');
125
+ if (signalRef)
126
+ compositionSections.push(signalRef);
127
+ }
128
+ if (compositionContext.sibling_schemas?.length) {
129
+ const siblings = compositionContext.sibling_schemas
130
+ .map(s => `- **${s.name}** (topic: \`${s.graph_topic}\`)\n Input: \`${JSON.stringify(s.input_schema)}\`\n Output: \`${JSON.stringify(s.output_schema)}\``)
131
+ .join('\n');
132
+ compositionSections.push(`## Sibling Workflows in This Plan\n\nThis workflow is part of a multi-workflow set. The following sibling workflows exist in the same namespace and can be invoked using \`type: await\` activities:\n\n${siblings}`);
133
+ }
134
+ }
135
+ const fullInventory = compositionSections.length
136
+ ? `${serverSection}\n\n${compositionSections.join('\n\n')}`
137
+ : serverSection;
114
138
  const messages = [
115
139
  {
116
140
  role: 'system',
117
- content: (0, prompts_1.BUILDER_SYSTEM_PROMPT)(serverSection),
141
+ content: (0, prompts_1.BUILDER_SYSTEM_PROMPT)(fullInventory),
118
142
  },
119
143
  ];
120
144
  // If refining a prior attempt, inject context