@hotmeshio/long-tail 0.4.14 → 0.4.16

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 (186) hide show
  1. package/build/adapters/express.js +14 -0
  2. package/build/api/escalations/claim.js +1 -10
  3. package/build/api/escalations/create.js +1 -11
  4. package/build/api/escalations/metadata.d.ts +2 -0
  5. package/build/api/escalations/metadata.js +6 -12
  6. package/build/api/escalations/resolve.js +4 -23
  7. package/build/api/settings.js +5 -6
  8. package/build/bin/ltc.js +2 -0
  9. package/build/index.js +2 -2
  10. package/build/lib/cli/commands/escalations.d.ts +2 -0
  11. package/build/lib/cli/commands/escalations.js +4 -0
  12. package/build/lib/events/nats-ws-proxy.d.ts +19 -0
  13. package/build/lib/events/nats-ws-proxy.js +68 -0
  14. package/build/lib/events/nats.d.ts +16 -0
  15. package/build/lib/events/nats.js +23 -1
  16. package/build/lib/events/publish.js +2 -0
  17. package/build/modules/config.d.ts +3 -0
  18. package/build/modules/config.js +3 -0
  19. package/build/routes/escalations/metadata.js +4 -2
  20. package/build/routes/nats-credentials.js +4 -4
  21. package/build/sdk/index.d.ts +2 -0
  22. package/build/services/escalation/crud.d.ts +1 -1
  23. package/build/services/escalation/crud.js +56 -6
  24. package/build/services/escalation/sql.d.ts +2 -2
  25. package/build/services/escalation/sql.js +5 -2
  26. package/build/services/interceptor/activities/escalation.js +1 -11
  27. package/build/services/interceptor/activities/task.js +2 -23
  28. package/build/services/interceptor/completion.js +2 -22
  29. package/build/services/interceptor/escalation.js +5 -44
  30. package/build/services/interceptor/index.js +26 -2
  31. package/build/services/interceptor/lifecycle.d.ts +1 -1
  32. package/build/services/interceptor/lifecycle.js +18 -32
  33. package/build/services/task/crud.js +36 -2
  34. package/build/start/index.js +14 -0
  35. package/build/tsconfig.tsbuildinfo +1 -1
  36. package/build/types/startup.d.ts +3 -0
  37. package/dashboard/dist/assets/{AdminDashboard-BuqyRY2r.js → AdminDashboard-Cfo0mwL2.js} +2 -2
  38. package/dashboard/dist/assets/{AdminDashboard-BuqyRY2r.js.map → AdminDashboard-Cfo0mwL2.js.map} +1 -1
  39. package/dashboard/dist/assets/{AgentConfigPage-Bum1dUIi.js → AgentConfigPage-DBtvb2x5.js} +2 -2
  40. package/dashboard/dist/assets/{AgentConfigPage-Bum1dUIi.js.map → AgentConfigPage-DBtvb2x5.js.map} +1 -1
  41. package/dashboard/dist/assets/{AgentDetailPage-0Kq-tBF2.js → AgentDetailPage-3mZA7SOb.js} +2 -2
  42. package/dashboard/dist/assets/{AgentDetailPage-0Kq-tBF2.js.map → AgentDetailPage-3mZA7SOb.js.map} +1 -1
  43. package/dashboard/dist/assets/{AgentsPage-B5gYDSOX.js → AgentsPage-CTVocfBb.js} +2 -2
  44. package/dashboard/dist/assets/{AgentsPage-B5gYDSOX.js.map → AgentsPage-CTVocfBb.js.map} +1 -1
  45. package/dashboard/dist/assets/{AvailableEscalationsPage-BWHThQDC.js → AvailableEscalationsPage-CA9x9o5s.js} +2 -2
  46. package/dashboard/dist/assets/{AvailableEscalationsPage-BWHThQDC.js.map → AvailableEscalationsPage-CA9x9o5s.js.map} +1 -1
  47. package/dashboard/dist/assets/{BotPicker-BQ336piW.js → BotPicker-BQp_Vs73.js} +2 -2
  48. package/dashboard/dist/assets/{BotPicker-BQ336piW.js.map → BotPicker-BQp_Vs73.js.map} +1 -1
  49. package/dashboard/dist/assets/{CapabilitiesPage-CkiJROX-.js → CapabilitiesPage-wpVtkGeU.js} +2 -2
  50. package/dashboard/dist/assets/{CapabilitiesPage-CkiJROX-.js.map → CapabilitiesPage-wpVtkGeU.js.map} +1 -1
  51. package/dashboard/dist/assets/{CollapsibleSection-SM8_UjNe.js → CollapsibleSection-2eZMMZiG.js} +2 -2
  52. package/dashboard/dist/assets/{CollapsibleSection-SM8_UjNe.js.map → CollapsibleSection-2eZMMZiG.js.map} +1 -1
  53. package/dashboard/dist/assets/{CredentialsPage-f6niro9_.js → CredentialsPage-DJGLssm0.js} +2 -2
  54. package/dashboard/dist/assets/{CredentialsPage-f6niro9_.js.map → CredentialsPage-DJGLssm0.js.map} +1 -1
  55. package/dashboard/dist/assets/{CronLabel-DINmdqoe.js → CronLabel-DY8VdTS9.js} +2 -2
  56. package/dashboard/dist/assets/{CronLabel-DINmdqoe.js.map → CronLabel-DY8VdTS9.js.map} +1 -1
  57. package/dashboard/dist/assets/{CustomDurationPicker-BCUcYxfB.js → CustomDurationPicker-DbyqfK35.js} +2 -2
  58. package/dashboard/dist/assets/{CustomDurationPicker-BCUcYxfB.js.map → CustomDurationPicker-DbyqfK35.js.map} +1 -1
  59. package/dashboard/dist/assets/{ElapsedCell-DPYZnXsX.js → ElapsedCell-BPYm8RA7.js} +2 -2
  60. package/dashboard/dist/assets/{ElapsedCell-DPYZnXsX.js.map → ElapsedCell-BPYm8RA7.js.map} +1 -1
  61. package/dashboard/dist/assets/{EscalationsOverview-CTB8AEBd.js → EscalationsOverview-kYGHfnLf.js} +2 -2
  62. package/dashboard/dist/assets/{EscalationsOverview-CTB8AEBd.js.map → EscalationsOverview-kYGHfnLf.js.map} +1 -1
  63. package/dashboard/dist/assets/{EventTable-8_r3Tg09.js → EventTable-DSDzJMer.js} +2 -2
  64. package/dashboard/dist/assets/{EventTable-8_r3Tg09.js.map → EventTable-DSDzJMer.js.map} +1 -1
  65. package/dashboard/dist/assets/{HomePage-Bjxnjv6p.js → HomePage-CwRebzmO.js} +2 -2
  66. package/dashboard/dist/assets/{HomePage-Bjxnjv6p.js.map → HomePage-CwRebzmO.js.map} +1 -1
  67. package/dashboard/dist/assets/{ListToolbar-B60JrvJ9.js → ListToolbar-DEef1_-T.js} +2 -2
  68. package/dashboard/dist/assets/{ListToolbar-B60JrvJ9.js.map → ListToolbar-DEef1_-T.js.map} +1 -1
  69. package/dashboard/dist/assets/{McpOverview-whVRP_Nj.js → McpOverview-CZFW5qMb.js} +2 -2
  70. package/dashboard/dist/assets/{McpOverview-whVRP_Nj.js.map → McpOverview-CZFW5qMb.js.map} +1 -1
  71. package/dashboard/dist/assets/{McpQueryDetailPage-DPuujJkH.js → McpQueryDetailPage-q9xH-QRo.js} +2 -2
  72. package/dashboard/dist/assets/{McpQueryDetailPage-DPuujJkH.js.map → McpQueryDetailPage-q9xH-QRo.js.map} +1 -1
  73. package/dashboard/dist/assets/{McpQueryPage-DciK6r7r.js → McpQueryPage-D14466yi.js} +2 -2
  74. package/dashboard/dist/assets/{McpQueryPage-DciK6r7r.js.map → McpQueryPage-D14466yi.js.map} +1 -1
  75. package/dashboard/dist/assets/{McpRunDetailPage-QEz8BCTu.js → McpRunDetailPage-X0sfRFTk.js} +2 -2
  76. package/dashboard/dist/assets/{McpRunDetailPage-QEz8BCTu.js.map → McpRunDetailPage-X0sfRFTk.js.map} +1 -1
  77. package/dashboard/dist/assets/{McpRunsPage-BA6AVpi_.js → McpRunsPage-aZg057y3.js} +2 -2
  78. package/dashboard/dist/assets/{McpRunsPage-BA6AVpi_.js.map → McpRunsPage-aZg057y3.js.map} +1 -1
  79. package/dashboard/dist/assets/{OperatorDashboard-DrUMzwnl.js → OperatorDashboard-iZEHnndU.js} +2 -2
  80. package/dashboard/dist/assets/{OperatorDashboard-DrUMzwnl.js.map → OperatorDashboard-iZEHnndU.js.map} +1 -1
  81. package/dashboard/dist/assets/{ProcessDetailPage-Dc5ASJpQ.js → ProcessDetailPage-DyzNjwu8.js} +2 -2
  82. package/dashboard/dist/assets/{ProcessDetailPage-Dc5ASJpQ.js.map → ProcessDetailPage-DyzNjwu8.js.map} +1 -1
  83. package/dashboard/dist/assets/{ProcessesListPage-Sa-bjC-g.js → ProcessesListPage-CT_3b5Wt.js} +2 -2
  84. package/dashboard/dist/assets/{ProcessesListPage-Sa-bjC-g.js.map → ProcessesListPage-CT_3b5Wt.js.map} +1 -1
  85. package/dashboard/dist/assets/{RolesPage-DmO8Jlbw.js → RolesPage-CpRJq-sg.js} +2 -2
  86. package/dashboard/dist/assets/{RolesPage-DmO8Jlbw.js.map → RolesPage-CpRJq-sg.js.map} +1 -1
  87. package/dashboard/dist/assets/{RunAsSelector-yWEwIZRe.js → RunAsSelector-C20rdNsC.js} +2 -2
  88. package/dashboard/dist/assets/{RunAsSelector-yWEwIZRe.js.map → RunAsSelector-C20rdNsC.js.map} +1 -1
  89. package/dashboard/dist/assets/{SwimlaneTimeline-CmzfFQ09.js → SwimlaneTimeline-CbFaU4bq.js} +2 -2
  90. package/dashboard/dist/assets/{SwimlaneTimeline-CmzfFQ09.js.map → SwimlaneTimeline-CbFaU4bq.js.map} +1 -1
  91. package/dashboard/dist/assets/{TaskDetailPage-CI4JTC62.js → TaskDetailPage-22cJsFmM.js} +2 -2
  92. package/dashboard/dist/assets/{TaskDetailPage-CI4JTC62.js.map → TaskDetailPage-22cJsFmM.js.map} +1 -1
  93. package/dashboard/dist/assets/{TasksListPage-xdNmQsNE.js → TasksListPage-BDmaUIKu.js} +2 -2
  94. package/dashboard/dist/assets/{TasksListPage-xdNmQsNE.js.map → TasksListPage-BDmaUIKu.js.map} +1 -1
  95. package/dashboard/dist/assets/{TimeAgo-B_um9BWR.js → TimeAgo-7wqEp87-.js} +2 -2
  96. package/dashboard/dist/assets/{TimeAgo-B_um9BWR.js.map → TimeAgo-7wqEp87-.js.map} +1 -1
  97. package/dashboard/dist/assets/{TimestampCell-BJ6trAqW.js → TimestampCell-BBCf8zsN.js} +2 -2
  98. package/dashboard/dist/assets/{TimestampCell-BJ6trAqW.js.map → TimestampCell-BBCf8zsN.js.map} +1 -1
  99. package/dashboard/dist/assets/{ToolTestPanel-DMQhLDES.js → ToolTestPanel-Dosq1cqG.js} +2 -2
  100. package/dashboard/dist/assets/{ToolTestPanel-DMQhLDES.js.map → ToolTestPanel-Dosq1cqG.js.map} +1 -1
  101. package/dashboard/dist/assets/{TopicDetailPage-YeGQA0vD.js → TopicDetailPage-DW97-YHQ.js} +2 -2
  102. package/dashboard/dist/assets/{TopicDetailPage-YeGQA0vD.js.map → TopicDetailPage-DW97-YHQ.js.map} +1 -1
  103. package/dashboard/dist/assets/{TopicsPage-B3QZNlWz.js → TopicsPage-tVPdz-k0.js} +2 -2
  104. package/dashboard/dist/assets/{TopicsPage-B3QZNlWz.js.map → TopicsPage-tVPdz-k0.js.map} +1 -1
  105. package/dashboard/dist/assets/{UserName-MpSZ2_EH.js → UserName-DX7IBjFn.js} +2 -2
  106. package/dashboard/dist/assets/{UserName-MpSZ2_EH.js.map → UserName-DX7IBjFn.js.map} +1 -1
  107. package/dashboard/dist/assets/{WorkflowExecutionPage-DqMqDb1h.js → WorkflowExecutionPage-BjC0j9_L.js} +2 -2
  108. package/dashboard/dist/assets/{WorkflowExecutionPage-DqMqDb1h.js.map → WorkflowExecutionPage-BjC0j9_L.js.map} +1 -1
  109. package/dashboard/dist/assets/{WorkflowsDashboard-BF7FpMmk.js → WorkflowsDashboard-eCH4gpAk.js} +2 -2
  110. package/dashboard/dist/assets/{WorkflowsDashboard-BF7FpMmk.js.map → WorkflowsDashboard-eCH4gpAk.js.map} +1 -1
  111. package/dashboard/dist/assets/{WorkflowsOverview-YFc_KBMS.js → WorkflowsOverview-DaJRDkNy.js} +2 -2
  112. package/dashboard/dist/assets/{WorkflowsOverview-YFc_KBMS.js.map → WorkflowsOverview-DaJRDkNy.js.map} +1 -1
  113. package/dashboard/dist/assets/{YamlWorkflowsPage-BOLs5KTB.js → YamlWorkflowsPage-CkpQaUmz.js} +2 -2
  114. package/dashboard/dist/assets/{YamlWorkflowsPage-BOLs5KTB.js.map → YamlWorkflowsPage-CkpQaUmz.js.map} +1 -1
  115. package/dashboard/dist/assets/{agents-CPYVSCQ3.js → agents-B-P5MlEx.js} +2 -2
  116. package/dashboard/dist/assets/{agents-CPYVSCQ3.js.map → agents-B-P5MlEx.js.map} +1 -1
  117. package/dashboard/dist/assets/{bots-DCXjHjID.js → bots-CZz9iVys.js} +2 -2
  118. package/dashboard/dist/assets/{bots-DCXjHjID.js.map → bots-CZz9iVys.js.map} +1 -1
  119. package/dashboard/dist/assets/{capabilities-CreogBYU.js → capabilities-DrZ8Vw_v.js} +2 -2
  120. package/dashboard/dist/assets/{capabilities-CreogBYU.js.map → capabilities-DrZ8Vw_v.js.map} +1 -1
  121. package/dashboard/dist/assets/{controlplane-Cm_-Gb1x.js → controlplane-cj-1c-1C.js} +2 -2
  122. package/dashboard/dist/assets/{controlplane-Cm_-Gb1x.js.map → controlplane-cj-1c-1C.js.map} +1 -1
  123. package/dashboard/dist/assets/{escalation-ulsBFHVb.js → escalation-BEVFyQnE.js} +2 -2
  124. package/dashboard/dist/assets/{escalation-ulsBFHVb.js.map → escalation-BEVFyQnE.js.map} +1 -1
  125. package/dashboard/dist/assets/{escalation-columns-CLqe28Ba.js → escalation-columns-Beox3TXH.js} +2 -2
  126. package/dashboard/dist/assets/{escalation-columns-CLqe28Ba.js.map → escalation-columns-Beox3TXH.js.map} +1 -1
  127. package/dashboard/dist/assets/{helpers-etjHeZEI.js → helpers-B4gzNq9h.js} +2 -2
  128. package/dashboard/dist/assets/{helpers-etjHeZEI.js.map → helpers-B4gzNq9h.js.map} +1 -1
  129. package/dashboard/dist/assets/{index-BkOv2dQA.js → index-3n5VREXN.js} +2 -2
  130. package/dashboard/dist/assets/{index-BkOv2dQA.js.map → index-3n5VREXN.js.map} +1 -1
  131. package/dashboard/dist/assets/{index-CKDOaej4.js → index-BAXzN-QB.js} +2 -2
  132. package/dashboard/dist/assets/{index-CKDOaej4.js.map → index-BAXzN-QB.js.map} +1 -1
  133. package/dashboard/dist/assets/{index-DVqtJBno.js → index-BCQ65lNu.js} +2 -2
  134. package/dashboard/dist/assets/{index-DVqtJBno.js.map → index-BCQ65lNu.js.map} +1 -1
  135. package/dashboard/dist/assets/{index-BkCkBW_D.js → index-BYXiz05a.js} +2 -2
  136. package/dashboard/dist/assets/{index-BkCkBW_D.js.map → index-BYXiz05a.js.map} +1 -1
  137. package/dashboard/dist/assets/{index-CcvHiZW-.js → index-Bh-PnP17.js} +2 -2
  138. package/dashboard/dist/assets/{index-CcvHiZW-.js.map → index-Bh-PnP17.js.map} +1 -1
  139. package/dashboard/dist/assets/{index-DYmrNJ_H.js → index-BpN31nuC.js} +17 -17
  140. package/dashboard/dist/assets/index-BpN31nuC.js.map +1 -0
  141. package/dashboard/dist/assets/{index-DT68ewTC.js → index-C5dHozmW.js} +2 -2
  142. package/dashboard/dist/assets/{index-DT68ewTC.js.map → index-C5dHozmW.js.map} +1 -1
  143. package/dashboard/dist/assets/{index-7Fbktqcl.js → index-D1MywQ2z.js} +2 -2
  144. package/dashboard/dist/assets/{index-7Fbktqcl.js.map → index-D1MywQ2z.js.map} +1 -1
  145. package/dashboard/dist/assets/{index-Cnpo94XG.js → index-D4KGadbW.js} +2 -2
  146. package/dashboard/dist/assets/{index-Cnpo94XG.js.map → index-D4KGadbW.js.map} +1 -1
  147. package/dashboard/dist/assets/{index-DT0JeuiL.js → index-DdKbIZNE.js} +2 -2
  148. package/dashboard/dist/assets/{index-DT0JeuiL.js.map → index-DdKbIZNE.js.map} +1 -1
  149. package/dashboard/dist/assets/{index-DFuHrLll.js → index-UtAfnStw.js} +2 -2
  150. package/dashboard/dist/assets/{index-DFuHrLll.js.map → index-UtAfnStw.js.map} +1 -1
  151. package/dashboard/dist/assets/{index-DGpIF_Td.js → index-_DfbFHXk.js} +2 -2
  152. package/dashboard/dist/assets/{index-DGpIF_Td.js.map → index-_DfbFHXk.js.map} +1 -1
  153. package/dashboard/dist/assets/{index-CihScSLF.js → index-aJRDh4zW.js} +2 -2
  154. package/dashboard/dist/assets/{index-CihScSLF.js.map → index-aJRDh4zW.js.map} +1 -1
  155. package/dashboard/dist/assets/{knowledge-CXA2DJwY.js → knowledge-DhtKWMON.js} +2 -2
  156. package/dashboard/dist/assets/{knowledge-CXA2DJwY.js.map → knowledge-DhtKWMON.js.map} +1 -1
  157. package/dashboard/dist/assets/{mcp-DeC-PpeL.js → mcp-BXN7-wGF.js} +2 -2
  158. package/dashboard/dist/assets/{mcp-DeC-PpeL.js.map → mcp-BXN7-wGF.js.map} +1 -1
  159. package/dashboard/dist/assets/{mcp-query-DldD_RPZ.js → mcp-query-BIJP4mQJ.js} +2 -2
  160. package/dashboard/dist/assets/{mcp-query-DldD_RPZ.js.map → mcp-query-BIJP4mQJ.js.map} +1 -1
  161. package/dashboard/dist/assets/{namespaces-BIGZ6exX.js → namespaces-ne_yDQZX.js} +2 -2
  162. package/dashboard/dist/assets/{namespaces-BIGZ6exX.js.map → namespaces-ne_yDQZX.js.map} +1 -1
  163. package/dashboard/dist/assets/{pipelines-BtihifKT.js → pipelines-Bcz62DoS.js} +2 -2
  164. package/dashboard/dist/assets/{pipelines-BtihifKT.js.map → pipelines-Bcz62DoS.js.map} +1 -1
  165. package/dashboard/dist/assets/{roles-4DocbpKy.js → roles-De2CzGCy.js} +2 -2
  166. package/dashboard/dist/assets/{roles-4DocbpKy.js.map → roles-De2CzGCy.js.map} +1 -1
  167. package/dashboard/dist/assets/{tasks-B9P_7SR_.js → tasks-4yL5EfxI.js} +2 -2
  168. package/dashboard/dist/assets/{tasks-B9P_7SR_.js.map → tasks-4yL5EfxI.js.map} +1 -1
  169. package/dashboard/dist/assets/{topics-CcLT-IrY.js → topics-DDKHpRwP.js} +2 -2
  170. package/dashboard/dist/assets/{topics-CcLT-IrY.js.map → topics-DDKHpRwP.js.map} +1 -1
  171. package/dashboard/dist/assets/{useEventHooks-B9UOxef_.js → useEventHooks-NzIyvoGY.js} +2 -2
  172. package/dashboard/dist/assets/{useEventHooks-B9UOxef_.js.map → useEventHooks-NzIyvoGY.js.map} +1 -1
  173. package/dashboard/dist/assets/{useYamlActivityEvents-V_MENSI5.js → useYamlActivityEvents-Dv6GhDkh.js} +2 -2
  174. package/dashboard/dist/assets/{useYamlActivityEvents-V_MENSI5.js.map → useYamlActivityEvents-Dv6GhDkh.js.map} +1 -1
  175. package/dashboard/dist/assets/{users-BHF3YOU1.js → users-pSMWP58G.js} +2 -2
  176. package/dashboard/dist/assets/{users-BHF3YOU1.js.map → users-pSMWP58G.js.map} +1 -1
  177. package/dashboard/dist/assets/{workflows-DorgmYSk.js → workflows-COYPOe2I.js} +2 -2
  178. package/dashboard/dist/assets/{workflows-DorgmYSk.js.map → workflows-COYPOe2I.js.map} +1 -1
  179. package/dashboard/dist/assets/{yaml-workflows-DTGpqnEG.js → yaml-workflows-1dF3ig6u.js} +2 -2
  180. package/dashboard/dist/assets/{yaml-workflows-DTGpqnEG.js.map → yaml-workflows-1dF3ig6u.js.map} +1 -1
  181. package/dashboard/dist/index.html +1 -1
  182. package/docs/api/http/escalations.md +6 -4
  183. package/docs/api/http/settings.md +1 -1
  184. package/docs/api/sdk/escalations.md +6 -4
  185. package/package.json +3 -2
  186. package/dashboard/dist/assets/index-DYmrNJ_H.js.map +0 -1
