@codemation/core 0.0.7 → 0.0.11

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 (195) hide show
  1. package/package.json +6 -1
  2. package/dist/EngineExecutionLimitsPolicy-8MEFIYx1.d.cts +0 -160
  3. package/dist/EngineExecutionLimitsPolicy-BWAXW9D6.d.cts +0 -160
  4. package/dist/EngineExecutionLimitsPolicy-Bp8PS1Ss.d.cts +0 -159
  5. package/dist/EngineExecutionLimitsPolicy-CLxcN-D2.d.ts +0 -159
  6. package/dist/EngineExecutionLimitsPolicy-DZXuix51.d.ts +0 -160
  7. package/dist/EngineExecutionLimitsPolicy-Gfz6ngFd.d.ts +0 -160
  8. package/dist/EngineFactory-CBnntY3J.cjs +0 -3152
  9. package/dist/EngineFactory-CBnntY3J.cjs.map +0 -1
  10. package/dist/EngineFactory-Cwn3R2YA.js +0 -3087
  11. package/dist/EngineFactory-Cwn3R2YA.js.map +0 -1
  12. package/dist/EngineFactory-DWCnNocp.js +0 -3063
  13. package/dist/EngineFactory-DWCnNocp.js.map +0 -1
  14. package/dist/EngineFactory-DhPFou4p.cjs +0 -3188
  15. package/dist/EngineFactory-DhPFou4p.cjs.map +0 -1
  16. package/dist/EngineFactory-l_9xmBtv.cjs +0 -3190
  17. package/dist/EngineFactory-l_9xmBtv.cjs.map +0 -1
  18. package/dist/EngineFactory-w-aOWuqh.js +0 -3089
  19. package/dist/EngineFactory-w-aOWuqh.js.map +0 -1
  20. package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js +0 -18
  21. package/dist/InMemoryLiveWorkflowRepository-1J9MHN_I.js.map +0 -1
  22. package/dist/InMemoryLiveWorkflowRepository-CULNqv96.d.ts +0 -1300
  23. package/dist/InMemoryLiveWorkflowRepository-D6eiiXxF.d.cts +0 -1168
  24. package/dist/InMemoryLiveWorkflowRepository-D7l8cjdZ.d.cts +0 -1130
  25. package/dist/InMemoryLiveWorkflowRepository-DL7LmC9S.d.ts +0 -1340
  26. package/dist/InMemoryLiveWorkflowRepository-jnv-OnOP.d.ts +0 -1300
  27. package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs +0 -24
  28. package/dist/InMemoryLiveWorkflowRepository-xny1_Z6i.cjs.map +0 -1
  29. package/dist/InMemoryLiveWorkflowRepository-xr7b4kvi.d.ts +0 -1338
  30. package/dist/InMemoryWorkflowCatalog-BIdFpwbK.d.ts +0 -1205
  31. package/dist/InMemoryWorkflowCatalog-BW00_3N3.d.cts +0 -12
  32. package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs +0 -24
  33. package/dist/InMemoryWorkflowCatalog-BiYHGoPw.cjs.map +0 -1
  34. package/dist/InMemoryWorkflowCatalog-BrG0ApMO.d.cts +0 -1115
  35. package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js +0 -139
  36. package/dist/InMemoryWorkflowCatalog-BzrAr--Y.js.map +0 -1
  37. package/dist/InMemoryWorkflowCatalog-C-EJlJ7y.d.cts +0 -1120
  38. package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs +0 -24
  39. package/dist/InMemoryWorkflowCatalog-C4482bpw.cjs.map +0 -1
  40. package/dist/InMemoryWorkflowCatalog-CZ0kZpOv.d.ts +0 -1289
  41. package/dist/InMemoryWorkflowCatalog-C_ACeLyW.d.cts +0 -1119
  42. package/dist/InMemoryWorkflowCatalog-CiHWIu5E.d.cts +0 -12
  43. package/dist/InMemoryWorkflowCatalog-CkH7gkya.js +0 -18
  44. package/dist/InMemoryWorkflowCatalog-CkH7gkya.js.map +0 -1
  45. package/dist/InMemoryWorkflowCatalog-CnpZVJM9.d.ts +0 -1205
  46. package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js +0 -18
  47. package/dist/InMemoryWorkflowCatalog-Cu68S8YR.js.map +0 -1
  48. package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs +0 -151
  49. package/dist/InMemoryWorkflowCatalog-D2w9nMj2.cjs.map +0 -1
  50. package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js +0 -18
  51. package/dist/InMemoryWorkflowCatalog-D5eMxEf7.js.map +0 -1
  52. package/dist/InMemoryWorkflowCatalog-D5nCp2yZ.d.ts +0 -1267
  53. package/dist/InMemoryWorkflowCatalog-DIq0bjqN.d.ts +0 -12
  54. package/dist/InMemoryWorkflowCatalog-DLgaEaw_.d.ts +0 -1288
  55. package/dist/InMemoryWorkflowCatalog-DNBFdK-x.d.cts +0 -1120
  56. package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs +0 -24
  57. package/dist/InMemoryWorkflowCatalog-DQBkCzb7.cjs.map +0 -1
  58. package/dist/InMemoryWorkflowCatalog-DS4-eX6i.d.cts +0 -1118
  59. package/dist/InMemoryWorkflowCatalog-DdVfy8MY.d.ts +0 -12
  60. package/dist/InMemoryWorkflowCatalog-DeVZu3g8.d.ts +0 -12
  61. package/dist/InMemoryWorkflowCatalog-GxkQjvt5.d.ts +0 -1200
  62. package/dist/InMemoryWorkflowCatalog-qaVRn1Lc.d.cts +0 -1115
  63. package/dist/InMemoryWorkflowCatalog-z1aIT4TC.d.cts +0 -12
  64. package/dist/InMemoryWorkflowRegistry-BBuOovLL.d.ts +0 -1007
  65. package/dist/InMemoryWorkflowRegistry-BIFnSl3k.d.ts +0 -1201
  66. package/dist/InMemoryWorkflowRegistry-BnGilthz.d.ts +0 -1137
  67. package/dist/InMemoryWorkflowRegistry-CEp5I8No.d.ts +0 -1146
  68. package/dist/InMemoryWorkflowRegistry-CHyMB9jW.d.cts +0 -976
  69. package/dist/InMemoryWorkflowRegistry-CUN7K86m.d.cts +0 -1061
  70. package/dist/InMemoryWorkflowRegistry-CVfHyELh.d.cts +0 -971
  71. package/dist/InMemoryWorkflowRegistry-CXXJrwAr.d.cts +0 -1052
  72. package/dist/InMemoryWorkflowRegistry-DDGfPTJy.d.ts +0 -1013
  73. package/dist/InMemoryWorkflowRegistry-DnYSOoT5.d.ts +0 -1120
  74. package/dist/InMemoryWorkflowRegistry-Dp5GiFF2.d.cts +0 -1035
  75. package/dist/InMemoryWorkflowRegistry-DypDBeOw.d.cts +0 -1116
  76. package/dist/InMemoryWorkflowRegistry-SzwJCAxT.d.ts +0 -1012
  77. package/dist/InMemoryWorkflowRegistry-jupvqyGc.d.cts +0 -977
  78. package/dist/InMemoryWorkflowRegistry-rAdKVWYT.d.ts +0 -1117
  79. package/dist/InProcessRetryRunner-BBNPkXjy.d.cts +0 -292
  80. package/dist/PersistedWorkflowSnapshotFactory-7RkOL3Kg.d.ts +0 -14
  81. package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs +0 -141
  82. package/dist/PersistedWorkflowSnapshotFactory-BmANa46W.cjs.map +0 -1
  83. package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js +0 -118
  84. package/dist/PersistedWorkflowSnapshotFactory-Bwb_etSt.js.map +0 -1
  85. package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js +0 -123
  86. package/dist/PersistedWorkflowSnapshotFactory-CRkKGNV6.js.map +0 -1
  87. package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js +0 -101
  88. package/dist/PersistedWorkflowSnapshotFactory-CZolnGy5.js.map +0 -1
  89. package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs +0 -131
  90. package/dist/PersistedWorkflowSnapshotFactory-Ca_oysOv.cjs.map +0 -1
  91. package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js +0 -103
  92. package/dist/PersistedWorkflowSnapshotFactory-CqIcShnX.js.map +0 -1
  93. package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js +0 -119
  94. package/dist/PersistedWorkflowSnapshotFactory-D-tBk4_G.js.map +0 -1
  95. package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs +0 -131
  96. package/dist/PersistedWorkflowSnapshotFactory-D4cXl2e2.cjs.map +0 -1
  97. package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs +0 -131
  98. package/dist/PersistedWorkflowSnapshotFactory-DINoP12r.cjs.map +0 -1
  99. package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js +0 -103
  100. package/dist/PersistedWorkflowSnapshotFactory-DJAwSuHU.js.map +0 -1
  101. package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs +0 -131
  102. package/dist/PersistedWorkflowSnapshotFactory-DSUjVCcf.cjs.map +0 -1
  103. package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs +0 -107
  104. package/dist/PersistedWorkflowSnapshotFactory-DdHuhkDb.cjs.map +0 -1
  105. package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js +0 -119
  106. package/dist/PersistedWorkflowSnapshotFactory-Dqc6NHis.js.map +0 -1
  107. package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs +0 -130
  108. package/dist/PersistedWorkflowSnapshotFactory-Dxa2dSrw.cjs.map +0 -1
  109. package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js +0 -123
  110. package/dist/PersistedWorkflowSnapshotFactory-Ep79Ah1G.js.map +0 -1
  111. package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js +0 -119
  112. package/dist/PersistedWorkflowSnapshotFactory-GyLfRuiJ.js.map +0 -1
  113. package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js +0 -102
  114. package/dist/PersistedWorkflowSnapshotFactory-HTpBsBzn.js.map +0 -1
  115. package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs +0 -141
  116. package/dist/PersistedWorkflowSnapshotFactory-LVmaaf3t.cjs.map +0 -1
  117. package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js +0 -119
  118. package/dist/PersistedWorkflowSnapshotFactory-PZCpo2ZS.js.map +0 -1
  119. package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs +0 -109
  120. package/dist/PersistedWorkflowSnapshotFactory-UjQ1SJev.cjs.map +0 -1
  121. package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs +0 -109
  122. package/dist/PersistedWorkflowSnapshotFactory-Y8kCrhcy.cjs.map +0 -1
  123. package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs +0 -108
  124. package/dist/PersistedWorkflowSnapshotFactory-Z_nB-fmB.cjs.map +0 -1
  125. package/dist/RunIntentService-1EE6N8ZL.cjs +0 -963
  126. package/dist/RunIntentService-1EE6N8ZL.cjs.map +0 -1
  127. package/dist/RunIntentService-2ivFmNQh.cjs +0 -3462
  128. package/dist/RunIntentService-2ivFmNQh.cjs.map +0 -1
  129. package/dist/RunIntentService-B0sUL5q-.js +0 -761
  130. package/dist/RunIntentService-B0sUL5q-.js.map +0 -1
  131. package/dist/RunIntentService-BFVbsOcg.js +0 -3131
  132. package/dist/RunIntentService-BFVbsOcg.js.map +0 -1
  133. package/dist/RunIntentService-BsBOwpVN.cjs +0 -1051
  134. package/dist/RunIntentService-BsBOwpVN.cjs.map +0 -1
  135. package/dist/RunIntentService-CSk3ETyn.js +0 -858
  136. package/dist/RunIntentService-CSk3ETyn.js.map +0 -1
  137. package/dist/RunIntentService-Ckn3u3tA.d.cts +0 -326
  138. package/dist/RunIntentService-DEo6GTTo.d.cts +0 -289
  139. package/dist/RunIntentService-DKrGtL0B.js +0 -782
  140. package/dist/RunIntentService-DKrGtL0B.js.map +0 -1
  141. package/dist/RunIntentService-DNOJc1R7.cjs +0 -942
  142. package/dist/RunIntentService-DNOJc1R7.cjs.map +0 -1
  143. package/dist/RunIntentService-Dq3pV53j.d.cts +0 -289
  144. package/dist/RunIntentService-NKobsfMQ.d.cts +0 -274
  145. package/dist/WorkflowSnapshotCodec-C3fuuS_R.d.cts +0 -22
  146. package/dist/WorkflowSnapshotCodec-CUudUo6f.js +0 -123
  147. package/dist/WorkflowSnapshotCodec-CUudUo6f.js.map +0 -1
  148. package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs +0 -129
  149. package/dist/WorkflowSnapshotCodec-CuCPQZTc.cjs.map +0 -1
  150. package/dist/WorkflowSnapshotCodec-DLiXQNvV.d.cts +0 -22
  151. package/dist/WorkflowSnapshotCodec-DNtdrZ7l.d.cts +0 -22
  152. package/dist/WorkflowSnapshotCodec-DTdWkoW_.d.cts +0 -22
  153. package/dist/credentialTypes-B5h3dI7r.d.cts +0 -1107
  154. package/dist/credentialTypes-B9okPCVo.d.cts +0 -963
  155. package/dist/credentialTypes-BFL70rgZ.d.cts +0 -964
  156. package/dist/credentialTypes-BGkh1O07.d.ts +0 -1010
  157. package/dist/credentialTypes-BNLi4Q7u.d.ts +0 -1030
  158. package/dist/credentialTypes-CeSoZGj3.d.cts +0 -994
  159. package/dist/credentialTypes-CpHc32Ig.d.cts +0 -984
  160. package/dist/credentialTypes-D0m7MQQl.d.cts +0 -1107
  161. package/dist/credentialTypes-D4nL2sUd.d.ts +0 -1000
  162. package/dist/credentialTypes-DBYK2Qbu.d.ts +0 -999
  163. package/dist/credentialTypes-DMJVy0r1.d.ts +0 -1000
  164. package/dist/credentialTypes-DhUAjYQp.d.ts +0 -1020
  165. package/dist/credentialTypes-gGITj5KL.d.cts +0 -964
  166. package/dist/credentialTypes-r3KVBJBE.d.cts +0 -974
  167. package/dist/diTokens-ClO27tjK.cjs +0 -34
  168. package/dist/diTokens-ClO27tjK.cjs.map +0 -1
  169. package/dist/diTokens-CoHBkwG6.js +0 -28
  170. package/dist/diTokens-CoHBkwG6.js.map +0 -1
  171. package/dist/index-6Doxmfnd.d.ts +0 -857
  172. package/dist/index-9g6Pfe9Z.d.ts +0 -689
  173. package/dist/index-AZ72Ej-K.d.ts +0 -920
  174. package/dist/index-BEk9V-q-.d.ts +0 -667
  175. package/dist/index-Bjt7_7oS.d.ts +0 -1192
  176. package/dist/index-CFGxsYXy.d.ts +0 -708
  177. package/dist/index-C_u8xFgn.d.ts +0 -690
  178. package/dist/index-CpbfsvOJ.d.ts +0 -1192
  179. package/dist/index-CsReNJN_.d.ts +0 -859
  180. package/dist/index-D5iNnXaW.d.ts +0 -667
  181. package/dist/index-DD_Eft1q.d.ts +0 -708
  182. package/dist/index-DiSYUe0G.d.ts +0 -1192
  183. package/dist/index-gIcH60sp.d.ts +0 -674
  184. package/dist/runtime-BIvd-1JA.cjs +0 -4112
  185. package/dist/runtime-BIvd-1JA.cjs.map +0 -1
  186. package/dist/runtime-D3eWKSQK.cjs +0 -3986
  187. package/dist/runtime-D3eWKSQK.cjs.map +0 -1
  188. package/dist/runtime-Dvp4xAjg.js +0 -3799
  189. package/dist/runtime-Dvp4xAjg.js.map +0 -1
  190. package/dist/runtime-vc76SSAa.js +0 -3685
  191. package/dist/runtime-vc76SSAa.js.map +0 -1
  192. package/dist/runtimeTypes-BK0b8SaG.d.cts +0 -884
  193. package/dist/runtimeTypes-CoYZkYQq.d.cts +0 -851
  194. package/dist/runtimeTypes-D-Pm0Uas.d.cts +0 -849
  195. package/dist/types-Cb5UK7Y6.d.ts +0 -857
