@codemation/core 0.0.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 (348) hide show
  1. package/README.md +30 -0
  2. package/dist/EngineExecutionLimitsPolicy-8MEFIYx1.d.cts +160 -0
  3. package/dist/EngineExecutionLimitsPolicy-BWAXW9D6.d.cts +160 -0
  4. package/dist/EngineExecutionLimitsPolicy-Bp8PS1Ss.d.cts +159 -0
  5. package/dist/EngineExecutionLimitsPolicy-CLxcN-D2.d.ts +159 -0
  6. package/dist/EngineExecutionLimitsPolicy-DZXuix51.d.ts +160 -0
  7. package/dist/EngineExecutionLimitsPolicy-Gfz6ngFd.d.ts +160 -0
  8. package/dist/EngineFactory-CBnntY3J.cjs +3152 -0
  9. package/dist/EngineFactory-CBnntY3J.cjs.map +1 -0
  10. package/dist/EngineFactory-Cwn3R2YA.js +3087 -0
  11. package/dist/EngineFactory-Cwn3R2YA.js.map +1 -0
  12. package/dist/EngineFactory-DWCnNocp.js +3063 -0
  13. package/dist/EngineFactory-DWCnNocp.js.map +1 -0
  14. package/dist/EngineFactory-DhPFou4p.cjs +3188 -0
  15. package/dist/EngineFactory-DhPFou4p.cjs.map +1 -0
  16. package/dist/EngineFactory-l_9xmBtv.cjs +3190 -0
  17. package/dist/EngineFactory-l_9xmBtv.cjs.map +1 -0
  18. package/dist/EngineFactory-w-aOWuqh.js +3089 -0
  19. package/dist/EngineFactory-w-aOWuqh.js.map +1 -0
  20. package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js +18 -0
  21. package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js.map +1 -0
  22. package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs +151 -0
  23. package/dist/InMemoryLiveWorkflowRepository-BTzHpQ6e.cjs.map +1 -0
  24. package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js +139 -0
  25. package/dist/InMemoryLiveWorkflowRepository-BoLNnVLg.js.map +1 -0
  26. package/dist/InMemoryLiveWorkflowRepository-CULNqv96.d.ts +1300 -0
  27. package/dist/InMemoryLiveWorkflowRepository-D6eiiXxF.d.cts +1168 -0
  28. package/dist/InMemoryLiveWorkflowRepository-D7l8cjdZ.d.cts +1130 -0
  29. package/dist/InMemoryLiveWorkflowRepository-DL7LmC9S.d.ts +1340 -0
  30. package/dist/InMemoryLiveWorkflowRepository-jnv-OnOP.d.ts +1300 -0
  31. package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs +24 -0
  32. package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs.map +1 -0
  33. package/dist/InMemoryLiveWorkflowRepository-xr7b4kvi.d.ts +1338 -0
  34. package/dist/InMemoryWorkflowCatalog-BIdFpwbK.d.ts +1205 -0
  35. package/dist/InMemoryWorkflowCatalog-BW00_3N3.d.cts +12 -0
  36. package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs +24 -0
  37. package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs.map +1 -0
  38. package/dist/InMemoryWorkflowCatalog-BrG0ApMO.d.cts +1115 -0
  39. package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js +139 -0
  40. package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js.map +1 -0
  41. package/dist/InMemoryWorkflowCatalog-C-EJlJ7y.d.cts +1120 -0
  42. package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs +24 -0
  43. package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs.map +1 -0
  44. package/dist/InMemoryWorkflowCatalog-CZ0kZpOv.d.ts +1289 -0
  45. package/dist/InMemoryWorkflowCatalog-C_ACeLyW.d.cts +1119 -0
  46. package/dist/InMemoryWorkflowCatalog-CiHWIu5E.d.cts +12 -0
  47. package/dist/InMemoryWorkflowCatalog-CkH7gkya.js +18 -0
  48. package/dist/InMemoryWorkflowCatalog-CkH7gkya.js.map +1 -0
  49. package/dist/InMemoryWorkflowCatalog-CnpZVJM9.d.ts +1205 -0
  50. package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js +18 -0
  51. package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js.map +1 -0
  52. package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs +151 -0
  53. package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs.map +1 -0
  54. package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js +18 -0
  55. package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js.map +1 -0
  56. package/dist/InMemoryWorkflowCatalog-D5nCp2yZ.d.ts +1267 -0
  57. package/dist/InMemoryWorkflowCatalog-DIq0bjqN.d.ts +12 -0
  58. package/dist/InMemoryWorkflowCatalog-DLgaEaw_.d.ts +1288 -0
  59. package/dist/InMemoryWorkflowCatalog-DNBFdK-x.d.cts +1120 -0
  60. package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs +24 -0
  61. package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs.map +1 -0
  62. package/dist/InMemoryWorkflowCatalog-DS4-eX6i.d.cts +1118 -0
  63. package/dist/InMemoryWorkflowCatalog-DdVfy8MY.d.ts +12 -0
  64. package/dist/InMemoryWorkflowCatalog-DeVZu3g8.d.ts +12 -0
  65. package/dist/InMemoryWorkflowCatalog-GxkQjvt5.d.ts +1200 -0
  66. package/dist/InMemoryWorkflowCatalog-qaVRn1Lc.d.cts +1115 -0
  67. package/dist/InMemoryWorkflowCatalog-z1aIT4TC.d.cts +12 -0
  68. package/dist/InMemoryWorkflowRegistry-BBuOovLL.d.ts +1007 -0
  69. package/dist/InMemoryWorkflowRegistry-BIFnSl3k.d.ts +1201 -0
  70. package/dist/InMemoryWorkflowRegistry-BnGilthz.d.ts +1137 -0
  71. package/dist/InMemoryWorkflowRegistry-CEp5I8No.d.ts +1146 -0
  72. package/dist/InMemoryWorkflowRegistry-CHyMB9jW.d.cts +976 -0
  73. package/dist/InMemoryWorkflowRegistry-CUN7K86m.d.cts +1061 -0
  74. package/dist/InMemoryWorkflowRegistry-CVfHyELh.d.cts +971 -0
  75. package/dist/InMemoryWorkflowRegistry-CXXJrwAr.d.cts +1052 -0
  76. package/dist/InMemoryWorkflowRegistry-DDGfPTJy.d.ts +1013 -0
  77. package/dist/InMemoryWorkflowRegistry-DnYSOoT5.d.ts +1120 -0
  78. package/dist/InMemoryWorkflowRegistry-Dp5GiFF2.d.cts +1035 -0
  79. package/dist/InMemoryWorkflowRegistry-DypDBeOw.d.cts +1116 -0
  80. package/dist/InMemoryWorkflowRegistry-SzwJCAxT.d.ts +1012 -0
  81. package/dist/InMemoryWorkflowRegistry-jupvqyGc.d.cts +977 -0
  82. package/dist/InMemoryWorkflowRegistry-rAdKVWYT.d.ts +1117 -0
  83. package/dist/InProcessRetryRunner-BBNPkXjy.d.cts +292 -0
  84. package/dist/PersistedWorkflowSnapshotFactory-7RkOL3Kg.d.ts +14 -0
  85. package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs +141 -0
  86. package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs.map +1 -0
  87. package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js +118 -0
  88. package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js.map +1 -0
  89. package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js +123 -0
  90. package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js.map +1 -0
  91. package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js +101 -0
  92. package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js.map +1 -0
  93. package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs +131 -0
  94. package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs.map +1 -0
  95. package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js +103 -0
  96. package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js.map +1 -0
  97. package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js +119 -0
  98. package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js.map +1 -0
  99. package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs +131 -0
  100. package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs.map +1 -0
  101. package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs +131 -0
  102. package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs.map +1 -0
  103. package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js +103 -0
  104. package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js.map +1 -0
  105. package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs +131 -0
  106. package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs.map +1 -0
  107. package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs +107 -0
  108. package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs.map +1 -0
  109. package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js +119 -0
  110. package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js.map +1 -0
  111. package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs +130 -0
  112. package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs.map +1 -0
  113. package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js +123 -0
  114. package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js.map +1 -0
  115. package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js +119 -0
  116. package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js.map +1 -0
  117. package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js +102 -0
  118. package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js.map +1 -0
  119. package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs +141 -0
  120. package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs.map +1 -0
  121. package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js +119 -0
  122. package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js.map +1 -0
  123. package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs +109 -0
  124. package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs.map +1 -0
  125. package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs +109 -0
  126. package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs.map +1 -0
  127. package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs +108 -0
  128. package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs.map +1 -0
  129. package/dist/RunIntentService-1EE6N8ZL.cjs +963 -0
  130. package/dist/RunIntentService-1EE6N8ZL.cjs.map +1 -0
  131. package/dist/RunIntentService-2ivFmNQh.cjs +3462 -0
  132. package/dist/RunIntentService-2ivFmNQh.cjs.map +1 -0
  133. package/dist/RunIntentService-B0sUL5q-.js +761 -0
  134. package/dist/RunIntentService-B0sUL5q-.js.map +1 -0
  135. package/dist/RunIntentService-BFVbsOcg.js +3131 -0
  136. package/dist/RunIntentService-BFVbsOcg.js.map +1 -0
  137. package/dist/RunIntentService-BsBOwpVN.cjs +1051 -0
  138. package/dist/RunIntentService-BsBOwpVN.cjs.map +1 -0
  139. package/dist/RunIntentService-CSk3ETyn.js +858 -0
  140. package/dist/RunIntentService-CSk3ETyn.js.map +1 -0
  141. package/dist/RunIntentService-Ckn3u3tA.d.cts +326 -0
  142. package/dist/RunIntentService-DEo6GTTo.d.cts +289 -0
  143. package/dist/RunIntentService-DKrGtL0B.js +782 -0
  144. package/dist/RunIntentService-DKrGtL0B.js.map +1 -0
  145. package/dist/RunIntentService-DNOJc1R7.cjs +942 -0
  146. package/dist/RunIntentService-DNOJc1R7.cjs.map +1 -0
  147. package/dist/RunIntentService-Dq3pV53j.d.cts +289 -0
  148. package/dist/RunIntentService-NKobsfMQ.d.cts +274 -0
  149. package/dist/WorkflowSnapshotCodec-C3fuuS_R.d.cts +22 -0
  150. package/dist/WorkflowSnapshotCodec-CUudUo6f.js +123 -0
  151. package/dist/WorkflowSnapshotCodec-CUudUo6f.js.map +1 -0
  152. package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs +129 -0
  153. package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs.map +1 -0
  154. package/dist/WorkflowSnapshotCodec-DLiXQNvV.d.cts +22 -0
  155. package/dist/WorkflowSnapshotCodec-DNtdrZ7l.d.cts +22 -0
  156. package/dist/WorkflowSnapshotCodec-DTdWkoW_.d.cts +22 -0
  157. package/dist/bootstrap/index.cjs +1028 -0
  158. package/dist/bootstrap/index.cjs.map +1 -0
  159. package/dist/bootstrap/index.d.cts +311 -0
  160. package/dist/bootstrap/index.d.ts +83 -0
  161. package/dist/bootstrap/index.js +994 -0
  162. package/dist/bootstrap/index.js.map +1 -0
  163. package/dist/credentialTypes-B5h3dI7r.d.cts +1107 -0
  164. package/dist/credentialTypes-B9okPCVo.d.cts +963 -0
  165. package/dist/credentialTypes-BFL70rgZ.d.cts +964 -0
  166. package/dist/credentialTypes-BGkh1O07.d.ts +1010 -0
  167. package/dist/credentialTypes-BNLi4Q7u.d.ts +1030 -0
  168. package/dist/credentialTypes-CeSoZGj3.d.cts +994 -0
  169. package/dist/credentialTypes-CpHc32Ig.d.cts +984 -0
  170. package/dist/credentialTypes-D0m7MQQl.d.cts +1107 -0
  171. package/dist/credentialTypes-D4nL2sUd.d.ts +1000 -0
  172. package/dist/credentialTypes-DBYK2Qbu.d.ts +999 -0
  173. package/dist/credentialTypes-DMJVy0r1.d.ts +1000 -0
  174. package/dist/credentialTypes-DhUAjYQp.d.ts +1020 -0
  175. package/dist/credentialTypes-gGITj5KL.d.cts +964 -0
  176. package/dist/credentialTypes-r3KVBJBE.d.cts +974 -0
  177. package/dist/diTokens-ClO27tjK.cjs +34 -0
  178. package/dist/diTokens-ClO27tjK.cjs.map +1 -0
  179. package/dist/diTokens-CoHBkwG6.js +28 -0
  180. package/dist/diTokens-CoHBkwG6.js.map +1 -0
  181. package/dist/index-6Doxmfnd.d.ts +857 -0
  182. package/dist/index-9g6Pfe9Z.d.ts +689 -0
  183. package/dist/index-AZ72Ej-K.d.ts +920 -0
  184. package/dist/index-BEk9V-q-.d.ts +667 -0
  185. package/dist/index-Bjt7_7oS.d.ts +1192 -0
  186. package/dist/index-CFGxsYXy.d.ts +708 -0
  187. package/dist/index-C_u8xFgn.d.ts +690 -0
  188. package/dist/index-CpbfsvOJ.d.ts +1192 -0
  189. package/dist/index-CsReNJN_.d.ts +859 -0
  190. package/dist/index-D5iNnXaW.d.ts +667 -0
  191. package/dist/index-DD_Eft1q.d.ts +708 -0
  192. package/dist/index-DiSYUe0G.d.ts +1192 -0
  193. package/dist/index-gIcH60sp.d.ts +674 -0
  194. package/dist/index.cjs +520 -0
  195. package/dist/index.cjs.map +1 -0
  196. package/dist/index.d.cts +345 -0
  197. package/dist/index.d.ts +3 -0
  198. package/dist/index.js +412 -0
  199. package/dist/index.js.map +1 -0
  200. package/dist/runtime-BIvd-1JA.cjs +4112 -0
  201. package/dist/runtime-BIvd-1JA.cjs.map +1 -0
  202. package/dist/runtime-D3eWKSQK.cjs +3986 -0
  203. package/dist/runtime-D3eWKSQK.cjs.map +1 -0
  204. package/dist/runtime-Dvp4xAjg.js +3799 -0
  205. package/dist/runtime-Dvp4xAjg.js.map +1 -0
  206. package/dist/runtime-vc76SSAa.js +3685 -0
  207. package/dist/runtime-vc76SSAa.js.map +1 -0
  208. package/dist/runtimeTypes-BK0b8SaG.d.cts +884 -0
  209. package/dist/runtimeTypes-CoYZkYQq.d.cts +851 -0
  210. package/dist/runtimeTypes-D-Pm0Uas.d.cts +849 -0
  211. package/dist/testing.cjs +18 -0
  212. package/dist/testing.cjs.map +1 -0
  213. package/dist/testing.d.cts +19 -0
  214. package/dist/testing.d.ts +18 -0
  215. package/dist/testing.js +16 -0
  216. package/dist/testing.js.map +1 -0
  217. package/dist/types-Cb5UK7Y6.d.ts +857 -0
  218. package/package.json +66 -0
  219. package/src/ai/AiHost.ts +115 -0
  220. package/src/binaries/DefaultExecutionBinaryServiceFactory.ts +37 -0
  221. package/src/binaries/DefaultNodeBinaryAttachmentServiceFactory.ts +120 -0
  222. package/src/binaries/UnavailableBinaryStorage.ts +19 -0
  223. package/src/binaries/index.ts +2 -0
  224. package/src/bootstrap/index.ts +46 -0
  225. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +180 -0
  226. package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +43 -0
  227. package/src/bootstrap/runtime/index.ts +6 -0
  228. package/src/browser.ts +8 -0
  229. package/src/contracts/Clock.ts +10 -0
  230. package/src/contracts/ExpRetryPolicy.ts +23 -0
  231. package/src/contracts/NoRetryPolicy.ts +5 -0
  232. package/src/contracts/RetryPolicy.ts +23 -0
  233. package/src/contracts/credentialTypes.ts +194 -0
  234. package/src/contracts/index.ts +6 -0
  235. package/src/contracts/retryPolicySpec.types.ts +30 -0
  236. package/src/contracts/runFinishedAtFactory.ts +19 -0
  237. package/src/contracts/runTypes.ts +314 -0
  238. package/src/contracts/runtimeTypes.ts +373 -0
  239. package/src/contracts/webhookTypes.ts +49 -0
  240. package/src/contracts/workflowActivationPolicy.ts +16 -0
  241. package/src/contracts/workflowTypes.ts +280 -0
  242. package/src/di/CoreTokens.ts +60 -0
  243. package/src/di/index.ts +24 -0
  244. package/src/events/EventPublishingWorkflowExecutionRepository.ts +67 -0
  245. package/src/events/InMemoryRunEventBusRegistry.ts +37 -0
  246. package/src/events/InMemoryRunEventSubscription.ts +9 -0
  247. package/src/events/NodeEventPublisher.ts +22 -0
  248. package/src/events/index.ts +4 -0
  249. package/src/events/runEvents.ts +54 -0
  250. package/src/execution/ActivationEnqueueService.ts +125 -0
  251. package/src/execution/CredentialResolverFactory.ts +39 -0
  252. package/src/execution/DefaultAsyncSleeper.ts +9 -0
  253. package/src/execution/DefaultExecutionContextFactory.ts +48 -0
  254. package/src/execution/InProcessRetryRunner.ts +115 -0
  255. package/src/execution/InProcessRetryRunnerFactory.ts +8 -0
  256. package/src/execution/NodeActivationRequestComposer.ts +113 -0
  257. package/src/execution/NodeExecutionSnapshotFactory.ts +152 -0
  258. package/src/execution/NodeExecutor.ts +43 -0
  259. package/src/execution/NodeExecutorFactory.ts +10 -0
  260. package/src/execution/NodeInputsByPortFactory.ts +14 -0
  261. package/src/execution/NodeInstanceFactory.ts +32 -0
  262. package/src/execution/NodeInstanceFactoryFactory.ts +9 -0
  263. package/src/execution/NodeRunStateWriter.ts +185 -0
  264. package/src/execution/NodeRunStateWriterFactory.ts +29 -0
  265. package/src/execution/PersistedRunStateTerminalBuilder.ts +25 -0
  266. package/src/execution/RunStateSemantics.ts +158 -0
  267. package/src/execution/WorkflowRunExecutionContextFactory.ts +45 -0
  268. package/src/execution/asyncSleeper.types.ts +3 -0
  269. package/src/execution/index.ts +26 -0
  270. package/src/index.ts +18 -0
  271. package/src/orchestration/Engine.ts +229 -0
  272. package/src/orchestration/EngineWaiters.ts +37 -0
  273. package/src/orchestration/RunContinuationService.ts +810 -0
  274. package/src/orchestration/RunStartService.ts +449 -0
  275. package/src/orchestration/TriggerRuntimeService.ts +260 -0
  276. package/src/orchestration/index.ts +5 -0
  277. package/src/planning/CurrentStateFrontierPlanner.ts +400 -0
  278. package/src/planning/EngineWorkflowPlanningFactory.ts +63 -0
  279. package/src/planning/RunQueuePlanner.ts +302 -0
  280. package/src/planning/WorkflowTopologyPlanner.ts +77 -0
  281. package/src/planning/index.ts +4 -0
  282. package/src/policies/WorkflowPolicyErrorServices.ts +38 -0
  283. package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +66 -0
  284. package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +14 -0
  285. package/src/policies/index.ts +10 -0
  286. package/src/policies/storage/RunPolicySnapshotFactory.ts +23 -0
  287. package/src/policies/storage/RunTerminalPersistenceCoordinator.ts +29 -0
  288. package/src/policies/storage/WorkflowStoragePolicyEvaluator.ts +39 -0
  289. package/src/runStorage/BinaryBodyBufferReader.ts +57 -0
  290. package/src/runStorage/BinaryBodyReadableStreamFactory.ts +21 -0
  291. package/src/runStorage/InMemoryBinaryStorageRegistry.ts +53 -0
  292. package/src/runStorage/InMemoryRunData.ts +33 -0
  293. package/src/runStorage/InMemoryRunDataFactory.ts +8 -0
  294. package/src/runStorage/InMemoryWorkflowExecutionRepository.ts +95 -0
  295. package/src/runStorage/RunSummaryMapper.ts +17 -0
  296. package/src/runStorage/index.ts +7 -0
  297. package/src/runtime/EngineFactory.ts +151 -0
  298. package/src/runtime/EngineWorkflowRunnerService.ts +39 -0
  299. package/src/runtime/EngineWorkflowRunnerServiceFactory.ts +11 -0
  300. package/src/runtime/InMemoryLiveWorkflowRepository.ts +20 -0
  301. package/src/runtime/RunIntentService.ts +175 -0
  302. package/src/runtime/RunIntentServiceFactory.ts +11 -0
  303. package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +144 -0
  304. package/src/runtime/WorkflowRepositoryWebhookTriggerMatcherFactory.ts +13 -0
  305. package/src/runtime/index.ts +9 -0
  306. package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +25 -0
  307. package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +46 -0
  308. package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +14 -0
  309. package/src/runtime-types/StackTraceCallSitePathResolver.ts +25 -0
  310. package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +33 -0
  311. package/src/runtime-types/runtimeTypeDecorators.types.ts +46 -0
  312. package/src/scheduler/ConfigDrivenOffloadPolicy.ts +28 -0
  313. package/src/scheduler/DefaultDrivingScheduler.ts +100 -0
  314. package/src/scheduler/HintOnlyOffloadPolicy.ts +9 -0
  315. package/src/scheduler/InlineDrivingScheduler.ts +145 -0
  316. package/src/scheduler/InlineDrivingSchedulerFactory.ts +9 -0
  317. package/src/scheduler/LocalOnlyScheduler.ts +7 -0
  318. package/src/serialization/ItemsInputNormalizer.ts +36 -0
  319. package/src/testing/RejectingCredentialSessionService.ts +15 -0
  320. package/src/testing.ts +6 -0
  321. package/src/types/index.ts +12 -0
  322. package/src/workflow/definition/ConnectionInvocationIdFactory.ts +17 -0
  323. package/src/workflow/definition/ConnectionNodeIdFactory.ts +42 -0
  324. package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +71 -0
  325. package/src/workflow/definition/WorkflowExecutableNodeClassifierFactory.ts +9 -0
  326. package/src/workflow/dsl/ChainCursorResolver.ts +103 -0
  327. package/src/workflow/dsl/WhenBuilder.ts +57 -0
  328. package/src/workflow/dsl/WorkflowBuilder.ts +55 -0
  329. package/src/workflow/dsl/workflowBuilderTypes.ts +63 -0
  330. package/src/workflow/graph/DefaultWorkflowGraphFactory.ts +8 -0
  331. package/src/workflow/graph/ExecutableGraph.ts +24 -0
  332. package/src/workflow/index.ts +11 -0
  333. package/src/workflowSnapshots/MissingRuntimeExecutionMarker.ts +5 -0
  334. package/src/workflowSnapshots/MissingRuntimeFallbacksFactory.ts +27 -0
  335. package/src/workflowSnapshots/MissingRuntimeNode.ts +12 -0
  336. package/src/workflowSnapshots/MissingRuntimeNodeConfig.ts +14 -0
  337. package/src/workflowSnapshots/MissingRuntimeNodeToken.ts +1 -0
  338. package/src/workflowSnapshots/MissingRuntimeTrigger.ts +16 -0
  339. package/src/workflowSnapshots/MissingRuntimeTriggerConfig.ts +14 -0
  340. package/src/workflowSnapshots/MissingRuntimeTriggerToken.ts +1 -0
  341. package/src/workflowSnapshots/PersistedRuntimeTypeIdFactory.ts +19 -0
  342. package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +89 -0
  343. package/src/workflowSnapshots/PersistedWorkflowTokenRegistryFactory.ts +2 -0
  344. package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +177 -0
  345. package/src/workflowSnapshots/WorkflowSnapshotResolver.ts +102 -0
  346. package/src/workflowSnapshots/index.ts +12 -0
  347. package/tsconfig.json +9 -0
  348. package/tsdown.config.ts +10 -0