@@ -17,8 +17,11 @@ exports.getEscalationsByOriginId = getEscalationsByOriginId;
17
17
  exports.findByMetadata = findByMetadata;
18
18
  exports.claimByMetadata = claimByMetadata;
19
19
  const db_1 = require("../../lib/db");
20
+ const publish_1 = require("../../lib/events/publish");
21
+ const logger_1 = require("../../lib/logger");
20
22
  const sql_1 = require("./sql");
21
23
  async function createEscalation(input) {
24
+ logger_1.loggerRegistry.info(`[escalation-crud] createEscalation called for wf=${input.workflow_id} type=${input.type} caller=${new Error().stack?.split('\n')[2]?.trim()}`);
22
25
  const pool = (0, db_1.getPool)();
23
26
  // Ensure the role exists in lt_roles (FK constraint)
24
27
  await pool.query(sql_1.ENSURE_ROLE_EXISTS, [input.role]);
@@ -40,7 +43,18 @@ async function createEscalation(input) {
40
43
  input.trace_id || null,
41
44
  input.span_id || null,
42
45
  ]);
43
- return rows[0];
46
+ const escalation = rows[0];
47
+ (0, publish_1.publishEscalationEvent)({
48
+ type: 'escalation.created',
49
+ source: 'service',
50
+ workflowId: escalation.workflow_id || '',
51
+ workflowName: escalation.workflow_type || '',
52
+ taskQueue: escalation.task_queue || '',
53
+ escalationId: escalation.id,
54
+ status: 'pending',
55
+ data: { type: input.type, role: input.role },
56
+ });
57
+ return escalation;
44
58
  }