@@ -1,3131 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import "reflect-metadata";
3
- import { container, delay, inject, injectAll, injectable, instanceCachingFactory, instancePerContainerCachingFactory, predicateAwareClassFactory, registry, singleton } from "tsyringe";
4
- import { ReadableStream } from "node:stream/web";
5
-
6
- //#region src/workflow/definition/ConnectionNodeIdFactory.ts
7
- /**
8
- * Deterministic ids for workflow connection-owned child nodes (LLM slot, tools, etc.).
9
- * These are stable across loads.
10
- */
11
- var ConnectionNodeIdFactory = class {
12
- static connectionSegment = "__conn__";
13
- static languageModelConnectionNodeId(parentNodeId) {
14
- return `${parentNodeId}${this.connectionSegment}llm`;
15
- }
16
- static toolConnectionNodeId(parentNodeId, toolName) {
17
- const normalized = this.normalizeToolName(toolName);
18
- return `${parentNodeId}${this.connectionSegment}tool${this.connectionSegment}${normalized}`;
19
- }
20
- static isLanguageModelConnectionNodeId(nodeId) {
21
- return nodeId.endsWith(`${this.connectionSegment}llm`);
22
- }
23
- static isToolConnectionNodeId(nodeId) {
24
- return nodeId.includes(`${this.connectionSegment}tool${this.connectionSegment}`);
25
- }
26
- /** True when `nodeId` is a connection-owned child of `parentNodeId` (LLM or tool slot). */
27
- static isConnectionOwnedDescendantOf(parentNodeId, nodeId) {
28
- return nodeId.startsWith(`${parentNodeId}${this.connectionSegment}`);
29
- }
30
- /** Normalizes a tool display name to a stable id segment. */
31
- static normalizeToolName(toolName) {
32
- return toolName.trim().toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "") || "tool";
33
- }
34
- };
35
-
36
- //#endregion
37
- //#region src/workflow/definition/WorkflowExecutableNodeClassifier.ts
38
- /**
39
- * Derives which workflow nodes participate in the main execution graph vs connection-only children.
40
- */
41
- var WorkflowExecutableNodeClassifier = class {
42
- connectionOwnedIds;
43
- constructor(workflow) {
44
- this.connectionOwnedIds = this.collectConnectionOwnedIds(workflow);
45
- }
46
- isConnectionOwnedNodeId(nodeId) {
47
- return this.connectionOwnedIds.has(nodeId);
48
- }
49
- isExecutableNodeId(nodeId) {
50
- return !this.connectionOwnedIds.has(nodeId);
51
- }
52
- filterExecutableNodeDefinitions(nodes) {
53
- return nodes.filter((n) => this.isExecutableNodeId(n.id));
54
- }
55
- collectConnectionOwnedIds(workflow) {
56
- const ids = /* @__PURE__ */ new Set();
57
- for (const connection of workflow.connections ?? []) for (const childId of connection.childNodeIds) ids.add(childId);
58
- return ids;
59
- }
60
- /**
61
- * Resolves the default start node: first trigger, else first executable node with no incoming edges from executable nodes.
62
- */
63
- findDefaultExecutableStartNodeId(workflow) {
64
- const firstTrigger = workflow.nodes.find((n) => n.kind === "trigger" && this.isExecutableNodeId(n.id))?.id;
65
- if (firstTrigger) return firstTrigger;
66
- const incoming = /* @__PURE__ */ new Map();
67
- for (const n of workflow.nodes) if (this.isExecutableNodeId(n.id)) incoming.set(n.id, 0);
68
- for (const e of workflow.edges) {
69
- if (!this.isExecutableNodeId(e.from.nodeId) || !this.isExecutableNodeId(e.to.nodeId)) continue;
70
- incoming.set(e.to.nodeId, (incoming.get(e.to.nodeId) ?? 0) + 1);
71
- }
72
- return workflow.nodes.find((n) => this.isExecutableNodeId(n.id) && (incoming.get(n.id) ?? 0) === 0)?.id ?? workflow.nodes.find((n) => this.isExecutableNodeId(n.id))?.id ?? (() => {
73
- throw new Error(`Workflow ${workflow.id} has no executable nodes`);
74
- })();
75
- }
76
- firstExecutableNodeIdInDefinitionOrder(workflow) {
77
- return workflow.nodes.find((n) => this.isExecutableNodeId(n.id))?.id;
78
- }
79
- lastExecutableNodeIdInDefinitionOrder(workflow) {
80
- for (let i = workflow.nodes.length - 1; i >= 0; i--) {
81
- const n = workflow.nodes[i];
82
- if (this.isExecutableNodeId(n.id)) return n.id;
83
- }
84
- throw new Error(`Workflow ${workflow.id} has no executable nodes`);
85
- }
86
- };
87
-
88
- //#endregion
89
- //#region src/workflow/definition/WorkflowExecutableNodeClassifierFactory.ts
90
- var WorkflowExecutableNodeClassifierFactory = class {
91
- static create(workflow) {
92
- return new WorkflowExecutableNodeClassifier(workflow);
93
- }
94
- };
95
-
96
- //#endregion
97
- //#region src/di/CoreTokens.ts
98
- const CoreTokens = {
99
- PersistedWorkflowTokenRegistry: Symbol.for("codemation.core.PersistedWorkflowTokenRegistry"),
100
- CredentialSessionService: Symbol.for("codemation.core.CredentialSessionService"),
101
- CredentialTypeRegistry: Symbol.for("codemation.core.CredentialTypeRegistry"),
102
- WorkflowRunnerService: Symbol.for("codemation.core.WorkflowRunnerService"),
103
- LiveWorkflowRepository: Symbol.for("codemation.core.LiveWorkflowRepository"),
104
- WorkflowRepository: Symbol.for("codemation.core.WorkflowRepository"),
105
- NodeResolver: Symbol.for("codemation.core.NodeResolver"),
106
- WorkflowNodeInstanceFactory: Symbol.for("codemation.core.WorkflowNodeInstanceFactory"),
107
- RunIdFactory: Symbol.for("codemation.core.RunIdFactory"),
108
- ActivationIdFactory: Symbol.for("codemation.core.ActivationIdFactory"),
109
- WorkflowExecutionRepository: Symbol.for("codemation.core.WorkflowExecutionRepository"),
110
- TriggerSetupStateRepository: Symbol.for("codemation.core.TriggerSetupStateRepository"),
111
- NodeActivationScheduler: Symbol.for("codemation.core.NodeActivationScheduler"),
112
- RunDataFactory: Symbol.for("codemation.core.RunDataFactory"),
113
- ExecutionContextFactory: Symbol.for("codemation.core.ExecutionContextFactory"),
114
- RunEventBus: Symbol.for("codemation.core.RunEventBus"),
115
- BinaryStorage: Symbol.for("codemation.core.BinaryStorage"),
116
- WebhookBasePath: Symbol.for("codemation.core.WebhookBasePath"),
117
- EngineExecutionLimitsPolicy: Symbol.for("codemation.core.EngineExecutionLimitsPolicy"),
118
- WorkflowActivationPolicy: Symbol.for("codemation.core.WorkflowActivationPolicy")
119
- };
120
-
121
- //#endregion
122
- //#region src/events/NodeEventPublisher.ts
123
- /** Publishes node lifecycle snapshots onto the run {@link RunEventBus}. */
124
- var NodeEventPublisher = class {
125
- constructor(eventBus) {
126
- this.eventBus = eventBus;
127
- }
128
- async publish(kind, snapshot) {
129
- if (!this.eventBus) return;
130
- await this.eventBus.publish({
131
- kind,
132
- runId: snapshot.runId,
133
- workflowId: snapshot.workflowId,
134
- parent: snapshot.parent,
135
- at: snapshot.updatedAt,
136
- snapshot
137
- });
138
- }
139
- };
140
-
141
- //#endregion
142
- //#region src/runtime-types/persistedRuntimeTypeModelRegistry.ts
143
- /** Shared metadata key used to attach persisted runtime-type information to decorated classes. */
144
- const persistedRuntimeTypeMetadataKey = Symbol.for("codemation.core.persistedRuntimeTypeMetadata");
145
- /** Normalizes decorator options so persistence metadata has stable defaults. */
146
- var PersistedRuntimeTypeDecoratorDefaults = class {
147
- static appPackageName = "app";
148
- static apply(options) {
149
- return {
150
- ...options,
151
- packageName: options.packageName ?? this.appPackageName
152
- };
153
- }
154
- };
155
-
156
- //#endregion
157
- //#region src/runtime-types/PersistedRuntimeTypeNameResolver.ts
158
- /** Resolves the persisted type name from either an explicit override or the class name itself. */
159
- var PersistedRuntimeTypeNameResolver = class {
160
- static resolve(target, override) {
161
- const resolved = override ?? target.name;
162
- if (!resolved) throw new Error("Persisted runtime token metadata requires a named class or an explicit decorator name override.");
163
- return resolved;
164
- }
165
- };
166
-
167
- //#endregion
168
- //#region src/runtime-types/StackTraceCallSitePathResolver.ts
169
- var StackTraceCallSitePathResolver = class {
170
- static resolve(decoratorFileUrl) {
171
- const stack = (/* @__PURE__ */ new Error()).stack ?? "";
172
- for (const line of stack.split("\n")) {
173
- const candidate = this.extractPath(line.trim());
174
- if (!candidate) continue;
175
- if (candidate === decoratorFileUrl || candidate.includes("runtimeTypeDecorators")) continue;
176
- return candidate;
177
- }
178
- }
179
- static extractPath(line) {
180
- const fileUrlMatch = line.match(/file:\/\/[^\s)]+/);
181
- if (fileUrlMatch) return fileUrlMatch[0];
182
- const parenMatch = line.match(/\((\/[^)]+)\)/);
183
- if (parenMatch) return parenMatch[1];
184
- return line.match(/at (\/[^\s]+)/)?.[1];
185
- }
186
- };
187
-
188
- //#endregion
189
- //#region src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts
190
- /**
191
- * Defines and retrieves persisted runtime metadata on decorated classes.
192
- * The metadata is attached as a non-enumerable property so runtime objects stay serializable.
193
- */
194
- var PersistedRuntimeTypeMetadataStore = class {
195
- static define(target, kind, options, decoratorFileUrl) {
196
- const normalizedOptions = PersistedRuntimeTypeDecoratorDefaults.apply(options);
197
- const metadata = {
198
- persistedName: PersistedRuntimeTypeNameResolver.resolve(target, normalizedOptions.name),
199
- kind,
200
- packageName: normalizedOptions.packageName ?? PersistedRuntimeTypeDecoratorDefaults.appPackageName,
201
- sourceHint: normalizedOptions.moduleUrl ?? StackTraceCallSitePathResolver.resolve(decoratorFileUrl)
202
- };
203
- Object.defineProperty(target, persistedRuntimeTypeMetadataKey, {
204
- configurable: false,
205
- enumerable: false,
206
- writable: false,
207
- value: metadata
208
- });
209
- }
210
- static get(target) {
211
- if (!target || typeof target !== "function" && typeof target !== "object") return;
212
- return target[persistedRuntimeTypeMetadataKey];
213
- }
214
- };
215
-
216
- //#endregion
217
- //#region src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts
218
- /**
219
- * Applies both tsyringe injectability and persisted runtime metadata in one decorator.
220
- * This keeps runtime-type decorators thin while still recording enough data for snapshot hydration.
221
- */
222
- var InjectableRuntimeDecoratorComposer = class {
223
- static compose(kind, options, decoratorFileUrl) {
224
- return (target) => {
225
- injectable()(target);
226
- PersistedRuntimeTypeMetadataStore.define(target, kind, options, decoratorFileUrl);
227
- };
228
- }
229
- };
230
-
231
- //#endregion
232
- //#region src/runtime-types/runtimeTypeDecorators.types.ts
233
- /** Reads persisted runtime metadata from a decorated class or object. */
234
- function getPersistedRuntimeTypeMetadata(target) {
235
- return PersistedRuntimeTypeMetadataStore.get(target);
236
- }
237
- /** Marks a class as a persisted node runtime type and an injectable tsyringe service. */
238
- function node(options = {}) {
239
- return InjectableRuntimeDecoratorComposer.compose("node", options, import.meta.url);
240
- }
241
- /** Marks a class as a persisted tool runtime type and an injectable tsyringe service. */
242
- function tool(options = {}) {
243
- return InjectableRuntimeDecoratorComposer.compose("tool", options, import.meta.url);
244
- }
245
- /** Marks a class as a persisted chat-model runtime type and an injectable tsyringe service. */
246
- function chatModel(options = {}) {
247
- return InjectableRuntimeDecoratorComposer.compose("chatModel", options, import.meta.url);
248
- }
249
-
250
- //#endregion
251
- //#region src/binaries/DefaultNodeBinaryAttachmentServiceFactory.ts
252
- var DefaultNodeBinaryAttachmentService = class DefaultNodeBinaryAttachmentService {
253
- constructor(storage, workflowId, runId, nodeId, activationId, now) {
254
- this.storage = storage;
255
- this.workflowId = workflowId;
256
- this.runId = runId;
257
- this.nodeId = nodeId;
258
- this.activationId = activationId;
259
- this.now = now;
260
- }
261
- async attach(args) {
262
- const attachmentId = this.createAttachmentId();
263
- const createdAt = this.now().toISOString();
264
- const storageKey = this.createStorageKey(args, attachmentId);
265
- const stored = await this.storage.write({
266
- storageKey,
267
- body: args.body
268
- });
269
- return {
270
- id: attachmentId,
271
- storageKey: stored.storageKey,
272
- mimeType: args.mimeType,
273
- size: stored.size,
274
- storageDriver: this.storage.driverName,
275
- previewKind: args.previewKind ?? this.resolvePreviewKind(args.mimeType),
276
- createdAt,
277
- runId: this.runId,
278
- workflowId: this.workflowId,
279
- nodeId: this.nodeId,
280
- activationId: this.activationId,
281
- filename: args.filename,
282
- sha256: stored.sha256
283
- };
284
- }
285
- withAttachment(item, name, attachment) {
286
- return {
287
- ...item,
288
- binary: {
289
- ...item.binary ?? {},
290
- [name]: attachment
291
- }
292
- };
293
- }
294
- forNode(args) {
295
- return new DefaultNodeBinaryAttachmentService(this.storage, this.workflowId, this.runId, args.nodeId, args.activationId, this.now);
296
- }
297
- async openReadStream(attachment) {
298
- return await this.storage.openReadStream(attachment.storageKey);
299
- }
300
- createAttachmentId() {
301
- return DefaultNodeBinaryAttachmentService.createAttachmentIdValue(`${this.activationId}-${this.now().getTime()}`);
302
- }
303
- static createAttachmentIdValue(fallbackValue) {
304
- const cryptoObject = globalThis.crypto;
305
- if (cryptoObject && typeof cryptoObject.randomUUID === "function") return cryptoObject.randomUUID();
306
- return fallbackValue;
307
- }
308
- createStorageKey(args, attachmentId) {
309
- const safeName = this.sanitizeSegment(args.name);
310
- const safeFilename = this.sanitizeFilename(args.filename);
311
- const filenameSuffix = safeFilename ? `-${safeFilename}` : "";
312
- return `${this.sanitizeSegment(this.workflowId)}/${this.sanitizeSegment(this.runId)}/${this.sanitizeSegment(this.nodeId)}/${this.sanitizeSegment(this.activationId)}/${attachmentId}-${safeName}${filenameSuffix}`;
313
- }
314
- sanitizeSegment(value) {
315
- const normalized = value.trim();
316
- if (!normalized) return "item";
317
- return normalized.replace(/[^a-zA-Z0-9._-]+/g, "_");
318
- }
319
- sanitizeFilename(value) {
320
- if (!value) return;
321
- const normalized = value.trim().split("/").at(-1)?.split("\\").at(-1) ?? value.trim();
322
- if (!normalized) return;
323
- return normalized.replace(/[^a-zA-Z0-9._-]+/g, "_");
324
- }
325
- resolvePreviewKind(mimeType) {
326
- if (mimeType.startsWith("image/")) return "image";
327
- if (mimeType.startsWith("audio/")) return "audio";
328
- if (mimeType.startsWith("video/")) return "video";
329
- return "download";
330
- }
331
- };
332
-
333
- //#endregion
334
- //#region src/binaries/UnavailableBinaryStorage.ts
335
- var UnavailableBinaryStorage = class {
336
- driverName = "unavailable";
337
- async write() {
338
- throw new Error("Binary storage is not configured for this runtime.");
339
- }
340
- async openReadStream() {}
341
- async stat() {
342
- return { exists: false };
343
- }
344
- async delete() {}
345
- };
346
-
347
- //#endregion
348
- //#region src/binaries/DefaultExecutionBinaryServiceFactory.ts
349
- var DefaultExecutionBinaryService = class {
350
- constructor(storage, workflowId, runId, now) {
351
- this.storage = storage;
352
- this.workflowId = workflowId;
353
- this.runId = runId;
354
- this.now = now;
355
- }
356
- forNode(args) {
357
- return new DefaultNodeBinaryAttachmentService(this.storage, this.workflowId, this.runId, args.nodeId, args.activationId, this.now);
358
- }
359
- async openReadStream(attachment) {
360
- return await this.storage.openReadStream(attachment.storageKey);
361
- }
362
- };
363
-
364
- //#endregion
365
- //#region src/execution/NodeExecutionSnapshotFactory.ts
366
- var NodeExecutionSnapshotFactory = class {
367
- static queued(args) {
368
- return {
369
- runId: args.runId,
370
- workflowId: args.workflowId,
371
- nodeId: args.nodeId,
372
- activationId: args.activationId,
373
- parent: args.parent,
374
- status: "queued",
375
- queuedAt: args.queuedAt,
376
- updatedAt: args.queuedAt,
377
- inputsByPort: args.inputsByPort
378
- };
379
- }
380
- static running(args) {
381
- return {
382
- runId: args.runId,
383
- workflowId: args.workflowId,
384
- nodeId: args.nodeId,
385
- activationId: args.activationId,
386
- parent: args.parent,
387
- status: "running",
388
- queuedAt: args.previous?.queuedAt,
389
- startedAt: args.startedAt,
390
- updatedAt: args.startedAt,
391
- inputsByPort: args.inputsByPort,
392
- outputs: args.previous?.outputs,
393
- error: void 0
394
- };
395
- }
396
- static completed(args) {
397
- const fromPinnedOutput = args.fromPinnedOutput ?? false;
398
- const startedAt = fromPinnedOutput ? args.previous?.startedAt ?? args.finishedAt : args.previous?.startedAt;
399
- return {
400
- runId: args.runId,
401
- workflowId: args.workflowId,
402
- nodeId: args.nodeId,
403
- activationId: args.activationId,
404
- parent: args.parent,
405
- status: "completed",
406
- queuedAt: args.previous?.queuedAt,
407
- startedAt,
408
- finishedAt: args.finishedAt,
409
- updatedAt: args.finishedAt,
410
- inputsByPort: args.inputsByPort,
411
- outputs: args.outputs,
412
- usedPinnedOutput: fromPinnedOutput,
413
- error: void 0
414
- };
415
- }
416
- static skipped(args) {
417
- return {
418
- runId: args.runId,
419
- workflowId: args.workflowId,
420
- nodeId: args.nodeId,
421
- activationId: args.activationId,
422
- parent: args.parent,
423
- status: "skipped",
424
- queuedAt: args.previous?.queuedAt,
425
- startedAt: args.previous?.startedAt,
426
- finishedAt: args.finishedAt,
427
- updatedAt: args.finishedAt,
428
- inputsByPort: args.inputsByPort,
429
- outputs: args.outputs,
430
- error: void 0
431
- };
432
- }
433
- static failed(args) {
434
- return {
435
- runId: args.runId,
436
- workflowId: args.workflowId,
437
- nodeId: args.nodeId,
438
- activationId: args.activationId,
439
- parent: args.parent,
440
- status: "failed",
441
- queuedAt: args.previous?.queuedAt,
442
- startedAt: args.previous?.startedAt,
443
- finishedAt: args.finishedAt,
444
- updatedAt: args.finishedAt,
445
- inputsByPort: args.inputsByPort,
446
- outputs: void 0,
447
- error: {
448
- message: args.error.message,
449
- name: args.error.name,
450
- stack: args.error.stack
451
- }
452
- };
453
- }
454
- };
455
-
456
- //#endregion
457
- //#region src/execution/NodeInputsByPortFactory.ts
458
- var NodeInputsByPortFactory = class {
459
- static empty() {
460
- return {};
461
- }
462
- static fromRequest(request) {
463
- if (request.kind === "multi") return request.inputsByPort;
464
- return { in: request.input };
465
- }
466
- };
467
-
468
- //#endregion
469
- //#region src/execution/ActivationEnqueueService.ts
470
- var ActivationEnqueueService = class {
471
- constructor(activationScheduler, workflowExecutionRepository, nodeEventPublisher) {
472
- this.activationScheduler = activationScheduler;
473
- this.workflowExecutionRepository = workflowExecutionRepository;
474
- this.nodeEventPublisher = nodeEventPublisher;
475
- }
476
- async enqueueActivation(args) {
477
- const { result, queuedSnapshot } = await this.enqueueActivationWithSnapshot(args);
478
- await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
479
- return result;
480
- }
481
- async enqueueActivationWithSnapshot(args) {
482
- const receipt = await this.activationScheduler.enqueue(args.request);
483
- const inputsByPort = NodeInputsByPortFactory.fromRequest(args.request);
484
- const itemsIn = args.request.kind === "multi" ? args.planner.sumItemsByPort(args.request.inputsByPort) : args.request.input.length;
485
- const enqueuedAt = (/* @__PURE__ */ new Date()).toISOString();
486
- const pending = {
487
- runId: args.runId,
488
- activationId: args.request.activationId,
489
- workflowId: args.workflowId,
490
- nodeId: args.request.nodeId,
491
- itemsIn,
492
- inputsByPort,
493
- receiptId: receipt.receiptId,
494
- queue: receipt.queue,
495
- batchId: args.request.batchId,
496
- enqueuedAt
497
- };
498
- const queuedSnapshot = NodeExecutionSnapshotFactory.queued({
499
- runId: args.runId,
500
- workflowId: args.workflowId,
501
- nodeId: args.request.nodeId,
502
- activationId: args.request.activationId,
503
- parent: args.parent,
504
- queuedAt: enqueuedAt,
505
- inputsByPort
506
- });
507
- await this.workflowExecutionRepository.save({
508
- runId: args.runId,
509
- workflowId: args.workflowId,
510
- startedAt: args.startedAt,
511
- parent: args.parent,
512
- executionOptions: args.executionOptions,
513
- control: args.control,
514
- workflowSnapshot: args.workflowSnapshot,
515
- mutableState: args.mutableState,
516
- policySnapshot: args.policySnapshot,
517
- engineCounters: args.engineCounters,
518
- connectionInvocations: args.connectionInvocations ? [...args.connectionInvocations] : [],
519
- status: "pending",
520
- pending,
521
- queue: args.pendingQueue.map((entry) => ({ ...entry })),
522
- outputsByNode: args.request.ctx.data.dump(),
523
- nodeSnapshotsByNodeId: {
524
- ...args.previousNodeSnapshotsByNodeId,
525
- [args.request.nodeId]: queuedSnapshot
526
- }
527
- });
528
- this.notifyPendingStatePersisted(args.runId);
529
- return {
530
- result: {
531
- runId: args.runId,
532
- workflowId: args.workflowId,
533
- startedAt: args.startedAt,
534
- status: "pending",
535
- pending
536
- },
537
- queuedSnapshot
538
- };
539
- }
540
- notifyPendingStatePersisted(runId) {
541
- this.activationScheduler.notifyPendingStatePersisted?.(runId);
542
- }
543
- };
544
-
545
- //#endregion
546
- //#region src/execution/CredentialResolverFactory.ts
547
- var CredentialResolverFactory = class {
548
- constructor(credentialSessions) {
549
- this.credentialSessions = credentialSessions;
550
- }
551
- create(workflowId, nodeId, config) {
552
- const acceptedTypesBySlot = /* @__PURE__ */ new Map();
553
- for (const requirement of config?.getCredentialRequirements?.() ?? []) acceptedTypesBySlot.set(requirement.slotKey, requirement.acceptedTypes);
554
- return async (slotKey) => {
555
- try {
556
- return await this.credentialSessions.getSession({
557
- workflowId,
558
- nodeId,
559
- slotKey
560
- });
561
- } catch (error) {
562
- const acceptedTypes = acceptedTypesBySlot.get(slotKey) ?? [];
563
- const message = error instanceof Error ? error.message : String(error);
564
- const alreadyListsAcceptedTypes = message.includes("Accepted types:") || message.includes("Accepted credential types:") || message.includes("binding points at an unknown type");
565
- const acceptedTypesSuffix = acceptedTypes.length > 0 && !alreadyListsAcceptedTypes ? ` Accepted types: ${acceptedTypes.join(", ")}.` : "";
566
- throw new Error(`Failed to resolve credential for workflow ${workflowId} node ${nodeId} slot "${slotKey}". ${message}${acceptedTypesSuffix}`, { cause: error });
567
- }
568
- };
569
- }
570
- };
571
-
572
- //#endregion
573
- //#region src/execution/DefaultAsyncSleeper.ts
574
- var DefaultAsyncSleeper = class {
575
- sleep(ms) {
576
- return new Promise((resolve) => {
577
- setTimeout(resolve, ms);
578
- });
579
- }
580
- };
581
-
582
- //#endregion
583
- //#region src/execution/DefaultExecutionContextFactory.ts
584
- var DefaultExecutionContextFactory = class {
585
- constructor(binaryStorage = new UnavailableBinaryStorage(), currentDate = () => /* @__PURE__ */ new Date()) {
586
- this.binaryStorage = binaryStorage;
587
- this.currentDate = currentDate;
588
- }
589
- create(args) {
590
- return {
591
- runId: args.runId,
592
- workflowId: args.workflowId,
593
- parent: args.parent,
594
- subworkflowDepth: args.subworkflowDepth,
595
- engineMaxNodeActivations: args.engineMaxNodeActivations,
596
- engineMaxSubworkflowDepth: args.engineMaxSubworkflowDepth,
597
- now: this.currentDate,
598
- data: args.data,
599
- nodeState: args.nodeState,
600
- binary: new DefaultExecutionBinaryService(this.binaryStorage, args.workflowId, args.runId, this.currentDate),
601
- getCredential: args.getCredential
602
- };
603
- }
604
- };
605
-
606
- //#endregion
607
- //#region src/execution/InProcessRetryRunner.ts
608
- var InProcessRetryRunner = class InProcessRetryRunner {
609
- constructor(sleeper) {
610
- this.sleeper = sleeper;
611
- }
612
- async run(policy, work) {
613
- const spec = InProcessRetryRunner.normalizePolicy(policy);
614
- let lastError;
615
- for (let attempt = 1; attempt <= spec.maxAttempts; attempt++) try {
616
- return await work();
617
- } catch (error) {
618
- lastError = error;
619
- if (attempt >= spec.maxAttempts) break;
620
- const delayMs = InProcessRetryRunner.delayAfterFailureMs(spec, attempt);
621
- await this.sleeper.sleep(delayMs);
622
- }
623
- throw lastError instanceof Error ? lastError : new Error(String(lastError));
624
- }
625
- static delayAfterFailureMs(spec, failedAttempt) {
626
- if (spec.kind === "none") return 0;
627
- if (spec.kind === "fixed") return spec.delayMs;
628
- const exponent = failedAttempt - 1;
629
- let ms = spec.initialDelayMs * Math.pow(spec.multiplier, exponent);
630
- if (spec.jitter === true) ms *= 1 + Math.random() * .2;
631
- if (spec.maxDelayMs !== void 0 && ms > spec.maxDelayMs) ms = spec.maxDelayMs;
632
- return Math.max(0, Math.floor(ms));
633
- }
634
- static normalizePolicy(policy) {
635
- if (policy === void 0) return {
636
- kind: "none",
637
- maxAttempts: 1
638
- };
639
- if (typeof policy !== "object" || policy === null) return {
640
- kind: "none",
641
- maxAttempts: 1
642
- };
643
- const kind = policy.kind;
644
- if (kind === "none") return {
645
- kind: "none",
646
- maxAttempts: 1
647
- };
648
- if (kind === "fixed") {
649
- const p = policy;
650
- return {
651
- kind: "fixed",
652
- maxAttempts: InProcessRetryRunner.assertPositiveInt(p.maxAttempts, "fixed.maxAttempts"),
653
- delayMs: InProcessRetryRunner.assertNonNegativeFinite(p.delayMs, "fixed.delayMs")
654
- };
655
- }
656
- if (kind === "exponential") {
657
- const p = policy;
658
- return {
659
- kind: "exponential",
660
- maxAttempts: InProcessRetryRunner.assertPositiveInt(p.maxAttempts, "exponential.maxAttempts"),
661
- initialDelayMs: InProcessRetryRunner.assertNonNegativeFinite(p.initialDelayMs, "exponential.initialDelayMs"),
662
- multiplier: InProcessRetryRunner.assertMultiplier(p.multiplier),
663
- maxDelayMs: p.maxDelayMs === void 0 ? void 0 : InProcessRetryRunner.assertNonNegativeFinite(p.maxDelayMs, "exponential.maxDelayMs"),
664
- jitter: p.jitter === true
665
- };
666
- }
667
- return {
668
- kind: "none",
669
- maxAttempts: 1
670
- };
671
- }
672
- static assertPositiveInt(value, label) {
673
- if (typeof value !== "number" || !Number.isFinite(value) || value < 1 || !Number.isInteger(value)) throw new Error(`Retry policy ${label} must be a positive integer`);
674
- return value;
675
- }
676
- static assertNonNegativeFinite(value, label) {
677
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) throw new Error(`Retry policy ${label} must be a non-negative finite number`);
678
- return value;
679
- }
680
- static assertMultiplier(value) {
681
- if (typeof value !== "number" || !Number.isFinite(value) || value < 1) throw new Error(`Retry policy exponential.multiplier must be >= 1`);
682
- return value;
683
- }
684
- };
685
-
686
- //#endregion
687
- //#region src/execution/InProcessRetryRunnerFactory.ts
688
- var InProcessRetryRunnerFactory = class {
689
- create(defaultAsyncSleeper) {
690
- return new InProcessRetryRunner(defaultAsyncSleeper);
691
- }
692
- };
693
-
694
- //#endregion
695
- //#region src/execution/NodeActivationRequestComposer.ts
696
- /**
697
- * Builds {@link NodeActivationRequest} values shared by workflow starters and continuation.
698
- */
699
- var NodeActivationRequestComposer = class {
700
- constructor(activationIdFactory, credentialResolverFactory) {
701
- this.activationIdFactory = activationIdFactory;
702
- this.credentialResolverFactory = credentialResolverFactory;
703
- }
704
- createSingleFromDefinition(args) {
705
- const activationId = this.activationIdFactory.makeActivationId();
706
- const ctx = this.createNodeExecutionContext(args, args.definition, activationId);
707
- return {
708
- kind: "single",
709
- runId: args.runId,
710
- activationId,
711
- workflowId: args.workflowId,
712
- nodeId: args.definition.id,
713
- parent: args.parent,
714
- executionOptions: args.executionOptions,
715
- batchId: args.batchId,
716
- input: args.input,
717
- ctx
718
- };
719
- }
720
- createFromPlannedActivation(args) {
721
- const activationId = this.activationIdFactory.makeActivationId();
722
- const ctx = this.createNodeExecutionContext(args, args.nodeDefinition, activationId);
723
- if (args.next.kind === "multi") return {
724
- kind: "multi",
725
- runId: args.runId,
726
- activationId,
727
- workflowId: args.workflowId,
728
- nodeId: args.nodeDefinition.id,
729
- parent: args.parent,
730
- executionOptions: args.executionOptions,
731
- batchId: args.next.batchId,
732
- inputsByPort: args.next.inputsByPort,
733
- ctx
734
- };
735
- return {
736
- kind: "single",
737
- runId: args.runId,
738
- activationId,
739
- workflowId: args.workflowId,
740
- nodeId: args.nodeDefinition.id,
741
- parent: args.parent,
742
- executionOptions: args.executionOptions,
743
- batchId: args.next.batchId,
744
- input: args.next.input,
745
- ctx
746
- };
747
- }
748
- createNodeExecutionContext(args, definition, activationId) {
749
- return {
750
- ...args.base,
751
- data: args.data,
752
- nodeId: definition.id,
753
- activationId,
754
- config: definition.config,
755
- binary: args.base.binary.forNode({
756
- nodeId: definition.id,
757
- activationId
758
- }),
759
- getCredential: this.credentialResolverFactory.create(args.workflowId, definition.id, definition.config)
760
- };
761
- }
762
- };
763
-
764
- //#endregion
765
- //#region src/execution/NodeExecutor.ts
766
- var NodeExecutor = class {
767
- constructor(nodeInstanceFactory, retryRunner) {
768
- this.nodeInstanceFactory = nodeInstanceFactory;
769
- this.retryRunner = retryRunner;
770
- }
771
- async execute(request) {
772
- const policy = request.ctx.config.retryPolicy;
773
- return await this.retryRunner.run(policy, async () => {
774
- const nodeInstance = this.nodeInstanceFactory.createByType(request.ctx.config.type);
775
- if (request.kind === "multi") return await this.executeMultiInputNode(request, nodeInstance);
776
- return await this.executeSingleInputNode(request, nodeInstance);
777
- });
778
- }
779
- async executeMultiInputNode(request, node$1) {
780
- const multiInputNode = node$1;
781
- if (typeof multiInputNode.executeMulti !== "function") throw new Error(`Node ${request.nodeId} does not support executeMulti but received multi-input activation`);
782
- return await multiInputNode.executeMulti(request.inputsByPort, request.ctx);
783
- }
784
- async executeSingleInputNode(request, node$1) {
785
- const singleInputNode = node$1;
786
- if (typeof singleInputNode.execute !== "function") throw new Error(`Node ${request.nodeId} does not support execute but received single-input activation`);
787
- return await singleInputNode.execute(request.input, request.ctx);
788
- }
789
- };
790
-
791
- //#endregion
792
- //#region src/execution/NodeExecutorFactory.ts
793
- var NodeExecutorFactory = class {
794
- create(workflowNodeInstanceFactory, retryRunner) {
795
- return new NodeExecutor(workflowNodeInstanceFactory, retryRunner);
796
- }
797
- };
798
-
799
- //#endregion
800
- //#region src/workflowSnapshots/MissingRuntimeExecutionMarker.ts
801
- var MissingRuntimeExecutionMarker = class {
802
- isMarked(config) {
803
- return Boolean(config?.missingRuntime);
804
- }
805
- };
806
-
807
- //#endregion
808
- //#region src/workflowSnapshots/MissingRuntimeNodeToken.ts
809
- var MissingRuntimeNodeToken = class {};
810
-
811
- //#endregion
812
- //#region src/workflowSnapshots/MissingRuntimeNodeConfig.ts
813
- var MissingRuntimeNodeConfig = class {
814
- kind = "node";
815
- type = MissingRuntimeNodeToken;
816
- constructor(name, missingTokenId, missingRuntime = true) {
817
- this.name = name;
818
- this.missingTokenId = missingTokenId;
819
- this.missingRuntime = missingRuntime;
820
- }
821
- };
822
-
823
- //#endregion
824
- //#region src/workflowSnapshots/MissingRuntimeTriggerToken.ts
825
- var MissingRuntimeTriggerToken = class {};
826
-
827
- //#endregion
828
- //#region src/workflowSnapshots/MissingRuntimeTriggerConfig.ts
829
- var MissingRuntimeTriggerConfig = class {
830
- kind = "trigger";
831
- type = MissingRuntimeTriggerToken;
832
- constructor(name, missingTokenId, missingRuntime = true) {
833
- this.name = name;
834
- this.missingTokenId = missingTokenId;
835
- this.missingRuntime = missingRuntime;
836
- }
837
- };
838
-
839
- //#endregion
840
- //#region src/workflowSnapshots/MissingRuntimeFallbacksFactory.ts
841
- var MissingRuntimeFallbacks = class {
842
- createDefinition(snapshotNode) {
843
- if (snapshotNode.kind === "trigger") return {
844
- id: snapshotNode.id,
845
- kind: "trigger",
846
- name: snapshotNode.name,
847
- type: MissingRuntimeTriggerToken,
848
- config: new MissingRuntimeTriggerConfig(snapshotNode.name ?? snapshotNode.id, snapshotNode.nodeTokenId)
849
- };
850
- return {
851
- id: snapshotNode.id,
852
- kind: "node",
853
- name: snapshotNode.name,
854
- type: MissingRuntimeNodeToken,
855
- config: new MissingRuntimeNodeConfig(snapshotNode.name ?? snapshotNode.id, snapshotNode.nodeTokenId)
856
- };
857
- }
858
- };
859
-
860
- //#endregion
861
- //#region src/workflowSnapshots/MissingRuntimeNode.ts
862
- var MissingRuntimeNode = class {
863
- kind = "node";
864
- outputPorts = ["main"];
865
- async execute(items) {
866
- return { main: items };
867
- }
868
- };
869
-
870
- //#endregion
871
- //#region src/workflowSnapshots/MissingRuntimeTrigger.ts
872
- var MissingRuntimeTrigger = class {
873
- kind = "trigger";
874
- outputPorts = ["main"];
875
- async setup(_ctx) {}
876
- async execute(items) {
877
- return { main: items };
878
- }
879
- };
880
-
881
- //#endregion
882
- //#region src/workflowSnapshots/PersistedRuntimeTypeIdFactory.ts
883
- var PersistedRuntimeTypeIdFactory = class {
884
- static fromMetadata(args) {
885
- const metadata = getPersistedRuntimeTypeMetadata(args.type);
886
- if (!metadata) return;
887
- const packageName = metadata.packageName;
888
- if (!packageName) return;
889
- return `${packageName}::${metadata.persistedName}`;
890
- }
891
- };
892
-
893
- //#endregion
894
- //#region src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts
895
- var PersistedWorkflowTokenRegistry = class {
896
- tokensById = /* @__PURE__ */ new Map();
897
- tokenIdsByToken = /* @__PURE__ */ new Map();
898
- /**
899
- * Register a token with its package ID. Token ID is inferred as `packageId::tokenName`.
900
- */
901
- register(type, packageId, persistedNameOverride) {
902
- const tokenId = `${packageId}::${persistedNameOverride ?? this.displayNameForTypeToken(type)}`;
903
- this.tokensById.set(tokenId, type);
904
- this.tokenIdsByToken.set(type, tokenId);
905
- return tokenId;
906
- }
907
- /**
908
- * Register all decorated runtime types discovered in workflows.
909
- */
910
- registerFromWorkflows(workflows) {
911
- for (const workflow of workflows) for (const node$1 of workflow.nodes) {
912
- this.registerDecoratedType(node$1.type);
913
- this.registerDecoratedType(node$1.config.type);
914
- this.registerNestedTypes(node$1.config);
915
- }
916
- }
917
- registerDecoratedType(type) {
918
- if (this.tokenIdsByToken.has(type)) return;
919
- const tokenId = PersistedRuntimeTypeIdFactory.fromMetadata({ type });
920
- if (!tokenId) return;
921
- this.tokensById.set(tokenId, type);
922
- this.tokenIdsByToken.set(type, tokenId);
923
- }
924
- registerNestedTypes(value) {
925
- if (Array.isArray(value)) {
926
- for (const entry of value) this.registerNestedTypes(entry);
927
- return;
928
- }
929
- if (!value || typeof value !== "object") return;
930
- const record = value;
931
- const type = this.asTypeToken(record.type);
932
- if (type) this.registerDecoratedType(type);
933
- for (const v of Object.values(record)) this.registerNestedTypes(v);
934
- }
935
- displayNameForTypeToken(token) {
936
- if (typeof token === "function" && token.name) return token.name;
937
- if (typeof token === "string") return token;
938
- return "";
939
- }
940
- asTypeToken(value) {
941
- if (typeof value === "function" || typeof value === "string" || typeof value === "symbol") return value;
942
- }
943
- getTokenId(token) {
944
- const existing = this.tokenIdsByToken.get(token);
945
- if (existing) return existing;
946
- const tokenId = PersistedRuntimeTypeIdFactory.fromMetadata({ type: token });
947
- if (!tokenId) return;
948
- this.tokensById.set(tokenId, token);
949
- this.tokenIdsByToken.set(token, tokenId);
950
- return tokenId;
951
- }
952
- resolve(tokenId) {
953
- return this.tokensById.get(tokenId);
954
- }
955
- };
956
-
957
- //#endregion
958
- //#region src/workflowSnapshots/WorkflowSnapshotResolver.ts
959
- var WorkflowSnapshotResolver = class {
960
- constructor(workflowRepository, tokenRegistry, codec, missingRuntimeFallbacks) {
961
- this.workflowRepository = workflowRepository;
962
- this.tokenRegistry = tokenRegistry;
963
- this.codec = codec;
964
- this.missingRuntimeFallbacks = missingRuntimeFallbacks;
965
- }
966
- resolve(args) {
967
- const liveWorkflow = this.workflowRepository.get(args.workflowId);
968
- if (!args.workflowSnapshot) return liveWorkflow;
969
- if (!liveWorkflow) return this.rebuildWorkflow(args.workflowSnapshot, void 0);
970
- return this.rebuildWorkflow(args.workflowSnapshot, liveWorkflow);
971
- }
972
- rebuildWorkflow(snapshot, liveWorkflow) {
973
- const liveNodesById = new Map((liveWorkflow?.nodes ?? []).map((node$1) => [node$1.id, node$1]));
974
- const nodes = snapshot.nodes.map((snapshotNode) => {
975
- const liveNode = liveNodesById.get(snapshotNode.id);
976
- if (!this.isCompatibleLiveNode(liveNode, snapshotNode)) return this.missingRuntimeFallbacks.createDefinition(snapshotNode);
977
- return {
978
- id: snapshotNode.id,
979
- kind: snapshotNode.kind,
980
- name: snapshotNode.name ?? liveNode.name,
981
- type: liveNode.type,
982
- config: this.codec.hydrate(snapshotNode, liveNode.config)
983
- };
984
- });
985
- const nodeIds = new Set(nodes.map((node$1) => node$1.id));
986
- const connectionsFromSnapshot = snapshot.connections?.map((connection) => ({
987
- ...connection,
988
- childNodeIds: connection.childNodeIds.filter((childId) => nodeIds.has(childId))
989
- })).filter((connection) => connection.childNodeIds.length > 0) ?? [];
990
- return {
991
- id: snapshot.id,
992
- name: snapshot.name,
993
- nodes,
994
- edges: snapshot.edges.filter((edge) => nodeIds.has(edge.from.nodeId) && nodeIds.has(edge.to.nodeId)),
995
- ...connectionsFromSnapshot.length > 0 ? { connections: connectionsFromSnapshot } : {},
996
- ...liveWorkflow?.discoveryPathSegments !== void 0 ? { discoveryPathSegments: liveWorkflow.discoveryPathSegments } : {}
997
- };
998
- }
999
- isCompatibleLiveNode(liveNode, snapshotNode) {
1000
- if (!liveNode || liveNode.kind !== snapshotNode.kind) return false;
1001
- if (!snapshotNode.nodeTokenId || !snapshotNode.configTokenId) throw new Error(`Persisted workflow snapshot node "${snapshotNode.id}" is missing stable token ids.`);
1002
- const liveNodeTokenId = this.resolveLiveTokenId(liveNode.type);
1003
- const liveConfigTokenId = this.resolveLiveTokenId(liveNode.config.type);
1004
- return liveNodeTokenId === snapshotNode.nodeTokenId && liveConfigTokenId === snapshotNode.configTokenId;
1005
- }
1006
- resolveLiveTokenId(type) {
1007
- const registeredTokenId = this.tokenRegistry.getTokenId(type);
1008
- if (registeredTokenId) return registeredTokenId;
1009
- if (typeof type === "function" && type.name) return type.name;
1010
- if (typeof type === "string") return type;
1011
- }
1012
- };
1013
-
1014
- //#endregion
1015
- //#region src/execution/NodeInstanceFactory.ts
1016
- var NodeInstanceFactory = class {
1017
- constructor(nodeResolver) {
1018
- this.nodeResolver = nodeResolver;
1019
- }
1020
- createNodes(workflow) {
1021
- const nodeInstances = /* @__PURE__ */ new Map();
1022
- for (const definition of workflow.nodes) nodeInstances.set(definition.id, this.createNode(definition));
1023
- return nodeInstances;
1024
- }
1025
- createNode(definition) {
1026
- return this.createByType(definition.type);
1027
- }
1028
- createByType(type) {
1029
- if (type === MissingRuntimeNodeToken) return new MissingRuntimeNode();
1030
- if (type === MissingRuntimeTriggerToken) return new MissingRuntimeTrigger();
1031
- return this.nodeResolver.resolve(type);
1032
- }
1033
- };
1034
-
1035
- //#endregion
1036
- //#region src/execution/NodeInstanceFactoryFactory.ts
1037
- var NodeInstanceFactoryFactory = class {
1038
- create(nodeResolver) {
1039
- return new NodeInstanceFactory(nodeResolver);
1040
- }
1041
- };
1042
-
1043
- //#endregion
1044
- //#region src/execution/NodeRunStateWriter.ts
1045
- var NodeRunStateWriter = class {
1046
- chain = Promise.resolve();
1047
- constructor(workflowExecutionRepository, runId, workflowId, parent, publishNodeEvent) {
1048
- this.workflowExecutionRepository = workflowExecutionRepository;
1049
- this.runId = runId;
1050
- this.workflowId = workflowId;
1051
- this.parent = parent;
1052
- this.publishNodeEvent = publishNodeEvent;
1053
- }
1054
- markQueued(args) {
1055
- return this.enqueue(async () => {
1056
- const state = await this.loadState();
1057
- const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
1058
- const queuedAt = (/* @__PURE__ */ new Date()).toISOString();
1059
- const snapshot = NodeExecutionSnapshotFactory.queued({
1060
- runId: this.runId,
1061
- workflowId: this.workflowId,
1062
- nodeId: args.nodeId,
1063
- activationId: args.activationId ?? previous?.activationId ?? `synthetic_${args.nodeId}`,
1064
- parent: this.parent,
1065
- queuedAt,
1066
- inputsByPort: args.inputsByPort ?? previous?.inputsByPort ?? NodeInputsByPortFactory.empty()
1067
- });
1068
- await this.saveSnapshot(state, snapshot);
1069
- await this.publishNodeEvent("nodeQueued", snapshot);
1070
- });
1071
- }
1072
- markRunning(args) {
1073
- return this.enqueue(async () => {
1074
- const state = await this.loadState();
1075
- const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
1076
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
1077
- const snapshot = NodeExecutionSnapshotFactory.running({
1078
- previous,
1079
- runId: this.runId,
1080
- workflowId: this.workflowId,
1081
- nodeId: args.nodeId,
1082
- activationId: args.activationId ?? previous?.activationId ?? `synthetic_${args.nodeId}`,
1083
- parent: this.parent,
1084
- startedAt,
1085
- inputsByPort: args.inputsByPort ?? previous?.inputsByPort ?? NodeInputsByPortFactory.empty()
1086
- });
1087
- await this.saveSnapshot(state, snapshot);
1088
- await this.publishNodeEvent("nodeStarted", snapshot);
1089
- });
1090
- }
1091
- markCompleted(args) {
1092
- return this.enqueue(async () => {
1093
- const state = await this.loadState();
1094
- const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
1095
- const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
1096
- const snapshot = NodeExecutionSnapshotFactory.completed({
1097
- previous,
1098
- runId: this.runId,
1099
- workflowId: this.workflowId,
1100
- nodeId: args.nodeId,
1101
- activationId: args.activationId ?? previous?.activationId ?? `synthetic_${args.nodeId}`,
1102
- parent: this.parent,
1103
- finishedAt,
1104
- inputsByPort: args.inputsByPort ?? previous?.inputsByPort ?? NodeInputsByPortFactory.empty(),
1105
- outputs: args.outputs ?? previous?.outputs ?? {}
1106
- });
1107
- await this.saveSnapshot(state, snapshot);
1108
- await this.publishNodeEvent("nodeCompleted", snapshot);
1109
- });
1110
- }
1111
- markFailed(args) {
1112
- return this.enqueue(async () => {
1113
- const state = await this.loadState();
1114
- const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
1115
- const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
1116
- const snapshot = NodeExecutionSnapshotFactory.failed({
1117
- previous,
1118
- runId: this.runId,
1119
- workflowId: this.workflowId,
1120
- nodeId: args.nodeId,
1121
- activationId: args.activationId ?? previous?.activationId ?? `synthetic_${args.nodeId}`,
1122
- parent: this.parent,
1123
- finishedAt,
1124
- inputsByPort: args.inputsByPort ?? previous?.inputsByPort ?? NodeInputsByPortFactory.empty(),
1125
- error: args.error
1126
- });
1127
- await this.saveSnapshot(state, snapshot);
1128
- await this.publishNodeEvent("nodeFailed", snapshot);
1129
- });
1130
- }
1131
- appendConnectionInvocation(args) {
1132
- return this.enqueue(async () => {
1133
- const state = await this.loadState();
1134
- const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1135
- const record = {
1136
- invocationId: args.invocationId,
1137
- runId: this.runId,
1138
- workflowId: this.workflowId,
1139
- connectionNodeId: args.connectionNodeId,
1140
- parentAgentNodeId: args.parentAgentNodeId,
1141
- parentAgentActivationId: args.parentAgentActivationId,
1142
- status: args.status,
1143
- managedInput: args.managedInput,
1144
- managedOutput: args.managedOutput,
1145
- error: args.error,
1146
- queuedAt: args.queuedAt,
1147
- startedAt: args.startedAt,
1148
- finishedAt: args.finishedAt,
1149
- updatedAt
1150
- };
1151
- await this.workflowExecutionRepository.save({
1152
- ...state,
1153
- connectionInvocations: [...state.connectionInvocations ?? [], record]
1154
- });
1155
- });
1156
- }
1157
- enqueue(work) {
1158
- const next = this.chain.then(work);
1159
- this.chain = next.catch(() => void 0);
1160
- return next;
1161
- }
1162
- async loadState() {
1163
- const state = await this.workflowExecutionRepository.load(this.runId);
1164
- if (!state) throw new Error(`Unknown runId: ${this.runId}`);
1165
- return state;
1166
- }
1167
- async saveSnapshot(state, snapshot) {
1168
- await this.workflowExecutionRepository.save({
1169
- ...state,
1170
- nodeSnapshotsByNodeId: {
1171
- ...state.nodeSnapshotsByNodeId ?? {},
1172
- [snapshot.nodeId]: snapshot
1173
- }
1174
- });
1175
- }
1176
- };
1177
-
1178
- //#endregion
1179
- //#region src/execution/NodeRunStateWriterFactory.ts
1180
- var NodeRunStateWriterFactory = class {
1181
- constructor(workflowExecutionRepository, nodeEventPublisher) {
1182
- this.workflowExecutionRepository = workflowExecutionRepository;
1183
- this.nodeEventPublisher = nodeEventPublisher;
1184
- }
1185
- create(runId, workflowId, parent) {
1186
- return new NodeRunStateWriter(this.workflowExecutionRepository, runId, workflowId, parent, async (kind, snapshot) => {
1187
- await this.nodeEventPublisher.publish(kind, snapshot);
1188
- });
1189
- }
1190
- };
1191
-
1192
- //#endregion
1193
- //#region src/execution/PersistedRunStateTerminalBuilder.ts
1194
- /**
1195
- * Merges common terminal-run fields onto a loaded {@link PersistedRunState} without repeating object literals.
1196
- */
1197
- var PersistedRunStateTerminalBuilder = class {
1198
- mergeTerminal(args) {
1199
- return {
1200
- ...args.state,
1201
- engineCounters: args.engineCounters,
1202
- status: args.status,
1203
- pending: void 0,
1204
- queue: args.queue,
1205
- outputsByNode: args.outputsByNode,
1206
- nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId
1207
- };
1208
- }
1209
- };
1210
-
1211
- //#endregion
1212
- //#region src/execution/RunStateSemantics.ts
1213
- var RunStateSemantics = class {
1214
- constructor(missingRuntimeExecutionMarker) {
1215
- this.missingRuntimeExecutionMarker = missingRuntimeExecutionMarker;
1216
- }
1217
- isStopConditionSatisfied(stopCondition, nodeId) {
1218
- if (!stopCondition || stopCondition.kind === "workflowCompleted") return false;
1219
- return stopCondition.nodeId === nodeId;
1220
- }
1221
- resolveResultOutputs(workflow, stopCondition, outputsByNode) {
1222
- if (stopCondition?.kind === "nodeCompleted") return outputsByNode[stopCondition.nodeId]?.main ?? [];
1223
- return outputsByNode[WorkflowExecutableNodeClassifierFactory.create(workflow).lastExecutableNodeIdInDefinitionOrder(workflow)]?.main ?? [];
1224
- }
1225
- applySkippedSnapshots(args) {
1226
- const snapshots = { ...args.currentState.nodeSnapshotsByNodeId };
1227
- const skippedPinnedNodeIds = new Set(args.preservedPinnedNodeIds.filter((nodeId) => args.skippedNodeIds.includes(nodeId)));
1228
- for (const nodeId of args.skippedNodeIds) if (args.currentState.mutableState?.nodesById?.[nodeId]?.pinnedOutputsByPort) skippedPinnedNodeIds.add(nodeId);
1229
- for (const nodeId of skippedPinnedNodeIds) {
1230
- const previous = snapshots[nodeId];
1231
- snapshots[nodeId] = NodeExecutionSnapshotFactory.completed({
1232
- previous,
1233
- runId: args.runId,
1234
- workflowId: args.workflowId,
1235
- nodeId,
1236
- activationId: previous?.activationId ?? `synthetic_${nodeId}`,
1237
- parent: args.parent,
1238
- finishedAt: args.finishedAt,
1239
- inputsByPort: previous?.inputsByPort ?? NodeInputsByPortFactory.empty(),
1240
- outputs: args.currentState.outputsByNode[nodeId] ?? {},
1241
- fromPinnedOutput: true
1242
- });
1243
- }
1244
- return snapshots;
1245
- }
1246
- applyPinnedQueueSkips(args) {
1247
- let changed = true;
1248
- while (changed) {
1249
- changed = false;
1250
- for (let index = 0; index < args.queue.length; index += 1) {
1251
- const queueEntry = args.queue[index];
1252
- const pinnedOutputs = args.mutableState?.nodesById?.[queueEntry.nodeId]?.pinnedOutputsByPort;
1253
- if (!pinnedOutputs) continue;
1254
- args.queue.splice(index, 1);
1255
- const previous = args.nodeSnapshotsByNodeId[queueEntry.nodeId];
1256
- args.nodeSnapshotsByNodeId[queueEntry.nodeId] = NodeExecutionSnapshotFactory.completed({
1257
- previous,
1258
- runId: args.runId,
1259
- workflowId: args.workflowId,
1260
- nodeId: queueEntry.nodeId,
1261
- activationId: previous?.activationId ?? `synthetic_${queueEntry.nodeId}`,
1262
- parent: args.parent,
1263
- finishedAt: args.finishedAt,
1264
- inputsByPort: this.resolveQueueEntryInputsByPort(queueEntry),
1265
- outputs: pinnedOutputs,
1266
- fromPinnedOutput: true
1267
- });
1268
- args.data.setOutputs(queueEntry.nodeId, pinnedOutputs);
1269
- args.planner.applyOutputs(args.queue, {
1270
- fromNodeId: queueEntry.nodeId,
1271
- outputs: pinnedOutputs,
1272
- batchId: queueEntry.batchId ?? "batch_1"
1273
- });
1274
- changed = true;
1275
- break;
1276
- }
1277
- }
1278
- }
1279
- createFinishedSnapshot(args) {
1280
- const definition = args.workflow.nodes.find((node$1) => node$1.id === args.nodeId);
1281
- if (this.missingRuntimeExecutionMarker.isMarked(definition?.config)) return NodeExecutionSnapshotFactory.skipped(args);
1282
- return NodeExecutionSnapshotFactory.completed(args);
1283
- }
1284
- resolveQueueEntryInputsByPort(queueEntry) {
1285
- if (queueEntry.collect) return queueEntry.collect.received;
1286
- return { [queueEntry.toInput ?? "in"]: queueEntry.input };
1287
- }
1288
- };
1289
-
1290
- //#endregion
1291
- //#region src/execution/WorkflowRunExecutionContextFactory.ts
1292
- /**
1293
- * Shared {@link ExecutionContextFactory#create} wiring for workflow runners (base context before node-specific fields).
1294
- */
1295
- var WorkflowRunExecutionContextFactory = class {
1296
- constructor(executionContextFactory, credentialResolverFactory) {
1297
- this.executionContextFactory = executionContextFactory;
1298
- this.credentialResolverFactory = credentialResolverFactory;
1299
- }
1300
- create(args) {
1301
- return this.executionContextFactory.create({
1302
- runId: args.runId,
1303
- workflowId: args.workflowId,
1304
- parent: args.parent,
1305
- subworkflowDepth: args.subworkflowDepth,
1306
- engineMaxNodeActivations: args.engineMaxNodeActivations,
1307
- engineMaxSubworkflowDepth: args.engineMaxSubworkflowDepth,
1308
- data: args.data,
1309
- nodeState: args.nodeState,
1310
- getCredential: this.credentialResolverFactory.create(args.workflowId, args.nodeId)
1311
- });
1312
- }
1313
- };
1314
-
1315
- //#endregion
1316
- //#region src/planning/WorkflowTopologyPlanner.ts
1317
- var WorkflowTopology = class WorkflowTopology {
1318
- constructor(defsById, outgoingByNode, incomingByNode, expectedInputsByNode, rootNodeIds) {
1319
- this.defsById = defsById;
1320
- this.outgoingByNode = outgoingByNode;
1321
- this.incomingByNode = incomingByNode;
1322
- this.expectedInputsByNode = expectedInputsByNode;
1323
- this.rootNodeIds = rootNodeIds;
1324
- }
1325
- static fromWorkflow(wf) {
1326
- const classifier = WorkflowExecutableNodeClassifierFactory.create(wf);
1327
- const defs = /* @__PURE__ */ new Map();
1328
- for (const n of wf.nodes) if (classifier.isExecutableNodeId(n.id)) defs.set(n.id, n);
1329
- const outgoing = /* @__PURE__ */ new Map();
1330
- for (const e of wf.edges) {
1331
- if (!classifier.isExecutableNodeId(e.from.nodeId) || !classifier.isExecutableNodeId(e.to.nodeId)) continue;
1332
- const list = outgoing.get(e.from.nodeId) ?? [];
1333
- list.push({
1334
- output: e.from.output,
1335
- to: {
1336
- nodeId: e.to.nodeId,
1337
- input: e.to.input
1338
- }
1339
- });
1340
- outgoing.set(e.from.nodeId, list);
1341
- }
1342
- const incomingByNode = /* @__PURE__ */ new Map();
1343
- for (const e of wf.edges) {
1344
- if (!classifier.isExecutableNodeId(e.from.nodeId) || !classifier.isExecutableNodeId(e.to.nodeId)) continue;
1345
- const list = incomingByNode.get(e.to.nodeId) ?? [];
1346
- list.push({
1347
- from: {
1348
- nodeId: e.from.nodeId,
1349
- output: e.from.output
1350
- },
1351
- input: e.to.input
1352
- });
1353
- incomingByNode.set(e.to.nodeId, list);
1354
- }
1355
- const expected = /* @__PURE__ */ new Map();
1356
- for (const [toNodeId, inputs] of incomingByNode.entries()) {
1357
- const counts = /* @__PURE__ */ new Map();
1358
- for (const edge of inputs) counts.set(edge.input, (counts.get(edge.input) ?? 0) + 1);
1359
- for (const [k, n] of counts.entries()) if (n > 1) throw new Error(`Node ${toNodeId} has multiple edges into input '${k}'. Use a Merge node upstream.`);
1360
- const order = [];
1361
- const seen = /* @__PURE__ */ new Set();
1362
- for (const edge of inputs) {
1363
- if (seen.has(edge.input)) continue;
1364
- seen.add(edge.input);
1365
- order.push(edge.input);
1366
- }
1367
- expected.set(toNodeId, order);
1368
- }
1369
- return new WorkflowTopology(defs, outgoing, incomingByNode, expected, wf.nodes.filter((node$1) => classifier.isExecutableNodeId(node$1.id) && !incomingByNode.has(node$1.id)).map((node$1) => node$1.id));
1370
- }
1371
- };
1372
-
1373
- //#endregion
1374
- //#region src/orchestration/RunContinuationService.ts
1375
- var RunContinuationService = class {
1376
- constructor(activationIdFactory, workflowExecutionRepository, runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy) {
1377
- this.activationIdFactory = activationIdFactory;
1378
- this.workflowExecutionRepository = workflowExecutionRepository;
1379
- this.runDataFactory = runDataFactory;
1380
- this.runExecutionContextFactory = runExecutionContextFactory;
1381
- this.workflowSnapshotResolver = workflowSnapshotResolver;
1382
- this.planningFactory = planningFactory;
1383
- this.nodeStatePublisherFactory = nodeStatePublisherFactory;
1384
- this.credentialResolverFactory = credentialResolverFactory;
1385
- this.nodeActivationRequestComposer = nodeActivationRequestComposer;
1386
- this.persistedRunStateTerminalBuilder = persistedRunStateTerminalBuilder;
1387
- this.activationEnqueueService = activationEnqueueService;
1388
- this.nodeEventPublisher = nodeEventPublisher;
1389
- this.semantics = semantics;
1390
- this.waiters = waiters;
1391
- this.policyErrorServices = policyErrorServices;
1392
- this.terminalPersistence = terminalPersistence;
1393
- this.executionLimitsPolicy = executionLimitsPolicy;
1394
- }
1395
- async markNodeRunning(args) {
1396
- const state = await this.workflowExecutionRepository.load(args.runId);
1397
- if (!state?.pending) return;
1398
- if (state.pending.activationId !== args.activationId || state.pending.nodeId !== args.nodeId) return;
1399
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
1400
- const previous = state.nodeSnapshotsByNodeId?.[args.nodeId];
1401
- const snapshot = NodeExecutionSnapshotFactory.running({
1402
- previous,
1403
- runId: state.runId,
1404
- workflowId: state.workflowId,
1405
- nodeId: args.nodeId,
1406
- activationId: args.activationId,
1407
- parent: state.parent,
1408
- startedAt,
1409
- inputsByPort: args.inputsByPort
1410
- });
1411
- await this.workflowExecutionRepository.save({
1412
- ...state,
1413
- nodeSnapshotsByNodeId: {
1414
- ...state.nodeSnapshotsByNodeId ?? {},
1415
- [args.nodeId]: snapshot
1416
- }
1417
- });
1418
- await this.nodeEventPublisher.publish("nodeStarted", snapshot);
1419
- }
1420
- async resumeFromNodeResult(args) {
1421
- const state = await this.workflowExecutionRepository.load(args.runId);
1422
- if (!state) throw new Error(`Unknown runId: ${args.runId}`);
1423
- if (state.status !== "pending" || !state.pending) throw new Error(`Run ${args.runId} is not pending`);
1424
- if (state.pending.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
1425
- if (state.pending.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
1426
- const wf = this.resolvePersistedWorkflow(state);
1427
- if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
1428
- const { topology, planner } = this.planningFactory.create(wf);
1429
- const data = this.runDataFactory.create(state.outputsByNode);
1430
- const limits = this.resolveEngineLimitsFromState(state);
1431
- const base = this.runExecutionContextFactory.create({
1432
- runId: state.runId,
1433
- workflowId: state.workflowId,
1434
- nodeId: args.nodeId,
1435
- parent: state.parent,
1436
- subworkflowDepth: state.executionOptions?.subworkflowDepth ?? 0,
1437
- engineMaxNodeActivations: limits.engineMaxNodeActivations,
1438
- engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
1439
- data,
1440
- nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
1441
- });
1442
- data.setOutputs(args.nodeId, args.outputs);
1443
- const completedAt = (/* @__PURE__ */ new Date()).toISOString();
1444
- const completedSnapshot = this.semantics.createFinishedSnapshot({
1445
- workflow: wf,
1446
- previous: state.nodeSnapshotsByNodeId?.[args.nodeId],
1447
- runId: state.runId,
1448
- workflowId: state.workflowId,
1449
- nodeId: args.nodeId,
1450
- activationId: args.activationId,
1451
- parent: state.parent,
1452
- finishedAt: completedAt,
1453
- inputsByPort: state.pending.inputsByPort,
1454
- outputs: args.outputs
1455
- });
1456
- const completedActivations = (state.engineCounters?.completedNodeActivations ?? 0) + 1;
1457
- const engineCounters = { completedNodeActivations: completedActivations };
1458
- const maxNodeActivations = state.executionOptions?.maxNodeActivations ?? Number.MAX_SAFE_INTEGER;
1459
- if (this.semantics.isStopConditionSatisfied(state.control?.stopCondition, args.nodeId)) {
1460
- const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1461
- state,
1462
- engineCounters,
1463
- status: "completed",
1464
- queue: [],
1465
- outputsByNode: data.dump(),
1466
- nodeSnapshotsByNodeId: {
1467
- ...state.nodeSnapshotsByNodeId ?? {},
1468
- [args.nodeId]: completedSnapshot
1469
- }
1470
- });
1471
- await this.workflowExecutionRepository.save(completedState);
1472
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1473
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1474
- workflow: wf,
1475
- state: completedState,
1476
- finalStatus: "completed",
1477
- finishedAt: completedAt
1478
- });
1479
- const result$1 = {
1480
- runId: state.runId,
1481
- workflowId: state.workflowId,
1482
- startedAt: state.startedAt,
1483
- status: "completed",
1484
- outputs: this.semantics.resolveResultOutputs(wf, state.control?.stopCondition, data.dump())
1485
- };
1486
- this.waiters.resolveRunCompletion(result$1);
1487
- return result$1;
1488
- }
1489
- const batchId = state.pending.batchId ?? "batch_1";
1490
- const queue = (state.queue ?? []).map((q) => ({
1491
- ...q,
1492
- batchId: q.batchId ?? batchId
1493
- }));
1494
- const nextNodeSnapshotsByNodeId = {
1495
- ...state.nodeSnapshotsByNodeId ?? {},
1496
- [args.nodeId]: completedSnapshot
1497
- };
1498
- planner.applyOutputs(queue, {
1499
- fromNodeId: args.nodeId,
1500
- outputs: args.outputs,
1501
- batchId
1502
- });
1503
- this.semantics.applyPinnedQueueSkips({
1504
- runId: state.runId,
1505
- workflowId: state.workflowId,
1506
- parent: state.parent,
1507
- mutableState: state.mutableState,
1508
- planner,
1509
- queue,
1510
- data,
1511
- nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
1512
- finishedAt: completedAt
1513
- });
1514
- let next;
1515
- try {
1516
- next = planner.nextActivation(queue);
1517
- } catch (cause) {
1518
- const completedDefinition = topology.defsById.get(args.nodeId);
1519
- const completedNodeLabel = this.formatNodeLabel({
1520
- definition: completedDefinition,
1521
- nodeId: args.nodeId
1522
- });
1523
- const reason = cause instanceof Error ? cause.message : String(cause);
1524
- throw new Error(`After completing ${completedNodeLabel}, the engine could not plan the next activation. ${reason} Outputs: ${this.formatOutputCounts(args.outputs)}.`, { cause });
1525
- }
1526
- if (!next) {
1527
- const lastNodeId = WorkflowExecutableNodeClassifierFactory.create(wf).lastExecutableNodeIdInDefinitionOrder(wf);
1528
- const outputs = data.getOutputItems(lastNodeId, "main");
1529
- const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1530
- state,
1531
- engineCounters,
1532
- status: "completed",
1533
- queue: [],
1534
- outputsByNode: data.dump(),
1535
- nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
1536
- });
1537
- await this.workflowExecutionRepository.save(completedState);
1538
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1539
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1540
- workflow: wf,
1541
- state: completedState,
1542
- finalStatus: "completed",
1543
- finishedAt: completedAt
1544
- });
1545
- const result$1 = {
1546
- runId: state.runId,
1547
- workflowId: state.workflowId,
1548
- startedAt: state.startedAt,
1549
- status: "completed",
1550
- outputs
1551
- };
1552
- this.waiters.resolveRunCompletion(result$1);
1553
- return result$1;
1554
- }
1555
- if (completedActivations >= maxNodeActivations) {
1556
- const message = `Run exceeded maxNodeActivations (${maxNodeActivations}) after ${completedActivations} completed node activations (next would be ${next.nodeId}).`;
1557
- const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1558
- state,
1559
- engineCounters,
1560
- status: "failed",
1561
- queue: queue.map((q) => ({ ...q })),
1562
- outputsByNode: data.dump(),
1563
- nodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId
1564
- });
1565
- await this.workflowExecutionRepository.save(failedState);
1566
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1567
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1568
- workflow: wf,
1569
- state: failedState,
1570
- finalStatus: "failed",
1571
- finishedAt: completedAt
1572
- });
1573
- const result$1 = {
1574
- runId: state.runId,
1575
- workflowId: state.workflowId,
1576
- startedAt: state.startedAt,
1577
- status: "failed",
1578
- error: { message }
1579
- };
1580
- this.waiters.resolveRunCompletion(result$1);
1581
- return result$1;
1582
- }
1583
- const def = topology.defsById.get(next.nodeId);
1584
- if (!def || def.kind !== "node") throw new Error(`Node ${next.nodeId} is not a runnable node`);
1585
- const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
1586
- next,
1587
- base,
1588
- data,
1589
- runId: state.runId,
1590
- workflowId: state.workflowId,
1591
- parent: state.parent,
1592
- executionOptions: state.executionOptions,
1593
- nodeDefinition: def
1594
- });
1595
- const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
1596
- runId: state.runId,
1597
- workflowId: state.workflowId,
1598
- startedAt: state.startedAt,
1599
- parent: state.parent,
1600
- executionOptions: state.executionOptions,
1601
- control: state.control,
1602
- workflowSnapshot: state.workflowSnapshot,
1603
- mutableState: state.mutableState,
1604
- policySnapshot: state.policySnapshot,
1605
- pendingQueue: queue,
1606
- request,
1607
- previousNodeSnapshotsByNodeId: nextNodeSnapshotsByNodeId,
1608
- planner,
1609
- engineCounters,
1610
- connectionInvocations: state.connectionInvocations ?? []
1611
- });
1612
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1613
- await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
1614
- return result;
1615
- }
1616
- async resumeFromNodeError(args) {
1617
- const state = await this.workflowExecutionRepository.load(args.runId);
1618
- if (!state) throw new Error(`Unknown runId: ${args.runId}`);
1619
- if (state.status !== "pending" || !state.pending) throw new Error(`Run ${args.runId} is not pending`);
1620
- if (state.pending.activationId !== args.activationId) throw new Error(`activationId mismatch for run ${args.runId}`);
1621
- if (state.pending.nodeId !== args.nodeId) throw new Error(`nodeId mismatch for run ${args.runId}`);
1622
- const wf = this.resolvePersistedWorkflow(state);
1623
- if (!wf) throw new Error(`Unknown workflowId: ${state.workflowId}`);
1624
- const failedDefinition = WorkflowTopology.fromWorkflow(wf).defsById.get(args.nodeId);
1625
- const webhookControlSignal = state.executionOptions?.webhook && failedDefinition?.kind === "trigger" ? this.asWebhookControlSignal(args.error) : void 0;
1626
- if (webhookControlSignal) return await this.resumeFromWebhookControl({
1627
- state,
1628
- workflow: wf,
1629
- args,
1630
- signal: webhookControlSignal
1631
- });
1632
- if (failedDefinition && failedDefinition.kind === "node") {
1633
- const nodeHandler = this.policyErrorServices.resolveNodeErrorHandler(failedDefinition.config.nodeErrorHandler);
1634
- if (nodeHandler) try {
1635
- const ctx = this.buildNodeExecutionContextForPending(state, wf, failedDefinition, args.nodeId);
1636
- const inputsByPort = state.pending.inputsByPort;
1637
- const portKeys = Object.keys(inputsByPort);
1638
- const kind = portKeys.length === 1 && portKeys[0] === "in" ? "single" : "multi";
1639
- const items = inputsByPort.in ?? [];
1640
- const recovered = await nodeHandler.handle({
1641
- kind,
1642
- items,
1643
- inputsByPort: kind === "multi" ? inputsByPort : void 0,
1644
- ctx,
1645
- error: args.error
1646
- });
1647
- return await this.resumeFromNodeResult({
1648
- runId: args.runId,
1649
- activationId: args.activationId,
1650
- nodeId: args.nodeId,
1651
- outputs: recovered
1652
- });
1653
- } catch {}
1654
- }
1655
- const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
1656
- const message = args.error?.message ?? String(args.error);
1657
- const failedSnapshot = NodeExecutionSnapshotFactory.failed({
1658
- previous: state.nodeSnapshotsByNodeId?.[args.nodeId],
1659
- runId: state.runId,
1660
- workflowId: state.workflowId,
1661
- nodeId: args.nodeId,
1662
- activationId: args.activationId,
1663
- parent: state.parent,
1664
- finishedAt,
1665
- inputsByPort: state.pending.inputsByPort,
1666
- error: args.error
1667
- });
1668
- const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1669
- state,
1670
- engineCounters: state.engineCounters ?? { completedNodeActivations: 0 },
1671
- status: "failed",
1672
- queue: (state.queue ?? []).map((q) => ({ ...q })),
1673
- outputsByNode: state.outputsByNode,
1674
- nodeSnapshotsByNodeId: {
1675
- ...state.nodeSnapshotsByNodeId ?? {},
1676
- [args.nodeId]: failedSnapshot
1677
- }
1678
- });
1679
- await this.workflowExecutionRepository.save(failedState);
1680
- await this.nodeEventPublisher.publish("nodeFailed", failedSnapshot);
1681
- const wfErr = this.policyErrorServices.resolveWorkflowErrorHandler(wf.workflowErrorHandler);
1682
- if (wfErr) await Promise.resolve(wfErr.onError({
1683
- runId: state.runId,
1684
- workflowId: state.workflowId,
1685
- workflow: wf,
1686
- failedNodeId: args.nodeId,
1687
- error: args.error,
1688
- startedAt: state.startedAt,
1689
- finishedAt
1690
- }));
1691
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1692
- workflow: wf,
1693
- state: failedState,
1694
- finalStatus: "failed",
1695
- finishedAt
1696
- });
1697
- const result = {
1698
- runId: state.runId,
1699
- workflowId: state.workflowId,
1700
- startedAt: state.startedAt,
1701
- status: "failed",
1702
- error: { message }
1703
- };
1704
- this.waiters.resolveRunCompletion(result);
1705
- return result;
1706
- }
1707
- async resumeFromStepResult(args) {
1708
- return await this.resumeFromNodeResult(args);
1709
- }
1710
- async resumeFromStepError(args) {
1711
- return await this.resumeFromNodeError(args);
1712
- }
1713
- async waitForCompletion(runId) {
1714
- const existing = await this.workflowExecutionRepository.load(runId);
1715
- if (existing?.status === "completed") {
1716
- const wf = this.resolvePersistedWorkflow(existing);
1717
- const outputs = wf ? this.semantics.resolveResultOutputs(wf, existing.control?.stopCondition, existing.outputsByNode) : [];
1718
- return {
1719
- runId: existing.runId,
1720
- workflowId: existing.workflowId,
1721
- startedAt: existing.startedAt,
1722
- status: "completed",
1723
- outputs
1724
- };
1725
- }
1726
- if (existing?.status === "failed") return {
1727
- runId: existing.runId,
1728
- workflowId: existing.workflowId,
1729
- startedAt: existing.startedAt,
1730
- status: "failed",
1731
- error: { message: "Run failed" }
1732
- };
1733
- const result = await this.waiters.waitForCompletion(runId);
1734
- if (result.status !== "completed" && result.status !== "failed") throw new Error(`Unexpected run completion status: ${result.status}`);
1735
- return result;
1736
- }
1737
- async waitForWebhookResponse(runId) {
1738
- return await this.waiters.waitForWebhookResponse(runId);
1739
- }
1740
- async resumeFromWebhookControl(args) {
1741
- const data = this.runDataFactory.create(args.state.outputsByNode);
1742
- const { topology, planner } = this.planningFactory.create(args.workflow);
1743
- const triggerOutputs = { main: args.signal.kind === "respondNowAndContinue" ? args.signal.continueItems ?? [] : args.signal.responseItems };
1744
- data.setOutputs(args.args.nodeId, triggerOutputs);
1745
- const completedSnapshot = this.semantics.createFinishedSnapshot({
1746
- workflow: args.workflow,
1747
- previous: args.state.nodeSnapshotsByNodeId?.[args.args.nodeId],
1748
- runId: args.state.runId,
1749
- workflowId: args.state.workflowId,
1750
- nodeId: args.args.nodeId,
1751
- activationId: args.args.activationId,
1752
- parent: args.state.parent,
1753
- finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
1754
- inputsByPort: args.state.pending?.inputsByPort ?? NodeInputsByPortFactory.empty(),
1755
- outputs: triggerOutputs
1756
- });
1757
- const completedActivations = (args.state.engineCounters?.completedNodeActivations ?? 0) + 1;
1758
- const engineCounters = { completedNodeActivations: completedActivations };
1759
- const maxNodeActivations = args.state.executionOptions?.maxNodeActivations ?? Number.MAX_SAFE_INTEGER;
1760
- if (this.semantics.isStopConditionSatisfied(args.state.control?.stopCondition, args.args.nodeId)) {
1761
- const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1762
- state: args.state,
1763
- engineCounters,
1764
- status: "completed",
1765
- queue: [],
1766
- outputsByNode: data.dump(),
1767
- nodeSnapshotsByNodeId: {
1768
- ...args.state.nodeSnapshotsByNodeId ?? {},
1769
- [args.args.nodeId]: completedSnapshot
1770
- }
1771
- });
1772
- await this.workflowExecutionRepository.save(completedState);
1773
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1774
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1775
- workflow: args.workflow,
1776
- state: completedState,
1777
- finalStatus: "completed",
1778
- finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
1779
- });
1780
- this.waiters.resolveWebhookResponse({
1781
- runId: args.state.runId,
1782
- workflowId: args.state.workflowId,
1783
- startedAt: args.state.startedAt,
1784
- runStatus: "completed",
1785
- response: args.signal.responseItems
1786
- });
1787
- const result$1 = {
1788
- runId: args.state.runId,
1789
- workflowId: args.state.workflowId,
1790
- startedAt: args.state.startedAt,
1791
- status: "completed",
1792
- outputs: this.semantics.resolveResultOutputs(args.workflow, args.state.control?.stopCondition, data.dump())
1793
- };
1794
- this.waiters.resolveRunCompletion(result$1);
1795
- return result$1;
1796
- }
1797
- if (args.signal.kind === "respondNow") {
1798
- const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1799
- state: args.state,
1800
- engineCounters,
1801
- status: "completed",
1802
- queue: [],
1803
- outputsByNode: data.dump(),
1804
- nodeSnapshotsByNodeId: {
1805
- ...args.state.nodeSnapshotsByNodeId ?? {},
1806
- [args.args.nodeId]: completedSnapshot
1807
- }
1808
- });
1809
- await this.workflowExecutionRepository.save(completedState);
1810
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1811
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1812
- workflow: args.workflow,
1813
- state: completedState,
1814
- finalStatus: "completed",
1815
- finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
1816
- });
1817
- const result$1 = {
1818
- runId: args.state.runId,
1819
- workflowId: args.state.workflowId,
1820
- startedAt: args.state.startedAt,
1821
- status: "completed",
1822
- outputs: args.signal.responseItems
1823
- };
1824
- this.waiters.resolveWebhookResponse({
1825
- runId: args.state.runId,
1826
- workflowId: args.state.workflowId,
1827
- startedAt: args.state.startedAt,
1828
- runStatus: "completed",
1829
- response: args.signal.responseItems
1830
- });
1831
- this.waiters.resolveRunCompletion(result$1);
1832
- return result$1;
1833
- }
1834
- const batchId = args.state.pending?.batchId ?? "batch_1";
1835
- const queue = (args.state.queue ?? []).map((entry) => ({
1836
- ...entry,
1837
- batchId: entry.batchId ?? batchId
1838
- }));
1839
- planner.applyOutputs(queue, {
1840
- fromNodeId: args.args.nodeId,
1841
- outputs: triggerOutputs,
1842
- batchId
1843
- });
1844
- const next = planner.nextActivation(queue);
1845
- if (!next) {
1846
- const lastNodeId = WorkflowExecutableNodeClassifierFactory.create(args.workflow).lastExecutableNodeIdInDefinitionOrder(args.workflow);
1847
- const outputs = data.getOutputItems(lastNodeId, "main");
1848
- const completedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1849
- state: args.state,
1850
- engineCounters,
1851
- status: "completed",
1852
- queue: [],
1853
- outputsByNode: data.dump(),
1854
- nodeSnapshotsByNodeId: {
1855
- ...args.state.nodeSnapshotsByNodeId ?? {},
1856
- [args.args.nodeId]: completedSnapshot
1857
- }
1858
- });
1859
- await this.workflowExecutionRepository.save(completedState);
1860
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1861
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1862
- workflow: args.workflow,
1863
- state: completedState,
1864
- finalStatus: "completed",
1865
- finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
1866
- });
1867
- const result$1 = {
1868
- runId: args.state.runId,
1869
- workflowId: args.state.workflowId,
1870
- startedAt: args.state.startedAt,
1871
- status: "completed",
1872
- outputs
1873
- };
1874
- this.waiters.resolveWebhookResponse({
1875
- runId: args.state.runId,
1876
- workflowId: args.state.workflowId,
1877
- startedAt: args.state.startedAt,
1878
- runStatus: "completed",
1879
- response: args.signal.responseItems
1880
- });
1881
- this.waiters.resolveRunCompletion(result$1);
1882
- return result$1;
1883
- }
1884
- if (completedActivations >= maxNodeActivations) {
1885
- const message = `Run exceeded maxNodeActivations (${maxNodeActivations}) after ${completedActivations} completed node activations (next would be ${next.nodeId}).`;
1886
- const failedState = this.persistedRunStateTerminalBuilder.mergeTerminal({
1887
- state: args.state,
1888
- engineCounters,
1889
- status: "failed",
1890
- queue: queue.map((q) => ({ ...q })),
1891
- outputsByNode: data.dump(),
1892
- nodeSnapshotsByNodeId: {
1893
- ...args.state.nodeSnapshotsByNodeId ?? {},
1894
- [args.args.nodeId]: completedSnapshot
1895
- }
1896
- });
1897
- await this.workflowExecutionRepository.save(failedState);
1898
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1899
- await this.terminalPersistence.maybeDeleteAfterTerminalState({
1900
- workflow: args.workflow,
1901
- state: failedState,
1902
- finalStatus: "failed",
1903
- finishedAt: completedSnapshot.finishedAt ?? completedSnapshot.updatedAt
1904
- });
1905
- const result$1 = {
1906
- runId: args.state.runId,
1907
- workflowId: args.state.workflowId,
1908
- startedAt: args.state.startedAt,
1909
- status: "failed",
1910
- error: { message }
1911
- };
1912
- this.waiters.resolveWebhookResponse({
1913
- runId: args.state.runId,
1914
- workflowId: args.state.workflowId,
1915
- startedAt: args.state.startedAt,
1916
- runStatus: "pending",
1917
- response: args.signal.responseItems
1918
- });
1919
- this.waiters.resolveRunCompletion(result$1);
1920
- return result$1;
1921
- }
1922
- const nextDefinition = topology.defsById.get(next.nodeId);
1923
- if (!nextDefinition || nextDefinition.kind !== "node") throw new Error(`Node ${next.nodeId} is not a runnable node`);
1924
- const webhookLimits = this.resolveEngineLimitsFromState(args.state);
1925
- const base = this.runExecutionContextFactory.create({
1926
- runId: args.state.runId,
1927
- workflowId: args.state.workflowId,
1928
- nodeId: nextDefinition.id,
1929
- parent: args.state.parent,
1930
- subworkflowDepth: args.state.executionOptions?.subworkflowDepth ?? 0,
1931
- engineMaxNodeActivations: webhookLimits.engineMaxNodeActivations,
1932
- engineMaxSubworkflowDepth: webhookLimits.engineMaxSubworkflowDepth,
1933
- data,
1934
- nodeState: this.nodeStatePublisherFactory.create(args.state.runId, args.state.workflowId, args.state.parent)
1935
- });
1936
- const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
1937
- next,
1938
- base,
1939
- data,
1940
- runId: args.state.runId,
1941
- workflowId: args.state.workflowId,
1942
- parent: args.state.parent,
1943
- executionOptions: args.state.executionOptions,
1944
- nodeDefinition: nextDefinition
1945
- });
1946
- const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
1947
- runId: args.state.runId,
1948
- workflowId: args.state.workflowId,
1949
- startedAt: args.state.startedAt,
1950
- parent: args.state.parent,
1951
- executionOptions: args.state.executionOptions,
1952
- control: args.state.control,
1953
- workflowSnapshot: args.state.workflowSnapshot,
1954
- mutableState: args.state.mutableState,
1955
- policySnapshot: args.state.policySnapshot,
1956
- pendingQueue: queue,
1957
- request,
1958
- previousNodeSnapshotsByNodeId: {
1959
- ...args.state.nodeSnapshotsByNodeId ?? {},
1960
- [args.args.nodeId]: completedSnapshot
1961
- },
1962
- planner,
1963
- engineCounters,
1964
- connectionInvocations: args.state.connectionInvocations ?? []
1965
- });
1966
- await this.nodeEventPublisher.publish("nodeCompleted", completedSnapshot);
1967
- await this.nodeEventPublisher.publish("nodeQueued", queuedSnapshot);
1968
- this.waiters.resolveWebhookResponse({
1969
- runId: args.state.runId,
1970
- workflowId: args.state.workflowId,
1971
- startedAt: args.state.startedAt,
1972
- runStatus: "pending",
1973
- response: args.signal.responseItems
1974
- });
1975
- return result;
1976
- }
1977
- asWebhookControlSignal(error) {
1978
- const candidate = error;
1979
- if (!candidate || candidate.__webhookControl !== true) return void 0;
1980
- if (candidate.kind !== "respondNow" && candidate.kind !== "respondNowAndContinue") return void 0;
1981
- if (!Array.isArray(candidate.responseItems)) return void 0;
1982
- return candidate;
1983
- }
1984
- resolvePersistedWorkflow(state) {
1985
- return this.workflowSnapshotResolver.resolve({
1986
- workflowId: state.workflowId,
1987
- workflowSnapshot: state.workflowSnapshot
1988
- });
1989
- }
1990
- buildNodeExecutionContextForPending(state, wf, def, nodeId) {
1991
- const data = this.runDataFactory.create(state.outputsByNode);
1992
- const limits = this.resolveEngineLimitsFromState(state);
1993
- const base = this.runExecutionContextFactory.create({
1994
- runId: state.runId,
1995
- workflowId: state.workflowId,
1996
- nodeId,
1997
- parent: state.parent,
1998
- subworkflowDepth: state.executionOptions?.subworkflowDepth ?? 0,
1999
- engineMaxNodeActivations: limits.engineMaxNodeActivations,
2000
- engineMaxSubworkflowDepth: limits.engineMaxSubworkflowDepth,
2001
- data,
2002
- nodeState: this.nodeStatePublisherFactory.create(state.runId, state.workflowId, state.parent)
2003
- });
2004
- const activationId = state.pending.activationId;
2005
- return {
2006
- ...base,
2007
- data,
2008
- nodeId,
2009
- activationId,
2010
- config: def.config,
2011
- binary: base.binary.forNode({
2012
- nodeId,
2013
- activationId
2014
- }),
2015
- getCredential: this.credentialResolverFactory.create(wf.id, nodeId, def.config)
2016
- };
2017
- }
2018
- resolveEngineLimitsFromState(state) {
2019
- const fb = this.executionLimitsPolicy.createRootExecutionOptions();
2020
- return {
2021
- engineMaxNodeActivations: state.executionOptions?.maxNodeActivations ?? fb.maxNodeActivations,
2022
- engineMaxSubworkflowDepth: state.executionOptions?.maxSubworkflowDepth ?? fb.maxSubworkflowDepth
2023
- };
2024
- }
2025
- formatNodeLabel(args) {
2026
- const tokenName = typeof args.definition?.type === "function" ? args.definition.type.name : "Node";
2027
- return args.definition?.name ? `"${args.definition.name}" (${tokenName}:${args.nodeId})` : `${tokenName}:${args.nodeId}`;
2028
- }
2029
- formatOutputCounts(outputs) {
2030
- const entries = Object.entries(outputs ?? {});
2031
- if (entries.length === 0) return "no outputs";
2032
- return entries.map(([port, items]) => `${port}=${items?.length ?? 0}`).join(", ");
2033
- }
2034
- };
2035
-
2036
- //#endregion
2037
- //#region src/planning/CurrentStateFrontierPlanner.ts
2038
- var CurrentStateFrontierPlanner = class CurrentStateFrontierPlanner {
2039
- constructor(topology) {
2040
- this.topology = topology;
2041
- }
2042
- /** Composition-root-friendly factory (avoids `new` at orchestration call sites under ESLint manual-DI rules). */
2043
- static createFromTopology(topology) {
2044
- return new CurrentStateFrontierPlanner(topology);
2045
- }
2046
- plan(args) {
2047
- const stopCondition = args.stopCondition ?? { kind: "workflowCompleted" };
2048
- const baseState = this.cloneCurrentState(args.currentState);
2049
- const normalizedState = this.overlayPinnedOutputs(baseState);
2050
- const resetResult = this.applyReset({
2051
- currentState: normalizedState,
2052
- reset: args.reset
2053
- });
2054
- const requiredNodeIds = this.collectRequiredNodeIds(stopCondition, resetResult.currentState);
2055
- const satisfiedNodeIds = this.collectSatisfiedNodeIds(resetResult.currentState);
2056
- const skippedNodeIds = [...new Set([...[...requiredNodeIds].filter((nodeId) => this.isNodeSatisfied(resetResult.currentState, nodeId)), ...resetResult.preservedPinnedNodeIds.filter((nodeId) => requiredNodeIds.has(nodeId))])];
2057
- const frontierNodeIds = this.collectFrontierNodeIds(requiredNodeIds, resetResult.currentState);
2058
- const rootNodeIds = frontierNodeIds.filter((nodeId) => (this.topology.incomingByNode.get(nodeId) ?? []).length === 0);
2059
- if (rootNodeIds.length > 1) throw new Error(`Ambiguous execution frontier. Multiple root nodes require input: ${rootNodeIds.join(", ")}`);
2060
- if (frontierNodeIds.length === 0) return {
2061
- queue: [],
2062
- currentState: resetResult.currentState,
2063
- stopCondition,
2064
- satisfiedNodeIds,
2065
- skippedNodeIds,
2066
- clearedNodeIds: resetResult.clearedNodeIds,
2067
- preservedPinnedNodeIds: resetResult.preservedPinnedNodeIds
2068
- };
2069
- if (rootNodeIds.length === 1) {
2070
- const rootNodeId = rootNodeIds[0];
2071
- const definition = this.topology.defsById.get(rootNodeId);
2072
- if (!definition) throw new Error(`Unknown frontier nodeId: ${rootNodeId}`);
2073
- return {
2074
- rootNodeId,
2075
- rootNodeInput: this.resolveRootNodeInput({
2076
- nodeKind: definition.kind,
2077
- items: args.items
2078
- }),
2079
- queue: [],
2080
- currentState: resetResult.currentState,
2081
- stopCondition,
2082
- satisfiedNodeIds,
2083
- skippedNodeIds,
2084
- clearedNodeIds: resetResult.clearedNodeIds,
2085
- preservedPinnedNodeIds: resetResult.preservedPinnedNodeIds
2086
- };
2087
- }
2088
- const queue = [];
2089
- for (const nodeId of frontierNodeIds) queue.push(...this.buildFrontierQueue(nodeId, resetResult.currentState));
2090
- return {
2091
- queue,
2092
- currentState: resetResult.currentState,
2093
- stopCondition,
2094
- satisfiedNodeIds,
2095
- skippedNodeIds,
2096
- clearedNodeIds: resetResult.clearedNodeIds,
2097
- preservedPinnedNodeIds: resetResult.preservedPinnedNodeIds
2098
- };
2099
- }
2100
- cloneCurrentState(currentState) {
2101
- if (!currentState) return {
2102
- outputsByNode: {},
2103
- nodeSnapshotsByNodeId: {},
2104
- connectionInvocations: [],
2105
- mutableState: void 0
2106
- };
2107
- return {
2108
- outputsByNode: { ...currentState.outputsByNode },
2109
- nodeSnapshotsByNodeId: { ...currentState.nodeSnapshotsByNodeId },
2110
- connectionInvocations: currentState.connectionInvocations ? [...currentState.connectionInvocations] : void 0,
2111
- mutableState: currentState.mutableState
2112
- };
2113
- }
2114
- overlayPinnedOutputs(currentState) {
2115
- const outputsByNode = { ...currentState.outputsByNode };
2116
- for (const [nodeId, nodeState] of Object.entries(currentState.mutableState?.nodesById ?? {})) {
2117
- const pinnedOutputs = nodeState.pinnedOutputsByPort;
2118
- if (!pinnedOutputs) continue;
2119
- outputsByNode[nodeId] = pinnedOutputs;
2120
- }
2121
- return {
2122
- outputsByNode,
2123
- nodeSnapshotsByNodeId: { ...currentState.nodeSnapshotsByNodeId },
2124
- connectionInvocations: currentState.connectionInvocations,
2125
- mutableState: currentState.mutableState
2126
- };
2127
- }
2128
- applyReset(args) {
2129
- if (!args.reset) return {
2130
- currentState: args.currentState,
2131
- clearedNodeIds: [],
2132
- preservedPinnedNodeIds: []
2133
- };
2134
- const outputsByNode = { ...args.currentState.outputsByNode };
2135
- const nodeSnapshotsByNodeId = { ...args.currentState.nodeSnapshotsByNodeId };
2136
- const clearedNodeIds = [];
2137
- const preservedPinnedNodeIds = [];
2138
- const descendants = this.collectDescendants(args.reset.clearFromNodeId);
2139
- const runtimeDescendants = this.collectRuntimeDescendants(args.currentState, descendants);
2140
- const clearedIdSet = new Set([...descendants, ...runtimeDescendants]);
2141
- for (const nodeId of [...descendants, ...runtimeDescendants]) {
2142
- const pinnedOutputs = this.getPinnedOutputs(args.currentState, nodeId);
2143
- if (pinnedOutputs) {
2144
- outputsByNode[nodeId] = pinnedOutputs;
2145
- delete nodeSnapshotsByNodeId[nodeId];
2146
- preservedPinnedNodeIds.push(nodeId);
2147
- continue;
2148
- }
2149
- delete outputsByNode[nodeId];
2150
- delete nodeSnapshotsByNodeId[nodeId];
2151
- clearedNodeIds.push(nodeId);
2152
- }
2153
- return {
2154
- currentState: {
2155
- outputsByNode,
2156
- nodeSnapshotsByNodeId,
2157
- connectionInvocations: this.filterConnectionInvocations(args.currentState.connectionInvocations, clearedIdSet),
2158
- mutableState: args.currentState.mutableState
2159
- },
2160
- clearedNodeIds,
2161
- preservedPinnedNodeIds
2162
- };
2163
- }
2164
- collectSatisfiedNodeIds(currentState) {
2165
- const satisfiedNodeIds = [];
2166
- for (const nodeId of this.topology.defsById.keys()) if (this.isNodeSatisfied(currentState, nodeId)) satisfiedNodeIds.push(nodeId);
2167
- return satisfiedNodeIds;
2168
- }
2169
- collectFrontierNodeIds(requiredNodeIds, currentState) {
2170
- const frontierNodeIds = [];
2171
- for (const nodeId of this.topology.defsById.keys()) {
2172
- if (!requiredNodeIds.has(nodeId) || this.isNodeSatisfied(currentState, nodeId)) continue;
2173
- if ((this.topology.incomingByNode.get(nodeId) ?? []).every((edge) => this.isEdgeSatisfied(currentState, nodeId, edge.input))) frontierNodeIds.push(nodeId);
2174
- }
2175
- return frontierNodeIds;
2176
- }
2177
- collectRequiredNodeIds(stopCondition, currentState) {
2178
- const requiredNodeIds = /* @__PURE__ */ new Set();
2179
- if (stopCondition.kind === "workflowCompleted") {
2180
- for (const nodeId of this.topology.defsById.keys()) if (!this.isNodeSatisfied(currentState, nodeId)) this.collectRequiredNode(requiredNodeIds, currentState, nodeId);
2181
- return requiredNodeIds;
2182
- }
2183
- if (!this.topology.defsById.has(stopCondition.nodeId)) throw new Error(`Unknown stop nodeId: ${stopCondition.nodeId}`);
2184
- this.collectRequiredNode(requiredNodeIds, currentState, stopCondition.nodeId);
2185
- return requiredNodeIds;
2186
- }
2187
- collectRequiredNode(requiredNodeIds, currentState, nodeId) {
2188
- if (requiredNodeIds.has(nodeId)) return;
2189
- if (this.isNodeSatisfied(currentState, nodeId) && !this.isNodeSatisfiedByOutputsOnly(currentState, nodeId)) return;
2190
- requiredNodeIds.add(nodeId);
2191
- for (const edge of this.topology.incomingByNode.get(nodeId) ?? []) if (!this.isEdgeSatisfied(currentState, nodeId, edge.input) || this.isNodeSatisfiedByOutputsOnly(currentState, edge.from.nodeId)) this.collectRequiredNode(requiredNodeIds, currentState, edge.from.nodeId);
2192
- }
2193
- buildFrontierQueue(nodeId, currentState) {
2194
- const incomingEdges = this.topology.incomingByNode.get(nodeId) ?? [];
2195
- if (incomingEdges.length === 0) return [];
2196
- const expectedInputs = this.topology.expectedInputsByNode.get(nodeId) ?? [];
2197
- if (expectedInputs.length !== 1 || expectedInputs[0] !== "in") {
2198
- const received = {};
2199
- for (const input$1 of expectedInputs) received[input$1] = this.resolveInput(currentState, nodeId, input$1);
2200
- return [{
2201
- nodeId,
2202
- input: [],
2203
- batchId: "batch_1",
2204
- collect: {
2205
- expectedInputs,
2206
- received
2207
- }
2208
- }];
2209
- }
2210
- const input = expectedInputs[0] ?? "in";
2211
- const incomingEdge = incomingEdges.find((edge) => edge.input === input);
2212
- return [{
2213
- nodeId,
2214
- input: this.resolveInput(currentState, nodeId, input),
2215
- toInput: input,
2216
- batchId: "batch_1",
2217
- from: incomingEdge?.from
2218
- }];
2219
- }
2220
- resolveRootNodeInput(args) {
2221
- if (args.items) return args.items;
2222
- if (args.nodeKind === "trigger") return [];
2223
- return [{ json: {} }];
2224
- }
2225
- isNodeSatisfied(currentState, nodeId) {
2226
- return this.hasOutputs(currentState, nodeId) || this.hasCompletedSnapshot(currentState, nodeId);
2227
- }
2228
- isNodeSatisfiedByOutputsOnly(currentState, nodeId) {
2229
- return this.hasOutputs(currentState, nodeId) && !this.hasCompletedSnapshot(currentState, nodeId);
2230
- }
2231
- isEdgeSatisfied(currentState, nodeId, input) {
2232
- const incomingEdge = (this.topology.incomingByNode.get(nodeId) ?? []).find((edge) => edge.input === input);
2233
- if (!incomingEdge) return false;
2234
- return this.hasOutputPort(currentState, incomingEdge.from.nodeId, incomingEdge.from.output);
2235
- }
2236
- resolveInput(currentState, nodeId, input) {
2237
- const incomingEdge = (this.topology.incomingByNode.get(nodeId) ?? []).find((edge) => edge.input === input);
2238
- if (!incomingEdge) return [];
2239
- return this.resolveOutputItems(currentState, incomingEdge.from.nodeId, incomingEdge.from.output);
2240
- }
2241
- hasOutputs(currentState, nodeId) {
2242
- return Object.prototype.hasOwnProperty.call(currentState.outputsByNode, nodeId);
2243
- }
2244
- hasCompletedSnapshot(currentState, nodeId) {
2245
- const snapshot = currentState.nodeSnapshotsByNodeId[nodeId];
2246
- return snapshot?.status === "completed" || snapshot?.status === "skipped";
2247
- }
2248
- hasOutputPort(currentState, nodeId, output) {
2249
- const outputs = currentState.outputsByNode[nodeId];
2250
- if (!outputs) return false;
2251
- return Object.prototype.hasOwnProperty.call(outputs, output);
2252
- }
2253
- resolveOutputItems(currentState, nodeId, output) {
2254
- return currentState.outputsByNode[nodeId]?.[output] ?? [];
2255
- }
2256
- getPinnedOutputs(currentState, nodeId) {
2257
- return currentState.mutableState?.nodesById?.[nodeId]?.pinnedOutputsByPort;
2258
- }
2259
- filterConnectionInvocations(invocations, clearedIdSet) {
2260
- if (!invocations || invocations.length === 0) return invocations;
2261
- const kept = invocations.filter((invocation) => !clearedIdSet.has(invocation.parentAgentNodeId) && !clearedIdSet.has(invocation.connectionNodeId));
2262
- return kept.length === invocations.length ? invocations : kept;
2263
- }
2264
- collectDescendants(startNodeId) {
2265
- const pendingNodeIds = [startNodeId];
2266
- const descendants = /* @__PURE__ */ new Set();
2267
- while (pendingNodeIds.length > 0) {
2268
- const nodeId = pendingNodeIds.pop();
2269
- if (!nodeId || descendants.has(nodeId)) continue;
2270
- descendants.add(nodeId);
2271
- for (const edge of this.topology.outgoingByNode.get(nodeId) ?? []) pendingNodeIds.push(edge.to.nodeId);
2272
- }
2273
- return [...descendants];
2274
- }
2275
- collectRuntimeDescendants(currentState, descendantNodeIds) {
2276
- const descendantSet = new Set(descendantNodeIds);
2277
- const runtimeNodeIds = /* @__PURE__ */ new Set();
2278
- for (const nodeId of [
2279
- ...Object.keys(currentState.outputsByNode),
2280
- ...Object.keys(currentState.nodeSnapshotsByNodeId),
2281
- ...Object.keys(currentState.mutableState?.nodesById ?? {})
2282
- ]) if (this.isRuntimeDescendant(nodeId, descendantSet)) runtimeNodeIds.add(nodeId);
2283
- return [...runtimeNodeIds];
2284
- }
2285
- isRuntimeDescendant(nodeId, descendantNodeIds) {
2286
- for (const descendantNodeId of descendantNodeIds) {
2287
- if (nodeId === descendantNodeId) return false;
2288
- if (ConnectionNodeIdFactory.isConnectionOwnedDescendantOf(descendantNodeId, nodeId)) return true;
2289
- }
2290
- return false;
2291
- }
2292
- };
2293
-
2294
- //#endregion
2295
- //#region src/policies/storage/RunPolicySnapshotFactory.ts
2296
- var RunPolicySnapshotFactory = class {
2297
- static create(workflow, defaults) {
2298
- const prune = workflow.prunePolicy;
2299
- return {
2300
- retentionSeconds: prune?.runDataRetentionSeconds ?? defaults?.retentionSeconds,
2301
- binaryRetentionSeconds: prune?.binaryRetentionSeconds ?? defaults?.binaryRetentionSeconds,
2302
- storagePolicy: typeof workflow.storagePolicy === "string" ? workflow.storagePolicy : defaults?.storagePolicy ?? "ALL"
2303
- };
2304
- }
2305
- };
2306
-
2307
- //#endregion
2308
- //#region src/orchestration/RunStartService.ts
2309
- var RunStartService = class {
2310
- constructor(runIdFactory, workflowExecutionRepository, runDataFactory, workflowSnapshotFactory, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, workflowPolicyRuntimeDefaults, executionLimitsPolicy) {
2311
- this.runIdFactory = runIdFactory;
2312
- this.workflowExecutionRepository = workflowExecutionRepository;
2313
- this.runDataFactory = runDataFactory;
2314
- this.workflowSnapshotFactory = workflowSnapshotFactory;
2315
- this.planningFactory = planningFactory;
2316
- this.nodeStatePublisherFactory = nodeStatePublisherFactory;
2317
- this.runExecutionContextFactory = runExecutionContextFactory;
2318
- this.nodeActivationRequestComposer = nodeActivationRequestComposer;
2319
- this.activationEnqueueService = activationEnqueueService;
2320
- this.semantics = semantics;
2321
- this.waiters = waiters;
2322
- this.workflowPolicyRuntimeDefaults = workflowPolicyRuntimeDefaults;
2323
- this.executionLimitsPolicy = executionLimitsPolicy;
2324
- }
2325
- async runWorkflow(workflow, startAt, items, parent, executionOptions, persistedStateOverrides) {
2326
- const runId = this.runIdFactory.makeRunId();
2327
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2328
- const workflowSnapshot = persistedStateOverrides?.workflowSnapshot ?? this.workflowSnapshotFactory.create(workflow);
2329
- const mutableState = persistedStateOverrides?.mutableState;
2330
- const policySnapshot = RunPolicySnapshotFactory.create(workflow, this.workflowPolicyRuntimeDefaults);
2331
- const mergedExecutionOptions = this.executionLimitsPolicy.mergeExecutionOptionsForNewRun(parent, executionOptions);
2332
- await this.workflowExecutionRepository.createRun({
2333
- runId,
2334
- workflowId: workflow.id,
2335
- startedAt,
2336
- parent,
2337
- executionOptions: mergedExecutionOptions,
2338
- workflowSnapshot,
2339
- mutableState,
2340
- policySnapshot,
2341
- engineCounters: { completedNodeActivations: 0 }
2342
- });
2343
- const data = this.runDataFactory.create();
2344
- const base = this.runExecutionContextFactory.create({
2345
- runId,
2346
- workflowId: workflow.id,
2347
- nodeId: startAt,
2348
- parent,
2349
- subworkflowDepth: mergedExecutionOptions.subworkflowDepth ?? 0,
2350
- engineMaxNodeActivations: mergedExecutionOptions.maxNodeActivations,
2351
- engineMaxSubworkflowDepth: mergedExecutionOptions.maxSubworkflowDepth,
2352
- data,
2353
- nodeState: this.nodeStatePublisherFactory.create(runId, workflow.id, parent)
2354
- });
2355
- const { topology, planner } = this.planningFactory.create(workflow);
2356
- const startDefinition = topology.defsById.get(startAt);
2357
- if (!startDefinition) throw new Error(`Unknown start nodeId: ${startAt}`);
2358
- const initialNodeSnapshotsByNodeId = {};
2359
- if (startDefinition.kind === "trigger") {
2360
- const request = this.nodeActivationRequestComposer.createSingleFromDefinition({
2361
- runId,
2362
- workflowId: workflow.id,
2363
- definition: startDefinition,
2364
- parent,
2365
- executionOptions: mergedExecutionOptions,
2366
- batchId: "batch_1",
2367
- input: items,
2368
- base,
2369
- data
2370
- });
2371
- return await this.activationEnqueueService.enqueueActivation({
2372
- runId,
2373
- workflowId: workflow.id,
2374
- startedAt,
2375
- parent,
2376
- executionOptions: mergedExecutionOptions,
2377
- workflowSnapshot,
2378
- mutableState,
2379
- policySnapshot,
2380
- control: void 0,
2381
- pendingQueue: [],
2382
- request,
2383
- previousNodeSnapshotsByNodeId: initialNodeSnapshotsByNodeId,
2384
- planner,
2385
- engineCounters: { completedNodeActivations: 0 },
2386
- connectionInvocations: []
2387
- });
2388
- }
2389
- const queue = [{
2390
- nodeId: startAt,
2391
- input: items,
2392
- toInput: "in",
2393
- batchId: "batch_1"
2394
- }];
2395
- return await this.scheduleQueuedPlan({
2396
- runId,
2397
- workflowId: workflow.id,
2398
- startedAt,
2399
- parent,
2400
- executionOptions: mergedExecutionOptions,
2401
- control: void 0,
2402
- workflowSnapshot,
2403
- mutableState,
2404
- policySnapshot,
2405
- workflow,
2406
- planner,
2407
- queue,
2408
- base,
2409
- data,
2410
- nodeSnapshotsByNodeId: initialNodeSnapshotsByNodeId,
2411
- connectionInvocations: []
2412
- });
2413
- }
2414
- async runWorkflowFromState(request) {
2415
- const runId = this.runIdFactory.makeRunId();
2416
- const startedAt = (/* @__PURE__ */ new Date()).toISOString();
2417
- const workflowSnapshot = request.workflowSnapshot ?? this.workflowSnapshotFactory.create(request.workflow);
2418
- const mutableState = request.mutableState ?? request.currentState?.mutableState;
2419
- const policySnapshot = RunPolicySnapshotFactory.create(request.workflow, this.workflowPolicyRuntimeDefaults);
2420
- const control = { stopCondition: request.stopCondition ?? { kind: "workflowCompleted" } };
2421
- const mergedExecutionOptions = this.executionLimitsPolicy.mergeExecutionOptionsForNewRun(request.parent, request.executionOptions);
2422
- await this.workflowExecutionRepository.createRun({
2423
- runId,
2424
- workflowId: request.workflow.id,
2425
- startedAt,
2426
- parent: request.parent,
2427
- executionOptions: mergedExecutionOptions,
2428
- control,
2429
- workflowSnapshot,
2430
- mutableState,
2431
- policySnapshot,
2432
- engineCounters: { completedNodeActivations: 0 }
2433
- });
2434
- const { topology, planner } = this.planningFactory.create(request.workflow);
2435
- const plan = CurrentStateFrontierPlanner.createFromTopology(topology).plan({
2436
- currentState: this.createRunCurrentState(request.currentState, mutableState),
2437
- stopCondition: control.stopCondition,
2438
- reset: request.reset,
2439
- items: request.items
2440
- });
2441
- const data = this.runDataFactory.create(plan.currentState.outputsByNode);
2442
- const base = this.runExecutionContextFactory.create({
2443
- runId,
2444
- workflowId: request.workflow.id,
2445
- nodeId: WorkflowExecutableNodeClassifierFactory.create(request.workflow).firstExecutableNodeIdInDefinitionOrder(request.workflow) ?? "unknown_node",
2446
- parent: request.parent,
2447
- subworkflowDepth: mergedExecutionOptions.subworkflowDepth ?? 0,
2448
- engineMaxNodeActivations: mergedExecutionOptions.maxNodeActivations,
2449
- engineMaxSubworkflowDepth: mergedExecutionOptions.maxSubworkflowDepth,
2450
- data,
2451
- nodeState: this.nodeStatePublisherFactory.create(runId, request.workflow.id, request.parent)
2452
- });
2453
- return await this.scheduleInitialPlan({
2454
- runId,
2455
- startedAt,
2456
- workflow: request.workflow,
2457
- workflowSnapshot,
2458
- mutableState,
2459
- policySnapshot,
2460
- executionOptions: mergedExecutionOptions,
2461
- control,
2462
- parent: request.parent,
2463
- planner,
2464
- plan,
2465
- base,
2466
- data
2467
- });
2468
- }
2469
- createRunCurrentState(currentState, mutableState) {
2470
- return {
2471
- outputsByNode: { ...currentState?.outputsByNode ?? {} },
2472
- nodeSnapshotsByNodeId: { ...currentState?.nodeSnapshotsByNodeId ?? {} },
2473
- connectionInvocations: currentState?.connectionInvocations ? [...currentState.connectionInvocations] : void 0,
2474
- mutableState: mutableState ?? currentState?.mutableState
2475
- };
2476
- }
2477
- async scheduleInitialPlan(args) {
2478
- const initialNodeSnapshotsByNodeId = this.semantics.applySkippedSnapshots({
2479
- runId: args.runId,
2480
- workflowId: args.workflow.id,
2481
- parent: args.parent,
2482
- currentState: args.plan.currentState,
2483
- skippedNodeIds: args.plan.skippedNodeIds,
2484
- preservedPinnedNodeIds: args.plan.preservedPinnedNodeIds,
2485
- finishedAt: args.startedAt
2486
- });
2487
- if (args.plan.rootNodeId) {
2488
- const startDef = WorkflowTopology.fromWorkflow(args.workflow).defsById.get(args.plan.rootNodeId);
2489
- if (!startDef) throw new Error(`Unknown frontier nodeId: ${args.plan.rootNodeId}`);
2490
- const startItems = args.plan.rootNodeInput ?? [];
2491
- const request = this.nodeActivationRequestComposer.createSingleFromDefinition({
2492
- runId: args.runId,
2493
- workflowId: args.workflow.id,
2494
- definition: startDef,
2495
- parent: args.parent,
2496
- executionOptions: args.executionOptions,
2497
- batchId: "batch_1",
2498
- input: startItems,
2499
- base: args.base,
2500
- data: args.data
2501
- });
2502
- return await this.activationEnqueueService.enqueueActivation({
2503
- runId: args.runId,
2504
- workflowId: args.workflow.id,
2505
- startedAt: args.startedAt,
2506
- parent: args.parent,
2507
- executionOptions: args.executionOptions,
2508
- control: args.control,
2509
- workflowSnapshot: args.workflowSnapshot,
2510
- mutableState: args.mutableState,
2511
- policySnapshot: args.policySnapshot,
2512
- pendingQueue: [],
2513
- request,
2514
- previousNodeSnapshotsByNodeId: initialNodeSnapshotsByNodeId,
2515
- planner: args.planner,
2516
- engineCounters: { completedNodeActivations: 0 },
2517
- connectionInvocations: args.plan.currentState.connectionInvocations ?? []
2518
- });
2519
- }
2520
- return await this.scheduleQueuedPlan({
2521
- runId: args.runId,
2522
- workflowId: args.workflow.id,
2523
- startedAt: args.startedAt,
2524
- parent: args.parent,
2525
- executionOptions: args.executionOptions,
2526
- control: args.control,
2527
- workflowSnapshot: args.workflowSnapshot,
2528
- mutableState: args.mutableState,
2529
- policySnapshot: args.policySnapshot,
2530
- workflow: args.workflow,
2531
- planner: args.planner,
2532
- queue: [...args.plan.queue],
2533
- base: args.base,
2534
- data: args.data,
2535
- nodeSnapshotsByNodeId: initialNodeSnapshotsByNodeId,
2536
- connectionInvocations: args.plan.currentState.connectionInvocations ?? []
2537
- });
2538
- }
2539
- async scheduleQueuedPlan(args) {
2540
- this.semantics.applyPinnedQueueSkips({
2541
- runId: args.runId,
2542
- workflowId: args.workflowId,
2543
- parent: args.parent,
2544
- mutableState: args.mutableState,
2545
- planner: args.planner,
2546
- queue: args.queue,
2547
- data: args.data,
2548
- nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId,
2549
- finishedAt: args.startedAt
2550
- });
2551
- const next = args.planner.nextActivation(args.queue);
2552
- if (!next) return await this.completeRun({
2553
- runId: args.runId,
2554
- workflowId: args.workflowId,
2555
- startedAt: args.startedAt,
2556
- parent: args.parent,
2557
- executionOptions: args.executionOptions,
2558
- control: args.control,
2559
- workflowSnapshot: args.workflowSnapshot,
2560
- mutableState: args.mutableState,
2561
- policySnapshot: args.policySnapshot,
2562
- workflow: args.workflow,
2563
- data: args.data,
2564
- nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId,
2565
- connectionInvocations: args.connectionInvocations
2566
- });
2567
- const definition = WorkflowTopology.fromWorkflow(args.workflow).defsById.get(next.nodeId);
2568
- if (!definition || definition.kind !== "node") throw new Error(`Node ${next.nodeId} is not a runnable node`);
2569
- const request = this.nodeActivationRequestComposer.createFromPlannedActivation({
2570
- next,
2571
- base: args.base,
2572
- data: args.data,
2573
- runId: args.runId,
2574
- workflowId: args.workflowId,
2575
- parent: args.parent,
2576
- executionOptions: args.executionOptions,
2577
- nodeDefinition: definition
2578
- });
2579
- return await this.activationEnqueueService.enqueueActivation({
2580
- runId: args.runId,
2581
- workflowId: args.workflowId,
2582
- startedAt: args.startedAt,
2583
- parent: args.parent,
2584
- executionOptions: args.executionOptions,
2585
- control: args.control,
2586
- workflowSnapshot: args.workflowSnapshot,
2587
- mutableState: args.mutableState,
2588
- policySnapshot: args.policySnapshot,
2589
- pendingQueue: args.queue,
2590
- request,
2591
- previousNodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId,
2592
- planner: args.planner,
2593
- engineCounters: { completedNodeActivations: 0 },
2594
- connectionInvocations: args.connectionInvocations ?? []
2595
- });
2596
- }
2597
- async completeRun(args) {
2598
- await this.workflowExecutionRepository.save({
2599
- runId: args.runId,
2600
- workflowId: args.workflowId,
2601
- startedAt: args.startedAt,
2602
- parent: args.parent,
2603
- executionOptions: args.executionOptions,
2604
- control: args.control,
2605
- workflowSnapshot: args.workflowSnapshot,
2606
- mutableState: args.mutableState,
2607
- policySnapshot: args.policySnapshot,
2608
- engineCounters: { completedNodeActivations: 0 },
2609
- connectionInvocations: args.connectionInvocations ? [...args.connectionInvocations] : [],
2610
- status: "completed",
2611
- pending: void 0,
2612
- queue: [],
2613
- outputsByNode: args.data.dump(),
2614
- nodeSnapshotsByNodeId: args.nodeSnapshotsByNodeId
2615
- });
2616
- const result = {
2617
- runId: args.runId,
2618
- workflowId: args.workflowId,
2619
- startedAt: args.startedAt,
2620
- status: "completed",
2621
- outputs: this.semantics.resolveResultOutputs(args.workflow, args.control?.stopCondition, args.data.dump())
2622
- };
2623
- this.waiters.resolveRunCompletion(result);
2624
- return result;
2625
- }
2626
- };
2627
-
2628
- //#endregion
2629
- //#region src/scheduler/ConfigDrivenOffloadPolicy.ts
2630
- var ConfigDrivenOffloadPolicy = class {
2631
- defaultMode;
2632
- constructor(defaultMode = "worker") {
2633
- this.defaultMode = defaultMode;
2634
- }
2635
- decide(args) {
2636
- const hint = args.config.execution?.hint;
2637
- const queue = args.config.execution?.queue;
2638
- if (hint === "local") return { mode: "local" };
2639
- if (hint === "worker") return {
2640
- mode: "worker",
2641
- queue
2642
- };
2643
- if (queue) return {
2644
- mode: "worker",
2645
- queue
2646
- };
2647
- return { mode: this.defaultMode };
2648
- }
2649
- };
2650
-
2651
- //#endregion
2652
- //#region src/scheduler/DefaultDrivingScheduler.ts
2653
- var DefaultDrivingScheduler = class {
2654
- constructor(offloadPolicy, workerScheduler, inline) {
2655
- this.offloadPolicy = offloadPolicy;
2656
- this.workerScheduler = workerScheduler;
2657
- this.inline = inline;
2658
- }
2659
- setContinuation(continuation) {
2660
- this.inline.setContinuation(continuation);
2661
- }
2662
- async enqueue(request) {
2663
- const selection = await this.selectScheduler(request);
2664
- if (selection.mode === "worker") {
2665
- if (request.kind === "multi") throw new Error(`Multi-input node ${request.nodeId} cannot be scheduled to worker (insert local placement)`);
2666
- const workerRequest = {
2667
- runId: request.runId,
2668
- activationId: request.activationId,
2669
- workflowId: request.workflowId,
2670
- nodeId: request.nodeId,
2671
- input: request.input,
2672
- parent: request.parent,
2673
- queue: selection.queue,
2674
- executionOptions: request.executionOptions
2675
- };
2676
- return {
2677
- receiptId: (await this.workerScheduler.enqueue(workerRequest)).receiptId,
2678
- mode: "worker",
2679
- queue: selection.queue
2680
- };
2681
- }
2682
- return await this.enqueueInline(request);
2683
- }
2684
- notifyPendingStatePersisted(runId) {
2685
- this.inline.notifyPendingStatePersisted(runId);
2686
- }
2687
- /**
2688
- * Scheduler precedence is explicit:
2689
- * 1. run-intent override (`executionOptions.localOnly`)
2690
- * 2. node-level execution hint / queue policy
2691
- * 3. container-default scheduler policy fallback
2692
- */
2693
- async selectScheduler(request) {
2694
- if (request.executionOptions?.localOnly) return {
2695
- mode: "local",
2696
- decision: "runIntentOverride"
2697
- };
2698
- const decision = this.offloadPolicy.decide({
2699
- workflowId: request.workflowId,
2700
- nodeId: request.nodeId,
2701
- config: request.ctx.config
2702
- });
2703
- if (this.hasNodeSchedulingPreference(request)) return {
2704
- mode: decision.mode,
2705
- queue: decision.queue,
2706
- decision: "nodePolicy"
2707
- };
2708
- return {
2709
- mode: decision.mode,
2710
- queue: decision.queue,
2711
- decision: "containerDefault"
2712
- };
2713
- }
2714
- hasNodeSchedulingPreference(request) {
2715
- return request.ctx.config.execution?.hint !== void 0 || request.ctx.config.execution?.queue !== void 0;
2716
- }
2717
- async enqueueInline(request) {
2718
- return {
2719
- ...await this.inline.enqueue(request),
2720
- mode: "local"
2721
- };
2722
- }
2723
- };
2724
-
2725
- //#endregion
2726
- //#region src/scheduler/HintOnlyOffloadPolicy.ts
2727
- var HintOnlyOffloadPolicy = class {
2728
- decide(args) {
2729
- if (args.config.execution?.hint === "worker") return {
2730
- mode: "worker",
2731
- queue: args.config.execution?.queue
2732
- };
2733
- return { mode: "local" };
2734
- }
2735
- };
2736
-
2737
- //#endregion
2738
- //#region src/scheduler/InlineDrivingScheduler.ts
2739
- var InlineDrivingScheduler = class {
2740
- continuation;
2741
- drainingRuns = /* @__PURE__ */ new Set();
2742
- queuesByRunId = /* @__PURE__ */ new Map();
2743
- scheduledRuns = /* @__PURE__ */ new Set();
2744
- seq = 0;
2745
- constructor(nodeExecutor) {
2746
- this.nodeExecutor = nodeExecutor;
2747
- }
2748
- setContinuation(continuation) {
2749
- this.continuation = continuation;
2750
- }
2751
- async enqueue(request) {
2752
- const receipt = {
2753
- receiptId: `inline_${++this.seq}`,
2754
- mode: "local"
2755
- };
2756
- const q = this.queuesByRunId.get(request.runId) ?? [];
2757
- q.push({
2758
- request,
2759
- receipt
2760
- });
2761
- this.queuesByRunId.set(request.runId, q);
2762
- return receipt;
2763
- }
2764
- notifyPendingStatePersisted(runId) {
2765
- if ((this.queuesByRunId.get(runId)?.length ?? 0) === 0) return;
2766
- this.scheduleDrain(runId);
2767
- }
2768
- async drainRun(runId) {
2769
- if (this.drainingRuns.has(runId)) return;
2770
- this.drainingRuns.add(runId);
2771
- this.scheduledRuns.delete(runId);
2772
- try {
2773
- const q = this.queuesByRunId.get(runId) ?? [];
2774
- while (q.length > 0) {
2775
- const { request } = q.shift();
2776
- const cont = this.continuation;
2777
- if (!cont) throw new Error("InlineDrivingScheduler is missing a continuation (setContinuation was not called)");
2778
- await cont.markNodeRunning({
2779
- runId: request.runId,
2780
- activationId: request.activationId,
2781
- nodeId: request.nodeId,
2782
- inputsByPort: request.kind === "multi" ? request.inputsByPort : { in: request.input }
2783
- });
2784
- let outputs;
2785
- try {
2786
- outputs = await this.nodeExecutor.execute(request);
2787
- } catch (e) {
2788
- await this.resumeAfterExecutionError(cont, request, this.asError(e));
2789
- continue;
2790
- }
2791
- await this.resumeAfterExecutionResult(cont, request, outputs ?? {});
2792
- }
2793
- } finally {
2794
- if ((this.queuesByRunId.get(runId)?.length ?? 0) === 0) this.queuesByRunId.delete(runId);
2795
- this.drainingRuns.delete(runId);
2796
- if ((this.queuesByRunId.get(runId)?.length ?? 0) > 0) this.scheduleDrain(runId);
2797
- }
2798
- }
2799
- scheduleDrain(runId) {
2800
- if (this.drainingRuns.has(runId) || this.scheduledRuns.has(runId)) return;
2801
- this.scheduledRuns.add(runId);
2802
- setTimeout(() => {
2803
- this.scheduledRuns.delete(runId);
2804
- this.drainRun(runId);
2805
- }, 0);
2806
- }
2807
- async resumeAfterExecutionResult(continuation, request, outputs) {
2808
- try {
2809
- await continuation.resumeFromNodeResult({
2810
- runId: request.runId,
2811
- activationId: request.activationId,
2812
- nodeId: request.nodeId,
2813
- outputs
2814
- });
2815
- } catch (e) {
2816
- this.rethrowUnlessIgnorableContinuationError(e);
2817
- }
2818
- }
2819
- async resumeAfterExecutionError(continuation, request, error) {
2820
- try {
2821
- await continuation.resumeFromNodeError({
2822
- runId: request.runId,
2823
- activationId: request.activationId,
2824
- nodeId: request.nodeId,
2825
- error
2826
- });
2827
- } catch (e) {
2828
- this.rethrowUnlessIgnorableContinuationError(e);
2829
- }
2830
- }
2831
- asError(e) {
2832
- return e instanceof Error ? e : new Error(String(e));
2833
- }
2834
- rethrowUnlessIgnorableContinuationError(e) {
2835
- if (this.isIgnorableContinuationError(e)) return;
2836
- throw this.asError(e);
2837
- }
2838
- isIgnorableContinuationError(e) {
2839
- const message = this.asError(e).message;
2840
- return message.includes(" is not pending") || message.includes("activationId mismatch") || message.includes("nodeId mismatch");
2841
- }
2842
- };
2843
-
2844
- //#endregion
2845
- //#region src/scheduler/LocalOnlyScheduler.ts
2846
- var LocalOnlyScheduler = class {
2847
- async enqueue(_request) {
2848
- throw new Error("No worker scheduler configured");
2849
- }
2850
- };
2851
-
2852
- //#endregion
2853
- //#region src/policies/executionLimits/EngineExecutionLimitsPolicy.ts
2854
- /** Framework defaults for {@link EngineExecutionLimitsPolicy} (merged with host `runtime.engineExecutionLimits`). */
2855
- const ENGINE_EXECUTION_LIMITS_DEFAULTS = {
2856
- defaultMaxNodeActivations: 1e5,
2857
- hardMaxNodeActivations: 1e5,
2858
- defaultMaxSubworkflowDepth: 32,
2859
- hardMaxSubworkflowDepth: 32
2860
- };
2861
- /**
2862
- * Resolves per-run execution limits: defaults, hard ceilings, and subworkflow depth for new runs.
2863
- */
2864
- var EngineExecutionLimitsPolicy = class {
2865
- constructor(config = ENGINE_EXECUTION_LIMITS_DEFAULTS) {
2866
- this.config = config;
2867
- }
2868
- /**
2869
- * Effective options for a new root run (depth 0): defaults merged with engine ceilings.
2870
- * Replaces a separate one-method factory for root-run bootstrap.
2871
- */
2872
- createRootExecutionOptions() {
2873
- return this.mergeExecutionOptionsForNewRun(void 0, void 0);
2874
- }
2875
- mergeExecutionOptionsForNewRun(parent, user) {
2876
- const subworkflowDepth = parent === void 0 ? 0 : (parent.subworkflowDepth ?? 0) + 1;
2877
- const inheritedMaxNode = parent?.engineMaxNodeActivations;
2878
- const inheritedMaxSub = parent?.engineMaxSubworkflowDepth;
2879
- const maxNodeActivations = this.capNumber(user?.maxNodeActivations ?? inheritedMaxNode, this.config.defaultMaxNodeActivations, this.config.hardMaxNodeActivations);
2880
- const maxSubworkflowDepth = this.capNumber(user?.maxSubworkflowDepth ?? inheritedMaxSub, this.config.defaultMaxSubworkflowDepth, this.config.hardMaxSubworkflowDepth);
2881
- if (subworkflowDepth > maxSubworkflowDepth) throw new Error(`Subworkflow nesting depth ${subworkflowDepth} exceeds maxSubworkflowDepth ${maxSubworkflowDepth} (run would be a child of parent run).`);
2882
- return {
2883
- ...user,
2884
- subworkflowDepth,
2885
- maxNodeActivations,
2886
- maxSubworkflowDepth
2887
- };
2888
- }
2889
- capNumber(requested, defaultValue, hardCeiling) {
2890
- const base = requested === void 0 ? defaultValue : requested;
2891
- return Math.min(base, hardCeiling);
2892
- }
2893
- };
2894
-
2895
- //#endregion
2896
- //#region src/runStorage/BinaryBodyBufferReader.ts
2897
- var BinaryBodyBufferReader = class {
2898
- async read(body) {
2899
- if (body instanceof Uint8Array) return body;
2900
- if (body instanceof ArrayBuffer) return new Uint8Array(body);
2901
- if (body instanceof ReadableStream) return await this.readReadableStream(body);
2902
- return await this.readAsyncIterable(body);
2903
- }
2904
- async readReadableStream(body) {
2905
- const reader = body.getReader();
2906
- const chunks = [];
2907
- let totalSize = 0;
2908
- try {
2909
- while (true) {
2910
- const result = await reader.read();
2911
- if (result.done) break;
2912
- chunks.push(result.value);
2913
- totalSize += result.value.byteLength;
2914
- }
2915
- } finally {
2916
- reader.releaseLock();
2917
- }
2918
- return this.joinChunks(chunks, totalSize);
2919
- }
2920
- async readAsyncIterable(body) {
2921
- const chunks = [];
2922
- let totalSize = 0;
2923
- for await (const chunk of body) {
2924
- chunks.push(chunk);
2925
- totalSize += chunk.byteLength;
2926
- }
2927
- return this.joinChunks(chunks, totalSize);
2928
- }
2929
- joinChunks(chunks, totalSize) {
2930
- const bytes = new Uint8Array(totalSize);
2931
- let offset = 0;
2932
- for (const chunk of chunks) {
2933
- bytes.set(chunk, offset);
2934
- offset += chunk.byteLength;
2935
- }
2936
- return bytes;
2937
- }
2938
- };
2939
-
2940
- //#endregion
2941
- //#region src/runStorage/BinaryBodyReadableStreamFactory.ts
2942
- var BinaryBodyReadableStreamFactory = class {
2943
- constructor(bytes) {
2944
- this.bytes = bytes;
2945
- }
2946
- create() {
2947
- const value = this.bytes;
2948
- let consumed = false;
2949
- return new ReadableStream({ pull(controller) {
2950
- if (consumed) {
2951
- controller.close();
2952
- return;
2953
- }
2954
- consumed = true;
2955
- controller.enqueue(value);
2956
- controller.close();
2957
- } });
2958
- }
2959
- };
2960
-
2961
- //#endregion
2962
- //#region src/runStorage/InMemoryBinaryStorageRegistry.ts
2963
- var InMemoryBinaryStorage = class {
2964
- driverName = "memory";
2965
- values = /* @__PURE__ */ new Map();
2966
- async write(args) {
2967
- const bytes = await new BinaryBodyBufferReader().read(args.body);
2968
- this.values.set(args.storageKey, bytes);
2969
- return {
2970
- storageKey: args.storageKey,
2971
- size: bytes.byteLength,
2972
- sha256: createHash("sha256").update(bytes).digest("hex")
2973
- };
2974
- }
2975
- async openReadStream(storageKey) {
2976
- const bytes = this.values.get(storageKey);
2977
- if (!bytes) return;
2978
- return {
2979
- body: new BinaryBodyReadableStreamFactory(bytes).create(),
2980
- size: bytes.byteLength
2981
- };
2982
- }
2983
- async stat(storageKey) {
2984
- const bytes = this.values.get(storageKey);
2985
- if (!bytes) return { exists: false };
2986
- return {
2987
- exists: true,
2988
- size: bytes.byteLength
2989
- };
2990
- }
2991
- async delete(storageKey) {
2992
- this.values.delete(storageKey);
2993
- }
2994
- };
2995
-
2996
- //#endregion
2997
- //#region src/runStorage/InMemoryRunData.ts
2998
- var InMemoryRunData = class {
2999
- byNode = /* @__PURE__ */ new Map();
3000
- constructor(initial) {
3001
- if (initial) for (const [nodeId, outputs] of Object.entries(initial)) this.byNode.set(nodeId, outputs);
3002
- }
3003
- setOutputs(nodeId, outputs) {
3004
- this.byNode.set(nodeId, outputs);
3005
- }
3006
- getOutputs(nodeId) {
3007
- return this.byNode.get(nodeId);
3008
- }
3009
- getOutputItems(nodeId, output = "main") {
3010
- return this.byNode.get(nodeId)?.[output] ?? [];
3011
- }
3012
- getOutputItem(nodeId, itemIndex, output = "main") {
3013
- return this.getOutputItems(nodeId, output)[itemIndex];
3014
- }
3015
- dump() {
3016
- const out = {};
3017
- for (const [nodeId, outputs] of this.byNode.entries()) out[nodeId] = outputs;
3018
- return out;
3019
- }
3020
- };
3021
-
3022
- //#endregion
3023
- //#region src/runStorage/InMemoryRunDataFactory.ts
3024
- var InMemoryRunDataFactory = class {
3025
- create(initial) {
3026
- return new InMemoryRunData(initial);
3027
- }
3028
- };
3029
-
3030
- //#endregion
3031
- //#region src/contracts/runFinishedAtFactory.ts
3032
- /** Derives workflow end time from node snapshots for run listings. */
3033
- var RunFinishedAtFactory = class {
3034
- static resolveIso(state) {
3035
- if (state.status === "running" || state.status === "pending") return;
3036
- let max;
3037
- for (const snap of Object.values(state.nodeSnapshotsByNodeId)) if (snap?.finishedAt && (!max || snap.finishedAt > max)) max = snap.finishedAt;
3038
- return max;
3039
- }
3040
- };
3041
-
3042
- //#endregion
3043
- //#region src/runtime/RunIntentService.ts
3044
- var RunIntentService = class {
3045
- constructor(engine, workflowRepository) {
3046
- this.engine = engine;
3047
- this.workflowRepository = workflowRepository;
3048
- }
3049
- async startWorkflow(args) {
3050
- if (args.startAt && !args.currentState && !args.stopCondition && !args.reset) return await this.engine.runWorkflow(args.workflow, args.startAt, args.items, args.parent, args.executionOptions, {
3051
- workflowSnapshot: args.workflowSnapshot,
3052
- mutableState: args.mutableState
3053
- });
3054
- return await this.engine.runWorkflowFromState({
3055
- workflow: args.workflow,
3056
- items: args.items,
3057
- parent: args.parent,
3058
- executionOptions: args.executionOptions,
3059
- workflowSnapshot: args.workflowSnapshot,
3060
- mutableState: args.mutableState,
3061
- currentState: args.currentState,
3062
- stopCondition: args.stopCondition ?? { kind: "workflowCompleted" },
3063
- reset: args.reset
3064
- });
3065
- }
3066
- async rerunFromNode(args) {
3067
- if (args.items) return await this.engine.runWorkflow(args.workflow, args.nodeId, args.items, args.parent, args.executionOptions, {
3068
- workflowSnapshot: args.workflowSnapshot,
3069
- mutableState: args.mutableState
3070
- });
3071
- return await this.engine.runWorkflowFromState({
3072
- workflow: args.workflow,
3073
- parent: args.parent,
3074
- executionOptions: args.executionOptions,
3075
- workflowSnapshot: args.workflowSnapshot,
3076
- mutableState: args.mutableState,
3077
- currentState: args.currentState,
3078
- stopCondition: { kind: "workflowCompleted" },
3079
- reset: { clearFromNodeId: args.nodeId }
3080
- });
3081
- }
3082
- resolveWebhookTrigger(args) {
3083
- return this.engine.resolveWebhookTrigger(args);
3084
- }
3085
- async runMatchedWebhook(args) {
3086
- const resolution = this.resolveWebhookTrigger(args);
3087
- if (resolution.status === "notFound") throw new Error("Unknown webhook endpoint");
3088
- if (resolution.status === "methodNotAllowed") throw new Error("Method not allowed");
3089
- return await this.runWebhookMatch({
3090
- match: resolution.match,
3091
- requestItem: args.requestItem
3092
- });
3093
- }
3094
- async runWebhookMatch(args) {
3095
- const workflow = this.workflowRepository.get(args.match.workflowId);
3096
- if (!workflow) throw new Error(`Unknown workflowId: ${args.match.workflowId}`);
3097
- const scheduled = await this.engine.runWorkflow(workflow, args.match.nodeId, [args.requestItem], void 0, this.createWebhookExecutionOptions());
3098
- if (scheduled.status === "failed") throw new Error(scheduled.error.message);
3099
- if (scheduled.status === "completed") return {
3100
- runId: scheduled.runId,
3101
- workflowId: scheduled.workflowId,
3102
- startedAt: scheduled.startedAt,
3103
- runStatus: "completed",
3104
- response: scheduled.outputs
3105
- };
3106
- return await Promise.race([this.engine.waitForWebhookResponse(scheduled.runId), this.engine.waitForCompletion(scheduled.runId).then((completed) => {
3107
- if (completed.status === "failed") throw new Error(completed.error.message);
3108
- return {
3109
- runId: completed.runId,
3110
- workflowId: completed.workflowId,
3111
- startedAt: completed.startedAt,
3112
- runStatus: "completed",
3113
- response: completed.outputs
3114
- };
3115
- })]);
3116
- }
3117
- /**
3118
- * Webhook-triggered runs always force inline execution first.
3119
- * This is the highest-precedence scheduler override: it wins over node hints and container defaults.
3120
- */
3121
- createWebhookExecutionOptions() {
3122
- return {
3123
- localOnly: true,
3124
- webhook: true
3125
- };
3126
- }
3127
- };
3128
-
3129
- //#endregion
3130
- export { instancePerContainerCachingFactory as $, InProcessRetryRunnerFactory as A, node as B, PersistedWorkflowTokenRegistry as C, NodeExecutorFactory as D, MissingRuntimeExecutionMarker as E, ActivationEnqueueService as F, PersistedRuntimeTypeNameResolver as G, InjectableRuntimeDecoratorComposer as H, DefaultExecutionBinaryService as I, delay as J, NodeEventPublisher as K, UnavailableBinaryStorage as L, DefaultExecutionContextFactory as M, DefaultAsyncSleeper as N, NodeExecutor as O, CredentialResolverFactory as P, instanceCachingFactory as Q, chatModel as R, WorkflowSnapshotResolver as S, MissingRuntimeTriggerToken as T, PersistedRuntimeTypeMetadataStore as U, tool as V, StackTraceCallSitePathResolver as W, injectAll as X, inject as Y, injectable as Z, RunStateSemantics as _, ENGINE_EXECUTION_LIMITS_DEFAULTS as a, WorkflowExecutableNodeClassifier as at, NodeInstanceFactoryFactory as b, InlineDrivingScheduler as c, ConfigDrivenOffloadPolicy as d, predicateAwareClassFactory as et, RunStartService as f, WorkflowRunExecutionContextFactory as g, WorkflowTopology as h, InMemoryBinaryStorage as i, WorkflowExecutableNodeClassifierFactory as it, InProcessRetryRunner as j, NodeActivationRequestComposer as k, HintOnlyOffloadPolicy as l, RunContinuationService as m, RunFinishedAtFactory as n, singleton as nt, EngineExecutionLimitsPolicy as o, ConnectionNodeIdFactory as ot, RunPolicySnapshotFactory as p, container as q, InMemoryRunDataFactory as r, CoreTokens as rt, LocalOnlyScheduler as s, RunIntentService as t, registry as tt, DefaultDrivingScheduler as u, PersistedRunStateTerminalBuilder as v, MissingRuntimeFallbacks as w, NodeInstanceFactory as x, NodeRunStateWriterFactory as y, getPersistedRuntimeTypeMetadata as z };
3131
- //# sourceMappingURL=RunIntentService-BFVbsOcg.js.map