@@ -0,0 +1,810 @@
1
+ import type {
2
+ ActivationIdFactory,
3
+ NodeActivationId,
4
+ NodeExecutionContext,
5
+ NodeId,
6
+ NodeInputsByPort,
7
+ NodeOutputs,
8
+ PersistedRunState,
9
+ RunDataFactory,
10
+ RunId,
11
+ RunQueueEntry,
12
+ RunResult,
13
+ WorkflowExecutionRepository,
14
+ WebhookControlSignal,
15
+ WebhookRunResult,
16
+ WorkflowDefinition,
17
+ WorkflowId,
18
+ WorkflowSnapshotResolver,
19
+ } from "../types";
20
+
21
+ import { WorkflowTopology } from "../planning/WorkflowTopologyPlanner";
22
+ import { WorkflowExecutableNodeClassifierFactory } from "../workflow/definition/WorkflowExecutableNodeClassifierFactory";
23
+
24
+ import { CredentialResolverFactory } from "../execution/CredentialResolverFactory";
25
+ import type { EngineExecutionLimitsPolicy } from "../policies/executionLimits/EngineExecutionLimitsPolicy";
26
+ import { RunTerminalPersistenceCoordinator } from "../policies/storage/RunTerminalPersistenceCoordinator";
27
+ import { WorkflowPolicyErrorServices } from "../policies/WorkflowPolicyErrorServices";
28
+ import { EngineWorkflowPlanningFactory } from "../planning/EngineWorkflowPlanningFactory";
29
+ import type { EngineWaiters } from "../orchestration/EngineWaiters";
30
+ import { NodeEventPublisher } from "../events/NodeEventPublisher";
31
+
32
+ import { ActivationEnqueueService } from "../execution/ActivationEnqueueService";
33
+ import { NodeExecutionSnapshotFactory } from "../execution/NodeExecutionSnapshotFactory";
34
+ import { NodeInputsByPortFactory } from "../execution/NodeInputsByPortFactory";
35
+ import { NodeRunStateWriterFactory } from "../execution/NodeRunStateWriterFactory";
36
+ import { NodeActivationRequestComposer } from "../execution/NodeActivationRequestComposer";
37
+ import { PersistedRunStateTerminalBuilder } from "../execution/PersistedRunStateTerminalBuilder";
38
+ import { RunStateSemantics } from "../execution/RunStateSemantics";
39
+ import { WorkflowRunExecutionContextFactory } from "../execution/WorkflowRunExecutionContextFactory";
40
+
41
+ export class RunContinuationService {
42
+ constructor(
43
+ private readonly activationIdFactory: ActivationIdFactory,
44
+ private readonly workflowExecutionRepository: WorkflowExecutionRepository,
45
+ private readonly runDataFactory: RunDataFactory,
46
+ private readonly runExecutionContextFactory: WorkflowRunExecutionContextFactory,
47
+ private readonly workflowSnapshotResolver: WorkflowSnapshotResolver,
48
+ private readonly planningFactory: EngineWorkflowPlanningFactory,
49
+ private readonly nodeStatePublisherFactory: NodeRunStateWriterFactory,
50
+ private readonly credentialResolverFactory: CredentialResolverFactory,
51
+ private readonly nodeActivationRequestComposer: NodeActivationRequestComposer,
52
+ private readonly persistedRunStateTerminalBuilder: PersistedRunStateTerminalBuilder,
53
+ private readonly activationEnqueueService: ActivationEnqueueService,
54
+ private readonly nodeEventPublisher: NodeEventPublisher,
55
+ private readonly semantics: RunStateSemantics,
56
+ private readonly waiters: EngineWaiters,
57
+ private readonly policyErrorServices: WorkflowPolicyErrorServices,
58
+ private readonly terminalPersistence: RunTerminalPersistenceCoordinator,
59
+ private readonly executionLimitsPolicy: EngineExecutionLimitsPolicy,
60
+ ) {}
61
+
62
+ async markNodeRunning(args: {
63
+ runId: RunId;
64
+ activationId: NodeActivationId;
65
+ nodeId: NodeId;
66
+ inputsByPort: NodeInputsByPort;
67
+ }): Promise<void> {
68
+ const state = await this.workflowExecutionRepository.load(args.runId);
69
+ if (!state?.pending) return;
70
+ if (state.pending.activationId !== args.activationId || state.pending.nodeId !== args.nodeId) return;
71
+
72
+ const startedAt = new Date().toISOString();
73
+ const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
74
+ const snapshot = NodeExecutionSnapshotFactory.running({
75
+ previous,
76
+ runId: state.runId,
77
+ workflowId: state.workflowId,
78
+ nodeId: args.nodeId,
79
+ activationId: args.activationId,
80
+ parent: state.parent,
81
+ startedAt,
82
+ inputsByPort: args.inputsByPort,
83
+ });
84
+
85
+ await this.workflowExecutionRepository.save({
86
+ ...state,
87
+ nodeSnapshotsByNodeId: {
88
+ ...(state.nodeSnapshotsByNodeId ?? {}),
89
+ [args.nodeId]: snapshot,
90
+ },
91
+ });
92
+ await this.nodeEventPublisher.publish("nodeStarted", snapshot);
93
+ }
94
+
95
+ async resumeFromNodeResult(args: {
96
+ runId: RunId;
97
+ activationId: NodeActivationId;
98
+ nodeId: NodeId;
99
+ outputs: NodeOutputs;
100
+ }): Promise<RunResult> {
101
+ const state = await this.workflowExecutionRepository.load(args.runId);
102
+ if (!state) throw new Error(`Unknown runId: ${args.runId}`);
103
+ if (state.status !== "pending" || !state.pending) throw new Error(`Run ${args.runId} is not pending`);
104
+ if (state.pending.activationId !== args.activationId)
105
+ throw new Error(`activationId mismatch for run ${args.runId}`);
106
+ if (state.pending.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
107
+
108
+ const wf = this.resolvePersistedWorkflow(state);
109
+ if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
110
+
111
+ const { topology, planner } = this.planningFactory.create(wf);
112
+
113
+ const data = this.runDataFactory.create(state.outputsByNode);
114
+ const limits = this.resolveEngineLimitsFromState(state);
115
+ const base = this.runExecutionContextFactory.create({
116
+ runId: state.runId,
117
+ workflowId: state.workflowId,
118
+ nodeId: args.nodeId,
119
+ parent: state.parent,
120
+ subworkflowDepth: state.executionOptions?.subworkflowDepth ?? 0,
121
+ engineMaxNodeActivations: limits.engineMaxNodeActivations,
122
+ engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
123
+ data,
124
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent),
125
+ });
126
+
127
+ data.setOutputs(args.nodeId, args.outputs);
128
+ const completedAt = new Date().toISOString();
129
+ const completedSnapshot = this.semantics.createFinishedSnapshot({
130
+ workflow: wf,
131
+ previous: state.nodeSnapshotsByNodeId?.[args.nodeId],
132
+ runId: state.runId,
133
+ workflowId: state.workflowId,
134
+ nodeId: args.nodeId,
135
+ activationId: args.activationId,
136
+ parent: state.parent,
137
+ finishedAt: completedAt,
138
+ inputsByPort: state.pending.inputsByPort,
139
+ outputs: args.outputs,
140
+ });
141
+
142
+ const completedActivations = (state.engineCounters?.completedNodeActivations ?? 0) + 1;
143
+ const engineCounters = { completedNodeActivations: completedActivations };
144
+ const maxNodeActivations = state.executionOptions?.maxNodeActivations ?? Number.MAX_SAFE_INTEGER;
145
+
146
+ if (this.semantics.isStopConditionSatisfied(state.control?.stopCondition, args.nodeId)) {
147
+ const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
148
+ state,
149
+ engineCounters,
150
+ status: "completed",
151
+ queue: [],
152
+ outputsByNode: data.dump(),
153
+ nodeSnapshotsByNodeId: {
154
+ ...(state.nodeSnapshotsByNodeId ?? {}),
155
+ [args.nodeId]: completedSnapshot,
156
+ },
157
+ });
158
+ await this.workflowExecutionRepository.save(completedState);
159
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
160
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
161
+ workflow: wf,
162
+ state: completedState,
163
+ finalStatus: "completed",
164
+ finishedAt: completedAt,
165
+ });
166
+ const result: RunResult = {
167
+ runId: state.runId,
168
+ workflowId: state.workflowId,
169
+ startedAt: state.startedAt,
170
+ status: "completed",
171
+ outputs: this.semantics.resolveResultOutputs(wf, state.control?.stopCondition, data.dump()),
172
+ };
173
+ this.waiters.resolveRunCompletion(result);
174
+ return result;
175
+ }
176
+
177
+ const batchId = state.pending.batchId ?? "batch_1";
178
+ const queue: RunQueueEntry[] = (state.queue ?? []).map((q) => ({ ...q, batchId: q.batchId ?? batchId }));
179
+ const nextNodeSnapshotsByNodeId = {
180
+ ...(state.nodeSnapshotsByNodeId ?? {}),
181
+ [args.nodeId]: completedSnapshot,
182
+ };
183
+
184
+ planner.applyOutputs(queue, { fromNodeId: args.nodeId, outputs: args.outputs as any, batchId });
185
+ this.semantics.applyPinnedQueueSkips({
186
+ runId: state.runId,
187
+ workflowId: state.workflowId,
188
+ parent: state.parent,
189
+ mutableState: state.mutableState,
190
+ planner,
191
+ queue,
192
+ data,
193
+ nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
194
+ finishedAt: completedAt,
195
+ });
196
+
197
+ let next: ReturnType<(typeof planner)["nextActivation"]>;
198
+ try {
199
+ next = planner.nextActivation(queue);
200
+ } catch (cause) {
201
+ const completedDefinition = topology.defsById.get(args.nodeId);
202
+ const completedNodeLabel = this.formatNodeLabel({
203
+ definition: completedDefinition,
204
+ nodeId: args.nodeId,
205
+ });
206
+ const reason = cause instanceof Error ? cause.message : String(cause);
207
+ throw new Error(
208
+ `After completing ${completedNodeLabel}, the engine could not plan the next activation. ${reason} Outputs: ${this.formatOutputCounts(args.outputs)}.`,
209
+ { cause },
210
+ );
211
+ }
212
+ if (!next) {
213
+ const lastNodeId = WorkflowExecutableNodeClassifierFactory.create(wf).lastExecutableNodeIdInDefinitionOrder(wf);
214
+ const outputs = data.getOutputItems(lastNodeId, "main");
215
+
216
+ const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
217
+ state,
218
+ engineCounters,
219
+ status: "completed",
220
+ queue: [],
221
+ outputsByNode: data.dump(),
222
+ nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
223
+ });
224
+ await this.workflowExecutionRepository.save(completedState);
225
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
226
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
227
+ workflow: wf,
228
+ state: completedState,
229
+ finalStatus: "completed",
230
+ finishedAt: completedAt,
231
+ });
232
+
233
+ const result: RunResult = {
234
+ runId: state.runId,
235
+ workflowId: state.workflowId,
236
+ startedAt: state.startedAt,
237
+ status: "completed",
238
+ outputs,
239
+ };
240
+ this.waiters.resolveRunCompletion(result);
241
+ return result;
242
+ }
243
+
244
+ if (completedActivations >= maxNodeActivations) {
245
+ const message = `Run exceeded maxNodeActivations (${maxNodeActivations}) after ${completedActivations} completed node activations (next would be ${next.nodeId}).`;
246
+ const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
247
+ state,
248
+ engineCounters,
249
+ status: "failed",
250
+ queue: queue.map((q) => ({ ...q })),
251
+ outputsByNode: data.dump(),
252
+ nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
253
+ });
254
+ await this.workflowExecutionRepository.save(failedState);
255
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
256
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
257
+ workflow: wf,
258
+ state: failedState,
259
+ finalStatus: "failed",
260
+ finishedAt: completedAt,
261
+ });
262
+ const result: RunResult = {
263
+ runId: state.runId,
264
+ workflowId: state.workflowId,
265
+ startedAt: state.startedAt,
266
+ status: "failed",
267
+ error: { message },
268
+ };
269
+ this.waiters.resolveRunCompletion(result);
270
+ return result;
271
+ }
272
+
273
+ const def = topology.defsById.get(next.nodeId);
274
+ if (!def || def.kind !== "node") throw new Error(`Node ${next.nodeId} is not a runnable node`);
275
+
276
+ const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
277
+ next,
278
+ base,
279
+ data,
280
+ runId: state.runId,
281
+ workflowId: state.workflowId,
282
+ parent: state.parent,
283
+ executionOptions: state.executionOptions,
284
+ nodeDefinition: def,
285
+ });
286
+
287
+ const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
288
+ runId: state.runId,
289
+ workflowId: state.workflowId,
290
+ startedAt: state.startedAt,
291
+ parent: state.parent,
292
+ executionOptions: state.executionOptions,
293
+ control: state.control,
294
+ workflowSnapshot: state.workflowSnapshot,
295
+ mutableState: state.mutableState,
296
+ policySnapshot: state.policySnapshot,
297
+ pendingQueue: queue,
298
+ request,
299
+ previousNodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
300
+ planner,
301
+ engineCounters,
302
+ connectionInvocations: state.connectionInvocations ?? [],
303
+ });
304
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
305
+ await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
306
+ return result;
307
+ }
308
+
309
+ async resumeFromNodeError(args: {
310
+ runId: RunId;
311
+ activationId: NodeActivationId;
312
+ nodeId: NodeId;
313
+ error: Error;
314
+ }): Promise<RunResult> {
315
+ const state = await this.workflowExecutionRepository.load(args.runId);
316
+ if (!state) throw new Error(`Unknown runId: ${args.runId}`);
317
+ if (state.status !== "pending" || !state.pending) throw new Error(`Run ${args.runId} is not pending`);
318
+ if (state.pending.activationId !== args.activationId)
319
+ throw new Error(`activationId mismatch for run ${args.runId}`);
320
+ if (state.pending.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
321
+
322
+ const wf = this.resolvePersistedWorkflow(state);
323
+ if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
324
+ const failedDefinition = WorkflowTopology.fromWorkflow(wf).defsById.get(args.nodeId);
325
+ const webhookControlSignal =
326
+ state.executionOptions?.webhook && failedDefinition?.kind === "trigger"
327
+ ? this.asWebhookControlSignal(args.error)
328
+ : undefined;
329
+ if (webhookControlSignal) {
330
+ return await this.resumeFromWebhookControl({ state, workflow: wf, args, signal: webhookControlSignal });
331
+ }
332
+
333
+ if (failedDefinition && failedDefinition.kind === "node") {
334
+ const nodeHandler = this.policyErrorServices.resolveNodeErrorHandler(failedDefinition.config.nodeErrorHandler);
335
+ if (nodeHandler) {
336
+ try {
337
+ const ctx = this.buildNodeExecutionContextForPending(state, wf, failedDefinition, args.nodeId);
338
+ const inputsByPort = state.pending.inputsByPort;
339
+ const portKeys = Object.keys(inputsByPort);
340
+ const kind = portKeys.length === 1 && portKeys[0] === "in" ? ("single" as const) : ("multi" as const);
341
+ const items = inputsByPort.in ?? [];
342
+ const recovered = await nodeHandler.handle({
343
+ kind,
344
+ items,
345
+ inputsByPort: kind === "multi" ? inputsByPort : undefined,
346
+ ctx,
347
+ error: args.error,
348
+ });
349
+ return await this.resumeFromNodeResult({
350
+ runId: args.runId,
351
+ activationId: args.activationId,
352
+ nodeId: args.nodeId,
353
+ outputs: recovered,
354
+ });
355
+ } catch {
356
+ // fall through to workflow-level failure
357
+ }
358
+ }
359
+ }
360
+
361
+ const finishedAt = new Date().toISOString();
362
+ const message = args.error?.message ?? String(args.error);
363
+ const failedSnapshot = NodeExecutionSnapshotFactory.failed({
364
+ previous: state.nodeSnapshotsByNodeId?.[args.nodeId],
365
+ runId: state.runId,
366
+ workflowId: state.workflowId,
367
+ nodeId: args.nodeId,
368
+ activationId: args.activationId,
369
+ parent: state.parent,
370
+ finishedAt,
371
+ inputsByPort: state.pending.inputsByPort,
372
+ error: args.error,
373
+ });
374
+ const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
375
+ state,
376
+ engineCounters: state.engineCounters ?? { completedNodeActivations: 0 },
377
+ status: "failed",
378
+ queue: (state.queue ?? []).map((q) => ({ ...q })),
379
+ outputsByNode: state.outputsByNode,
380
+ nodeSnapshotsByNodeId: {
381
+ ...(state.nodeSnapshotsByNodeId ?? {}),
382
+ [args.nodeId]: failedSnapshot,
383
+ },
384
+ });
385
+ await this.workflowExecutionRepository.save(failedState);
386
+ await this.nodeEventPublisher.publish("nodeFailed", failedSnapshot);
387
+
388
+ const wfErr = this.policyErrorServices.resolveWorkflowErrorHandler(wf.workflowErrorHandler);
389
+ if (wfErr) {
390
+ await Promise.resolve(
391
+ wfErr.onError({
392
+ runId: state.runId,
393
+ workflowId: state.workflowId,
394
+ workflow: wf,
395
+ failedNodeId: args.nodeId,
396
+ error: args.error,
397
+ startedAt: state.startedAt,
398
+ finishedAt,
399
+ }),
400
+ );
401
+ }
402
+
403
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
404
+ workflow: wf,
405
+ state: failedState,
406
+ finalStatus: "failed",
407
+ finishedAt,
408
+ });
409
+
410
+ const result: RunResult = {
411
+ runId: state.runId,
412
+ workflowId: state.workflowId,
413
+ startedAt: state.startedAt,
414
+ status: "failed",
415
+ error: { message },
416
+ };
417
+ this.waiters.resolveRunCompletion(result);
418
+ return result;
419
+ }
420
+
421
+ async resumeFromStepResult(args: {
422
+ runId: RunId;
423
+ activationId: NodeActivationId;
424
+ nodeId: NodeId;
425
+ outputs: NodeOutputs;
426
+ }): Promise<RunResult> {
427
+ return await this.resumeFromNodeResult(args);
428
+ }
429
+
430
+ async resumeFromStepError(args: {
431
+ runId: RunId;
432
+ activationId: NodeActivationId;
433
+ nodeId: NodeId;
434
+ error: Error;
435
+ }): Promise<RunResult> {
436
+ return await this.resumeFromNodeError(args);
437
+ }
438
+
439
+ async waitForCompletion(runId: RunId): Promise<Extract<RunResult, { status: "completed" | "failed" }>> {
440
+ const existing = await this.workflowExecutionRepository.load(runId);
441
+ if (existing?.status === "completed") {
442
+ const wf = this.resolvePersistedWorkflow(existing);
443
+ const outputs = wf
444
+ ? this.semantics.resolveResultOutputs(wf, existing.control?.stopCondition, existing.outputsByNode)
445
+ : [];
446
+ return {
447
+ runId: existing.runId,
448
+ workflowId: existing.workflowId,
449
+ startedAt: existing.startedAt,
450
+ status: "completed",
451
+ outputs,
452
+ };
453
+ }
454
+ if (existing?.status === "failed") {
455
+ return {
456
+ runId: existing.runId,
457
+ workflowId: existing.workflowId,
458
+ startedAt: existing.startedAt,
459
+ status: "failed",
460
+ error: { message: "Run failed" },
461
+ };
462
+ }
463
+
464
+ const result = await this.waiters.waitForCompletion(runId);
465
+ if (result.status !== "completed" && result.status !== "failed") {
466
+ throw new Error(`Unexpected run completion status: ${result.status}`);
467
+ }
468
+ return result;
469
+ }
470
+
471
+ async waitForWebhookResponse(runId: RunId): Promise<WebhookRunResult> {
472
+ return await this.waiters.waitForWebhookResponse(runId);
473
+ }
474
+
475
+ private async resumeFromWebhookControl(args: {
476
+ state: NonNullable<Awaited<ReturnType<WorkflowExecutionRepository["load"]>>>;
477
+ workflow: WorkflowDefinition;
478
+ args: { runId: RunId; activationId: NodeActivationId; nodeId: NodeId; error: Error };
479
+ signal: WebhookControlSignal;
480
+ }): Promise<RunResult> {
481
+ const data = this.runDataFactory.create(args.state.outputsByNode);
482
+ const { topology, planner } = this.planningFactory.create(args.workflow);
483
+
484
+ const continuedItems =
485
+ args.signal.kind === "respondNowAndContinue" ? (args.signal.continueItems ?? []) : args.signal.responseItems;
486
+ const triggerOutputs: NodeOutputs = { main: continuedItems };
487
+ data.setOutputs(args.args.nodeId, triggerOutputs);
488
+
489
+ const completedSnapshot = this.semantics.createFinishedSnapshot({
490
+ workflow: args.workflow,
491
+ previous: args.state.nodeSnapshotsByNodeId?.[args.args.nodeId],
492
+ runId: args.state.runId,
493
+ workflowId: args.state.workflowId,
494
+ nodeId: args.args.nodeId,
495
+ activationId: args.args.activationId,
496
+ parent: args.state.parent,
497
+ finishedAt: new Date().toISOString(),
498
+ inputsByPort: args.state.pending?.inputsByPort ?? NodeInputsByPortFactory.empty(),
499
+ outputs: triggerOutputs,
500
+ });
501
+
502
+ const completedActivations = (args.state.engineCounters?.completedNodeActivations ?? 0) + 1;
503
+ const engineCounters = { completedNodeActivations: completedActivations };
504
+ const maxNodeActivations = args.state.executionOptions?.maxNodeActivations ?? Number.MAX_SAFE_INTEGER;
505
+
506
+ if (this.semantics.isStopConditionSatisfied(args.state.control?.stopCondition, args.args.nodeId)) {
507
+ const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
508
+ state: args.state,
509
+ engineCounters,
510
+ status: "completed",
511
+ queue: [],
512
+ outputsByNode: data.dump(),
513
+ nodeSnapshotsByNodeId: {
514
+ ...(args.state.nodeSnapshotsByNodeId ?? {}),
515
+ [args.args.nodeId]: completedSnapshot,
516
+ },
517
+ });
518
+ await this.workflowExecutionRepository.save(completedState);
519
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
520
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
521
+ workflow: args.workflow,
522
+ state: completedState,
523
+ finalStatus: "completed",
524
+ finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt,
525
+ });
526
+ this.waiters.resolveWebhookResponse({
527
+ runId: args.state.runId,
528
+ workflowId: args.state.workflowId,
529
+ startedAt: args.state.startedAt,
530
+ runStatus: "completed",
531
+ response: args.signal.responseItems,
532
+ });
533
+ const result: RunResult = {
534
+ runId: args.state.runId,
535
+ workflowId: args.state.workflowId,
536
+ startedAt: args.state.startedAt,
537
+ status: "completed",
538
+ outputs: this.semantics.resolveResultOutputs(args.workflow, args.state.control?.stopCondition, data.dump()),
539
+ };
540
+ this.waiters.resolveRunCompletion(result);
541
+ return result;
542
+ }
543
+
544
+ if (args.signal.kind === "respondNow") {
545
+ const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
546
+ state: args.state,
547
+ engineCounters,
548
+ status: "completed",
549
+ queue: [],
550
+ outputsByNode: data.dump(),
551
+ nodeSnapshotsByNodeId: {
552
+ ...(args.state.nodeSnapshotsByNodeId ?? {}),
553
+ [args.args.nodeId]: completedSnapshot,
554
+ },
555
+ });
556
+ await this.workflowExecutionRepository.save(completedState);
557
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
558
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
559
+ workflow: args.workflow,
560
+ state: completedState,
561
+ finalStatus: "completed",
562
+ finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt,
563
+ });
564
+
565
+ const result: RunResult = {
566
+ runId: args.state.runId,
567
+ workflowId: args.state.workflowId,
568
+ startedAt: args.state.startedAt,
569
+ status: "completed",
570
+ outputs: args.signal.responseItems,
571
+ };
572
+ this.waiters.resolveWebhookResponse({
573
+ runId: args.state.runId,
574
+ workflowId: args.state.workflowId,
575
+ startedAt: args.state.startedAt,
576
+ runStatus: "completed",
577
+ response: args.signal.responseItems,
578
+ });
579
+ this.waiters.resolveRunCompletion(result);
580
+ return result;
581
+ }
582
+
583
+ const batchId = args.state.pending?.batchId ?? "batch_1";
584
+ const queue: RunQueueEntry[] = (args.state.queue ?? []).map((entry) => ({
585
+ ...entry,
586
+ batchId: entry.batchId ?? batchId,
587
+ }));
588
+ planner.applyOutputs(queue, { fromNodeId: args.args.nodeId, outputs: triggerOutputs as any, batchId });
589
+ const next = planner.nextActivation(queue);
590
+
591
+ if (!next) {
592
+ const lastNodeId = WorkflowExecutableNodeClassifierFactory.create(
593
+ args.workflow,
594
+ ).lastExecutableNodeIdInDefinitionOrder(args.workflow);
595
+ const outputs = data.getOutputItems(lastNodeId, "main");
596
+ const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
597
+ state: args.state,
598
+ engineCounters,
599
+ status: "completed",
600
+ queue: [],
601
+ outputsByNode: data.dump(),
602
+ nodeSnapshotsByNodeId: {
603
+ ...(args.state.nodeSnapshotsByNodeId ?? {}),
604
+ [args.args.nodeId]: completedSnapshot,
605
+ },
606
+ });
607
+ await this.workflowExecutionRepository.save(completedState);
608
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
609
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
610
+ workflow: args.workflow,
611
+ state: completedState,
612
+ finalStatus: "completed",
613
+ finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt,
614
+ });
615
+
616
+ const result: RunResult = {
617
+ runId: args.state.runId,
618
+ workflowId: args.state.workflowId,
619
+ startedAt: args.state.startedAt,
620
+ status: "completed",
621
+ outputs,
622
+ };
623
+ this.waiters.resolveWebhookResponse({
624
+ runId: args.state.runId,
625
+ workflowId: args.state.workflowId,
626
+ startedAt: args.state.startedAt,
627
+ runStatus: "completed",
628
+ response: args.signal.responseItems,
629
+ });
630
+ this.waiters.resolveRunCompletion(result);
631
+ return result;
632
+ }
633
+
634
+ if (completedActivations >= maxNodeActivations) {
635
+ const message = `Run exceeded maxNodeActivations (${maxNodeActivations}) after ${completedActivations} completed node activations (next would be ${next.nodeId}).`;
636
+ const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
637
+ state: args.state,
638
+ engineCounters,
639
+ status: "failed",
640
+ queue: queue.map((q) => ({ ...q })),
641
+ outputsByNode: data.dump(),
642
+ nodeSnapshotsByNodeId: {
643
+ ...(args.state.nodeSnapshotsByNodeId ?? {}),
644
+ [args.args.nodeId]: completedSnapshot,
645
+ },
646
+ });
647
+ await this.workflowExecutionRepository.save(failedState);
648
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
649
+ await this.terminalPersistence.maybeDeleteAfterTerminalState({
650
+ workflow: args.workflow,
651
+ state: failedState,
652
+ finalStatus: "failed",
653
+ finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt,
654
+ });
655
+ const result: RunResult = {
656
+ runId: args.state.runId,
657
+ workflowId: args.state.workflowId,
658
+ startedAt: args.state.startedAt,
659
+ status: "failed",
660
+ error: { message },
661
+ };
662
+ this.waiters.resolveWebhookResponse({
663
+ runId: args.state.runId,
664
+ workflowId: args.state.workflowId,
665
+ startedAt: args.state.startedAt,
666
+ runStatus: "pending",
667
+ response: args.signal.responseItems,
668
+ });
669
+ this.waiters.resolveRunCompletion(result);
670
+ return result;
671
+ }
672
+
673
+ const nextDefinition = topology.defsById.get(next.nodeId);
674
+ if (!nextDefinition || nextDefinition.kind !== "node") {
675
+ throw new Error(`Node ${next.nodeId} is not a runnable node`);
676
+ }
677
+
678
+ const webhookLimits = this.resolveEngineLimitsFromState(args.state);
679
+ const base = this.runExecutionContextFactory.create({
680
+ runId: args.state.runId,
681
+ workflowId: args.state.workflowId,
682
+ nodeId: nextDefinition.id,
683
+ parent: args.state.parent,
684
+ subworkflowDepth: args.state.executionOptions?.subworkflowDepth ?? 0,
685
+ engineMaxNodeActivations: webhookLimits.engineMaxNodeActivations,
686
+ engineMaxSubworkflowDepth: webhookLimits.engineMaxSubworkflowDepth,
687
+ data,
688
+ nodeState: this.nodeStatePublisherFactory.create(args.state.runId, args.state.workflowId, args.state.parent),
689
+ });
690
+ const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
691
+ next,
692
+ base,
693
+ data,
694
+ runId: args.state.runId,
695
+ workflowId: args.state.workflowId,
696
+ parent: args.state.parent,
697
+ executionOptions: args.state.executionOptions,
698
+ nodeDefinition: nextDefinition,
699
+ });
700
+
701
+ const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
702
+ runId: args.state.runId,
703
+ workflowId: args.state.workflowId,
704
+ startedAt: args.state.startedAt,
705
+ parent: args.state.parent,
706
+ executionOptions: args.state.executionOptions,
707
+ control: args.state.control,
708
+ workflowSnapshot: args.state.workflowSnapshot,
709
+ mutableState: args.state.mutableState,
710
+ policySnapshot: args.state.policySnapshot,
711
+ pendingQueue: queue,
712
+ request,
713
+ previousNodeSnapshotsByNodeId: {
714
+ ...(args.state.nodeSnapshotsByNodeId ?? {}),
715
+ [args.args.nodeId]: completedSnapshot,
716
+ },
717
+ planner,
718
+ engineCounters,
719
+ connectionInvocations: args.state.connectionInvocations ?? [],
720
+ });
721
+ await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
722
+ await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
723
+ this.waiters.resolveWebhookResponse({
724
+ runId: args.state.runId,
725
+ workflowId: args.state.workflowId,
726
+ startedAt: args.state.startedAt,
727
+ runStatus: "pending",
728
+ response: args.signal.responseItems,
729
+ });
730
+ return result;
731
+ }
732
+
733
+ private asWebhookControlSignal(error: Error): WebhookControlSignal | undefined {
734
+ const candidate = error as Partial<WebhookControlSignal> | undefined;
735
+ if (!candidate || candidate.__webhookControl !== true) return undefined;
736
+ if (candidate.kind !== "respondNow" && candidate.kind !== "respondNowAndContinue") return undefined;
737
+ if (!Array.isArray(candidate.responseItems)) return undefined;
738
+ return candidate as WebhookControlSignal;
739
+ }
740
+
741
+ private resolvePersistedWorkflow(state: {
742
+ workflowId: WorkflowId;
743
+ workflowSnapshot?: NonNullable<Awaited<ReturnType<WorkflowExecutionRepository["load"]>>>["workflowSnapshot"];
744
+ }): WorkflowDefinition | undefined {
745
+ return this.workflowSnapshotResolver.resolve({
746
+ workflowId: state.workflowId,
747
+ workflowSnapshot: state.workflowSnapshot,
748
+ });
749
+ }
750
+
751
+ private buildNodeExecutionContextForPending(
752
+ state: NonNullable<Awaited<ReturnType<WorkflowExecutionRepository["load"]>>>,
753
+ wf: WorkflowDefinition,
754
+ def: Readonly<{ id: NodeId; config: NodeExecutionContext["config"] }>,
755
+ nodeId: NodeId,
756
+ ): NodeExecutionContext {
757
+ const data = this.runDataFactory.create(state.outputsByNode);
758
+ const limits = this.resolveEngineLimitsFromState(state);
759
+ const base = this.runExecutionContextFactory.create({
760
+ runId: state.runId,
761
+ workflowId: state.workflowId,
762
+ nodeId,
763
+ parent: state.parent,
764
+ subworkflowDepth: state.executionOptions?.subworkflowDepth ?? 0,
765
+ engineMaxNodeActivations: limits.engineMaxNodeActivations,
766
+ engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
767
+ data,
768
+ nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent),
769
+ });
770
+ const activationId = state.pending!.activationId;
771
+ return {
772
+ ...base,
773
+ data,
774
+ nodeId,
775
+ activationId,
776
+ config: def.config,
777
+ binary: base.binary.forNode({ nodeId, activationId }),
778
+ getCredential: this.credentialResolverFactory.create(wf.id, nodeId, def.config),
779
+ };
780
+ }
781
+
782
+ private resolveEngineLimitsFromState(state: PersistedRunState): {
783
+ engineMaxNodeActivations: number;
784
+ engineMaxSubworkflowDepth: number;
785
+ } {
786
+ const fb = this.executionLimitsPolicy.createRootExecutionOptions();
787
+ return {
788
+ engineMaxNodeActivations: state.executionOptions?.maxNodeActivations ?? fb.maxNodeActivations!,
789
+ engineMaxSubworkflowDepth: state.executionOptions?.maxSubworkflowDepth ?? fb.maxSubworkflowDepth!,
790
+ };
791
+ }
792
+
793
+ private formatNodeLabel(args: {
794
+ definition?: Readonly<{ id: NodeId; name?: string; type: unknown }>;
795
+ nodeId: NodeId;
796
+ }): string {
797
+ const tokenName = typeof args.definition?.type === "function" ? args.definition.type.name : "Node";
798
+ return args.definition?.name
799
+ ? `"${args.definition.name}" (${tokenName}:${args.nodeId})`
800
+ : `${tokenName}:${args.nodeId}`;
801
+ }
802
+
803
+ private formatOutputCounts(outputs: NodeOutputs): string {
804
+ const entries = Object.entries(outputs ?? {});
805
+ if (entries.length === 0) {
806
+ return "no outputs";
807
+ }
808
+ return entries.map(([port, items]) => `${port}=${items?.length ?? 0}`).join(", ");
809
+ }
810
+ }