@hotmeshio/long-tail 0.4.24 → 0.5.1

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 (229) hide show
  1. package/README.md +41 -1
  2. package/build/api/yaml-workflows/crud.d.ts +1 -0
  3. package/build/api/yaml-workflows/crud.js +2 -2
  4. package/build/lib/db/schemas/011_escalation_index_audit.sql +50 -0
  5. package/build/routes/mcp-endpoint.js +3 -5
  6. package/build/services/escalation/sql.d.ts +2 -2
  7. package/build/services/escalation/sql.js +2 -2
  8. package/build/services/topics/system-topics.js +27 -27
  9. package/build/services/yaml-workflow/invoke.js +77 -6
  10. package/build/start/graph-workflows.d.ts +14 -0
  11. package/build/start/graph-workflows.js +126 -0
  12. package/build/start/workers.js +14 -0
  13. package/build/system/mcp-servers/admin/schemas.d.ts +2 -2
  14. package/build/tsconfig.tsbuildinfo +1 -1
  15. package/build/types/startup.d.ts +28 -0
  16. package/dashboard/dist/assets/{AdminDashboard-CgJC8ZZF.js → AdminDashboard-CMzR4d-w.js} +2 -2
  17. package/dashboard/dist/assets/{AdminDashboard-CgJC8ZZF.js.map → AdminDashboard-CMzR4d-w.js.map} +1 -1
  18. package/dashboard/dist/assets/{AgentConfigPage-Bjl2Lsvo.js → AgentConfigPage-DHCpN4xk.js} +6 -6
  19. package/dashboard/dist/assets/{AgentConfigPage-Bjl2Lsvo.js.map → AgentConfigPage-DHCpN4xk.js.map} +1 -1
  20. package/dashboard/dist/assets/{AgentDetailPage-D5dHrfaM.js → AgentDetailPage-CSrejvSl.js} +3 -3
  21. package/dashboard/dist/assets/{AgentDetailPage-D5dHrfaM.js.map → AgentDetailPage-CSrejvSl.js.map} +1 -1
  22. package/dashboard/dist/assets/{AgentsPage-Mom3N1Av.js → AgentsPage-ntuzWHCD.js} +2 -2
  23. package/dashboard/dist/assets/{AgentsPage-Mom3N1Av.js.map → AgentsPage-ntuzWHCD.js.map} +1 -1
  24. package/dashboard/dist/assets/{AvailableEscalationsPage-B2ZAb41C.js → AvailableEscalationsPage-Ci24fdxC.js} +2 -2
  25. package/dashboard/dist/assets/{AvailableEscalationsPage-B2ZAb41C.js.map → AvailableEscalationsPage-Ci24fdxC.js.map} +1 -1
  26. package/dashboard/dist/assets/{BotPicker-dCvnjynP.js → BotPicker-lj42d48P.js} +2 -2
  27. package/dashboard/dist/assets/{BotPicker-dCvnjynP.js.map → BotPicker-lj42d48P.js.map} +1 -1
  28. package/dashboard/dist/assets/CapabilitiesPage-Bea9yLmU.js +2 -0
  29. package/dashboard/dist/assets/CapabilitiesPage-Bea9yLmU.js.map +1 -0
  30. package/dashboard/dist/assets/{CollapsibleSection-bW0UZN9b.js → CollapsibleSection-BeBsI1M4.js} +2 -2
  31. package/dashboard/dist/assets/{CollapsibleSection-bW0UZN9b.js.map → CollapsibleSection-BeBsI1M4.js.map} +1 -1
  32. package/dashboard/dist/assets/{CredentialsPage-DVOK3aaR.js → CredentialsPage-BDzFa3HV.js} +2 -2
  33. package/dashboard/dist/assets/{CredentialsPage-DVOK3aaR.js.map → CredentialsPage-BDzFa3HV.js.map} +1 -1
  34. package/dashboard/dist/assets/{CronLabel-Cv5em7OP.js → CronLabel-DeNm1I4r.js} +2 -2
  35. package/dashboard/dist/assets/{CronLabel-Cv5em7OP.js.map → CronLabel-DeNm1I4r.js.map} +1 -1
  36. package/dashboard/dist/assets/{CustomDurationPicker-Dy4NBqhZ.js → CustomDurationPicker-C2OH9YcV.js} +2 -2
  37. package/dashboard/dist/assets/{CustomDurationPicker-Dy4NBqhZ.js.map → CustomDurationPicker-C2OH9YcV.js.map} +1 -1
  38. package/dashboard/dist/assets/{DropZone-CptiQ0wc.js → DropZone-Dwpgbueb.js} +2 -2
  39. package/dashboard/dist/assets/{DropZone-CptiQ0wc.js.map → DropZone-Dwpgbueb.js.map} +1 -1
  40. package/dashboard/dist/assets/{ElapsedCell-TQqWaVRq.js → ElapsedCell-WdzqA0dR.js} +2 -2
  41. package/dashboard/dist/assets/{ElapsedCell-TQqWaVRq.js.map → ElapsedCell-WdzqA0dR.js.map} +1 -1
  42. package/dashboard/dist/assets/{EscalationsOverview-Cv5UvuHI.js → EscalationsOverview-BIEeflEV.js} +2 -2
  43. package/dashboard/dist/assets/{EscalationsOverview-Cv5UvuHI.js.map → EscalationsOverview-BIEeflEV.js.map} +1 -1
  44. package/dashboard/dist/assets/{EventTable-Doky6fCO.js → EventTable-NIhWP__B.js} +2 -2
  45. package/dashboard/dist/assets/{EventTable-Doky6fCO.js.map → EventTable-NIhWP__B.js.map} +1 -1
  46. package/dashboard/dist/assets/GraphInvokePage-DtAW8ilc.js +2 -0
  47. package/dashboard/dist/assets/GraphInvokePage-DtAW8ilc.js.map +1 -0
  48. package/dashboard/dist/assets/HomePage-HsO-M8ub.js +2 -0
  49. package/dashboard/dist/assets/{HomePage-CzvVyTq4.js.map → HomePage-HsO-M8ub.js.map} +1 -1
  50. package/dashboard/dist/assets/{ListToolbar-Cfec9gz_.js → ListToolbar-DqaRlXrF.js} +2 -2
  51. package/dashboard/dist/assets/{ListToolbar-Cfec9gz_.js.map → ListToolbar-DqaRlXrF.js.map} +1 -1
  52. package/dashboard/dist/assets/{McpOverview-BN4GsBGI.js → McpOverview-B4GsHxij.js} +2 -2
  53. package/dashboard/dist/assets/{McpOverview-BN4GsBGI.js.map → McpOverview-B4GsHxij.js.map} +1 -1
  54. package/dashboard/dist/assets/McpQueryDetailPage-DZKpzWST.js +5 -0
  55. package/dashboard/dist/assets/McpQueryDetailPage-DZKpzWST.js.map +1 -0
  56. package/dashboard/dist/assets/{McpQueryPage-BK5L2PqJ.js → McpQueryPage-B-8WR3GV.js} +2 -2
  57. package/dashboard/dist/assets/{McpQueryPage-BK5L2PqJ.js.map → McpQueryPage-B-8WR3GV.js.map} +1 -1
  58. package/dashboard/dist/assets/McpRunDetailPage-Dt7Ai3qB.js +2 -0
  59. package/dashboard/dist/assets/McpRunDetailPage-Dt7Ai3qB.js.map +1 -0
  60. package/dashboard/dist/assets/{McpRunsPage-QsXid9Xe.js → McpRunsPage-Bdke-HoQ.js} +2 -2
  61. package/dashboard/dist/assets/{McpRunsPage-QsXid9Xe.js.map → McpRunsPage-Bdke-HoQ.js.map} +1 -1
  62. package/dashboard/dist/assets/NamespacePill-DnJl4Lre.js +2 -0
  63. package/dashboard/dist/assets/NamespacePill-DnJl4Lre.js.map +1 -0
  64. package/dashboard/dist/assets/{OperatorDashboard-CZQSINho.js → OperatorDashboard-VZ97mufd.js} +2 -2
  65. package/dashboard/dist/assets/{OperatorDashboard-CZQSINho.js.map → OperatorDashboard-VZ97mufd.js.map} +1 -1
  66. package/dashboard/dist/assets/{PageHeader-BuJpMxyu.js → PageHeader-Bnt2iQQa.js} +2 -2
  67. package/dashboard/dist/assets/{PageHeader-BuJpMxyu.js.map → PageHeader-Bnt2iQQa.js.map} +1 -1
  68. package/dashboard/dist/assets/{PageHeaderWithStats-yD_PTbOl.js → PageHeaderWithStats-BuKc9MKt.js} +2 -2
  69. package/dashboard/dist/assets/{PageHeaderWithStats-yD_PTbOl.js.map → PageHeaderWithStats-BuKc9MKt.js.map} +1 -1
  70. package/dashboard/dist/assets/{ProcessDetailPage-DUCOOvOK.js → ProcessDetailPage-BLfLfmWX.js} +2 -2
  71. package/dashboard/dist/assets/{ProcessDetailPage-DUCOOvOK.js.map → ProcessDetailPage-BLfLfmWX.js.map} +1 -1
  72. package/dashboard/dist/assets/{ProcessesListPage-CXvSLTIM.js → ProcessesListPage-DG54t-Nd.js} +2 -2
  73. package/dashboard/dist/assets/{ProcessesListPage-CXvSLTIM.js.map → ProcessesListPage-DG54t-Nd.js.map} +1 -1
  74. package/dashboard/dist/assets/{RolePill-SasQKc_B.js → RolePill-DQTT1s9v.js} +2 -2
  75. package/dashboard/dist/assets/{RolePill-SasQKc_B.js.map → RolePill-DQTT1s9v.js.map} +1 -1
  76. package/dashboard/dist/assets/{RolesPage-DlQR0Iz_.js → RolesPage-Bdlv3DdW.js} +2 -2
  77. package/dashboard/dist/assets/{RolesPage-DlQR0Iz_.js.map → RolesPage-Bdlv3DdW.js.map} +1 -1
  78. package/dashboard/dist/assets/{RunAsSelector-DP-jxsv6.js → RunAsSelector-BFxxMvL3.js} +2 -2
  79. package/dashboard/dist/assets/{RunAsSelector-DP-jxsv6.js.map → RunAsSelector-BFxxMvL3.js.map} +1 -1
  80. package/dashboard/dist/assets/{SwimlaneTimeline-BmASA0nN.js → SwimlaneTimeline-BZmad7WQ.js} +2 -2
  81. package/dashboard/dist/assets/{SwimlaneTimeline-BmASA0nN.js.map → SwimlaneTimeline-BZmad7WQ.js.map} +1 -1
  82. package/dashboard/dist/assets/{TagInput-DvF3j8MA.js → TagInput-B00uqhjX.js} +2 -2
  83. package/dashboard/dist/assets/{TagInput-DvF3j8MA.js.map → TagInput-B00uqhjX.js.map} +1 -1
  84. package/dashboard/dist/assets/{TaskDetailPage-CRowpkeZ.js → TaskDetailPage-CLl2mgBC.js} +2 -2
  85. package/dashboard/dist/assets/{TaskDetailPage-CRowpkeZ.js.map → TaskDetailPage-CLl2mgBC.js.map} +1 -1
  86. package/dashboard/dist/assets/{TaskQueuePill-BCQrS2oK.js → TaskQueuePill-CUsofm0X.js} +2 -2
  87. package/dashboard/dist/assets/{TaskQueuePill-BCQrS2oK.js.map → TaskQueuePill-CUsofm0X.js.map} +1 -1
  88. package/dashboard/dist/assets/{TasksListPage-uJ6z37J-.js → TasksListPage-DoHXxZF-.js} +2 -2
  89. package/dashboard/dist/assets/{TasksListPage-uJ6z37J-.js.map → TasksListPage-DoHXxZF-.js.map} +1 -1
  90. package/dashboard/dist/assets/{TimeAgo-BxwngK1D.js → TimeAgo-DZF9w8Rl.js} +2 -2
  91. package/dashboard/dist/assets/{TimeAgo-BxwngK1D.js.map → TimeAgo-DZF9w8Rl.js.map} +1 -1
  92. package/dashboard/dist/assets/{TimestampCell-CDmichOM.js → TimestampCell-DPpoTdrw.js} +2 -2
  93. package/dashboard/dist/assets/{TimestampCell-CDmichOM.js.map → TimestampCell-DPpoTdrw.js.map} +1 -1
  94. package/dashboard/dist/assets/ToolPill-DjvedZSn.js +2 -0
  95. package/dashboard/dist/assets/ToolPill-DjvedZSn.js.map +1 -0
  96. package/dashboard/dist/assets/ToolTestPanel-DtAgJQfr.js +2 -0
  97. package/dashboard/dist/assets/ToolTestPanel-DtAgJQfr.js.map +1 -0
  98. package/dashboard/dist/assets/TopicDetailPage-W9RKkNNp.js +9 -0
  99. package/dashboard/dist/assets/TopicDetailPage-W9RKkNNp.js.map +1 -0
  100. package/dashboard/dist/assets/{TopicsPage-letISGGD.js → TopicsPage-Bc-4ne6V.js} +2 -2
  101. package/dashboard/dist/assets/{TopicsPage-letISGGD.js.map → TopicsPage-Bc-4ne6V.js.map} +1 -1
  102. package/dashboard/dist/assets/{UserName-W6_Iz2Qb.js → UserName-O2Q4-E6E.js} +2 -2
  103. package/dashboard/dist/assets/{UserName-W6_Iz2Qb.js.map → UserName-O2Q4-E6E.js.map} +1 -1
  104. package/dashboard/dist/assets/{WorkflowExecutionPage-Cfx-xlRT.js → WorkflowExecutionPage-DEDsBmn1.js} +2 -2
  105. package/dashboard/dist/assets/{WorkflowExecutionPage-Cfx-xlRT.js.map → WorkflowExecutionPage-DEDsBmn1.js.map} +1 -1
  106. package/dashboard/dist/assets/{WorkflowPill-Z-zHRKOK.js → WorkflowPill-F1oKUzmc.js} +2 -2
  107. package/dashboard/dist/assets/{WorkflowPill-Z-zHRKOK.js.map → WorkflowPill-F1oKUzmc.js.map} +1 -1
  108. package/dashboard/dist/assets/{WorkflowsDashboard-DC4XHMWt.js → WorkflowsDashboard-Bcf17vCt.js} +2 -2
  109. package/dashboard/dist/assets/{WorkflowsDashboard-DC4XHMWt.js.map → WorkflowsDashboard-Bcf17vCt.js.map} +1 -1
  110. package/dashboard/dist/assets/{WorkflowsOverview-GefO_yn0.js → WorkflowsOverview-Cwo2rqGT.js} +2 -2
  111. package/dashboard/dist/assets/{WorkflowsOverview-GefO_yn0.js.map → WorkflowsOverview-Cwo2rqGT.js.map} +1 -1
  112. package/dashboard/dist/assets/YamlWorkflowDetailPage-Bv8ZFwO-.js +33 -0
  113. package/dashboard/dist/assets/YamlWorkflowDetailPage-Bv8ZFwO-.js.map +1 -0
  114. package/dashboard/dist/assets/YamlWorkflowsPage-DOiEQDOq.js +2 -0
  115. package/dashboard/dist/assets/YamlWorkflowsPage-DOiEQDOq.js.map +1 -0
  116. package/dashboard/dist/assets/{agents-BI5OeN84.js → agents-D09G0HCv.js} +2 -2
  117. package/dashboard/dist/assets/{agents-BI5OeN84.js.map → agents-D09G0HCv.js.map} +1 -1
  118. package/dashboard/dist/assets/{bots-1UzUCsrR.js → bots-D0LhyZZM.js} +2 -2
  119. package/dashboard/dist/assets/{bots-1UzUCsrR.js.map → bots-D0LhyZZM.js.map} +1 -1
  120. package/dashboard/dist/assets/{capabilities-BUbl-ojp.js → capabilities-DON4-NXs.js} +2 -2
  121. package/dashboard/dist/assets/{capabilities-BUbl-ojp.js.map → capabilities-DON4-NXs.js.map} +1 -1
  122. package/dashboard/dist/assets/{controlplane-DTFrH_vN.js → controlplane-Bihd1kXf.js} +2 -2
  123. package/dashboard/dist/assets/{controlplane-DTFrH_vN.js.map → controlplane-Bihd1kXf.js.map} +1 -1
  124. package/dashboard/dist/assets/{escalation-BQhCt4W0.js → escalation-CP2XbdXK.js} +2 -2
  125. package/dashboard/dist/assets/{escalation-BQhCt4W0.js.map → escalation-CP2XbdXK.js.map} +1 -1
  126. package/dashboard/dist/assets/{escalation-columns-J20k5CcY.js → escalation-columns-9aw8Y4qq.js} +2 -2
  127. package/dashboard/dist/assets/{escalation-columns-J20k5CcY.js.map → escalation-columns-9aw8Y4qq.js.map} +1 -1
  128. package/dashboard/dist/assets/helpers-DzO-OGPe.js +2 -0
  129. package/dashboard/dist/assets/helpers-DzO-OGPe.js.map +1 -0
  130. package/dashboard/dist/assets/{index-CVGgSoda.js → index-B-BK3vtk.js} +2 -2
  131. package/dashboard/dist/assets/{index-CVGgSoda.js.map → index-B-BK3vtk.js.map} +1 -1
  132. package/dashboard/dist/assets/{index-CWEOhAiK.js → index-B7lEd0cY.js} +25 -25
  133. package/dashboard/dist/assets/index-B7lEd0cY.js.map +1 -0
  134. package/dashboard/dist/assets/index-BBBGETMs.js +6 -0
  135. package/dashboard/dist/assets/index-BBBGETMs.js.map +1 -0
  136. package/dashboard/dist/assets/index-BFyzZGtv.css +1 -0
  137. package/dashboard/dist/assets/{index-vgxjge70.js → index-BInTEEIX.js} +2 -2
  138. package/dashboard/dist/assets/{index-vgxjge70.js.map → index-BInTEEIX.js.map} +1 -1
  139. package/dashboard/dist/assets/index-BTp73vYK.js +2 -0
  140. package/dashboard/dist/assets/index-BTp73vYK.js.map +1 -0
  141. package/dashboard/dist/assets/index-CCup2uaP.js +2 -0
  142. package/dashboard/dist/assets/{index-C9ClHiiW.js.map → index-CCup2uaP.js.map} +1 -1
  143. package/dashboard/dist/assets/index-CMRW_PE-.js +9 -0
  144. package/dashboard/dist/assets/index-CMRW_PE-.js.map +1 -0
  145. package/dashboard/dist/assets/index-Cb7aSzox.js +2 -0
  146. package/dashboard/dist/assets/{index-si70YcIP.js.map → index-Cb7aSzox.js.map} +1 -1
  147. package/dashboard/dist/assets/index-Cjb8ulHm.js +2 -0
  148. package/dashboard/dist/assets/{index-WQQJ_cp7.js.map → index-Cjb8ulHm.js.map} +1 -1
  149. package/dashboard/dist/assets/index-DgLZ8Ix5.js +2 -0
  150. package/dashboard/dist/assets/{index-DasoTRjT.js.map → index-DgLZ8Ix5.js.map} +1 -1
  151. package/dashboard/dist/assets/index-H5Yb8CY2.js +2 -0
  152. package/dashboard/dist/assets/index-H5Yb8CY2.js.map +1 -0
  153. package/dashboard/dist/assets/{index-CLUYzdwz.js → index-_JsRJPds.js} +2 -2
  154. package/dashboard/dist/assets/{index-CLUYzdwz.js.map → index-_JsRJPds.js.map} +1 -1
  155. package/dashboard/dist/assets/{index-C-mbURj-.js → index-rbuNUyAh.js} +2 -2
  156. package/dashboard/dist/assets/{index-C-mbURj-.js.map → index-rbuNUyAh.js.map} +1 -1
  157. package/dashboard/dist/assets/{knowledge-D9Tuh-o-.js → knowledge-Bl_KaoKJ.js} +2 -2
  158. package/dashboard/dist/assets/{knowledge-D9Tuh-o-.js.map → knowledge-Bl_KaoKJ.js.map} +1 -1
  159. package/dashboard/dist/assets/{mcp-BO8QnWyk.js → mcp-DXbFGoA8.js} +2 -2
  160. package/dashboard/dist/assets/{mcp-BO8QnWyk.js.map → mcp-DXbFGoA8.js.map} +1 -1
  161. package/dashboard/dist/assets/{mcp-query-WLtQtr51.js → mcp-query-Bg69DF2x.js} +2 -2
  162. package/dashboard/dist/assets/{mcp-query-WLtQtr51.js.map → mcp-query-Bg69DF2x.js.map} +1 -1
  163. package/dashboard/dist/assets/{pipelines-BAVf9xud.js → pipelines-DK9LTg9F.js} +2 -2
  164. package/dashboard/dist/assets/{pipelines-BAVf9xud.js.map → pipelines-DK9LTg9F.js.map} +1 -1
  165. package/dashboard/dist/assets/{roles-mGO2-2hA.js → roles-BrsBN4hO.js} +2 -2
  166. package/dashboard/dist/assets/{roles-mGO2-2hA.js.map → roles-BrsBN4hO.js.map} +1 -1
  167. package/dashboard/dist/assets/{tasks-JVRVCx0f.js → tasks-CwjvPECN.js} +2 -2
  168. package/dashboard/dist/assets/{tasks-JVRVCx0f.js.map → tasks-CwjvPECN.js.map} +1 -1
  169. package/dashboard/dist/assets/{topics-BLVnahd7.js → topics-BrwkmaFR.js} +2 -2
  170. package/dashboard/dist/assets/{topics-BLVnahd7.js.map → topics-BrwkmaFR.js.map} +1 -1
  171. package/dashboard/dist/assets/{useEventHooks-BwjAi0Qq.js → useEventHooks-Cd1GM1NG.js} +2 -2
  172. package/dashboard/dist/assets/{useEventHooks-BwjAi0Qq.js.map → useEventHooks-Cd1GM1NG.js.map} +1 -1
  173. package/dashboard/dist/assets/{useNamespace-DkHmXddZ.js → useNamespace-D9lghZ25.js} +2 -2
  174. package/dashboard/dist/assets/{useNamespace-DkHmXddZ.js.map → useNamespace-D9lghZ25.js.map} +1 -1
  175. package/dashboard/dist/assets/useYamlActivityEvents-vOhAwmKO.js +2 -0
  176. package/dashboard/dist/assets/useYamlActivityEvents-vOhAwmKO.js.map +1 -0
  177. package/dashboard/dist/assets/{users-BvizpAkV.js → users-ChQ7soaq.js} +2 -2
  178. package/dashboard/dist/assets/{users-BvizpAkV.js.map → users-ChQ7soaq.js.map} +1 -1
  179. package/dashboard/dist/assets/{vendor-icons-Doy0g69_.js → vendor-icons-Dj2F0Jrb.js} +38 -38
  180. package/dashboard/dist/assets/vendor-icons-Dj2F0Jrb.js.map +1 -0
  181. package/dashboard/dist/assets/workflows-BLKji1_1.js +2 -0
  182. package/dashboard/dist/assets/{workflows-CyEYa01a.js.map → workflows-BLKji1_1.js.map} +1 -1
  183. package/dashboard/dist/assets/yaml-workflows-BUhMfdaw.js +2 -0
  184. package/dashboard/dist/assets/{yaml-workflows-i3GzrEme.js.map → yaml-workflows-BUhMfdaw.js.map} +1 -1
  185. package/dashboard/dist/index.html +3 -3
  186. package/docs/story.md +13 -9
  187. package/package.json +2 -2
  188. package/dashboard/dist/assets/CapabilitiesPage-CK2fJ9Sy.js +0 -2
  189. package/dashboard/dist/assets/CapabilitiesPage-CK2fJ9Sy.js.map +0 -1
  190. package/dashboard/dist/assets/HomePage-CzvVyTq4.js +0 -2
  191. package/dashboard/dist/assets/McpQueryDetailPage-lCW668WQ.js +0 -5
  192. package/dashboard/dist/assets/McpQueryDetailPage-lCW668WQ.js.map +0 -1
  193. package/dashboard/dist/assets/McpRunDetailPage-CQOeYqxa.js +0 -2
  194. package/dashboard/dist/assets/McpRunDetailPage-CQOeYqxa.js.map +0 -1
  195. package/dashboard/dist/assets/ServerName-CHspudaC.js +0 -2
  196. package/dashboard/dist/assets/ServerName-CHspudaC.js.map +0 -1
  197. package/dashboard/dist/assets/StepIndicator-CuUIGxKk.js +0 -2
  198. package/dashboard/dist/assets/StepIndicator-CuUIGxKk.js.map +0 -1
  199. package/dashboard/dist/assets/ToolPill-1aTqYtzp.js +0 -2
  200. package/dashboard/dist/assets/ToolPill-1aTqYtzp.js.map +0 -1
  201. package/dashboard/dist/assets/ToolTestPanel-xjTn8sU8.js +0 -2
  202. package/dashboard/dist/assets/ToolTestPanel-xjTn8sU8.js.map +0 -1
  203. package/dashboard/dist/assets/TopicDetailPage-Dm0hDlS8.js +0 -9
  204. package/dashboard/dist/assets/TopicDetailPage-Dm0hDlS8.js.map +0 -1
  205. package/dashboard/dist/assets/YamlWorkflowsPage-CMsrFooO.js +0 -2
  206. package/dashboard/dist/assets/YamlWorkflowsPage-CMsrFooO.js.map +0 -1
  207. package/dashboard/dist/assets/helpers-ge6Eu90Y.js +0 -2
  208. package/dashboard/dist/assets/helpers-ge6Eu90Y.js.map +0 -1
  209. package/dashboard/dist/assets/index-C--SEsU7.css +0 -1
  210. package/dashboard/dist/assets/index-C45DvtAZ.js +0 -15
  211. package/dashboard/dist/assets/index-C45DvtAZ.js.map +0 -1
  212. package/dashboard/dist/assets/index-C9ClHiiW.js +0 -2
  213. package/dashboard/dist/assets/index-CWEOhAiK.js.map +0 -1
  214. package/dashboard/dist/assets/index-CWlP6vHG.js +0 -6
  215. package/dashboard/dist/assets/index-CWlP6vHG.js.map +0 -1
  216. package/dashboard/dist/assets/index-DasoTRjT.js +0 -2
  217. package/dashboard/dist/assets/index-FhasoOjO.js +0 -2
  218. package/dashboard/dist/assets/index-FhasoOjO.js.map +0 -1
  219. package/dashboard/dist/assets/index-WQQJ_cp7.js +0 -2
  220. package/dashboard/dist/assets/index-hAZiac0C.js +0 -2
  221. package/dashboard/dist/assets/index-hAZiac0C.js.map +0 -1
  222. package/dashboard/dist/assets/index-si70YcIP.js +0 -2
  223. package/dashboard/dist/assets/useExpandedRows-CkcEntB-.js +0 -2
  224. package/dashboard/dist/assets/useExpandedRows-CkcEntB-.js.map +0 -1
  225. package/dashboard/dist/assets/useYamlActivityEvents-CsaR5dWj.js +0 -2
  226. package/dashboard/dist/assets/useYamlActivityEvents-CsaR5dWj.js.map +0 -1
  227. package/dashboard/dist/assets/vendor-icons-Doy0g69_.js.map +0 -1
  228. package/dashboard/dist/assets/workflows-CyEYa01a.js +0 -2
  229. package/dashboard/dist/assets/yaml-workflows-i3GzrEme.js +0 -2
