@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,63 @@
1
+ import type { WorkflowDefinition, WorkflowNodeInstanceFactory } from "../types";
2
+ import { WorkflowExecutableNodeClassifierFactory } from "../workflow/definition/WorkflowExecutableNodeClassifierFactory";
3
+
4
+ import { RunQueuePlanner } from "./RunQueuePlanner";
5
+ import { WorkflowTopology } from "./WorkflowTopologyPlanner";
6
+
7
+ export class EngineWorkflowPlanningFactory {
8
+ constructor(private readonly workflowNodeInstanceFactory: WorkflowNodeInstanceFactory) {}
9
+
10
+ create(workflow: WorkflowDefinition): Readonly<{ topology: WorkflowTopology; planner: RunQueuePlanner }> {
11
+ this.validateAcyclic(workflow);
12
+ const topology = WorkflowTopology.fromWorkflow(workflow);
13
+ const nodeInstances = this.workflowNodeInstanceFactory.createNodes(workflow);
14
+ const planner = new RunQueuePlanner(topology, nodeInstances);
15
+ planner.validateNodeKinds();
16
+ return { topology, planner };
17
+ }
18
+
19
+ private validateAcyclic(workflow: WorkflowDefinition): void {
20
+ const classifier = WorkflowExecutableNodeClassifierFactory.create(workflow);
21
+ const outgoing = new Map<string, string[]>();
22
+ const visitState = new Map<string, "unvisited" | "visiting" | "done">();
23
+
24
+ for (const node of workflow.nodes) {
25
+ if (classifier.isExecutableNodeId(node.id)) {
26
+ visitState.set(node.id, "unvisited");
27
+ }
28
+ }
29
+
30
+ for (const edge of workflow.edges) {
31
+ if (!classifier.isExecutableNodeId(edge.from.nodeId) || !classifier.isExecutableNodeId(edge.to.nodeId)) {
32
+ continue;
33
+ }
34
+ const destinations = outgoing.get(edge.from.nodeId) ?? [];
35
+ destinations.push(edge.to.nodeId);
36
+ outgoing.set(edge.from.nodeId, destinations);
37
+ }
38
+
39
+ for (const node of workflow.nodes) {
40
+ if (classifier.isExecutableNodeId(node.id) && visitState.get(node.id) === "unvisited") {
41
+ this.depthFirstSearch(node.id, outgoing, visitState);
42
+ }
43
+ }
44
+ }
45
+
46
+ private depthFirstSearch(
47
+ nodeId: string,
48
+ outgoing: ReadonlyMap<string, ReadonlyArray<string>>,
49
+ visitState: Map<string, "unvisited" | "visiting" | "done">,
50
+ ): void {
51
+ visitState.set(nodeId, "visiting");
52
+ for (const toNodeId of outgoing.get(nodeId) ?? []) {
53
+ const state = visitState.get(toNodeId);
54
+ if (state === "visiting") {
55
+ throw new Error(`Workflow graph contains a directed cycle (edge ${nodeId} -> ${toNodeId}).`);
56
+ }
57
+ if (state === "unvisited") {
58
+ this.depthFirstSearch(toNodeId, outgoing, visitState);
59
+ }
60
+ }
61
+ visitState.set(nodeId, "done");
62
+ }
63
+ }
@@ -0,0 +1,302 @@
1
+ import type { InputPortKey, Items, NodeId, OutputPortKey, RunQueueEntry } from "../types";
2
+
3
+ import { WorkflowTopology } from "./WorkflowTopologyPlanner";
4
+
5
+ export type PlannedActivation =
6
+ | Readonly<{ kind: "single"; nodeId: NodeId; input: Items; batchId: string }>
7
+ | Readonly<{ kind: "multi"; nodeId: NodeId; inputsByPort: Readonly<Record<InputPortKey, Items>>; batchId: string }>;
8
+
9
+ export class RunQueuePlanner {
10
+ constructor(
11
+ private readonly topology: WorkflowTopology,
12
+ private readonly nodeInstances: ReadonlyMap<NodeId, unknown>,
13
+ ) {}
14
+
15
+ validateNodeKinds(): void {
16
+ for (const [toNodeId, inputs] of this.topology.expectedInputsByNode.entries()) {
17
+ if (inputs.length <= 1) {
18
+ const only = inputs[0];
19
+ if (only && only !== "in") {
20
+ const inst = this.nodeInstances.get(toNodeId);
21
+ if (!this.isMultiInputNode(inst))
22
+ throw new Error(`Node ${toNodeId} only supports input 'in' (got '${only}').`);
23
+ }
24
+ continue;
25
+ }
26
+
27
+ const inst = this.nodeInstances.get(toNodeId);
28
+ if (!this.isMultiInputNode(inst)) {
29
+ throw new Error(
30
+ `Node ${toNodeId} has ${inputs.length} inbound edges. Insert a Merge node to combine branches.`,
31
+ );
32
+ }
33
+ }
34
+ }
35
+
36
+ seedFromTrigger(args: { startNodeId: NodeId; items: Items; batchId: string }): RunQueueEntry[] {
37
+ const queue: RunQueueEntry[] = [];
38
+ for (const e of this.topology.outgoingByNode.get(args.startNodeId) ?? []) {
39
+ if (e.output !== "main") continue;
40
+ this.enqueueEdge(queue, {
41
+ batchId: args.batchId,
42
+ to: e.to,
43
+ from: { nodeId: args.startNodeId, output: "main" },
44
+ items: args.items,
45
+ });
46
+ }
47
+ return queue;
48
+ }
49
+
50
+ applyOutputs(
51
+ queue: RunQueueEntry[],
52
+ args: { fromNodeId: NodeId; outputs: Record<string, Items | undefined>; batchId: string },
53
+ ): void {
54
+ for (const e of this.topology.outgoingByNode.get(args.fromNodeId) ?? []) {
55
+ const outItems = (args.outputs as any)[e.output] ?? [];
56
+ this.enqueueEdge(queue, {
57
+ batchId: args.batchId,
58
+ to: e.to,
59
+ from: { nodeId: args.fromNodeId, output: e.output },
60
+ items: outItems,
61
+ });
62
+ }
63
+ }
64
+
65
+ nextActivation(queue: RunQueueEntry[]): PlannedActivation | null {
66
+ const readyCollect = this.resolveReadyCollect(queue);
67
+ if (readyCollect) {
68
+ return readyCollect;
69
+ }
70
+
71
+ const jobIdx = queue.findIndex((q) => !q.collect);
72
+ if (jobIdx === -1) {
73
+ if (queue.length === 0) return null;
74
+ const sealedCollect = this.resolveSealedCollect(queue);
75
+ if (sealedCollect) {
76
+ return sealedCollect;
77
+ }
78
+ const stuck = queue[0]!;
79
+ throw new Error(this.describeUnsatisfiedCollect(stuck));
80
+ }
81
+
82
+ const job = queue.splice(jobIdx, 1)[0]!;
83
+ const def = this.topology.defsById.get(job.nodeId);
84
+ if (!def || def.kind !== "node") return this.nextActivation(queue);
85
+ return { kind: "single", nodeId: job.nodeId, input: job.input, batchId: job.batchId ?? "batch_1" };
86
+ }
87
+
88
+ sumItemsByPort(inputsByPort: Readonly<Record<InputPortKey, Items>>): number {
89
+ let n = 0;
90
+ for (const v of Object.values(inputsByPort)) n += v?.length ?? 0;
91
+ return n;
92
+ }
93
+
94
+ private resolveReadyCollect(queue: RunQueueEntry[]): PlannedActivation | null {
95
+ for (let i = 0; i < queue.length; i++) {
96
+ const ready = this.tryDequeueCollect(queue, i);
97
+ if (ready) {
98
+ return ready;
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+
104
+ private resolveSealedCollect(queue: RunQueueEntry[]): PlannedActivation | null {
105
+ for (let i = 0; i < queue.length; i++) {
106
+ const queueEntry = queue[i]!;
107
+ if (!queueEntry.collect) {
108
+ continue;
109
+ }
110
+ const received = queueEntry.collect.received as Record<InputPortKey, Items>;
111
+ if (Object.keys(received).length === 0) {
112
+ continue;
113
+ }
114
+ this.fillMissingCollectInputs(queueEntry);
115
+ const ready = this.tryDequeueCollect(queue, i);
116
+ if (ready) {
117
+ return ready;
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+
123
+ private tryDequeueCollect(queue: RunQueueEntry[], index: number): PlannedActivation | null {
124
+ const queueEntry = queue[index]!;
125
+ if (!queueEntry.collect) {
126
+ return null;
127
+ }
128
+ const batchId = queueEntry.batchId ?? "batch_1";
129
+ const expected = queueEntry.collect.expectedInputs ?? [];
130
+ const received = queueEntry.collect.received as Record<InputPortKey, Items>;
131
+ for (const input of expected) {
132
+ if (!(input in received)) {
133
+ return null;
134
+ }
135
+ }
136
+ queue.splice(index, 1);
137
+ return { kind: "multi", nodeId: queueEntry.nodeId, inputsByPort: received, batchId };
138
+ }
139
+
140
+ private fillMissingCollectInputs(queueEntry: RunQueueEntry): void {
141
+ if (!queueEntry.collect) {
142
+ return;
143
+ }
144
+ const received = queueEntry.collect.received as Record<InputPortKey, Items>;
145
+ for (const input of queueEntry.collect.expectedInputs ?? []) {
146
+ if (!(input in received)) {
147
+ received[input] = [];
148
+ }
149
+ }
150
+ }
151
+
152
+ private enqueueEdge(
153
+ queue: RunQueueEntry[],
154
+ args: Readonly<{
155
+ batchId: string;
156
+ to: { nodeId: NodeId; input: InputPortKey };
157
+ from: { nodeId: NodeId; output: OutputPortKey };
158
+ items: Items;
159
+ }>,
160
+ ): void {
161
+ const target = this.nodeInstances.get(args.to.nodeId);
162
+ const isMulti = this.isMultiInputNode(target);
163
+
164
+ if (!isMulti) {
165
+ if (args.items.length === 0) {
166
+ if (this.shouldContinueAfterEmptyOutputFromSource(args.from.nodeId)) {
167
+ queue.push({
168
+ nodeId: args.to.nodeId,
169
+ input: args.items,
170
+ toInput: args.to.input,
171
+ batchId: args.batchId,
172
+ from: args.from,
173
+ });
174
+ return;
175
+ }
176
+ this.propagateEmptyPath(queue, args.to.nodeId, args.batchId);
177
+ return;
178
+ }
179
+ queue.push({
180
+ nodeId: args.to.nodeId,
181
+ input: args.items,
182
+ toInput: args.to.input,
183
+ batchId: args.batchId,
184
+ from: args.from,
185
+ });
186
+ return;
187
+ }
188
+
189
+ const expected = this.topology.expectedInputsByNode.get(args.to.nodeId) ?? [];
190
+ let collect = queue.find(
191
+ (q) => q.nodeId === args.to.nodeId && (q.batchId ?? "batch_1") === args.batchId && !!q.collect,
192
+ );
193
+ if (!collect) {
194
+ collect = {
195
+ nodeId: args.to.nodeId,
196
+ input: [],
197
+ batchId: args.batchId,
198
+ collect: { expectedInputs: expected, received: {} as Record<InputPortKey, Items> },
199
+ };
200
+ queue.push(collect);
201
+ }
202
+
203
+ const received = (collect.collect as any).received as Record<InputPortKey, Items>;
204
+ received[args.to.input] = args.items;
205
+ }
206
+
207
+ private shouldContinueAfterEmptyOutputFromSource(fromNodeId: NodeId): boolean {
208
+ const def = this.topology.defsById.get(fromNodeId);
209
+ if (!def) {
210
+ return false;
211
+ }
212
+ return def.config.continueWhenEmptyOutput === true;
213
+ }
214
+
215
+ private propagateEmptyPath(queue: RunQueueEntry[], nodeId: NodeId, batchId: string): void {
216
+ for (const edge of this.topology.outgoingByNode.get(nodeId) ?? []) {
217
+ this.enqueueEdge(queue, {
218
+ batchId,
219
+ to: edge.to,
220
+ from: { nodeId, output: edge.output },
221
+ items: [],
222
+ });
223
+ }
224
+ }
225
+
226
+ private isMultiInputNode(n: unknown): boolean {
227
+ return typeof (n as any)?.executeMulti === "function";
228
+ }
229
+
230
+ private describeUnsatisfiedCollect(queueEntry: RunQueueEntry): string {
231
+ const batchId = queueEntry.batchId ?? "batch_1";
232
+ const expectedInputs = queueEntry.collect?.expectedInputs ?? [];
233
+ const receivedInputs = Object.keys(
234
+ (queueEntry.collect?.received ?? {}) as Record<InputPortKey, Items>,
235
+ ) as InputPortKey[];
236
+ const missingInputs = expectedInputs.filter((input) => !receivedInputs.includes(input));
237
+ const mergeNodeLabel = this.formatNodeLabel(queueEntry.nodeId);
238
+ const receivedSummary = this.describeReceivedInputs(queueEntry);
239
+ const missingSummary = this.describeMissingInputs(queueEntry.nodeId, missingInputs);
240
+
241
+ return [
242
+ `Multi-input collect is stuck at ${mergeNodeLabel} (batchId=${batchId}).`,
243
+ `Expected inputs: ${this.formatInputList(expectedInputs)}.`,
244
+ `Received inputs: ${receivedSummary}.`,
245
+ `Missing inputs: ${missingSummary}.`,
246
+ ].join(" ");
247
+ }
248
+
249
+ private describeReceivedInputs(queueEntry: RunQueueEntry): string {
250
+ const received = (queueEntry.collect?.received ?? {}) as Record<InputPortKey, Items>;
251
+ const receivedEntries = Object.entries(received);
252
+ if (receivedEntries.length === 0) {
253
+ return "none";
254
+ }
255
+ return receivedEntries
256
+ .map(([input, items]) => `${input} (${items.length} item${items.length === 1 ? "" : "s"})`)
257
+ .join(", ");
258
+ }
259
+
260
+ private describeMissingInputs(nodeId: NodeId, missingInputs: ReadonlyArray<InputPortKey>): string {
261
+ if (missingInputs.length === 0) {
262
+ return "none";
263
+ }
264
+ return missingInputs
265
+ .map((input) => {
266
+ const sources = this.findSources(nodeId, input);
267
+ if (sources.length === 0) {
268
+ return input;
269
+ }
270
+ return `${input} from ${sources.join(" or ")}`;
271
+ })
272
+ .join(", ");
273
+ }
274
+
275
+ private findSources(nodeId: NodeId, input: InputPortKey): string[] {
276
+ const matches: string[] = [];
277
+ for (const [sourceNodeId, edges] of this.topology.outgoingByNode.entries()) {
278
+ for (const edge of edges) {
279
+ if (edge.to.nodeId === nodeId && edge.to.input === input) {
280
+ matches.push(this.formatNodeLabel(sourceNodeId));
281
+ }
282
+ }
283
+ }
284
+ return matches;
285
+ }
286
+
287
+ private formatInputList(inputs: ReadonlyArray<InputPortKey>): string {
288
+ return inputs.length > 0 ? `[${inputs.join(", ")}]` : "[]";
289
+ }
290
+
291
+ private formatNodeLabel(nodeId: NodeId): string {
292
+ const definition = this.topology.defsById.get(nodeId);
293
+ const instance = this.nodeInstances.get(nodeId);
294
+ const typeName =
295
+ definition?.type && typeof definition.type === "function"
296
+ ? definition.type.name
297
+ : instance && typeof instance === "object" && "constructor" in instance
298
+ ? ((instance.constructor as { name?: string }).name ?? "Node")
299
+ : "Node";
300
+ return definition?.name ? `"${definition.name}" (${typeName}:${nodeId})` : `${typeName}:${nodeId}`;
301
+ }
302
+ }
@@ -0,0 +1,77 @@
1
+ import type { InputPortKey, NodeId, OutputPortKey, WorkflowDefinition } from "../types";
2
+ import { WorkflowExecutableNodeClassifierFactory } from "../workflow/definition/WorkflowExecutableNodeClassifierFactory";
3
+
4
+ type NodeDef = WorkflowDefinition["nodes"][number];
5
+
6
+ export class WorkflowTopology {
7
+ private constructor(
8
+ public readonly defsById: ReadonlyMap<NodeId, NodeDef>,
9
+ public readonly outgoingByNode: ReadonlyMap<
10
+ NodeId,
11
+ ReadonlyArray<Readonly<{ output: OutputPortKey; to: Readonly<{ nodeId: NodeId; input: InputPortKey }> }>>
12
+ >,
13
+ public readonly incomingByNode: ReadonlyMap<
14
+ NodeId,
15
+ ReadonlyArray<Readonly<{ from: Readonly<{ nodeId: NodeId; output: OutputPortKey }>; input: InputPortKey }>>
16
+ >,
17
+ public readonly expectedInputsByNode: ReadonlyMap<NodeId, ReadonlyArray<InputPortKey>>,
18
+ public readonly rootNodeIds: ReadonlyArray<NodeId>,
19
+ ) {}
20
+
21
+ static fromWorkflow(wf: WorkflowDefinition): WorkflowTopology {
22
+ const classifier = WorkflowExecutableNodeClassifierFactory.create(wf);
23
+ const defs = new Map<NodeId, NodeDef>();
24
+ for (const n of wf.nodes) {
25
+ if (classifier.isExecutableNodeId(n.id)) defs.set(n.id, n);
26
+ }
27
+
28
+ const outgoing = new Map<
29
+ NodeId,
30
+ Array<Readonly<{ output: OutputPortKey; to: Readonly<{ nodeId: NodeId; input: InputPortKey }> }>>
31
+ >();
32
+ for (const e of wf.edges) {
33
+ if (!classifier.isExecutableNodeId(e.from.nodeId) || !classifier.isExecutableNodeId(e.to.nodeId)) {
34
+ continue;
35
+ }
36
+ const list = outgoing.get(e.from.nodeId) ?? [];
37
+ list.push({ output: e.from.output, to: { nodeId: e.to.nodeId, input: e.to.input } });
38
+ outgoing.set(e.from.nodeId, list);
39
+ }
40
+
41
+ const incomingByNode = new Map<
42
+ NodeId,
43
+ Array<Readonly<{ from: Readonly<{ nodeId: NodeId; output: OutputPortKey }>; input: InputPortKey }>>
44
+ >();
45
+ for (const e of wf.edges) {
46
+ if (!classifier.isExecutableNodeId(e.from.nodeId) || !classifier.isExecutableNodeId(e.to.nodeId)) {
47
+ continue;
48
+ }
49
+ const list = incomingByNode.get(e.to.nodeId) ?? [];
50
+ list.push({ from: { nodeId: e.from.nodeId, output: e.from.output }, input: e.to.input });
51
+ incomingByNode.set(e.to.nodeId, list);
52
+ }
53
+
54
+ const expected = new Map<NodeId, InputPortKey[]>();
55
+ for (const [toNodeId, inputs] of incomingByNode.entries()) {
56
+ const counts = new Map<InputPortKey, number>();
57
+ for (const edge of inputs) counts.set(edge.input, (counts.get(edge.input) ?? 0) + 1);
58
+ for (const [k, n] of counts.entries()) {
59
+ if (n > 1) throw new Error(`Node ${toNodeId} has multiple edges into input '${k}'. Use a Merge node upstream.`);
60
+ }
61
+
62
+ const order: InputPortKey[] = [];
63
+ const seen = new Set<InputPortKey>();
64
+ for (const edge of inputs) {
65
+ if (seen.has(edge.input)) continue;
66
+ seen.add(edge.input);
67
+ order.push(edge.input);
68
+ }
69
+ expected.set(toNodeId, order);
70
+ }
71
+
72
+ const rootNodeIds = wf.nodes
73
+ .filter((node) => classifier.isExecutableNodeId(node.id) && !incomingByNode.has(node.id))
74
+ .map((node) => node.id);
75
+ return new WorkflowTopology(defs, outgoing, incomingByNode, expected, rootNodeIds);
76
+ }
77
+ }
@@ -0,0 +1,4 @@
1
+ export { CurrentStateFrontierPlanner } from "./CurrentStateFrontierPlanner";
2
+ export { EngineWorkflowPlanningFactory } from "./EngineWorkflowPlanningFactory";
3
+ export { RunQueuePlanner } from "./RunQueuePlanner";
4
+ export { WorkflowTopology } from "./WorkflowTopologyPlanner";
@@ -0,0 +1,38 @@
1
+ import type { TypeToken } from "../di";
2
+ import type {
3
+ NodeErrorHandler,
4
+ NodeErrorHandlerSpec,
5
+ NodeResolver,
6
+ WorkflowErrorHandler,
7
+ WorkflowErrorHandlerSpec,
8
+ } from "../types";
9
+
10
+ export class WorkflowPolicyErrorServices {
11
+ constructor(private readonly nodeResolver: NodeResolver) {}
12
+
13
+ resolveNodeErrorHandler(spec: NodeErrorHandlerSpec | undefined): NodeErrorHandler | undefined {
14
+ if (!spec) return undefined;
15
+ if (
16
+ typeof spec === "object" &&
17
+ spec !== null &&
18
+ "handle" in spec &&
19
+ typeof (spec as NodeErrorHandler).handle === "function"
20
+ ) {
21
+ return spec as NodeErrorHandler;
22
+ }
23
+ return this.nodeResolver.resolve(spec as TypeToken<NodeErrorHandler>);
24
+ }
25
+
26
+ resolveWorkflowErrorHandler(spec: WorkflowErrorHandlerSpec | undefined): WorkflowErrorHandler | undefined {
27
+ if (!spec) return undefined;
28
+ if (
29
+ typeof spec === "object" &&
30
+ spec !== null &&
31
+ "onError" in spec &&
32
+ typeof (spec as WorkflowErrorHandler).onError === "function"
33
+ ) {
34
+ return spec as WorkflowErrorHandler;
35
+ }
36
+ return this.nodeResolver.resolve(spec as TypeToken<WorkflowErrorHandler>);
37
+ }
38
+ }
@@ -0,0 +1,66 @@
1
+ import type { ParentExecutionRef, RunExecutionOptions } from "../../types";
2
+
3
+ export interface EngineExecutionLimitsPolicyConfig {
4
+ readonly defaultMaxNodeActivations: number;
5
+ readonly hardMaxNodeActivations: number;
6
+ readonly defaultMaxSubworkflowDepth: number;
7
+ readonly hardMaxSubworkflowDepth: number;
8
+ }
9
+
10
+ /** Framework defaults for {@link EngineExecutionLimitsPolicy} (merged with host `runtime.engineExecutionLimits`). */
11
+ export const ENGINE_EXECUTION_LIMITS_DEFAULTS: EngineExecutionLimitsPolicyConfig = {
12
+ defaultMaxNodeActivations: 100_000,
13
+ hardMaxNodeActivations: 100_000,
14
+ defaultMaxSubworkflowDepth: 32,
15
+ hardMaxSubworkflowDepth: 32,
16
+ };
17
+
18
+ /**
19
+ * Resolves per-run execution limits: defaults, hard ceilings, and subworkflow depth for new runs.
20
+ */
21
+ export class EngineExecutionLimitsPolicy {
22
+ constructor(private readonly config: EngineExecutionLimitsPolicyConfig = ENGINE_EXECUTION_LIMITS_DEFAULTS) {}
23
+
24
+ /**
25
+ * Effective options for a new root run (depth 0): defaults merged with engine ceilings.
26
+ * Replaces a separate one-method factory for root-run bootstrap.
27
+ */
28
+ createRootExecutionOptions(): RunExecutionOptions {
29
+ return this.mergeExecutionOptionsForNewRun(undefined, undefined);
30
+ }
31
+
32
+ mergeExecutionOptionsForNewRun(
33
+ parent: ParentExecutionRef | undefined,
34
+ user: RunExecutionOptions | undefined,
35
+ ): RunExecutionOptions {
36
+ const subworkflowDepth = parent === undefined ? 0 : (parent.subworkflowDepth ?? 0) + 1;
37
+ const inheritedMaxNode = parent?.engineMaxNodeActivations;
38
+ const inheritedMaxSub = parent?.engineMaxSubworkflowDepth;
39
+ const maxNodeActivations = this.capNumber(
40
+ user?.maxNodeActivations ?? inheritedMaxNode,
41
+ this.config.defaultMaxNodeActivations,
42
+ this.config.hardMaxNodeActivations,
43
+ );
44
+ const maxSubworkflowDepth = this.capNumber(
45
+ user?.maxSubworkflowDepth ?? inheritedMaxSub,
46
+ this.config.defaultMaxSubworkflowDepth,
47
+ this.config.hardMaxSubworkflowDepth,
48
+ );
49
+ if (subworkflowDepth > maxSubworkflowDepth) {
50
+ throw new Error(
51
+ `Subworkflow nesting depth ${subworkflowDepth} exceeds maxSubworkflowDepth ${maxSubworkflowDepth} (run would be a child of parent run).`,
52
+ );
53
+ }
54
+ return {
55
+ ...user,
56
+ subworkflowDepth,
57
+ maxNodeActivations,
58
+ maxSubworkflowDepth,
59
+ };
60
+ }
61
+
62
+ private capNumber(requested: number | undefined, defaultValue: number, hardCeiling: number): number {
63
+ const base = requested === undefined ? defaultValue : requested;
64
+ return Math.min(base, hardCeiling);
65
+ }
66
+ }
@@ -0,0 +1,14 @@
1
+ import {
2
+ EngineExecutionLimitsPolicy,
3
+ ENGINE_EXECUTION_LIMITS_DEFAULTS,
4
+ type EngineExecutionLimitsPolicyConfig,
5
+ } from "./EngineExecutionLimitsPolicy";
6
+
7
+ /**
8
+ * Builds {@link EngineExecutionLimitsPolicy} by merging {@link ENGINE_EXECUTION_LIMITS_DEFAULTS} with optional `overrides` (e.g. host `runtime.engineExecutionLimits`).
9
+ */
10
+ export class EngineExecutionLimitsPolicyFactory {
11
+ create(overrides?: Partial<EngineExecutionLimitsPolicyConfig>): EngineExecutionLimitsPolicy {
12
+ return new EngineExecutionLimitsPolicy({ ...ENGINE_EXECUTION_LIMITS_DEFAULTS, ...overrides });
13
+ }
14
+ }
@@ -0,0 +1,10 @@
1
+ export {
2
+ ENGINE_EXECUTION_LIMITS_DEFAULTS,
3
+ EngineExecutionLimitsPolicy,
4
+ type EngineExecutionLimitsPolicyConfig,
5
+ } from "./executionLimits/EngineExecutionLimitsPolicy";
6
+ export { EngineExecutionLimitsPolicyFactory } from "./executionLimits/EngineExecutionLimitsPolicyFactory";
7
+ export { RunPolicySnapshotFactory } from "./storage/RunPolicySnapshotFactory";
8
+ export { RunTerminalPersistenceCoordinator } from "./storage/RunTerminalPersistenceCoordinator";
9
+ export { WorkflowPolicyErrorServices } from "./WorkflowPolicyErrorServices";
10
+ export { WorkflowStoragePolicyEvaluator } from "./storage/WorkflowStoragePolicyEvaluator";
@@ -0,0 +1,23 @@
1
+ import type {
2
+ PersistedRunPolicySnapshot,
3
+ WorkflowDefinition,
4
+ WorkflowPolicyRuntimeDefaults,
5
+ WorkflowStoragePolicyMode,
6
+ } from "../../types";
7
+
8
+ export class RunPolicySnapshotFactory {
9
+ static create(workflow: WorkflowDefinition, defaults?: WorkflowPolicyRuntimeDefaults): PersistedRunPolicySnapshot {
10
+ const prune = workflow.prunePolicy;
11
+ const retentionSeconds = prune?.runDataRetentionSeconds ?? defaults?.retentionSeconds;
12
+ const binaryRetentionSeconds = prune?.binaryRetentionSeconds ?? defaults?.binaryRetentionSeconds;
13
+ const storagePolicy: WorkflowStoragePolicyMode =
14
+ typeof workflow.storagePolicy === "string"
15
+ ? (workflow.storagePolicy as WorkflowStoragePolicyMode)
16
+ : (defaults?.storagePolicy ?? "ALL");
17
+ return {
18
+ retentionSeconds,
19
+ binaryRetentionSeconds,
20
+ storagePolicy,
21
+ };
22
+ }
23
+ }
@@ -0,0 +1,29 @@
1
+ import type { PersistedRunState, WorkflowDefinition, WorkflowExecutionRepository } from "../../types";
2
+
3
+ import { WorkflowStoragePolicyEvaluator } from "./WorkflowStoragePolicyEvaluator";
4
+
5
+ export class RunTerminalPersistenceCoordinator {
6
+ constructor(
7
+ private readonly runRepository: WorkflowExecutionRepository,
8
+ private readonly storageEvaluator: WorkflowStoragePolicyEvaluator,
9
+ ) {}
10
+
11
+ async maybeDeleteAfterTerminalState(args: {
12
+ workflow: WorkflowDefinition;
13
+ state: PersistedRunState;
14
+ finalStatus: "completed" | "failed";
15
+ finishedAt: string;
16
+ }): Promise<void> {
17
+ const persist = await this.storageEvaluator.shouldPersist(args.workflow, args.state.policySnapshot, {
18
+ runId: args.state.runId,
19
+ workflowId: args.state.workflowId,
20
+ workflow: args.workflow,
21
+ finalStatus: args.finalStatus,
22
+ startedAt: args.state.startedAt,
23
+ finishedAt: args.finishedAt,
24
+ });
25
+ if (persist) return;
26
+ if (!this.runRepository.deleteRun) return;
27
+ await this.runRepository.deleteRun(args.state.runId);
28
+ }
29
+ }
@@ -0,0 +1,39 @@
1
+ import type { TypeToken } from "../../di";
2
+ import type {
3
+ NodeResolver,
4
+ PersistedRunPolicySnapshot,
5
+ WorkflowDefinition,
6
+ WorkflowStoragePolicyDecisionArgs,
7
+ WorkflowStoragePolicyMode,
8
+ WorkflowStoragePolicyResolver,
9
+ } from "../../types";
10
+
11
+ export class WorkflowStoragePolicyEvaluator {
12
+ constructor(private readonly nodeResolver: NodeResolver) {}
13
+
14
+ async shouldPersist(
15
+ workflow: WorkflowDefinition,
16
+ snapshot: PersistedRunPolicySnapshot | undefined,
17
+ args: WorkflowStoragePolicyDecisionArgs,
18
+ ): Promise<boolean> {
19
+ const spec = workflow.storagePolicy;
20
+ if (spec === undefined) {
21
+ return this.modeMatches(snapshot?.storagePolicy ?? "ALL", args);
22
+ }
23
+ if (typeof spec === "string") {
24
+ return this.modeMatches(spec as WorkflowStoragePolicyMode, args);
25
+ }
26
+ const resolver = this.nodeResolver.resolve(
27
+ spec as TypeToken<WorkflowStoragePolicyResolver>,
28
+ ) as WorkflowStoragePolicyResolver;
29
+ return Boolean(await resolver.shouldPersist(args));
30
+ }
31
+
32
+ private modeMatches(mode: WorkflowStoragePolicyMode, args: WorkflowStoragePolicyDecisionArgs): boolean {
33
+ if (mode === "ALL") return true;
34
+ if (mode === "NEVER") return false;
35
+ if (mode === "SUCCESS") return args.finalStatus === "completed";
36
+ if (mode === "ERROR") return args.finalStatus === "failed";
37
+ return true;
38
+ }
39
+ }