45
59
  /**
46
60
  * Atomic claim operation. Does NOT change status — "claimed" is implicit
@@ -58,15 +72,39 @@ async function claimEscalation(id, userId, durationMinutes = 30) {
58
72
  if (rows.length === 0)
59
73
  return null;
60
74
  const row = rows[0];
75
+ const escalation = row;
76
+ (0, publish_1.publishEscalationEvent)({
77
+ type: 'escalation.claimed',
78
+ source: 'service',
79
+ workflowId: escalation.workflow_id || '',
80
+ workflowName: escalation.workflow_type || '',
81
+ taskQueue: escalation.task_queue || '',
82
+ escalationId: escalation.id,
83
+ status: 'claimed',
84
+ data: { assigned_to: userId },
85
+ });
61
86
  return {
62
- escalation: row,
87
+ escalation,
63
88
  isExtension: row.prev_assigned_to === userId,
64
89
  };
65
90
  }
66
91
  async function resolveEscalation(id, resolverPayload) {
67
92
  const pool = (0, db_1.getPool)();
68
93
  const { rows } = await pool.query(sql_1.RESOLVE_ESCALATION, [id, JSON.stringify(resolverPayload)]);
69
- return rows[0] || null;
94
+ const escalation = rows[0] || null;
95
+ if (escalation) {
96
+ (0, publish_1.publishEscalationEvent)({
97
+ type: 'escalation.resolved',
98
+ source: 'service',
99
+ workflowId: escalation.workflow_id || '',
100
+ workflowName: escalation.workflow_type || '',
101
+ taskQueue: escalation.task_queue || '',
102
+ escalationId: escalation.id,
103
+ status: 'resolved',
104
+ data: {},
105
+ });
106
+ }
107
+ return escalation;
70
108
  }
71
109
  /**
72
110
  * Bulk update priority for a set of escalations.
@@ -163,15 +201,27 @@ async function findByMetadata(key, value, status, limit = 50, offset = 0) {
163
201
  total: parseInt(countResult.rows[0].count, 10),
164
202
  };
165
203
  }
166
- async function claimByMetadata(key, value, userId, durationMinutes = 30) {
204
+ async function claimByMetadata(key, value, userId, durationMinutes = 30, metadata) {
167
205
  const pool = (0, db_1.getPool)();
168
206
  const filter = JSON.stringify({ [key]: value });
169
- const { rows } = await pool.query(sql_1.CLAIM_BY_METADATA, [filter, userId, durationMinutes]);
207
+ const metaPatch = metadata ? JSON.stringify(metadata) : null;
208
+ const { rows } = await pool.query(sql_1.CLAIM_BY_METADATA, [filter, userId, durationMinutes, metaPatch]);
170
209
  if (rows.length === 0)
171
210
  return null;
172
211
  const row = rows[0];
212
+ const escalation = row;
213
+ (0, publish_1.publishEscalationEvent)({
214
+ type: 'escalation.claimed',
215
+ source: 'service',
216
+ workflowId: escalation.workflow_id || '',
217
+ workflowName: escalation.workflow_type || '',
218
+ taskQueue: escalation.task_queue || '',
219
+ escalationId: escalation.id,
220
+ status: 'claimed',
221
+ data: { assigned_to: userId },
222
+ });
173
223
  return {
174
- escalation: row,
224
+ escalation,
175
225
  isExtension: row.prev_assigned_to === userId,
176
226
  };
177
227
  }
@@ -22,5 +22,5 @@ export declare const LIST_DISTINCT_TYPES = "SELECT DISTINCT type FROM lt_escalat
22
22
  /** Find escalations by a single metadata key-value pair. */