package/README.md CHANGED
@@ -74,10 +74,12 @@ curl -X PUT http://localhost:3000/api/workflows/reviewContent/config \
74
74
 
75
75
  **Step 3 — React to events.** Workflows publish topics. Agents subscribe. When `activity.failed` fires, an automation can re-run the step, notify a team, or trigger a different workflow. The choreography is dynamic — add subscribers through the dashboard without changing code.
76
76
 
77
- **Step 4 — Compile what repeats.** The Pipeline Designer takes a working execution and compiles it into a deterministic YAML DAG. No LLM at runtime, no replay overhead, typed inputs and outputs. It deploys as a reusable tool that any workflow or API call can invoke.
77
+ **Step 4 — Compile what repeats.** The same workflow has two forms. What you wrote in Step 1 is the *procedural* form — readable, Temporal-like, emulated atop the graph: cheap to maintain, heavier to run. The Designer compiles a working execution into the *graph* form — the same durable workflow as a deterministic DAG: no LLM at runtime, no replay overhead, typed in and out, roughly 3x faster. Every procedural pattern has a graph equivalent and the reverse; you pick readability or speed without giving up durability, escalation, or transactional guarantees. It deploys as a reusable tool that any workflow or API call can invoke.
78
78
 
79
79
  Over time, the system accumulates compiled tools. Problems that once required a human, then required AI reasoning, eventually require neither.
