flowcraft 2.2.0 → 2.3.0

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 (147) hide show
  1. package/README.md +40 -34
  2. package/dist/analysis.d.ts +3 -1
  3. package/dist/chunk-33NO4PUJ.js +74 -0
  4. package/dist/chunk-33NO4PUJ.js.map +1 -0
  5. package/dist/chunk-5KKSQWSC.js +90 -0
  6. package/dist/chunk-5KKSQWSC.js.map +1 -0
  7. package/dist/{chunk-QLGJUDQF.js → chunk-6INWPSZT.js} +6 -6
  8. package/dist/chunk-6INWPSZT.js.map +1 -0
  9. package/dist/chunk-BC4G7OM6.js +42 -0
  10. package/dist/chunk-BC4G7OM6.js.map +1 -0
  11. package/dist/chunk-BCRWXTWX.js +21 -0
  12. package/dist/chunk-BCRWXTWX.js.map +1 -0
  13. package/dist/{chunk-ZCHFZBGL.js → chunk-C4HYIJI3.js} +120 -5
  14. package/dist/chunk-C4HYIJI3.js.map +1 -0
  15. package/dist/chunk-CD3Q4N6V.js +13 -0
  16. package/dist/chunk-CD3Q4N6V.js.map +1 -0
  17. package/dist/chunk-CD4FUZOJ.js +114 -0
  18. package/dist/chunk-CD4FUZOJ.js.map +1 -0
  19. package/dist/chunk-CY755I7I.js +25 -0
  20. package/dist/chunk-CY755I7I.js.map +1 -0
  21. package/dist/chunk-DL7KVYZF.js +39 -0
  22. package/dist/chunk-DL7KVYZF.js.map +1 -0
  23. package/dist/chunk-FRKO3WX4.js +32 -0
  24. package/dist/chunk-FRKO3WX4.js.map +1 -0
  25. package/dist/chunk-G53CSLBF.js +54 -0
  26. package/dist/chunk-G53CSLBF.js.map +1 -0
  27. package/dist/chunk-G5BGBPFP.js +172 -0
  28. package/dist/chunk-G5BGBPFP.js.map +1 -0
  29. package/dist/chunk-HAZ26F3P.js +98 -0
  30. package/dist/chunk-HAZ26F3P.js.map +1 -0
  31. package/dist/chunk-IB2BISIC.js +446 -0
  32. package/dist/chunk-IB2BISIC.js.map +1 -0
  33. package/dist/{chunk-U5V5O5MN.js → chunk-LNK7LZER.js} +5 -3
  34. package/dist/chunk-LNK7LZER.js.map +1 -0
  35. package/dist/chunk-MCGK3FXQ.js +143 -0
  36. package/dist/chunk-MCGK3FXQ.js.map +1 -0
  37. package/dist/chunk-MUYLRTSR.js +82 -0
  38. package/dist/chunk-MUYLRTSR.js.map +1 -0
  39. package/dist/chunk-NVJ3ZO3P.js +3 -0
  40. package/dist/{chunk-HMR2GEGE.js.map → chunk-NVJ3ZO3P.js.map} +1 -1
  41. package/dist/chunk-NVLZFLYM.js +3 -0
  42. package/dist/chunk-NVLZFLYM.js.map +1 -0
  43. package/dist/chunk-ONH7PIJZ.js +300 -0
  44. package/dist/chunk-ONH7PIJZ.js.map +1 -0
  45. package/dist/chunk-QNYXQKFW.js +25 -0
  46. package/dist/chunk-QNYXQKFW.js.map +1 -0
  47. package/dist/chunk-RM677CNU.js +52 -0
  48. package/dist/chunk-RM677CNU.js.map +1 -0
  49. package/dist/chunk-WWGFIYKW.js +47 -0
  50. package/dist/chunk-WWGFIYKW.js.map +1 -0
  51. package/dist/chunk-XNRIM27H.js +76 -0
  52. package/dist/chunk-XNRIM27H.js.map +1 -0
  53. package/dist/container-factory.d.ts +17 -0
  54. package/dist/container-factory.js +13 -0
  55. package/dist/container-factory.js.map +1 -0
  56. package/dist/container.d.ts +23 -0
  57. package/dist/container.js +3 -0
  58. package/dist/container.js.map +1 -0
  59. package/dist/context.d.ts +3 -1
  60. package/dist/errors.d.ts +18 -17
  61. package/dist/errors.js +1 -1
  62. package/dist/evaluator.d.ts +3 -1
  63. package/dist/flow.d.ts +12 -2
  64. package/dist/flow.js +2 -2
  65. package/dist/index.d.ts +7 -8
  66. package/dist/index.js +26 -14
  67. package/dist/linter.d.ts +3 -1
  68. package/dist/logger.d.ts +3 -1
  69. package/dist/node.d.ts +3 -1
  70. package/dist/node.js +1 -1
  71. package/dist/nodes/batch-gather.d.ts +9 -0
  72. package/dist/nodes/batch-gather.js +4 -0
  73. package/dist/nodes/batch-gather.js.map +1 -0
  74. package/dist/nodes/batch-scatter.d.ts +9 -0
  75. package/dist/nodes/batch-scatter.js +4 -0
  76. package/dist/nodes/batch-scatter.js.map +1 -0
  77. package/dist/nodes/subflow.d.ts +9 -0
  78. package/dist/nodes/subflow.js +10 -0
  79. package/dist/nodes/subflow.js.map +1 -0
  80. package/dist/nodes/wait.d.ts +9 -0
  81. package/dist/nodes/wait.js +4 -0
  82. package/dist/nodes/wait.js.map +1 -0
  83. package/dist/runtime/adapter.d.ts +3 -5
  84. package/dist/runtime/adapter.js +19 -9
  85. package/dist/runtime/execution-context.d.ts +3 -0
  86. package/dist/runtime/execution-context.js +6 -0
  87. package/dist/runtime/execution-context.js.map +1 -0
  88. package/dist/runtime/executors.d.ts +3 -26
  89. package/dist/runtime/executors.js +2 -2
  90. package/dist/runtime/index.d.ts +5 -7
  91. package/dist/runtime/index.js +21 -10
  92. package/dist/runtime/node-executor-factory.d.ts +12 -0
  93. package/dist/runtime/node-executor-factory.js +6 -0
  94. package/dist/runtime/node-executor-factory.js.map +1 -0
  95. package/dist/runtime/orchestrator.d.ts +9 -0
  96. package/dist/runtime/orchestrator.js +8 -0
  97. package/dist/runtime/orchestrator.js.map +1 -0
  98. package/dist/runtime/orchestrators/step-by-step.d.ts +16 -0
  99. package/dist/runtime/orchestrators/step-by-step.js +5 -0
  100. package/dist/runtime/orchestrators/step-by-step.js.map +1 -0
  101. package/dist/runtime/orchestrators/utils.d.ts +35 -0
  102. package/dist/runtime/orchestrators/utils.js +4 -0
  103. package/dist/runtime/orchestrators/utils.js.map +1 -0
  104. package/dist/runtime/runtime.d.ts +3 -41
  105. package/dist/runtime/runtime.js +18 -8
  106. package/dist/runtime/state.d.ts +3 -21
  107. package/dist/runtime/state.js +2 -1
  108. package/dist/runtime/traverser.d.ts +3 -26
  109. package/dist/runtime/traverser.js +1 -2
  110. package/dist/runtime/types.d.ts +3 -16
  111. package/dist/runtime/types.js +1 -1
  112. package/dist/runtime/workflow-logic-handler.d.ts +17 -0
  113. package/dist/runtime/workflow-logic-handler.js +5 -0
  114. package/dist/runtime/workflow-logic-handler.js.map +1 -0
  115. package/dist/sanitizer.d.ts +3 -1
  116. package/dist/serializer.d.ts +3 -1
  117. package/dist/testing/event-logger.d.ts +63 -0
  118. package/dist/testing/event-logger.js +3 -0
  119. package/dist/testing/event-logger.js.map +1 -0
  120. package/dist/testing/index.d.ts +6 -0
  121. package/dist/testing/index.js +31 -0
  122. package/dist/testing/index.js.map +1 -0
  123. package/dist/testing/run-with-trace.d.ts +38 -0
  124. package/dist/testing/run-with-trace.js +29 -0
  125. package/dist/testing/run-with-trace.js.map +1 -0
  126. package/dist/testing/stepper.d.ts +79 -0
  127. package/dist/testing/stepper.js +11 -0
  128. package/dist/testing/stepper.js.map +1 -0
  129. package/dist/types-ezHUBdpL.d.ts +564 -0
  130. package/dist/types.d.ts +3 -1
  131. package/package.json +55 -51
  132. package/LICENSE +0 -21
  133. package/dist/chunk-5ZXV3R5D.js +0 -28
  134. package/dist/chunk-5ZXV3R5D.js.map +0 -1
  135. package/dist/chunk-GEKDR2SS.js +0 -201
  136. package/dist/chunk-GEKDR2SS.js.map +0 -1
  137. package/dist/chunk-HMR2GEGE.js +0 -3
  138. package/dist/chunk-M2FRTT2K.js +0 -144
  139. package/dist/chunk-M2FRTT2K.js.map +0 -1
  140. package/dist/chunk-OTS5YJ3S.js +0 -494
  141. package/dist/chunk-OTS5YJ3S.js.map +0 -1
  142. package/dist/chunk-QLGJUDQF.js.map +0 -1
  143. package/dist/chunk-U5V5O5MN.js.map +0 -1
  144. package/dist/chunk-VSGQDLBF.js +0 -61
  145. package/dist/chunk-VSGQDLBF.js.map +0 -1
  146. package/dist/chunk-ZCHFZBGL.js.map +0 -1
  147. package/dist/types-CsTeXTiA.d.ts +0 -222