23
23
  export declare const FIND_BY_METADATA = "SELECT * FROM lt_escalations\nWHERE metadata @> $1::jsonb\n AND ($2::text IS NULL OR status = $2)\nORDER BY priority ASC, created_at ASC\nLIMIT $3 OFFSET $4";
24
24
  export declare const COUNT_BY_METADATA = "SELECT COUNT(*) FROM lt_escalations\nWHERE metadata @> $1::jsonb\n AND ($2::text IS NULL OR status = $2)";
25
- /** Atomic claim by metadata: find one available escalation and claim it. */
26
- export declare const CLAIM_BY_METADATA = "WITH target AS (\n SELECT id, assigned_to\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n assigned_to IS NULL\n OR assigned_until <= NOW()\n OR assigned_to = $2\n )\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 FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT * FROM updated";
25
+ /** Atomic claim by metadata: find one available escalation, claim it, and optionally merge metadata. */
26
+ export declare const CLAIM_BY_METADATA = "WITH target AS (\n SELECT id, assigned_to\n FROM lt_escalations\n WHERE metadata @> $1::jsonb\n AND status = 'pending'\n AND (\n assigned_to IS NULL\n OR assigned_until <= NOW()\n OR assigned_to = $2\n )\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 FROM target t\n WHERE e.id = t.id\n RETURNING e.*, t.assigned_to AS prev_assigned_to\n)\nSELECT * FROM updated";
@@ -145,7 +145,7 @@ exports.COUNT_BY_METADATA = `\
145
145
  SELECT COUNT(*) FROM lt_escalations
146
146
  WHERE metadata @> $1::jsonb
147
147
  AND ($2::text IS NULL OR status = $2)`;