80
80
 
81
+ These four steps map to how the dashboard is organized. **React** is the reactive side (Step 3) — topics, subscriptions, automations. **Orchestrate** is the orchestrated side (Steps 1 and 4) — procedural and graph flows side by side, both durable and pull-based under the hood. **Design** is the optional bridge: with an `ANTHROPIC_API_KEY` it turns a description or a tool run into a graph flow; without one, choreography and orchestration stand on their own, no tradeoff.
82
+
81
83
  ## Register MCP tools
82
84
 
83
85
  Long Tail connects to any MCP server. Registered tools become durable activities and are available to the Pipeline Designer.
@@ -145,6 +147,43 @@ npx ltc compile workflows/
145
147
 
146
148
  The source is the spec. The compiled YAML is the optimized execution. Both live in the repo. See the [Compiler Guide](docs/compiler.md).
147
149
 
150
+ ## Register a graph flow by hand
151
+
152
+ `graphWorkflows` is the graph-form peer of `workers`: hand-author the HotMesh YAML and it's created, deployed, and activated at startup. This hello-world assembles a greeting from the input with a single trigger mapping:
153
+
154
+ ```typescript
155
+ const lt = await start({
156
+ database: { connectionString: process.env.DATABASE_URL },
157
+ graphWorkflows: [{
158
+ name: 'hello_world',
159
+ namespace: 'graph',
160
+ inputSchema: { type: 'object', properties: { name: { type: 'string' } }, required: ['name'] },
161
+ yaml: `
162
+ app:
163
+ id: graph
164
+ version: '1'
165
+ graphs:
166
+ - subscribes: hello_world
167
+ publishes: hello_world.done
168
+ input: { schema: { type: object, properties: { name: { type: string } } } }
169
+ output: { schema: { type: object, properties: { greeting: { type: string } } } }
170
+ activities:
171
+ trigger:
172
+ type: trigger
173
+ job:
174
+ maps:
175
+ greeting:
176
+ '@pipe':
177
+ - ['Hello, ', '{$self.input.data.name}', '!']
178
+ - ['{@string.concat}']
179
+ transitions: {}
180
+ `,
181
+ }],
182
+ });
183
+ ```
184
+
185
+ It appears under **Orchestrate › Graph** and runs the same way a procedural workflow does — durable, transactional, invocable from the dashboard or API.
186
+
148
187
  ## Full configuration