@@ -0,0 +1,172 @@
1
+ import { analyzeBlueprint } from './chunk-233SESC2.js';
2
+
3
+ // src/runtime/traverser.ts
4
+ var GraphTraverser = class _GraphTraverser {
5
+ frontier = /* @__PURE__ */ new Set();
6
+ allPredecessors;
7
+ dynamicBlueprint;
8
+ completedNodes = /* @__PURE__ */ new Set();
9
+ constructor(blueprint, isStrictMode = false) {
10
+ this.dynamicBlueprint = structuredClone(blueprint);
11
+ this.allPredecessors = /* @__PURE__ */ new Map();
12
+ for (const node of this.dynamicBlueprint.nodes) {
13
+ this.allPredecessors.set(node.id, /* @__PURE__ */ new Set());
14
+ }
15
+ for (const edge of this.dynamicBlueprint.edges) {
16
+ this.allPredecessors.get(edge.target)?.add(edge.source);
17
+ }
18
+ const analysis = analyzeBlueprint(blueprint);
19
+ this.frontier = new Set(analysis.startNodeIds.filter((id) => !this.isFallbackNode(id)));
20
+ if (this.frontier.size === 0 && analysis.cycles.length > 0 && !isStrictMode) {
21
+ const uniqueStartNodes = /* @__PURE__ */ new Set();
22
+ const cycleEntryPoints = new Set(blueprint.metadata?.cycleEntryPoints || []);
23
+ for (const cycle of analysis.cycles) {
24
+ if (cycle.length > 0) {
25
+ const entryPoint = cycle.find((node) => cycleEntryPoints.has(node));
26
+ uniqueStartNodes.add(entryPoint || cycle[0]);
27
+ }
28
+ }
29
+ this.frontier = new Set(uniqueStartNodes);
30
+ }
31
+ }
32
+ /**
33
+ * Clears all nodes from the execution frontier.
34
+ */
35
+ clearFrontier() {
36
+ this.frontier.clear();
37
+ }
38
+ /**
39
+ * Creates and initializes a GraphTraverser from a saved workflow state.
40
+ * This is the correct way to prepare a traverser for a `resume` operation.
41
+ * @param blueprint The workflow blueprint.
42
+ * @param state The workflow state being resumed.
43
+ * @returns A configured GraphTraverser instance.
44
+ */
45
+ static fromState(blueprint, state) {
46
+ const traverser = new _GraphTraverser(blueprint);
47
+ traverser.clearFrontier();
48
+ const completedNodes = state.getCompletedNodes();
49
+ traverser.completedNodes = new Set(completedNodes);
50
+ for (const node of traverser.dynamicBlueprint.nodes) {
51
+ if (traverser.completedNodes.has(node.id)) continue;
52
+ const requiredPredecessors = traverser.allPredecessors.get(node.id);
53
+ const joinStrategy = traverser.getEffectiveJoinStrategy(node.id);
54
+ if (!requiredPredecessors || requiredPredecessors.size === 0) {
55
+ traverser.frontier.add(node.id);
56
+ continue;
57
+ }
58
+ const completedPredecessors = [...requiredPredecessors].filter((p) => traverser.completedNodes.has(p));
59
+ const isReady = joinStrategy === "any" ? completedPredecessors.length > 0 : completedPredecessors.length === requiredPredecessors.size;
60
+ if (isReady) traverser.frontier.add(node.id);
61
+ }
62
+ return traverser;
63
+ }
64
+ isFallbackNode(nodeId) {
65
+ return this.dynamicBlueprint.nodes.some((n) => n.config?.fallback === nodeId);
66
+ }
67
+ getEffectiveJoinStrategy(nodeId) {
68
+ const node = this.dynamicBlueprint.nodes.find((n) => n.id === nodeId);
69
+ const baseJoinStrategy = node?.config?.joinStrategy || "all";
70
+ if (node?.uses === "loop-controller") {
71
+ return "any";
72
+ }
73
+ const predecessors = this.allPredecessors.get(nodeId);
74
+ if (predecessors) {
75
+ for (const predecessorId of predecessors) {
76
+ const predecessorNode = this.dynamicBlueprint.nodes.find((n) => n.id === predecessorId);
77
+ if (predecessorNode?.uses === "loop-controller") {
78
+ return "any";
79
+ }
80
+ }
81
+ }
82
+ return baseJoinStrategy;
83
+ }
84
+ getReadyNodes() {
85
+ const readyNodes = [];
86
+ for (const nodeId of this.frontier) {
87
+ const nodeDef = this.dynamicBlueprint.nodes.find((n) => n.id === nodeId);
88
+ if (nodeDef) {
89
+ readyNodes.push({ nodeId, nodeDef });
90
+ }
91
+ }
92
+ this.frontier.clear();
93
+ return readyNodes;
94
+ }
95
+ hasMoreWork() {
96
+ return this.frontier.size > 0;
97
+ }
98
+ markNodeCompleted(nodeId, result, nextNodes) {
99
+ this.completedNodes.add(nodeId);
100
+ if (result.dynamicNodes && result.dynamicNodes.length > 0) {
101
+ const gatherNodeId = result.output?.gatherNodeId;
102
+ for (const dynamicNode of result.dynamicNodes) {
103
+ this.dynamicBlueprint.nodes.push(dynamicNode);
104
+ this.allPredecessors.set(dynamicNode.id, /* @__PURE__ */ new Set([nodeId]));
105
+ if (gatherNodeId) {
106
+ this.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id);
107
+ }
108
+ this.frontier.add(dynamicNode.id);
109
+ }
110
+ }
111
+ for (const node of nextNodes) {
112
+ const joinStrategy = this.getEffectiveJoinStrategy(node.id);
113
+ if (joinStrategy !== "any" && this.completedNodes.has(node.id)) continue;
114
+ const requiredPredecessors = this.allPredecessors.get(node.id);
115
+ if (!requiredPredecessors) continue;
116
+ const isReady = joinStrategy === "any" ? requiredPredecessors.has(nodeId) : [...requiredPredecessors].every((p) => this.completedNodes.has(p));
117
+ if (isReady) {
118
+ this.frontier.add(node.id);
119
+ }
120
+ }
121
+ if (nextNodes.length === 0) {
122
+ for (const [potentialNextId, predecessors] of this.allPredecessors) {
123
+ if (predecessors.has(nodeId) && !this.completedNodes.has(potentialNextId)) {
124
+ const joinStrategy = this.getEffectiveJoinStrategy(potentialNextId);
125
+ const isReady = joinStrategy === "any" ? predecessors.has(nodeId) : [...predecessors].every((p) => this.completedNodes.has(p));
126
+ if (isReady) {
127
+ this.frontier.add(potentialNextId);
128
+ }
129
+ }
130
+ }
131
+ }
132
+ }
133
+ getAllNodeIds() {
134
+ return new Set(this.dynamicBlueprint.nodes.map((n) => n.id));
135
+ }
136
+ getFallbackNodeIds() {
137
+ const fallbackNodeIds = /* @__PURE__ */ new Set();
138
+ for (const node of this.dynamicBlueprint.nodes) {
139
+ if (node.config?.fallback) fallbackNodeIds.add(node.config.fallback);
140
+ }
141
+ return fallbackNodeIds;
142
+ }
143
+ getCompletedNodes() {
144
+ return new Set(this.completedNodes);
145
+ }
146
+ getDynamicBlueprint() {
147
+ return this.dynamicBlueprint;
148
+ }
149
+ getAllPredecessors() {
150
+ return this.allPredecessors;
151
+ }
152
+ addDynamicNode(_nodeId, dynamicNode, predecessorId, gatherNodeId) {
153
+ this.dynamicBlueprint.nodes.push(dynamicNode);
154
+ this.allPredecessors.set(dynamicNode.id, /* @__PURE__ */ new Set([predecessorId]));
155
+ if (gatherNodeId) {
156
+ this.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id);
157
+ }
158
+ this.frontier.add(dynamicNode.id);
159
+ }
160
+ /**
161
+ * Manually adds a node ID back to the execution frontier.
162
+ * Used by orchestrators that need fine-grained control over steps.
163
+ * @param nodeId The ID of the node to add to the frontier.
164
+ */
165
+ addToFrontier(nodeId) {
166
+ this.frontier.add(nodeId);
167
+ }
168
+ };
169
+
170
+ export { GraphTraverser };
171
+ //# sourceMappingURL=chunk-G5BGBPFP.js.map
172
+ //# sourceMappingURL=chunk-G5BGBPFP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/traverser.ts"],"names":[],"mappings":";;;AASO,IAAM,cAAA,GAAN,MAAM,eAAA,CAAe;AAAA,EACnB,QAAA,uBAAe,GAAA,EAAY;AAAA,EAC3B,eAAA;AAAA,EACA,gBAAA;AAAA,EACA,cAAA,uBAAqB,GAAA,EAAY;AAAA,EAEzC,WAAA,CAAY,SAAA,EAA8B,YAAA,GAAwB,KAAA,EAAO;AACxE,IAAA,IAAA,CAAK,gBAAA,GAAmB,gBAAgB,SAAS,CAAA;AACjD,IAAA,IAAA,CAAK,eAAA,uBAAsB,GAAA,EAAyB;AACpD,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO;AAC/C,MAAA,IAAA,CAAK,gBAAgB,GAAA,CAAI,IAAA,CAAK,EAAA,kBAAI,IAAI,KAAK,CAAA;AAAA,IAC5C;AACA,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO;AAC/C,MAAA,IAAA,CAAK,gBAAgB,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,IACvD;AACA,IAAA,MAAM,QAAA,GAAW,iBAAiB,SAAS,CAAA;AAC3C,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,GAAA,CAAI,QAAA,CAAS,YAAA,CAAa,MAAA,CAAO,CAAC,EAAA,KAAO,CAAC,IAAA,CAAK,cAAA,CAAe,EAAE,CAAC,CAAC,CAAA;AACtF,IAAA,IAAI,IAAA,CAAK,SAAS,IAAA,KAAS,CAAA,IAAK,SAAS,MAAA,CAAO,MAAA,GAAS,CAAA,IAAK,CAAC,YAAA,EAAc;AAC5E,MAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAY;AACzC,MAAA,MAAM,mBAAmB,IAAI,GAAA,CAAI,UAAU,QAAA,EAAU,gBAAA,IAAoB,EAAE,CAAA;AAC3E,MAAA,KAAA,MAAW,KAAA,IAAS,SAAS,MAAA,EAAQ;AACpC,QAAA,IAAI,KAAA,CAAM,SAAS,CAAA,EAAG;AACrB,UAAA,MAAM,UAAA,GAAa,MAAM,IAAA,CAAK,CAAC,SAAS,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAC,CAAA;AAClE,UAAA,gBAAA,CAAiB,GAAA,CAAI,UAAA,IAAc,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,QAC5C;AAAA,MACD;AACA,MAAA,IAAA,CAAK,QAAA,GAAW,IAAI,GAAA,CAAI,gBAAgB,CAAA;AAAA,IACzC;AAAA,EACD;AAAA;AAAA;AAAA;AAAA,EAKO,aAAA,GAAsB;AAC5B,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,OAAc,SAAA,CAAU,SAAA,EAA8B,KAAA,EAA2C;AAChG,IAAA,MAAM,SAAA,GAAY,IAAI,eAAA,CAAe,SAAS,CAAA;AAG9C,IAAA,SAAA,CAAU,aAAA,EAAc;AAGxB,IAAA,MAAM,cAAA,GAAiB,MAAM,iBAAA,EAAkB;AAC/C,IAAA,SAAA,CAAU,cAAA,GAAiB,IAAI,GAAA,CAAI,cAAc,CAAA;AAEjD,IAAA,KAAA,MAAW,IAAA,IAAQ,SAAA,CAAU,gBAAA,CAAiB,KAAA,EAAO;AACpD,MAAA,IAAI,SAAA,CAAU,cAAA,CAAe,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AAE3C,MAAA,MAAM,oBAAA,GAAuB,SAAA,CAAU,eAAA,CAAgB,GAAA,CAAI,KAAK,EAAE,CAAA;AAClE,MAAA,MAAM,YAAA,GAAe,SAAA,CAAU,wBAAA,CAAyB,IAAA,CAAK,EAAE,CAAA;AAG/D,MAAA,IAAI,CAAC,oBAAA,IAAwB,oBAAA,CAAqB,IAAA,KAAS,CAAA,EAAG;AAC7D,QAAA,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAC9B,QAAA;AAAA,MACD;AAEA,MAAA,MAAM,qBAAA,GAAwB,CAAC,GAAG,oBAAoB,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,KAAM,SAAA,CAAU,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,CAAA;AACrG,MAAA,MAAM,OAAA,GACL,iBAAiB,KAAA,GACd,qBAAA,CAAsB,SAAS,CAAA,GAC/B,qBAAA,CAAsB,WAAW,oBAAA,CAAqB,IAAA;AAE1D,MAAA,IAAI,OAAA,EAAS,SAAA,CAAU,QAAA,CAAS,GAAA,CAAI,KAAK,EAAE,CAAA;AAAA,IAC5C;AAEA,IAAA,OAAO,SAAA;AAAA,EACR;AAAA,EAEQ,eAAe,MAAA,EAAyB;AAC/C,IAAA,OAAO,IAAA,CAAK,iBAAiB,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,EAAQ,QAAA,KAAa,MAAM,CAAA;AAAA,EAC7E;AAAA,EAEQ,yBAAyB,MAAA,EAA+B;AAC/D,IAAA,MAAM,IAAA,GAAO,KAAK,gBAAA,CAAiB,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,MAAM,CAAA;AACpE,IAAA,MAAM,gBAAA,GAAmB,IAAA,EAAM,MAAA,EAAQ,YAAA,IAAgB,KAAA;AAEvD,IAAA,IAAI,IAAA,EAAM,SAAS,iBAAA,EAAmB;AACrC,MAAA,OAAO,KAAA;AAAA,IACR;AAEA,IAAA,MAAM,YAAA,GAAe,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA;AACpD,IAAA,IAAI,YAAA,EAAc;AACjB,MAAA,KAAA,MAAW,iBAAiB,YAAA,EAAc;AACzC,QAAA,MAAM,eAAA,GAAkB,KAAK,gBAAA,CAAiB,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,aAAa,CAAA;AACtF,QAAA,IAAI,eAAA,EAAiB,SAAS,iBAAA,EAAmB;AAChD,UAAA,OAAO,KAAA;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAEA,IAAA,OAAO,gBAAA;AAAA,EACR;AAAA,EAEA,aAAA,GAA6B;AAC5B,IAAA,MAAM,aAA0B,EAAC;AACjC,IAAA,KAAA,MAAW,MAAA,IAAU,KAAK,QAAA,EAAU;AACnC,MAAA,MAAM,OAAA,GAAU,KAAK,gBAAA,CAAiB,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,EAAA,KAAO,MAAM,CAAA;AACvE,MAAA,IAAI,OAAA,EAAS;AACZ,QAAA,UAAA,CAAW,IAAA,CAAK,EAAE,MAAA,EAAQ,OAAA,EAAS,CAAA;AAAA,MACpC;AAAA,IACD;AACA,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;AACpB,IAAA,OAAO,UAAA;AAAA,EACR;AAAA,EAEA,WAAA,GAAuB;AACtB,IAAA,OAAO,IAAA,CAAK,SAAS,IAAA,GAAO,CAAA;AAAA,EAC7B;AAAA,EAEA,iBAAA,CAAkB,MAAA,EAAgB,MAAA,EAA8B,SAAA,EAAmC;AAClG,IAAA,IAAA,CAAK,cAAA,CAAe,IAAI,MAAM,CAAA;AAE9B,IAAA,IAAI,MAAA,CAAO,YAAA,IAAgB,MAAA,CAAO,YAAA,CAAa,SAAS,CAAA,EAAG;AAC1D,MAAA,MAAM,YAAA,GAAe,OAAO,MAAA,EAAQ,YAAA;AACpC,MAAA,KAAA,MAAW,WAAA,IAAe,OAAO,YAAA,EAAc;AAC9C,QAAA,IAAA,CAAK,gBAAA,CAAiB,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA;AAC5C,QAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,WAAA,CAAY,EAAA,sBAAQ,GAAA,CAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC1D,QAAA,IAAI,YAAA,EAAc;AACjB,UAAA,IAAA,CAAK,gBAAgB,GAAA,CAAI,YAAY,CAAA,EAAG,GAAA,CAAI,YAAY,EAAE,CAAA;AAAA,QAC3D;AACA,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,WAAA,CAAY,EAAE,CAAA;AAAA,MACjC;AAAA,IACD;AAEA,IAAA,KAAA,MAAW,QAAQ,SAAA,EAAW;AAC7B,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,wBAAA,CAAyB,IAAA,CAAK,EAAE,CAAA;AAC1D,MAAA,IAAI,iBAAiB,KAAA,IAAS,IAAA,CAAK,eAAe,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AAEhE,MAAA,MAAM,oBAAA,GAAuB,IAAA,CAAK,eAAA,CAAgB,GAAA,CAAI,KAAK,EAAE,CAAA;AAC7D,MAAA,IAAI,CAAC,oBAAA,EAAsB;AAE3B,MAAA,MAAM,UACL,YAAA,KAAiB,KAAA,GACd,qBAAqB,GAAA,CAAI,MAAM,IAC/B,CAAC,GAAG,oBAAoB,CAAA,CAAE,MAAM,CAAC,CAAA,KAAM,KAAK,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,CAAA;AAErE,MAAA,IAAI,OAAA,EAAS;AACZ,QAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAAA,MAC1B;AAAA,IACD;AAEA,IAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC3B,MAAA,KAAA,MAAW,CAAC,eAAA,EAAiB,YAAY,CAAA,IAAK,KAAK,eAAA,EAAiB;AACnE,QAAA,IAAI,YAAA,CAAa,IAAI,MAAM,CAAA,IAAK,CAAC,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,eAAe,CAAA,EAAG;AAC1E,UAAA,MAAM,YAAA,GAAe,IAAA,CAAK,wBAAA,CAAyB,eAAe,CAAA;AAClE,UAAA,MAAM,UACL,YAAA,KAAiB,KAAA,GACd,aAAa,GAAA,CAAI,MAAM,IACvB,CAAC,GAAG,YAAY,CAAA,CAAE,MAAM,CAAC,CAAA,KAAM,KAAK,cAAA,CAAe,GAAA,CAAI,CAAC,CAAC,CAAA;AAC7D,UAAA,IAAI,OAAA,EAAS;AACZ,YAAA,IAAA,CAAK,QAAA,CAAS,IAAI,eAAe,CAAA;AAAA,UAClC;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EAEA,aAAA,GAA6B;AAC5B,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,gBAAA,CAAiB,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,EAAE,CAAC,CAAA;AAAA,EAC5D;AAAA,EAEA,kBAAA,GAAkC;AACjC,IAAA,MAAM,eAAA,uBAAsB,GAAA,EAAY;AACxC,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,gBAAA,CAAiB,KAAA,EAAO;AAC/C,MAAA,IAAI,KAAK,MAAA,EAAQ,QAAA,kBAA0B,GAAA,CAAI,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,IACpE;AACA,IAAA,OAAO,eAAA;AAAA,EACR;AAAA,EAEA,iBAAA,GAAiC;AAChC,IAAA,OAAO,IAAI,GAAA,CAAI,IAAA,CAAK,cAAc,CAAA;AAAA,EACnC;AAAA,EAEA,mBAAA,GAAyC;AACxC,IAAA,OAAO,IAAA,CAAK,gBAAA;AAAA,EACb;AAAA,EAEA,kBAAA,GAA+C;AAC9C,IAAA,OAAO,IAAA,CAAK,eAAA;AAAA,EACb;AAAA,EAEA,cAAA,CAAe,OAAA,EAAiB,WAAA,EAA6B,aAAA,EAAuB,YAAA,EAA6B;AAChH,IAAA,IAAA,CAAK,gBAAA,CAAiB,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA;AAC5C,IAAA,IAAA,CAAK,eAAA,CAAgB,IAAI,WAAA,CAAY,EAAA,sBAAQ,GAAA,CAAI,CAAC,aAAa,CAAC,CAAC,CAAA;AACjE,IAAA,IAAI,YAAA,EAAc;AACjB,MAAA,IAAA,CAAK,gBAAgB,GAAA,CAAI,YAAY,CAAA,EAAG,GAAA,CAAI,YAAY,EAAE,CAAA;AAAA,IAC3D;AACA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,WAAA,CAAY,EAAE,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,cAAc,MAAA,EAAsB;AAC1C,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,MAAM,CAAA;AAAA,EACzB;AACD","file":"chunk-G5BGBPFP.js","sourcesContent":["import { analyzeBlueprint } from '../analysis'\nimport type { NodeDefinition, NodeResult, WorkflowBlueprint } from '../types'\nimport type { WorkflowState } from './state'\n\nexport interface ReadyNode {\n\tnodeId: string\n\tnodeDef: NodeDefinition\n}\n\nexport class GraphTraverser {\n\tprivate frontier = new Set<string>()\n\tprivate allPredecessors: Map<string, Set<string>>\n\tprivate dynamicBlueprint: WorkflowBlueprint\n\tprivate completedNodes = new Set<string>()\n\n\tconstructor(blueprint: WorkflowBlueprint, isStrictMode: boolean = false) {\n\t\tthis.dynamicBlueprint = structuredClone(blueprint) as WorkflowBlueprint\n\t\tthis.allPredecessors = new Map<string, Set<string>>()\n\t\tfor (const node of this.dynamicBlueprint.nodes) {\n\t\t\tthis.allPredecessors.set(node.id, new Set())\n\t\t}\n\t\tfor (const edge of this.dynamicBlueprint.edges) {\n\t\t\tthis.allPredecessors.get(edge.target)?.add(edge.source)\n\t\t}\n\t\tconst analysis = analyzeBlueprint(blueprint)\n\t\tthis.frontier = new Set(analysis.startNodeIds.filter((id) => !this.isFallbackNode(id)))\n\t\tif (this.frontier.size === 0 && analysis.cycles.length > 0 && !isStrictMode) {\n\t\t\tconst uniqueStartNodes = new Set<string>()\n\t\t\tconst cycleEntryPoints = new Set(blueprint.metadata?.cycleEntryPoints || [])\n\t\t\tfor (const cycle of analysis.cycles) {\n\t\t\t\tif (cycle.length > 0) {\n\t\t\t\t\tconst entryPoint = cycle.find((node) => cycleEntryPoints.has(node))\n\t\t\t\t\tuniqueStartNodes.add(entryPoint || cycle[0])\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.frontier = new Set(uniqueStartNodes)\n\t\t}\n\t}\n\n\t/**\n\t * Clears all nodes from the execution frontier.\n\t */\n\tpublic clearFrontier(): void {\n\t\tthis.frontier.clear()\n\t}\n\n\t/**\n\t * Creates and initializes a GraphTraverser from a saved workflow state.\n\t * This is the correct way to prepare a traverser for a `resume` operation.\n\t * @param blueprint The workflow blueprint.\n\t * @param state The workflow state being resumed.\n\t * @returns A configured GraphTraverser instance.\n\t */\n\tpublic static fromState(blueprint: WorkflowBlueprint, state: WorkflowState<any>): GraphTraverser {\n\t\tconst traverser = new GraphTraverser(blueprint)\n\n\t\t// clear auto-populated frontier from constructor\n\t\ttraverser.clearFrontier()\n\n\t\t// re-hydrate the set of completed nodes\n\t\tconst completedNodes = state.getCompletedNodes()\n\t\ttraverser.completedNodes = new Set(completedNodes)\n\n\t\tfor (const node of traverser.dynamicBlueprint.nodes) {\n\t\t\tif (traverser.completedNodes.has(node.id)) continue\n\n\t\t\tconst requiredPredecessors = traverser.allPredecessors.get(node.id)\n\t\t\tconst joinStrategy = traverser.getEffectiveJoinStrategy(node.id)\n\n\t\t\t// if no predecessors and not completed, it's a start node and should be in the frontier\n\t\t\tif (!requiredPredecessors || requiredPredecessors.size === 0) {\n\t\t\t\ttraverser.frontier.add(node.id)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tconst completedPredecessors = [...requiredPredecessors].filter((p) => traverser.completedNodes.has(p))\n\t\t\tconst isReady =\n\t\t\t\tjoinStrategy === 'any'\n\t\t\t\t\t? completedPredecessors.length > 0\n\t\t\t\t\t: completedPredecessors.length === requiredPredecessors.size\n\n\t\t\tif (isReady) traverser.frontier.add(node.id)\n\t\t}\n\n\t\treturn traverser\n\t}\n\n\tprivate isFallbackNode(nodeId: string): boolean {\n\t\treturn this.dynamicBlueprint.nodes.some((n) => n.config?.fallback === nodeId)\n\t}\n\n\tprivate getEffectiveJoinStrategy(nodeId: string): 'any' | 'all' {\n\t\tconst node = this.dynamicBlueprint.nodes.find((n) => n.id === nodeId)\n\t\tconst baseJoinStrategy = node?.config?.joinStrategy || 'all'\n\n\t\tif (node?.uses === 'loop-controller') {\n\t\t\treturn 'any'\n\t\t}\n\n\t\tconst predecessors = this.allPredecessors.get(nodeId)\n\t\tif (predecessors) {\n\t\t\tfor (const predecessorId of predecessors) {\n\t\t\t\tconst predecessorNode = this.dynamicBlueprint.nodes.find((n) => n.id === predecessorId)\n\t\t\t\tif (predecessorNode?.uses === 'loop-controller') {\n\t\t\t\t\treturn 'any'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn baseJoinStrategy\n\t}\n\n\tgetReadyNodes(): ReadyNode[] {\n\t\tconst readyNodes: ReadyNode[] = []\n\t\tfor (const nodeId of this.frontier) {\n\t\t\tconst nodeDef = this.dynamicBlueprint.nodes.find((n) => n.id === nodeId)\n\t\t\tif (nodeDef) {\n\t\t\t\treadyNodes.push({ nodeId, nodeDef })\n\t\t\t}\n\t\t}\n\t\tthis.frontier.clear()\n\t\treturn readyNodes\n\t}\n\n\thasMoreWork(): boolean {\n\t\treturn this.frontier.size > 0\n\t}\n\n\tmarkNodeCompleted(nodeId: string, result: NodeResult<any, any>, nextNodes: NodeDefinition[]): void {\n\t\tthis.completedNodes.add(nodeId)\n\n\t\tif (result.dynamicNodes && result.dynamicNodes.length > 0) {\n\t\t\tconst gatherNodeId = result.output?.gatherNodeId\n\t\t\tfor (const dynamicNode of result.dynamicNodes) {\n\t\t\t\tthis.dynamicBlueprint.nodes.push(dynamicNode)\n\t\t\t\tthis.allPredecessors.set(dynamicNode.id, new Set([nodeId]))\n\t\t\t\tif (gatherNodeId) {\n\t\t\t\t\tthis.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id)\n\t\t\t\t}\n\t\t\t\tthis.frontier.add(dynamicNode.id)\n\t\t\t}\n\t\t}\n\n\t\tfor (const node of nextNodes) {\n\t\t\tconst joinStrategy = this.getEffectiveJoinStrategy(node.id)\n\t\t\tif (joinStrategy !== 'any' && this.completedNodes.has(node.id)) continue\n\n\t\t\tconst requiredPredecessors = this.allPredecessors.get(node.id)\n\t\t\tif (!requiredPredecessors) continue\n\n\t\t\tconst isReady =\n\t\t\t\tjoinStrategy === 'any'\n\t\t\t\t\t? requiredPredecessors.has(nodeId)\n\t\t\t\t\t: [...requiredPredecessors].every((p) => this.completedNodes.has(p))\n\n\t\t\tif (isReady) {\n\t\t\t\tthis.frontier.add(node.id)\n\t\t\t}\n\t\t}\n\n\t\tif (nextNodes.length === 0) {\n\t\t\tfor (const [potentialNextId, predecessors] of this.allPredecessors) {\n\t\t\t\tif (predecessors.has(nodeId) && !this.completedNodes.has(potentialNextId)) {\n\t\t\t\t\tconst joinStrategy = this.getEffectiveJoinStrategy(potentialNextId)\n\t\t\t\t\tconst isReady =\n\t\t\t\t\t\tjoinStrategy === 'any'\n\t\t\t\t\t\t\t? predecessors.has(nodeId)\n\t\t\t\t\t\t\t: [...predecessors].every((p) => this.completedNodes.has(p))\n\t\t\t\t\tif (isReady) {\n\t\t\t\t\t\tthis.frontier.add(potentialNextId)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tgetAllNodeIds(): Set<string> {\n\t\treturn new Set(this.dynamicBlueprint.nodes.map((n) => n.id))\n\t}\n\n\tgetFallbackNodeIds(): Set<string> {\n\t\tconst fallbackNodeIds = new Set<string>()\n\t\tfor (const node of this.dynamicBlueprint.nodes) {\n\t\t\tif (node.config?.fallback) fallbackNodeIds.add(node.config.fallback)\n\t\t}\n\t\treturn fallbackNodeIds\n\t}\n\n\tgetCompletedNodes(): Set<string> {\n\t\treturn new Set(this.completedNodes)\n\t}\n\n\tgetDynamicBlueprint(): WorkflowBlueprint {\n\t\treturn this.dynamicBlueprint\n\t}\n\n\tgetAllPredecessors(): Map<string, Set<string>> {\n\t\treturn this.allPredecessors\n\t}\n\n\taddDynamicNode(_nodeId: string, dynamicNode: NodeDefinition, predecessorId: string, gatherNodeId?: string): void {\n\t\tthis.dynamicBlueprint.nodes.push(dynamicNode)\n\t\tthis.allPredecessors.set(dynamicNode.id, new Set([predecessorId]))\n\t\tif (gatherNodeId) {\n\t\t\tthis.allPredecessors.get(gatherNodeId)?.add(dynamicNode.id)\n\t\t}\n\t\tthis.frontier.add(dynamicNode.id)\n\t}\n\n\t/**\n\t * Manually adds a node ID back to the execution frontier.\n\t * Used by orchestrators that need fine-grained control over steps.\n\t * @param nodeId The ID of the node to add to the frontier.\n\t */\n\tpublic addToFrontier(nodeId: string): void {\n\t\tthis.frontier.add(nodeId)\n\t}\n}\n"]}
@@ -0,0 +1,98 @@
1
+ import { FlowcraftError } from './chunk-BCRWXTWX.js';
2
+
3
+ // src/runtime/orchestrators/utils.ts
4
+ async function executeBatch(readyNodes, blueprint, state, executorFactory, runtime, maxConcurrency) {
5
+ const concurrency = maxConcurrency || readyNodes.length;
6
+ const results = [];
7
+ for (let i = 0; i < readyNodes.length; i += concurrency) {
8
+ const batch = readyNodes.slice(i, i + concurrency);
9
+ const batchPromises = batch.map(async ({ nodeId }) => {
10
+ try {
11
+ const executor = executorFactory(nodeId);
12
+ if (!executor) throw new Error(`No executor for node ${nodeId}`);
13
+ const executionResult = await executor.execute(
14
+ await runtime.resolveNodeInput(nodeId, blueprint, state.getContext())
15
+ );
16
+ results.push({
17
+ status: "fulfilled",
18
+ value: { nodeId, executionResult }
19
+ });
20
+ } catch (error) {
21
+ results.push({
22
+ status: "rejected",
23
+ reason: { nodeId, error }
24
+ });
25
+ }
26
+ });
27
+ await Promise.all(batchPromises);
28
+ }
29
+ return results;
30
+ }
31
+ async function processResults(settledResults, traverser, state, runtime, _blueprint, executionId) {
32
+ for (const promiseResult of settledResults) {
33
+ if (promiseResult.status === "rejected") {
34
+ const { nodeId: nodeId2, error } = promiseResult.reason;
35
+ if (error instanceof FlowcraftError && error.message.includes("cancelled")) {
36
+ throw error;
37
+ }
38
+ state.addError(nodeId2, error);
39
+ continue;
40
+ }
41
+ const { nodeId, executionResult } = promiseResult.value;
42
+ if (executionResult.status === "success") {
43
+ const result = executionResult.result;
44
+ state.addCompletedNode(nodeId, result.output);
45
+ if (result._fallbackExecuted) {
46
+ state.markFallbackExecuted();
47
+ }
48
+ if (result.dynamicNodes && result.dynamicNodes.length > 0) {
49
+ const gatherNodeId = result.output?.gatherNodeId;
50
+ for (const dynamicNode of result.dynamicNodes) {
51
+ traverser.addDynamicNode(dynamicNode.id, dynamicNode, nodeId, gatherNodeId);
52
+ }
53
+ }
54
+ const matched = await runtime.determineNextNodes(
55
+ traverser.getDynamicBlueprint(),
56
+ nodeId,
57
+ result,
58
+ state.getContext(),
59
+ executionId
60
+ );
61
+ const loopControllerMatch = matched.find(
62
+ (m) => m.node.uses === "loop-controller"
63
+ );
64
+ const finalMatched = loopControllerMatch ? [loopControllerMatch] : matched;
65
+ for (const { node, edge } of finalMatched) {
66
+ await runtime.applyEdgeTransform(edge, result, node, state.getContext(), traverser.getAllPredecessors());
67
+ }
68
+ traverser.markNodeCompleted(
69
+ nodeId,
70
+ result,
71
+ finalMatched.map((m) => m.node)
72
+ );
73
+ } else if (executionResult.status === "failed_with_fallback") {
74
+ const { fallbackNodeId, error } = executionResult;
75
+ const blueprint = traverser.getDynamicBlueprint();
76
+ const fallbackNodeDef = blueprint.nodes.find((n) => n.id === fallbackNodeId);
77
+ if (!fallbackNodeDef) {
78
+ const notFoundError = new FlowcraftError(`Fallback node '${fallbackNodeId}' not found in blueprint.`, {
79
+ nodeId,
80
+ cause: error
81
+ });
82
+ state.addError(nodeId, notFoundError);
83
+ } else {
84
+ state.addCompletedNode(nodeId, null);
85
+ state.markFallbackExecuted();
86
+ traverser.markNodeCompleted(nodeId, { action: "fallback", output: null, _fallbackExecuted: true }, [
87
+ fallbackNodeDef
88
+ ]);
89
+ }
90
+ } else {
91
+ state.addError(nodeId, executionResult.error);
92
+ }
93
+ }
94
+ }
95
+
96
+ export { executeBatch, processResults };
97
+ //# sourceMappingURL=chunk-HAZ26F3P.js.map
98
+ //# sourceMappingURL=chunk-HAZ26F3P.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime/orchestrators/utils.ts"],"names":["nodeId"],"mappings":"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","file":"chunk-HAZ26F3P.js","sourcesContent":["import { FlowcraftError } from '../../errors'\nimport type { NodeDefinition, WorkflowBlueprint } from '../../types'\nimport type { NodeExecutionResult } from '../executors'\nimport type { WorkflowState } from '../state'\nimport type { GraphTraverser } from '../traverser'\n\nexport async function executeBatch(\n\treadyNodes: Array<{ nodeId: string; nodeDef: any }>,\n\tblueprint: WorkflowBlueprint,\n\tstate: WorkflowState<any>,\n\texecutorFactory: (nodeId: string) => any,\n\truntime: any,\n\tmaxConcurrency?: number,\n): Promise<\n\tArray<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t>\n> {\n\tconst concurrency = maxConcurrency || readyNodes.length\n\tconst results: Array<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t> = []\n\n\tfor (let i = 0; i < readyNodes.length; i += concurrency) {\n\t\tconst batch = readyNodes.slice(i, i + concurrency)\n\t\tconst batchPromises = batch.map(async ({ nodeId }) => {\n\t\t\ttry {\n\t\t\t\tconst executor = executorFactory(nodeId)\n\t\t\t\tif (!executor) throw new Error(`No executor for node ${nodeId}`)\n\t\t\t\tconst executionResult = await executor.execute(\n\t\t\t\t\tawait runtime.resolveNodeInput(nodeId, blueprint, state.getContext()),\n\t\t\t\t)\n\t\t\t\tresults.push({\n\t\t\t\t\tstatus: 'fulfilled' as const,\n\t\t\t\t\tvalue: { nodeId, executionResult },\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tstatus: 'rejected' as const,\n\t\t\t\t\treason: { nodeId, error },\n\t\t\t\t})\n\t\t\t}\n\t\t})\n\n\t\tawait Promise.all(batchPromises)\n\t}\n\n\treturn results\n}\n\nexport async function processResults(\n\tsettledResults: Array<\n\t\t| { status: 'fulfilled'; value: { nodeId: string; executionResult: NodeExecutionResult } }\n\t\t| { status: 'rejected'; reason: { nodeId: string; error: unknown } }\n\t>,\n\ttraverser: GraphTraverser,\n\tstate: WorkflowState<any>,\n\truntime: any,\n\t_blueprint: WorkflowBlueprint,\n\texecutionId?: string,\n): Promise<void> {\n\tfor (const promiseResult of settledResults) {\n\t\tif (promiseResult.status === 'rejected') {\n\t\t\tconst { nodeId, error } = promiseResult.reason\n\t\t\tif (error instanceof FlowcraftError && error.message.includes('cancelled')) {\n\t\t\t\tthrow error\n\t\t\t}\n\t\t\tstate.addError(nodeId, error as Error)\n\t\t\tcontinue\n\t\t}\n\n\t\tconst { nodeId, executionResult } = promiseResult.value\n\n\t\tif (executionResult.status === 'success') {\n\t\t\tconst result = executionResult.result\n\t\t\tstate.addCompletedNode(nodeId, result.output)\n\t\t\tif (result._fallbackExecuted) {\n\t\t\t\tstate.markFallbackExecuted()\n\t\t\t}\n\n\t\t\tif (result.dynamicNodes && result.dynamicNodes.length > 0) {\n\t\t\t\tconst gatherNodeId = result.output?.gatherNodeId\n\t\t\t\tfor (const dynamicNode of result.dynamicNodes) {\n\t\t\t\t\ttraverser.addDynamicNode(dynamicNode.id, dynamicNode, nodeId, gatherNodeId)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst matched = await runtime.determineNextNodes(\n\t\t\t\ttraverser.getDynamicBlueprint(),\n\t\t\t\tnodeId,\n\t\t\t\tresult,\n\t\t\t\tstate.getContext(),\n\t\t\t\texecutionId,\n\t\t\t)\n\n\t\t\tconst loopControllerMatch = matched.find(\n\t\t\t\t(m: { node: NodeDefinition; edge: any }) => m.node.uses === 'loop-controller',\n\t\t\t)\n\t\t\tconst finalMatched = loopControllerMatch ? [loopControllerMatch] : matched\n\n\t\t\tfor (const { node, edge } of finalMatched) {\n\t\t\t\tawait runtime.applyEdgeTransform(edge, result, node, state.getContext(), traverser.getAllPredecessors())\n\t\t\t}\n\n\t\t\ttraverser.markNodeCompleted(\n\t\t\t\tnodeId,\n\t\t\t\tresult,\n\t\t\t\tfinalMatched.map((m: { node: NodeDefinition; edge: any }) => m.node),\n\t\t\t)\n\t\t} else if (executionResult.status === 'failed_with_fallback') {\n\t\t\tconst { fallbackNodeId, error } = executionResult\n\t\t\tconst blueprint = traverser.getDynamicBlueprint()\n\t\t\tconst fallbackNodeDef = blueprint.nodes.find((n) => n.id === fallbackNodeId)\n\n\t\t\tif (!fallbackNodeDef) {\n\t\t\t\tconst notFoundError = new FlowcraftError(`Fallback node '${fallbackNodeId}' not found in blueprint.`, {\n\t\t\t\t\tnodeId,\n\t\t\t\t\tcause: error,\n\t\t\t\t})\n\t\t\t\tstate.addError(nodeId, notFoundError)\n\t\t\t} else {\n\t\t\t\tstate.addCompletedNode(nodeId, null)\n\t\t\t\tstate.markFallbackExecuted()\n\n\t\t\t\ttraverser.markNodeCompleted(nodeId, { action: 'fallback', output: null, _fallbackExecuted: true }, [\n\t\t\t\t\tfallbackNodeDef,\n\t\t\t\t])\n\t\t\t}\n\t\t} else {\n\t\t\tstate.addError(nodeId, executionResult.error)\n\t\t}\n\t}\n}\n"]}