148
- /** Atomic claim by metadata: find one available escalation and claim it. */
148
+ /** Atomic claim by metadata: find one available escalation, claim it, and optionally merge metadata. */
149
149
  exports.CLAIM_BY_METADATA = `\
150
150
  WITH target AS (
151
151
  SELECT id, assigned_to
@@ -165,7 +165,10 @@ updated AS (
165
165
  UPDATE lt_escalations e
166
166
  SET assigned_to = $2,
167
167
  claimed_at = NOW(),
168
- assigned_until = NOW() + INTERVAL '1 minute' * $3
168
+ assigned_until = NOW() + INTERVAL '1 minute' * $3,
169
+ metadata = CASE WHEN $4::jsonb IS NOT NULL
170
+ THEN COALESCE(e.metadata, '{}'::jsonb) || $4::jsonb
171
+ ELSE e.metadata END
169
172
  FROM target t
170
173
  WHERE e.id = t.id
171
174
  RETURNING e.*, t.assigned_to AS prev_assigned_to
@@ -39,7 +39,6 @@ exports.ltEnrichEscalationRouting = ltEnrichEscalationRouting;
39
39
  exports.ltCreateEscalation = ltCreateEscalation;
40
40
  const escalationService = __importStar(require("../../escalation"));
41
41
  const logger_1 = require("../../../lib/logger");
42
- const publish_1 = require("../../../lib/events/publish");
43
42
  /**
44
43
  * Resolve an escalation record. Called by the interceptor after
45
44
  * detecting a re-run (resolver data present in the envelope).
@@ -107,15 +106,6 @@ async function ltCreateEscalation(input) {
107
106
  trace_id: input.traceId,
108
107
  span_id: input.spanId,
109
108
  });
110
- (0, publish_1.publishEscalationEvent)({
111
- type: 'escalation.created',
112
- source: 'interceptor',
113
- workflowId: input.workflowId || '',
114
- workflowName: input.workflowType || '',
115
- taskQueue: input.taskQueue || '',
116
- escalationId: escalation.id,
117
- status: 'pending',
118
- data: { type: input.type, role: input.role },
119
- });
109
+ // Event published by service layer (services/escalation/crud.ts)
120
110
  return escalation.id;
121
111
  }
@@ -81,16 +81,7 @@ async function ltCreateTask(input) {
81
81
  executing_as: input.executingAs,
82
82
  status: input.status,
83
83
  });
84
- (0, publish_1.publishTaskEvent)({
85
- type: 'task.created',
86
- source: 'interceptor',
87
- workflowId: input.workflowId,
88
- workflowName: input.workflowType,
89
- taskQueue: input.taskQueue || 'unknown',
90
- taskId: task.id,
91
- originId: input.originId,
92
- status: input.status || 'pending',
93
- });
84
+ // Event published by service layer (services/task/crud.ts)
94
85
  return task.id;
95
86
  }
96
87
  /**
@@ -109,19 +100,7 @@ async function ltCompleteTask(input) {
109
100
  data: input.data,
110
101
  milestones: input.milestones,
111
102
  });
112
- // Publish task.completed event
113
- if (input.workflowId) {
114
- (0, publish_1.publishTaskEvent)({
115
- type: 'task.completed',
116
- source: 'orchestrator',
117
- workflowId: input.workflowId,
118
- workflowName: input.workflowName || 'unknown',
119
- taskQueue: input.taskQueue || 'unknown',
120
- taskId: input.taskId,
121
- status: 'completed',
122
- milestones: input.milestones,
123
- });
124
- }
103
+ // task.completed event published by service layer (services/task/crud.ts)
125
104
  // Publish milestone event from orchestrator context
126
105
  if (input.milestones?.length && input.workflowId) {
127
106
  (0, publish_1.publishMilestoneEvent)({
@@ -115,28 +115,8 @@ async function createAdvisoryEscalation(state, result) {
115
115
  traceId: state.traceId,
116
116
  spanId: state.spanId,
117
117
  });
118
- (0, publish_1.publishEscalationEvent)({
119
- type: 'escalation.created',
120
- source: 'interceptor',
121
- workflowId: state.workflowId,
122
- workflowName: state.workflowName,
123
- taskQueue: state.taskQueue,
124
- taskId: state.taskId,
125
- escalationId,
126
- originId: state.envelope?.lt?.originId,
127
- status: 'pending',
128
- data: result.data,
129
- });
130
- (0, publish_1.publishTaskEvent)({
131
- type: 'task.escalated',
132
- source: 'interceptor',
133
- workflowId: state.workflowId,
134
- workflowName: state.workflowName,
135
- taskQueue: state.taskQueue,
136
- taskId: state.taskId,
137
- originId: state.envelope?.lt?.originId,
138
- status: 'needs_intervention',
139
- });
118
+ // escalation.created event published by service layer (services/escalation/crud.ts)
119
+ // task.escalated event published by service layer (services/task/crud.ts)
140
120
  // Auto-claim to submitting user if known
141
121
  const userId = state.envelope?.lt?.userId;
142
122
  if (userId) {
@@ -41,28 +41,8 @@ async function handleEscalation(state, result) {
41
41
  traceId: state.traceId,
42
42
  spanId: state.spanId,
43
43
  });
44
- (0, publish_1.publishEscalationEvent)({
45
- type: 'escalation.created',
46
- source: 'interceptor',
47
- workflowId: state.workflowId,
48
- workflowName: state.workflowName,
49
- taskQueue: state.taskQueue,
50
- taskId: state.taskId,
51
- escalationId,
52
- originId: state.envelope?.lt?.originId,
53
- status: 'pending',
54
- data: result.data,
55
- });
56
- (0, publish_1.publishTaskEvent)({
57
- type: 'task.escalated',
58
- source: 'interceptor',
59
- workflowId: state.workflowId,
60
- workflowName: state.workflowName,
61
- taskQueue: state.taskQueue,
62
- taskId: state.taskId,
63
- originId: state.envelope?.lt?.originId,
64
- status: 'needs_intervention',
65
- });
44
+ // escalation.created event published by service layer (services/escalation/crud.ts)
45
+ // task.escalated event published by service layer (services/task/crud.ts)
66
46
  return result;
67
47
  }
68
48
  /**
@@ -109,28 +89,9 @@ async function handleErrorEscalation(state, err) {
109
89
  traceId: state.traceId,
110
90
  spanId: state.spanId,
111
91
  });
112
- (0, publish_1.publishEscalationEvent)({
113
- type: 'escalation.created',
114
- source: 'interceptor',
115
- workflowId: state.workflowId,
116
- workflowName: state.workflowName,
117
- taskQueue: state.taskQueue,
118
- taskId: state.taskId,
119
- escalationId: errorEscalationId,
120
- originId: state.envelope?.lt?.originId,
121
- status: 'pending',
122
- data: { error: err.message },
123
- });
124
- (0, publish_1.publishTaskEvent)({
125
- type: 'task.escalated',
126
- source: 'interceptor',
127
- workflowId: state.workflowId,
128
- workflowName: state.workflowName,
129
- taskQueue: state.taskQueue,
130
- taskId: state.taskId,
131
- originId: state.envelope?.lt?.originId,
132
- status: 'needs_intervention',
133
- });
92
+ // escalation.created event published by service layer (services/escalation/crud.ts)
93
+ // task.escalated event published by service layer (services/task/crud.ts)
94
+ // Publish workflow.failed event (error path only runs once — no replay guard needed)
134
95
  (0, publish_1.publishWorkflowEvent)({
135
96
  type: 'workflow.failed',
136
97
  source: 'interceptor',
@@ -44,6 +44,7 @@ const escalation_1 = require("./escalation");
44
44
  const completion_1 = require("./completion");
45
45
  const lifecycle_1 = require("./lifecycle");
46
46
  const context_2 = require("../iam/context");
47
+ const publish_1 = require("../../lib/events/publish");
47
48
  const envelope_1 = require("../iam/envelope");
48
49
  const DEFAULT_ACTIVITY_QUEUE = 'lt-interceptor';
49
50
  /**
@@ -104,13 +105,36 @@ function createLTInterceptor(options) {
104
105
  // task creation, and escalation wiring.
105
106
  if (envelope?.metadata?.certified !== true) {
106
107
  const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
107
- return toolCtx ? (0, context_2.runWithToolContext)(toolCtx, next) : next();
108
+ // Publish workflow events even for uncertified workflows
109
+ const taskQueue = (0, lifecycle_1.deriveTaskQueue)(wf);
110
+ (0, lifecycle_1.publishStartedEvents)(wf, taskQueue, undefined, wf.workflowId);
111
+ const result = toolCtx ? await (0, context_2.runWithToolContext)(toolCtx, next) : await next();
112
+ (0, publish_1.publishWorkflowEvent)({
113
+ type: 'workflow.completed',
114
+ source: 'interceptor',
115
+ workflowId: wf.workflowId,
116
+ workflowName: wf.workflowName,
117
+ taskQueue,
118
+ status: 'completed',
119
+ });
120
+ return result;
108
121
  }
109
122
  // 3. Load config — unregistered/uncertified workflows get ToolContext only
110
123
  const wfConfig = await activities.ltGetWorkflowConfig(wf.workflowName);
111
124
  if (!wfConfig) {
112
125
  const toolCtx = (0, envelope_1.buildToolContextFromEnvelope)(envelope, wf.workflowId, wf.workflowTrace, wf.workflowSpan);
113
- return toolCtx ? (0, context_2.runWithToolContext)(toolCtx, next) : next();
126
+ const taskQueue2 = (0, lifecycle_1.deriveTaskQueue)(wf);
127
+ (0, lifecycle_1.publishStartedEvents)(wf, taskQueue2, undefined, wf.workflowId);
128
+ const result2 = toolCtx ? await (0, context_2.runWithToolContext)(toolCtx, next) : await next();
129
+ (0, publish_1.publishWorkflowEvent)({
130
+ type: 'workflow.completed',
131
+ source: 'interceptor',
132
+ workflowId: wf.workflowId,
133
+ workflowName: wf.workflowName,
134
+ taskQueue: taskQueue2,
135
+ status: 'completed',
136
+ });
137
+ return result2;
114
138
  }
115
139
  const taskQueue = (0, lifecycle_1.deriveTaskQueue)(wf);
116
140
  // 3. Find existing task and handle re-run escalation resolution
@@ -37,7 +37,7 @@ export declare function resolveReRun(activities: ProxiedActivities, envelope: LT
37
37
  * Also injects originId back into the envelope for downstream consistency.
38
38
  */
39
39
  export declare function ensureTaskWithRouting(activities: ProxiedActivities, wf: WorkflowIdentity, envelope: LTEnvelope | undefined, existingTask: any | null, taskQueue: string, reRun: ReRunContext): Promise<TaskContext>;
40
- /** Publish workflow.started + task.started events. */
40
+ /** Publish workflow.started event (guarded against replay). */
41
41
  export declare function publishStartedEvents(wf: WorkflowIdentity, taskQueue: string, taskId: string | undefined, originId: string): void;
42
42
  /** Complete a task and signal parent for plain (non-LTReturn) results. */
43
43
  export declare function completePlainResult(activities: ProxiedActivities, wf: WorkflowIdentity, taskQueue: string, taskId: string | undefined, routing: Record<string, any> | null, result: any): Promise<void>;
@@ -13,6 +13,7 @@ exports.resolveReRun = resolveReRun;
13
13
  exports.ensureTaskWithRouting = ensureTaskWithRouting;
14
14
  exports.publishStartedEvents = publishStartedEvents;
15
15
  exports.completePlainResult = completePlainResult;
16
+ const hotmesh_1 = require("@hotmeshio/hotmesh");
16
17
  const publish_1 = require("../../lib/events/publish");
17
18
  // ── Helpers ──────────────────────────────────────────────────────────────────
18
19
  /** Extract workflow identity fields from the HotMesh context map. */
@@ -56,17 +57,7 @@ async function resolveReRun(activities, envelope, existingTask, wf, taskQueue) {
56
57
  escalationId: escalationId,
57
58
  resolverPayload: envelope.resolver,
58
59
  });
59
- (0, publish_1.publishEscalationEvent)({
60
- type: 'escalation.resolved',
61
- source: 'interceptor',
62
- workflowId: wf.workflowId,
63
- workflowName: wf.workflowName,
64
- taskQueue,
65
- taskId: task?.id || existingTask?.id,
66
- escalationId: escalationId,
67
- originId: envelope?.lt?.originId,
68
- status: 'resolved',
69
- });
60
+ // escalation.resolved event published by service layer (services/escalation/crud.ts)
70
61
  }
71
62
  return { isReRun, task, metadata };
72
63
  }
@@ -128,28 +119,23 @@ async function ensureTaskWithRouting(activities, wf, envelope, existingTask, tas
128
119
  }
129
120
  return { taskId, routing, originId };
130
121
  }
131
- /** Publish workflow.started + task.started events. */
122
+ /** Publish workflow.started event (guarded against replay). */
132
123
  function publishStartedEvents(wf, taskQueue, taskId, originId) {
133
- (0, publish_1.publishWorkflowEvent)({
134
- type: 'workflow.started',
135
- source: 'interceptor',
136
- workflowId: wf.workflowId,
137
- workflowName: wf.workflowName,
138
- taskQueue,
139
- taskId,
140
- originId,
141
- status: 'running',
142
- });
143
- (0, publish_1.publishTaskEvent)({
144
- type: 'task.started',
145
- source: 'interceptor',
146
- workflowId: wf.workflowId,
147
- workflowName: wf.workflowName,
148
- taskQueue,
149
- taskId: taskId,
150
- originId,
151
- status: 'in_progress',
152
- });
124
+ const { replay } = hotmesh_1.Durable.workflow.workflowInfo();
125
+ const isFirstExecution = Object.keys(replay).length === 0;
126
+ if (isFirstExecution) {
127
+ (0, publish_1.publishWorkflowEvent)({
128
+ type: 'workflow.started',
129
+ source: 'interceptor',
130
+ workflowId: wf.workflowId,
131
+ workflowName: wf.workflowName,
132
+ taskQueue,
133
+ taskId,
134
+ originId,
135
+ status: 'running',
136
+ });
137
+ }
138
+ // task.started event published by service layer (services/task/crud.ts)
153
139
  }
154
140
  /** Complete a task and signal parent for plain (non-LTReturn) results. */
155
141
  async function completePlainResult(activities, wf, taskQueue, taskId, routing, result) {
@@ -8,6 +8,7 @@ exports.getTaskBySignalId = getTaskBySignalId;
8
8
  exports.getTaskByWorkflowId = getTaskByWorkflowId;
9
9
  exports.listTasks = listTasks;
10
10
  const db_1 = require("../../lib/db");
11
+ const publish_1 = require("../../lib/events/publish");
11
12
  const sql_1 = require("./sql");
12
13
  async function createTask(input) {
13
14
  const pool = (0, db_1.getPool)();
@@ -30,7 +31,18 @@ async function createTask(input) {
30
31
  input.executing_as || null,
31
32
  input.status || null,
32
33
  ]);
33
- return rows[0];
34
+ const task = rows[0];
35
+ (0, publish_1.publishTaskEvent)({
36
+ type: 'task.created',
37
+ source: 'service',
38
+ workflowId: task.workflow_id || '',
39
+ workflowName: task.workflow_type || '',
40
+ taskQueue: task.task_queue || '',
41
+ taskId: task.id,
42
+ originId: task.origin_id || undefined,
43
+ status: task.status || 'pending',
44
+ });
45
+ return task;
34
46
  }
35
47
  async function updateTask(id, input) {
36
48
  const pool = (0, db_1.getPool)();
@@ -59,7 +71,29 @@ async function updateTask(id, input) {
59
71
  }
60
72
  values.push(id);
61
73
  const { rows } = await pool.query(`UPDATE lt_tasks SET ${sets.join(', ')} WHERE id = $${idx} RETURNING *`, values);
62
- return rows[0];
74
+ const task = rows[0];
75
+ // Publish status-driven events from the single write path
76
+ if (input.status && task) {
77
+ const STATUS_EVENTS = {
78
+ in_progress: 'task.started',
79
+ completed: 'task.completed',
80
+ needs_intervention: 'task.escalated',
81
+ };
82
+ const eventType = STATUS_EVENTS[input.status];
83
+ if (eventType) {
84
+ (0, publish_1.publishTaskEvent)({
85
+ type: eventType,
86
+ source: 'service',
87
+ workflowId: task.workflow_id || '',
88
+ workflowName: task.workflow_type || '',
89
+ taskQueue: task.task_queue || '',
90
+ taskId: task.id,
91
+ originId: task.origin_id || undefined,
92
+ status: input.status,
93
+ });
94
+ }
95
+ }
96
+ return task;
63
97
  }
64
98
  async function appendMilestones(id, milestones) {
65
99
  const pool = (0, db_1.getPool)();
@@ -14,6 +14,8 @@ const adapters_1 = require("./adapters");
14
14
  const workers_1 = require("./workers");
15
15
  const server_1 = require("./server");
16
16
  const socketio_1 = require("../lib/events/socketio");
17
+ const nats_1 = require("../lib/events/nats");
18
+ const nats_ws_proxy_1 = require("../lib/events/nats-ws-proxy");
17
19
  /**
18
20
  * Start Long Tail with a declarative configuration.
19
21
  *
@@ -79,6 +81,18 @@ async function start(startConfig) {
79
81
  socketAdapter.attachServer(httpServer);
80
82
  await socketAdapter.connect();
81
83
  }
84
+ // Attach NATS WebSocket proxy (if configured)
85
+ const natsAdapter = events_1.eventRegistry.getAdapter(nats_1.NatsEventAdapter);
86
+ if (natsAdapter?.wsProxyTarget && httpServer) {
87
+ (0, nats_ws_proxy_1.attachNatsWsProxy)(httpServer, natsAdapter.wsProxyTarget, {
88
+ onWsUrlDerived: (url) => {
89
+ // Auto-set wsUrl if not explicitly configured
90
+ if (!natsAdapter.wsUrl) {
91
+ natsAdapter.setWsUrl(url);
92
+ }
93
+ },
94
+ });
95
+ }
82
96
  }
83
97
  // 7. Return instance
84
98
  const connection = (0, workers_1.buildConnection)();