149
188
 
150
189
  ```typescript
@@ -153,6 +192,7 @@ const lt = await start({
153
192
  workers: [{ taskQueue: 'default', workflow: reviewContent }],
154
193
 
155
194
  // Everything below is optional
195
+ graphWorkflows: [{ name: 'hello_world', namespace: 'graph', yaml: helloWorldYaml }],
156
196
  seed: { admin: { externalId: 'admin', password: process.env.ADMIN_PASSWORD } },
157
197
  mcp: { server: { enabled: true }, serverFactories: { 'my-tools': createMyToolsServer } },
158
198
  escalation: { strategy: 'mcp' },
@@ -76,6 +76,7 @@ export declare function createYamlWorkflowDirect(input: {
76
76
  description?: string;
77
77
  yaml_content: string;
78
78
  input_schema?: any;
79
+ output_schema?: any;
79
80
  activity_manifest?: any[];
80
81
  tags?: string[];
81
82
  app_id?: string;
@@ -216,7 +216,7 @@ async function createYamlWorkflow(input) {
216
216
  */
217
217
  async function createYamlWorkflowDirect(input) {
218
218
  try {
219
- const { name, description, yaml_content, input_schema, activity_manifest, tags, app_id, graph_topic } = input;
219
+ const { name, description, yaml_content, input_schema, output_schema, activity_manifest, tags, app_id, graph_topic } = input;
220
220
  if (!name || !yaml_content) {
221
221
  return { status: 400, error: 'name and yaml_content are required' };
222
222
  }
@@ -258,7 +258,7 @@ async function createYamlWorkflowDirect(input) {
258
258
  yaml_content: finalYaml,
259
259
  graph_topic: graphTopic,
260
260
  input_schema: input_schema || {},
261
- output_schema: {},
261
+ output_schema: output_schema || {},
262
262
  activity_manifest: normalizeManifestToolNames(activity_manifest) || [],
263
263
  tags: tags || [],
264
264
  original_prompt: description,
@@ -0,0 +1,50 @@
1
+ -- ─── lt_escalations index audit ────────────────────────────────────────────
2
+ --
3
+ -- Motivation (hotmesh 0.20.0, PR perf/claim-path-hotspots):
4
+ -- Each stream/queue row pays index maintenance on every INSERT and on every
5
+ -- non-HOT UPDATE that touches an indexed column. The HITL claim path is
6
+ -- UPDATE-heavy (claim/resolve/release touch status, assigned_to,
7
+ -- assigned_until, claimed_at, priority, metadata, role — nearly all indexed),
8
+ -- so every claim is a non-HOT update that maintains all 18 btree indexes plus
9
+ -- the metadata GIN. 0.20.0 cut redundant stream-table indexes for exactly this
10
+ -- reason; this migration applies the same discipline to lt_escalations.
11
+ --
12
+ -- Scope: only drop indexes that are PROVABLY redundant — a strict leading-prefix
13
+ -- subset of another index whose partial predicate is no stricter. Anything that
14
+ -- merely "looks" duplicative is left in place and flagged below for EXPLAIN-driven
15
+ -- review against production data, not dropped speculatively.
16
+
17
+ -- 1. idx_lt_escalations_role_type (role, status, type, created_at DESC)
18
+ -- is an exact leading prefix of
19
+ -- idx_lt_escalations_role_subtype (role, status, type, subtype, created_at DESC).
20
+ -- Every query the former can serve (equality/range on role,status,type and the
21
+ -- created_at ordering) is served by the latter scanning the same prefix.
22
+ DROP INDEX IF EXISTS idx_lt_escalations_role_type;
23
+
24
+ -- 2. idx_lt_escalations_origin_id (origin_id) WHERE origin_id IS NOT NULL
25
+ -- is fully covered by idx_lt_escalations_origin (origin_id, created_at DESC):
26
+ -- `origin_id = $1` implies `origin_id IS NOT NULL`, origin_id leads the composite,
27
+ -- and the composite additionally serves the `ORDER BY created_at DESC` used by
28
+ -- GET_ESCALATIONS_BY_ORIGIN_ID. The partial index adds no reachable plan.
29
+ DROP INDEX IF EXISTS idx_lt_escalations_origin_id;
30
+
31
+ -- ── Review candidates (NOT dropped — verify with EXPLAIN on production volume) ──
32
+ --
33
+ -- These overlap but are not provably redundant. Confirm with EXPLAIN (ANALYZE,
34
+ -- BUFFERS) on representative data before removing any of them:
35
+ --
36
+ -- idx_lt_escalations_available (status, role, assigned_until, created_at DESC)
37
+ -- vs idx_lt_escalations_available_v2 (role, priority, created_at DESC)
38
+ -- WHERE status = 'pending'
39
+ -- The "_v2" naming implies intent to supersede v1, but v1 is full-table and
40
+ -- v1 alone positions assigned_until for the available-pool predicate. Confirm
41
+ -- which (if either) the listAvailableEscalations plan actually uses.
42
+ --
43
+ -- idx_lt_escalations_status (status, created_at DESC)
44
+ -- Partially overlaps status-leading composites, but is the only index that
45
+ -- serves `status = $1 ORDER BY created_at DESC` index-ordered for non-pending
46
+ -- statuses. Keep unless EXPLAIN shows it unused.
47
+ --
48
+ -- idx_lt_escalations_priority_desc (priority DESC, created_at DESC)
49
+ -- Backs the user-selectable `sort_by=priority` dashboard sort (SORTABLE_COLUMNS).
50
+ -- Keep while that sort is exposed.
@@ -22,10 +22,8 @@ const logger_1 = require("../lib/logger");
22
22
  const external_server_1 = require("../services/mcp/external-server");
23
23
  const exposure_1 = require("../services/mcp/exposure");
24
24
  const router = (0, express_1.Router)();
25
- // All MCP endpoint requests require authentication
26
- router.use(auth_1.requireAuth);
27
25
  // POST /mcp — JSON-RPC messages
28
- router.post('/', async (req, res) => {
26
+ router.post('/', auth_1.requireAuth, async (req, res) => {
29
27
  try {
30
28
  const exposure = (0, exposure_1.getExposureConfig)();
31
29
  const callerScopes = req.auth?.scopes;
@@ -52,7 +50,7 @@ router.post('/', async (req, res) => {
52
50
  }
53
51
  });
54
52
  // GET /mcp — SSE stream (not supported in stateless mode)
55
- router.get('/', (_req, res) => {
53
+ router.get('/', auth_1.requireAuth, (_req, res) => {
56
54
  res.status(405).json({
57
55
  jsonrpc: '2.0',
58
56
  error: { code: -32000, message: 'Method not allowed. Use POST for stateless requests.' },
@@ -60,7 +58,7 @@ router.get('/', (_req, res) => {
60
58
  });
61
59
  });
62
60
  // DELETE /mcp — session close (not supported in stateless mode)
63
- router.delete('/', (_req, res) => {
61
+ router.delete('/', auth_1.requireAuth, (_req, res) => {
64
62
  res.status(405).json({
65
63
  jsonrpc: '2.0',
66
64
  error: { code: -32000, message: 'Method not allowed. Stateless mode has no sessions.' },
@@ -26,7 +26,7 @@ export declare const FIND_BY_METADATA = "SELECT *, COUNT(*) OVER() AS _total\nFR
26
26
  * $1 = metadata filter (jsonb), $2 = userId, $3 = durationMinutes,
27
27
  * $4 = metadata patch (jsonb, nullable), $5 = allowed roles (text[], null = no filter)
28
28
  */
29
- export declare const CLAIM_BY_METADATA_GUARDED = "WITH target AS (\n SELECT id, assigned_to\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (assigned_to IS NULL OR assigned_until <= NOW() OR assigned_to = $2)\n AND ($5::text[] IS NULL OR role = ANY($5))\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n),\nupdated AS (\n UPDATE lt_escalations e\n SET assigned_to = $2,\n claimed_at = NOW(),\n assigned_until = NOW() + INTERVAL '1 minute' * $3,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END,\n updated_at = NOW()\n FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT *,\n (SELECT COUNT(*) FROM lt_escalations WHERE metadata @> $1::jsonb AND status = 'pending') AS candidates_exist\nFROM updated";
29
+ export declare const CLAIM_BY_METADATA_GUARDED = "WITH target AS MATERIALIZED (\n SELECT id, assigned_to\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (assigned_to IS NULL OR assigned_until <= NOW() OR assigned_to = $2)\n AND ($5::text[] IS NULL OR role = ANY($5))\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n),\nupdated AS (\n UPDATE lt_escalations e\n SET assigned_to = $2,\n claimed_at = NOW(),\n assigned_until = NOW() + INTERVAL '1 minute' * $3,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END,\n updated_at = NOW()\n FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT *,\n (SELECT COUNT(*) FROM lt_escalations WHERE metadata @> $1::jsonb AND status = 'pending') AS candidates_exist\nFROM updated";
30
30
  /**
31
31
  * Atomic resolve by metadata with signal guard.
32
32
  *
@@ -39,4 +39,4 @@ export declare const CLAIM_BY_METADATA_GUARDED = "WITH target AS (\n SELECT id,
39
39
  * $1 = metadata filter (jsonb), $2 = userId, $3 = resolver_payload (jsonb),
40
40
  * $4 = metadata patch (jsonb, nullable), $5 = allowed roles (text[], null = no filter)
41
41
  */
42
- export declare const RESOLVE_BY_METADATA_ATOMIC = "WITH target AS (\n SELECT *\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND ($5::text[] IS NULL OR role = ANY($5))\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE\n),\nclaimed AS (\n UPDATE lt_escalations e\n SET assigned_to = COALESCE(e.assigned_to, $2),\n claimed_at = COALESCE(e.claimed_at, NOW()),\n assigned_until = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.assigned_until\n ELSE NOW() + INTERVAL '5 minutes' END,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END\n FROM target\n WHERE e.id = target.id\n AND (target.metadata->>'signal_id') IS NULL\n RETURNING e.*\n),\nresolved AS (\n UPDATE lt_escalations e\n SET status = 'resolved',\n resolved_at = NOW(),\n resolver_payload = $3,\n updated_at = NOW()\n FROM claimed\n WHERE e.id = claimed.id\n RETURNING e.*\n)\nSELECT\n resolved.*,\n target.id AS target_id,\n target.metadata->>'signal_id' AS signal_id,\n target.workflow_id AS target_workflow_id,\n target.workflow_type AS target_workflow_type,\n target.task_queue AS target_task_queue,\n CASE WHEN resolved.id IS NOT NULL THEN 'resolved' ELSE 'signal_required' END AS outcome\nFROM target\nLEFT JOIN resolved ON resolved.id = target.id";
42
+ export declare const RESOLVE_BY_METADATA_ATOMIC = "WITH target AS MATERIALIZED (\n SELECT *\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND ($5::text[] IS NULL OR role = ANY($5))\n ORDER BY priority ASC, created_at ASC\n LIMIT 1\n FOR UPDATE\n),\nclaimed AS (\n UPDATE lt_escalations e\n SET assigned_to = COALESCE(e.assigned_to, $2),\n claimed_at = COALESCE(e.claimed_at, NOW()),\n assigned_until = CASE\n WHEN e.assigned_to IS NOT NULL AND e.assigned_until > NOW() THEN e.assigned_until\n ELSE NOW() + INTERVAL '5 minutes' END,\n metadata = CASE WHEN $4::jsonb IS NOT NULL\n THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb\n ELSE e.metadata END\n FROM target\n WHERE e.id = target.id\n AND (target.metadata->>'signal_id') IS NULL\n RETURNING e.*\n),\nresolved AS (\n UPDATE lt_escalations e\n SET status = 'resolved',\n resolved_at = NOW(),\n resolver_payload = $3,\n updated_at = NOW()\n FROM claimed\n WHERE e.id = claimed.id\n RETURNING e.*\n)\nSELECT\n resolved.*,\n target.id AS target_id,\n target.metadata->>'signal_id' AS signal_id,\n target.workflow_id AS target_workflow_id,\n target.workflow_type AS target_workflow_type,\n target.task_queue AS target_task_queue,\n CASE WHEN resolved.id IS NOT NULL THEN 'resolved' ELSE 'signal_required' END AS outcome\nFROM target\nLEFT JOIN resolved ON resolved.id = target.id";
@@ -148,7 +148,7 @@ LIMIT $3 OFFSET $4`;
148
148
  * $4 = metadata patch (jsonb, nullable), $5 = allowed roles (text[], null = no filter)
149
149
  */
150
150
  exports.CLAIM_BY_METADATA_GUARDED = `\
151
- WITH target AS (
151
+ WITH target AS MATERIALIZED (
152
152
  SELECT id, assigned_to
153
153
  FROM lt_escalations
154
154
  WHERE metadata @> $1::jsonb
@@ -188,7 +188,7 @@ FROM updated`;
188
188
  * $4 = metadata patch (jsonb, nullable), $5 = allowed roles (text[], null = no filter)
189
189
  */
190
190
  exports.RESOLVE_BY_METADATA_ATOMIC = `\
191
- WITH target AS (
191
+ WITH target AS MATERIALIZED (
192
192
  SELECT *
193
193
  FROM lt_escalations
194
194
  WHERE metadata @> $1::jsonb
@@ -20,7 +20,7 @@ const SYSTEM_TOPICS = [
20
20
  // Task lifecycle
21
21
  {
22
22
  topic: 'system.task.*.created',
23
- description: 'A new task has been created and queued for execution.',
23
+ description: 'A new task has been queued.',
24
24
  category: 'task',
25
25
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string', description: 'Task ID' }, status: STATUS_FIELD, data: { type: 'object', description: 'Task input data' } }),
26
26
  example_payload: { taskId: 'tsk-001', status: 'pending', workflowName: 'processOrder' },
@@ -28,7 +28,7 @@ const SYSTEM_TOPICS = [
28
28
  },
29
29
  {
30
30
  topic: 'system.task.*.started',
31
- description: 'A task has begun execution.',
31
+ description: 'A task has started.',
32
32
  category: 'task',
33
33
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD }),
34
34
  example_payload: { taskId: 'tsk-001', status: 'running', workflowName: 'processOrder' },
@@ -36,7 +36,7 @@ const SYSTEM_TOPICS = [
36
36
  },
37
37
  {
38
38
  topic: 'system.task.*.completed',
39
- description: 'A task has finished successfully.',
39
+ description: 'A task has finished.',
40
40
  category: 'task',
41
41
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD, milestones: { type: 'array', items: { type: 'object' }, description: 'Milestones reported' }, data: { type: 'object', description: 'Task result data' } }),
42
42
  example_payload: { taskId: 'tsk-001', status: 'completed', workflowName: 'processOrder' },
@@ -44,7 +44,7 @@ const SYSTEM_TOPICS = [
44
44
  },
45
45
  {
46
46
  topic: 'system.task.*.escalated',
47
- description: 'A task has been escalated for human review.',
47
+ description: 'A task has been escalated.',
48
48
  category: 'task',
49
49
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object' } }),
50
50
  example_payload: { taskId: 'tsk-001', status: 'escalated', workflowName: 'processOrder' },
@@ -52,7 +52,7 @@ const SYSTEM_TOPICS = [
52
52
  },
53
53
  {
54
54
  topic: 'system.task.*.failed',
55
- description: 'A task has failed execution.',
55
+ description: 'A task has failed.',
56
56
  category: 'task',
57
57
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object', description: 'Error details' } }),
58
58
  example_payload: { taskId: 'tsk-001', status: 'failed', workflowName: 'processOrder' },
@@ -61,7 +61,7 @@ const SYSTEM_TOPICS = [
61
61
  // Workflow lifecycle
62
62
  {
63
63
  topic: 'system.workflow.*.started',
64
- description: 'A workflow execution has started.',
64
+ description: 'A workflow has started.',
65
65
  category: 'workflow',
66
66
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD }),
67
67
  example_payload: { workflowId: 'wf-abc', workflowName: 'processOrder', status: 'running' },
@@ -69,7 +69,7 @@ const SYSTEM_TOPICS = [
69
69
  },
70
70
  {
71
71
  topic: 'system.workflow.*.completed',
72
- description: 'A workflow execution has completed successfully.',
72
+ description: 'A workflow has completed.',
73
73
  category: 'workflow',
74
74
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object' } }),
75
75
  example_payload: { workflowId: 'wf-abc', workflowName: 'processOrder', status: 'completed' },
@@ -77,7 +77,7 @@ const SYSTEM_TOPICS = [
77
77
  },
78
78
  {
79
79
  topic: 'system.workflow.*.failed',
80
- description: 'A workflow execution has failed.',
80
+ description: 'A workflow has failed.',
81
81
  category: 'workflow',
82
82
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, taskId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object', description: 'Error details' } }),
83
83
  example_payload: { workflowId: 'wf-abc', workflowName: 'processOrder', status: 'failed' },
@@ -86,7 +86,7 @@ const SYSTEM_TOPICS = [
86
86
  // Escalation lifecycle
87
87
  {
88
88
  topic: 'system.escalation.*.created',
89
- description: 'A new escalation has been created for human review.',
89
+ description: 'An escalation has been created.',
90
90
  category: 'escalation',
91
91
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, escalationId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object' } }),
92
92
  example_payload: { escalationId: 'esc-001', status: 'pending', workflowName: 'processOrder' },
@@ -94,7 +94,7 @@ const SYSTEM_TOPICS = [
94
94
  },
95
95
  {
96
96
  topic: 'system.escalation.*.resolved',
97
- description: 'An escalation has been resolved by a human operator.',
97
+ description: 'An escalation has been resolved.',
98
98
  category: 'escalation',
99
99
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, escalationId: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object' } }),
100
100
  example_payload: { escalationId: 'esc-001', status: 'resolved', workflowName: 'processOrder' },
@@ -102,7 +102,7 @@ const SYSTEM_TOPICS = [
102
102
  },
103
103
  {
104
104
  topic: 'system.escalation.*.claimed',
105
- description: 'An escalation has been claimed by an operator.',
105
+ description: 'An escalation has been claimed.',
106
106
  category: 'escalation',
107
107
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, escalationId: { type: 'string' }, status: STATUS_FIELD }),
108
108
  example_payload: { escalationId: 'esc-001', status: 'claimed' },
@@ -110,7 +110,7 @@ const SYSTEM_TOPICS = [
110
110
  },
111
111
  {
112
112
  topic: 'system.escalation.*.released',
113
- description: 'An escalation has been released back to the queue.',
113
+ description: 'An escalation has been returned to the queue.',
114
114
  category: 'escalation',
115
115
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, escalationId: { type: 'string' }, status: STATUS_FIELD }),
116
116
  example_payload: { escalationId: 'esc-001', status: 'pending' },
@@ -119,32 +119,32 @@ const SYSTEM_TOPICS = [
119
119
  // Activity lifecycle
120
120
  {
121
121
  topic: 'system.activity.*.*.started',
122
- description: 'A YAML workflow activity step has started.',
122
+ description: 'A workflow activity has started.',
123
123
  category: 'activity',
124
124
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, activityName: { type: 'string', description: 'Activity step name' } }),
125
125
  example_payload: { workflowId: 'wf-abc', activityName: 'fetchOrder', workflowName: 'processOrder' },
126
- tags: ['lifecycle', 'yaml'],
126
+ tags: ['lifecycle', 'graph'],
127
127
  },
128
128
  {
129
129
  topic: 'system.activity.*.*.completed',
130
- description: 'A YAML workflow activity step has completed.',
130
+ description: 'A workflow activity has completed.',
131
131
  category: 'activity',
132
132
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, activityName: { type: 'string' }, data: { type: 'object' } }),
133
133
  example_payload: { workflowId: 'wf-abc', activityName: 'fetchOrder', workflowName: 'processOrder' },
134
- tags: ['lifecycle', 'yaml'],
134
+ tags: ['lifecycle', 'graph'],
135
135
  },
136
136
  {
137
137
  topic: 'system.activity.*.*.failed',
138
- description: 'A YAML workflow activity step has failed.',
138
+ description: 'A workflow activity has failed.',
139
139
  category: 'activity',
140
140
  payload_schema: objectSchema({ ...WORKFLOW_CONTEXT_PROPS, activityName: { type: 'string' }, data: { type: 'object', description: 'Error details' } }),
141
141
  example_payload: { workflowId: 'wf-abc', activityName: 'fetchOrder', workflowName: 'processOrder' },
142
- tags: ['lifecycle', 'yaml', 'error'],
142
+ tags: ['lifecycle', 'graph', 'error'],
143
143
  },
144
144
  // Knowledge lifecycle
145
145
  {
146
146
  topic: 'system.knowledge.*.stored',
147
- description: 'A knowledge entry has been written to the knowledge store.',
147
+ description: 'A knowledge entry has been saved.',
148
148
  category: 'knowledge',
149
149
  payload_schema: objectSchema({ domain: { type: 'string', description: 'Knowledge domain' }, key: { type: 'string', description: 'Knowledge entry key' } }),
150
150
  example_payload: { domain: 'orders', key: 'order-12345' },
@@ -152,7 +152,7 @@ const SYSTEM_TOPICS = [
152
152
  },
153
153
  {
154
154
  topic: 'system.knowledge.*.deleted',
155
- description: 'A knowledge entry has been removed from the knowledge store.',
155
+ description: 'A knowledge entry has been deleted.',
156
156
  category: 'knowledge',
157
157
  payload_schema: objectSchema({ domain: { type: 'string', description: 'Knowledge domain' }, key: { type: 'string', description: 'Knowledge entry key' } }),
158
158
  example_payload: { domain: 'orders', key: 'order-12345' },
@@ -161,7 +161,7 @@ const SYSTEM_TOPICS = [
161
161
  // File storage
162
162
  {
163
163
  topic: 'system.file.stored',
164
- description: 'A file has been written to storage.',
164
+ description: 'A file has been saved to storage.',
165
165
  category: 'file',
166
166
  payload_schema: objectSchema({
167
167
  path: { type: 'string', description: 'File path in storage' },
@@ -176,7 +176,7 @@ const SYSTEM_TOPICS = [
176
176
  },
177
177
  {
178
178
  topic: 'system.file.deleted',
179
- description: 'A file has been removed from storage.',
179
+ description: 'A file has been deleted from storage.',
180
180
  category: 'file',
181
181
  payload_schema: objectSchema({
182
182
  path: { type: 'string', description: 'File path in storage' },
@@ -190,7 +190,7 @@ const SYSTEM_TOPICS = [
190
190
  // Agent lifecycle
191
191
  {
192
192
  topic: 'system.agent.*.started',
193
- description: 'An agent reaction workflow has started in response to an event.',
193
+ description: 'An agent automation has started in response to an event.',
194
194
  category: 'agent',
195
195
  payload_schema: objectSchema({ agentId: { type: 'string', description: 'Agent ID' }, agentName: { type: 'string', description: 'Agent name' }, status: STATUS_FIELD, data: { type: 'object', description: 'Trigger context' } }),
196
196
  example_payload: { agentId: 'agt-001', agentName: 'error-handler', status: 'running' },
@@ -198,7 +198,7 @@ const SYSTEM_TOPICS = [
198
198
  },
199
199
  {
200
200
  topic: 'system.agent.*.completed',
201
- description: 'An agent reaction workflow has completed successfully.',
201
+ description: 'An agent automation has completed.',
202
202
  category: 'agent',
203
203
  payload_schema: objectSchema({ agentId: { type: 'string' }, agentName: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object' } }),
204
204
  example_payload: { agentId: 'agt-001', agentName: 'error-handler', status: 'completed' },
@@ -206,7 +206,7 @@ const SYSTEM_TOPICS = [
206
206
  },
207
207
  {
208
208
  topic: 'system.agent.*.failed',
209
- description: 'An agent reaction workflow has failed.',
209
+ description: 'An agent automation has failed.',
210
210
  category: 'agent',
211
211
  payload_schema: objectSchema({ agentId: { type: 'string' }, agentName: { type: 'string' }, status: STATUS_FIELD, data: { type: 'object', description: 'Error details' } }),
212
212
  example_payload: { agentId: 'agt-001', agentName: 'error-handler', status: 'failed' },
@@ -214,7 +214,7 @@ const SYSTEM_TOPICS = [
214
214
  },
215
215
  {
216
216
  topic: 'system.agent.*.status_changed',
217
- description: 'An agent\'s status has changed (activated, paused, errored).',
217
+ description: 'An agent automation\'s status has changed.',
218
218
  category: 'agent',
219
219
  payload_schema: objectSchema({ agentId: { type: 'string' }, agentName: { type: 'string' }, status: STATUS_FIELD }),
220
220
  example_payload: { agentId: 'agt-001', agentName: 'error-handler', status: 'active' },
@@ -223,7 +223,7 @@ const SYSTEM_TOPICS = [
223
223
  // Milestone
224
224
  {
225
225
  topic: 'system.milestone.*',
226
- description: 'A workflow or activity has reported progress milestones.',
226
+ description: 'A workflow or workflow activity has reported progress.',
227
227
  category: 'milestone',
228
228
  payload_schema: objectSchema({
229
229
  ...WORKFLOW_CONTEXT_PROPS,
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.invokeYamlWorkflow = invokeYamlWorkflow;
37
37
  const yamlDeployer = __importStar(require("./deployer"));
38
38
  const principal_1 = require("../iam/principal");
39
+ const publish_1 = require("../../lib/events/publish");
39
40
  /**
40
41
  * Invoke a YAML workflow with scope injection.
41
42
  * Shared by HTTP route and cron callback.
@@ -71,14 +72,84 @@ async function invokeYamlWorkflow(wf, options = {}) {
71
72
  data._metadata = {};
72
73
  data._metadata.source = options.source;
73
74
  }
74
- // Build context with deterministic job ID when provided (agent subscriptions)
75
- const context = options.jobId
76
- ? { metadata: { jid: options.jobId } }
77
- : undefined;
75
+ const wfMeta = {
76
+ workflowName: wf.graph_topic,
77
+ taskQueue: wf.app_id,
78
+ };
78
79
  if (options.sync) {
79
- const { job_id, result } = await yamlDeployer.invokeYamlWorkflowSync(wf.app_id, wf.graph_topic, data, options.timeout, wf.graph_topic);
80
- return { job_id, result };
80
+ (0, publish_1.publishWorkflowEvent)({
81
+ type: 'workflow.started',
82
+ source: 'graph',
83
+ workflowId: options.jobId || wf.graph_topic,
84
+ ...wfMeta,
85
+ status: 'running',
86
+ });
87
+ try {
88
+ const { job_id, result } = await yamlDeployer.invokeYamlWorkflowSync(wf.app_id, wf.graph_topic, data, options.timeout, wf.graph_topic);
89
+ (0, publish_1.publishWorkflowEvent)({
90
+ type: 'workflow.completed',
91
+ source: 'graph',
92
+ workflowId: job_id,
93
+ ...wfMeta,
94
+ status: 'completed',
95
+ data: typeof result === 'object' && result !== null ? result : undefined,
96
+ });
97
+ return { job_id, result };
98
+ }
99
+ catch (err) {
100
+ (0, publish_1.publishWorkflowEvent)({
101
+ type: 'workflow.failed',
102
+ source: 'graph',
103
+ workflowId: options.jobId || wf.graph_topic,
104
+ ...wfMeta,
105
+ status: 'failed',
106
+ data: { error: err?.message ?? String(err) },
107
+ });
108
+ throw err;
109
+ }
81
110
  }
111
+ // Async path — include ngn so HotMesh routes the completion reply back to
112
+ // this engine instance, enabling fire-and-forget lifecycle event tracking.
113
+ const engine = await yamlDeployer.getEngine(wf.app_id);
114
+ const internalEngine = engine.engine;
115
+ const ngn = internalEngine?.guid;
116
+ const context = (options.jobId || ngn)
117
+ ? {
118
+ metadata: {
119
+ ...(options.jobId ? { jid: options.jobId } : {}),
120
+ ...(ngn ? { ngn } : {}),
121
+ },
122
+ }
123
+ : undefined;
82
124
  const jobId = await yamlDeployer.invokeYamlWorkflow(wf.app_id, wf.graph_topic, data, wf.graph_topic, context);
125
+ (0, publish_1.publishWorkflowEvent)({
126
+ type: 'workflow.started',
127
+ source: 'graph',
128
+ workflowId: jobId,
129
+ ...wfMeta,
130
+ status: 'running',
131
+ });
132
+ // Register a best-effort completion callback. Fires when HotMesh routes the
133
+ // job reply back to this engine (requires ngn set above). Cleans itself up
134
+ // after 5 minutes regardless so there is no unbounded callback accumulation.
135
+ if (ngn && internalEngine?.registerJobCallback) {
136
+ const timeoutMs = 5 * 60_000;
137
+ const timer = setTimeout(() => internalEngine.delistJobCallback?.(jobId), timeoutMs);
138
+ internalEngine.registerJobCallback(jobId, (_topic, output) => {
139
+ clearTimeout(timer);
140
+ internalEngine.delistJobCallback?.(jobId);
141
+ const failed = !!output?.metadata?.err;
142
+ (0, publish_1.publishWorkflowEvent)({
143
+ type: failed ? 'workflow.failed' : 'workflow.completed',
144
+ source: 'graph',
145
+ workflowId: jobId,
146
+ ...wfMeta,
147
+ status: failed ? 'failed' : 'completed',
148
+ data: failed
149
+ ? { error: output.metadata.err }
150
+ : (output?.data && typeof output.data === 'object' ? output.data : undefined),
151
+ });
152
+ });
153
+ }
83
154
  return { job_id: jobId };
84
155
  }
@@ -0,0 +1,14 @@
1
+ import type { LTGraphWorkflowConfig } from '../types/startup';
2
+ /**
3
+ * Register declarative graph (YAML/DAG) workflows at startup — the graph-form
4
+ * peer of durable `workers`. Each flow is created insert-if-absent, then
5
+ * deployed + activated through the same path the dashboard uses.
6
+ *
7
+ * On a re-boot where the flow already exists:
8
+ * - description and output_schema are synced if stale
9
+ * - when the YAML version bumps, yaml_content is updated and the flow is redeployed
10
+ *
11
+ * Per-flow failures are logged and skipped so a single malformed flow can never
12
+ * block boot.
13
+ */
14
+ export declare function seedGraphWorkflows(configs: LTGraphWorkflowConfig[]): Promise<void>;