agentfootprint 2.14.5 → 3.0.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 (219) hide show
  1. package/dist/cache/CacheDecisionSubflow.js +3 -1
  2. package/dist/cache/CacheDecisionSubflow.js.map +1 -1
  3. package/dist/conventions.js +3 -2
  4. package/dist/conventions.js.map +1 -1
  5. package/dist/core/Agent.js +69 -23
  6. package/dist/core/Agent.js.map +1 -1
  7. package/dist/core/LLMCall.js +44 -5
  8. package/dist/core/LLMCall.js.map +1 -1
  9. package/dist/core/RunnerBase.js +173 -0
  10. package/dist/core/RunnerBase.js.map +1 -1
  11. package/dist/core/agent/buildAgentChart.js +12 -2
  12. package/dist/core/agent/buildAgentChart.js.map +1 -1
  13. package/dist/core/runner.js +4 -3
  14. package/dist/core/runner.js.map +1 -1
  15. package/dist/core/slots/buildMessagesSlot.js +1 -1
  16. package/dist/core/slots/buildMessagesSlot.js.map +1 -1
  17. package/dist/core/slots/buildSystemPromptSlot.js +1 -1
  18. package/dist/core/slots/buildSystemPromptSlot.js.map +1 -1
  19. package/dist/core/slots/buildThinkingSubflow.js +1 -1
  20. package/dist/core/slots/buildThinkingSubflow.js.map +1 -1
  21. package/dist/core/slots/buildToolsSlot.js +3 -1
  22. package/dist/core/slots/buildToolsSlot.js.map +1 -1
  23. package/dist/core/translator.js +32 -0
  24. package/dist/core/translator.js.map +1 -0
  25. package/dist/core-flow/Conditional.js +72 -10
  26. package/dist/core-flow/Conditional.js.map +1 -1
  27. package/dist/core-flow/Loop.js +59 -16
  28. package/dist/core-flow/Loop.js.map +1 -1
  29. package/dist/core-flow/Parallel.js +239 -92
  30. package/dist/core-flow/Parallel.js.map +1 -1
  31. package/dist/core-flow/Sequence.js +50 -8
  32. package/dist/core-flow/Sequence.js.map +1 -1
  33. package/dist/esm/cache/CacheDecisionSubflow.js +3 -1
  34. package/dist/esm/cache/CacheDecisionSubflow.js.map +1 -1
  35. package/dist/esm/conventions.js +3 -2
  36. package/dist/esm/conventions.js.map +1 -1
  37. package/dist/esm/core/Agent.js +69 -23
  38. package/dist/esm/core/Agent.js.map +1 -1
  39. package/dist/esm/core/LLMCall.js +44 -5
  40. package/dist/esm/core/LLMCall.js.map +1 -1
  41. package/dist/esm/core/RunnerBase.js +173 -0
  42. package/dist/esm/core/RunnerBase.js.map +1 -1
  43. package/dist/esm/core/agent/buildAgentChart.js +12 -2
  44. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  45. package/dist/esm/core/runner.js +4 -3
  46. package/dist/esm/core/runner.js.map +1 -1
  47. package/dist/esm/core/slots/buildMessagesSlot.js +1 -1
  48. package/dist/esm/core/slots/buildMessagesSlot.js.map +1 -1
  49. package/dist/esm/core/slots/buildSystemPromptSlot.js +1 -1
  50. package/dist/esm/core/slots/buildSystemPromptSlot.js.map +1 -1
  51. package/dist/esm/core/slots/buildThinkingSubflow.js +1 -1
  52. package/dist/esm/core/slots/buildThinkingSubflow.js.map +1 -1
  53. package/dist/esm/core/slots/buildToolsSlot.js +3 -1
  54. package/dist/esm/core/slots/buildToolsSlot.js.map +1 -1
  55. package/dist/esm/core/translator.js +31 -0
  56. package/dist/esm/core/translator.js.map +1 -0
  57. package/dist/esm/core-flow/Conditional.js +72 -10
  58. package/dist/esm/core-flow/Conditional.js.map +1 -1
  59. package/dist/esm/core-flow/Loop.js +59 -16
  60. package/dist/esm/core-flow/Loop.js.map +1 -1
  61. package/dist/esm/core-flow/Parallel.js +240 -93
  62. package/dist/esm/core-flow/Parallel.js.map +1 -1
  63. package/dist/esm/core-flow/Sequence.js +50 -8
  64. package/dist/esm/core-flow/Sequence.js.map +1 -1
  65. package/dist/esm/index.js +1 -0
  66. package/dist/esm/index.js.map +1 -1
  67. package/dist/esm/lib/injection-engine/buildInjectionEngineSubflow.js +1 -1
  68. package/dist/esm/lib/injection-engine/buildInjectionEngineSubflow.js.map +1 -1
  69. package/dist/esm/memory/causal/snapshotPipeline.js +6 -2
  70. package/dist/esm/memory/causal/snapshotPipeline.js.map +1 -1
  71. package/dist/esm/memory/pipeline/auto.js +2 -2
  72. package/dist/esm/memory/pipeline/auto.js.map +1 -1
  73. package/dist/esm/memory/pipeline/default.js +4 -2
  74. package/dist/esm/memory/pipeline/default.js.map +1 -1
  75. package/dist/esm/memory/pipeline/ephemeral.js +3 -1
  76. package/dist/esm/memory/pipeline/ephemeral.js.map +1 -1
  77. package/dist/esm/memory/pipeline/fact.js +4 -2
  78. package/dist/esm/memory/pipeline/fact.js.map +1 -1
  79. package/dist/esm/memory/pipeline/narrative.js +4 -2
  80. package/dist/esm/memory/pipeline/narrative.js.map +1 -1
  81. package/dist/esm/memory/pipeline/semantic.js +2 -2
  82. package/dist/esm/memory/pipeline/semantic.js.map +1 -1
  83. package/dist/esm/observe.js +1 -1
  84. package/dist/esm/observe.js.map +1 -1
  85. package/dist/esm/patterns/MapReduce.js +5 -5
  86. package/dist/esm/patterns/MapReduce.js.map +1 -1
  87. package/dist/esm/patterns/Swarm.js +1 -1
  88. package/dist/esm/patterns/Swarm.js.map +1 -1
  89. package/dist/esm/recorders/observability/BoundaryRecorder.js +315 -36
  90. package/dist/esm/recorders/observability/BoundaryRecorder.js.map +1 -1
  91. package/dist/esm/recorders/observability/FlowchartRecorder.js +10 -0
  92. package/dist/esm/recorders/observability/FlowchartRecorder.js.map +1 -1
  93. package/dist/esm/recorders/observability/LiveStateRecorder.js +112 -21
  94. package/dist/esm/recorders/observability/LiveStateRecorder.js.map +1 -1
  95. package/dist/esm/recorders/observability/RunStepRecorder.js +652 -0
  96. package/dist/esm/recorders/observability/RunStepRecorder.js.map +1 -0
  97. package/dist/esm/recorders/observability/internal/ActorArrowClassifier.js +34 -0
  98. package/dist/esm/recorders/observability/internal/ActorArrowClassifier.js.map +1 -0
  99. package/dist/esm/recorders/observability/internal/CandidateAnswerBuffer.js +32 -0
  100. package/dist/esm/recorders/observability/internal/CandidateAnswerBuffer.js.map +1 -0
  101. package/dist/esm/recorders/observability/internal/ForkTracker.js +84 -0
  102. package/dist/esm/recorders/observability/internal/ForkTracker.js.map +1 -0
  103. package/dist/esm/recorders/observability/internal/RootInferrer.js +114 -0
  104. package/dist/esm/recorders/observability/internal/RootInferrer.js.map +1 -0
  105. package/dist/esm/recorders/observability/internal/SequenceSiblingTracker.js +31 -0
  106. package/dist/esm/recorders/observability/internal/SequenceSiblingTracker.js.map +1 -0
  107. package/dist/esm/recorders/observability/observeRunId.js +21 -0
  108. package/dist/esm/recorders/observability/observeRunId.js.map +1 -0
  109. package/dist/esm/reliability/buildReliabilityGateChart.js +1 -1
  110. package/dist/esm/reliability/buildReliabilityGateChart.js.map +1 -1
  111. package/dist/index.js +7 -3
  112. package/dist/index.js.map +1 -1
  113. package/dist/lib/injection-engine/buildInjectionEngineSubflow.js +1 -1
  114. package/dist/lib/injection-engine/buildInjectionEngineSubflow.js.map +1 -1
  115. package/dist/memory/causal/snapshotPipeline.js +6 -2
  116. package/dist/memory/causal/snapshotPipeline.js.map +1 -1
  117. package/dist/memory/pipeline/auto.js +2 -2
  118. package/dist/memory/pipeline/auto.js.map +1 -1
  119. package/dist/memory/pipeline/default.js +4 -2
  120. package/dist/memory/pipeline/default.js.map +1 -1
  121. package/dist/memory/pipeline/ephemeral.js +3 -1
  122. package/dist/memory/pipeline/ephemeral.js.map +1 -1
  123. package/dist/memory/pipeline/fact.js +4 -2
  124. package/dist/memory/pipeline/fact.js.map +1 -1
  125. package/dist/memory/pipeline/narrative.js +4 -2
  126. package/dist/memory/pipeline/narrative.js.map +1 -1
  127. package/dist/memory/pipeline/semantic.js +2 -2
  128. package/dist/memory/pipeline/semantic.js.map +1 -1
  129. package/dist/observe.js +1 -1
  130. package/dist/observe.js.map +1 -1
  131. package/dist/patterns/MapReduce.js +5 -5
  132. package/dist/patterns/MapReduce.js.map +1 -1
  133. package/dist/patterns/Swarm.js +1 -1
  134. package/dist/patterns/Swarm.js.map +1 -1
  135. package/dist/recorders/observability/BoundaryRecorder.js +314 -35
  136. package/dist/recorders/observability/BoundaryRecorder.js.map +1 -1
  137. package/dist/recorders/observability/FlowchartRecorder.js +10 -0
  138. package/dist/recorders/observability/FlowchartRecorder.js.map +1 -1
  139. package/dist/recorders/observability/LiveStateRecorder.js +111 -20
  140. package/dist/recorders/observability/LiveStateRecorder.js.map +1 -1
  141. package/dist/recorders/observability/RunStepRecorder.js +658 -0
  142. package/dist/recorders/observability/RunStepRecorder.js.map +1 -0
  143. package/dist/recorders/observability/internal/ActorArrowClassifier.js +38 -0
  144. package/dist/recorders/observability/internal/ActorArrowClassifier.js.map +1 -0
  145. package/dist/recorders/observability/internal/CandidateAnswerBuffer.js +36 -0
  146. package/dist/recorders/observability/internal/CandidateAnswerBuffer.js.map +1 -0
  147. package/dist/recorders/observability/internal/ForkTracker.js +88 -0
  148. package/dist/recorders/observability/internal/ForkTracker.js.map +1 -0
  149. package/dist/recorders/observability/internal/RootInferrer.js +118 -0
  150. package/dist/recorders/observability/internal/RootInferrer.js.map +1 -0
  151. package/dist/recorders/observability/internal/SequenceSiblingTracker.js +35 -0
  152. package/dist/recorders/observability/internal/SequenceSiblingTracker.js.map +1 -0
  153. package/dist/recorders/observability/observeRunId.js +25 -0
  154. package/dist/recorders/observability/observeRunId.js.map +1 -0
  155. package/dist/reliability/buildReliabilityGateChart.js +1 -1
  156. package/dist/reliability/buildReliabilityGateChart.js.map +1 -1
  157. package/dist/types/cache/CacheDecisionSubflow.d.ts.map +1 -1
  158. package/dist/types/conventions.d.ts.map +1 -1
  159. package/dist/types/core/Agent.d.ts +20 -18
  160. package/dist/types/core/Agent.d.ts.map +1 -1
  161. package/dist/types/core/LLMCall.d.ts +28 -2
  162. package/dist/types/core/LLMCall.d.ts.map +1 -1
  163. package/dist/types/core/RunnerBase.d.ts +124 -4
  164. package/dist/types/core/RunnerBase.d.ts.map +1 -1
  165. package/dist/types/core/agent/buildAgentChart.d.ts +7 -1
  166. package/dist/types/core/agent/buildAgentChart.d.ts.map +1 -1
  167. package/dist/types/core/agent/types.d.ts +29 -0
  168. package/dist/types/core/agent/types.d.ts.map +1 -1
  169. package/dist/types/core/runner.d.ts +51 -5
  170. package/dist/types/core/runner.d.ts.map +1 -1
  171. package/dist/types/core/slots/buildMessagesSlot.d.ts.map +1 -1
  172. package/dist/types/core/slots/buildSystemPromptSlot.d.ts.map +1 -1
  173. package/dist/types/core/slots/buildThinkingSubflow.d.ts.map +1 -1
  174. package/dist/types/core/slots/buildToolsSlot.d.ts.map +1 -1
  175. package/dist/types/core/translator.d.ts +95 -0
  176. package/dist/types/core/translator.d.ts.map +1 -0
  177. package/dist/types/core-flow/Conditional.d.ts +48 -4
  178. package/dist/types/core-flow/Conditional.d.ts.map +1 -1
  179. package/dist/types/core-flow/Loop.d.ts +42 -3
  180. package/dist/types/core-flow/Loop.d.ts.map +1 -1
  181. package/dist/types/core-flow/Parallel.d.ts +99 -4
  182. package/dist/types/core-flow/Parallel.d.ts.map +1 -1
  183. package/dist/types/core-flow/Sequence.d.ts +49 -3
  184. package/dist/types/core-flow/Sequence.d.ts.map +1 -1
  185. package/dist/types/events/payloads.d.ts +15 -1
  186. package/dist/types/events/payloads.d.ts.map +1 -1
  187. package/dist/types/index.d.ts +4 -2
  188. package/dist/types/index.d.ts.map +1 -1
  189. package/dist/types/lib/injection-engine/buildInjectionEngineSubflow.d.ts.map +1 -1
  190. package/dist/types/memory/causal/snapshotPipeline.d.ts.map +1 -1
  191. package/dist/types/memory/pipeline/auto.d.ts.map +1 -1
  192. package/dist/types/memory/pipeline/default.d.ts.map +1 -1
  193. package/dist/types/memory/pipeline/ephemeral.d.ts.map +1 -1
  194. package/dist/types/memory/pipeline/fact.d.ts.map +1 -1
  195. package/dist/types/memory/pipeline/narrative.d.ts.map +1 -1
  196. package/dist/types/memory/pipeline/semantic.d.ts.map +1 -1
  197. package/dist/types/observe.d.ts +2 -2
  198. package/dist/types/observe.d.ts.map +1 -1
  199. package/dist/types/recorders/observability/BoundaryRecorder.d.ts +160 -6
  200. package/dist/types/recorders/observability/BoundaryRecorder.d.ts.map +1 -1
  201. package/dist/types/recorders/observability/FlowchartRecorder.d.ts.map +1 -1
  202. package/dist/types/recorders/observability/LiveStateRecorder.d.ts +42 -6
  203. package/dist/types/recorders/observability/LiveStateRecorder.d.ts.map +1 -1
  204. package/dist/types/recorders/observability/RunStepRecorder.d.ts +232 -0
  205. package/dist/types/recorders/observability/RunStepRecorder.d.ts.map +1 -0
  206. package/dist/types/recorders/observability/internal/ActorArrowClassifier.d.ts +26 -0
  207. package/dist/types/recorders/observability/internal/ActorArrowClassifier.d.ts.map +1 -0
  208. package/dist/types/recorders/observability/internal/CandidateAnswerBuffer.d.ts +29 -0
  209. package/dist/types/recorders/observability/internal/CandidateAnswerBuffer.d.ts.map +1 -0
  210. package/dist/types/recorders/observability/internal/ForkTracker.d.ts +61 -0
  211. package/dist/types/recorders/observability/internal/ForkTracker.d.ts.map +1 -0
  212. package/dist/types/recorders/observability/internal/RootInferrer.d.ts +52 -0
  213. package/dist/types/recorders/observability/internal/RootInferrer.d.ts.map +1 -0
  214. package/dist/types/recorders/observability/internal/SequenceSiblingTracker.d.ts +25 -0
  215. package/dist/types/recorders/observability/internal/SequenceSiblingTracker.d.ts.map +1 -0
  216. package/dist/types/recorders/observability/observeRunId.d.ts +37 -0
  217. package/dist/types/recorders/observability/observeRunId.d.ts.map +1 -0
  218. package/dist/types/reliability/buildReliabilityGateChart.d.ts.map +1 -1
  219. package/package.json +3 -3
@@ -30,6 +30,10 @@ export class Loop extends RunnerBase {
30
30
  maxIterations;
31
31
  maxWallclockMs;
32
32
  until;
33
+ opts;
34
+ /** Per-method translator override on `.repeat()`, when set. Applies
35
+ * to the body member's `uiGroup`. */
36
+ bodyTranslator;
33
37
  currentRunContext = {
34
38
  runStartMs: 0,
35
39
  runId: 'pending',
@@ -37,21 +41,55 @@ export class Loop extends RunnerBase {
37
41
  };
38
42
  constructor(opts, body, config) {
39
43
  super();
44
+ this.opts = opts;
40
45
  this.name = opts.name ?? 'Loop';
41
46
  this.id = opts.id ?? 'loop';
42
47
  this.body = body;
43
48
  this.maxIterations = clampIterations(config.maxIterations);
44
49
  this.maxWallclockMs = config.maxWallclockMs;
45
50
  this.until = config.until;
51
+ this.bodyTranslator = config.bodyTranslator;
52
+ // Eager chart construction — see `RunnerBase.initChart` JSDoc.
53
+ this.initChart(() => this.buildChart());
46
54
  }
47
55
  static create(opts = {}) {
48
56
  return new LoopBuilder(opts);
49
57
  }
50
- toFlowChart() {
51
- return this.buildChart();
58
+ // `getSpec()` inherited from RunnerBase — returns the cached chart.
59
+ // ─── UI group translation (L1b) ───────────────────────────────
60
+ getGroupTranslator() {
61
+ return this.opts.groupTranslator;
62
+ }
63
+ /** Loop has a single body member + iteration budgets in `extra`.
64
+ * Per-method override (L1c) takes precedence over the body
65
+ * runner's own translator. */
66
+ buildUIGroupMetadata() {
67
+ const members = [
68
+ {
69
+ memberId: 'body',
70
+ runner: this.body,
71
+ uiGroup: this.bodyTranslator !== undefined
72
+ ? this.body.getUIGroupWith(this.bodyTranslator)
73
+ : this.body.getUIGroup(),
74
+ },
75
+ ];
76
+ return {
77
+ kind: 'Loop',
78
+ id: this.id,
79
+ name: this.name,
80
+ members,
81
+ extra: {
82
+ maxIterations: this.maxIterations,
83
+ ...(this.maxWallclockMs !== undefined && {
84
+ maxWallclockMs: this.maxWallclockMs,
85
+ }),
86
+ hasUntilGuard: this.until !== undefined,
87
+ },
88
+ };
52
89
  }
53
90
  async run(input, options) {
54
91
  const executor = this.createExecutor();
92
+ this.lastExecutor = executor;
55
93
  const result = await executor.run({
56
94
  input: { message: input.message },
57
95
  ...(options ?? {}),
@@ -70,8 +108,8 @@ export class Loop extends RunnerBase {
70
108
  runId: makeRunId(),
71
109
  compositionPath: [`Loop:${this.id}`],
72
110
  };
73
- const chart = this.buildChart();
74
- const executor = new FlowChartExecutor(chart);
111
+ // Reuse the cached chart built at constructor time.
112
+ const executor = new FlowChartExecutor(this.getSpec());
75
113
  const dispatcher = this.getDispatcher();
76
114
  const getRunCtx = () => this.currentRunContext;
77
115
  executor.attachCombinedRecorder(new ContextRecorder({ dispatcher, getRunContext: getRunCtx }));
@@ -171,9 +209,14 @@ export class Loop extends RunnerBase {
171
209
  };
172
210
  // Root description prefix `Loop:` is the taxonomy marker — see
173
211
  // FlowchartRecorder.mapTopologyToSteps for the consumer side.
174
- return flowChart('Seed', seed, 'seed', undefined, 'Loop: iterated body')
212
+ return flowChart('Seed', seed, 'seed', {
213
+ ...(this.opts.structureRecorders !== undefined && {
214
+ structureRecorders: [...this.opts.structureRecorders],
215
+ }),
216
+ description: 'Loop: iterated body',
217
+ })
175
218
  .addFunction('IterationStart', iterationStart, 'iteration-start', 'Loop iteration marker')
176
- .addSubFlowChartNext('body', body.toFlowChart(), 'body', {
219
+ .addSubFlowChartNext('body', body.getSpec(), 'body', {
177
220
  inputMapper: (parent) => ({ message: parent.current ?? '' }),
178
221
  // Body's string return becomes next iteration's input via `current`.
179
222
  outputMapper: (sfOutput) => ({
@@ -185,18 +228,10 @@ export class Loop extends RunnerBase {
185
228
  .build();
186
229
  }
187
230
  }
188
- /**
189
- * Fluent builder. Reads as natural English:
190
- * Loop.create().repeat(runner).times(10).forAtMost(30_000).until(fn).build()
191
- * → "Loop: repeat runner, up to 10 times, for at most 30 seconds, until fn."
192
- *
193
- * Enforces a body runner is supplied before .build(). Default budget is
194
- * 10 iterations (hard ceiling 500). Any of .times / .forAtMost / .until
195
- * can fire to exit the loop.
196
- */
197
231
  export class LoopBuilder {
198
232
  opts;
199
233
  _body;
234
+ _bodyTranslator;
200
235
  _maxIterations;
201
236
  _maxWallclockMs;
202
237
  _until;
@@ -206,12 +241,19 @@ export class LoopBuilder {
206
241
  /**
207
242
  * The runner that executes each iteration. Required.
208
243
  * Each iteration's output string becomes the next iteration's input `{ message }`.
244
+ *
245
+ * Optional second arg `opts.groupTranslator` overrides the body
246
+ * runner's own translator for THIS loop only — only its
247
+ * `member.uiGroup` flips to the override's output.
209
248
  */
210
- repeat(runner) {
249
+ repeat(runner, opts) {
211
250
  if (this._body !== undefined) {
212
251
  throw new Error('Loop.repeat(): already set');
213
252
  }
214
253
  this._body = runner;
254
+ if (opts?.groupTranslator !== undefined) {
255
+ this._bodyTranslator = opts.groupTranslator;
256
+ }
215
257
  return this;
216
258
  }
217
259
  /**
@@ -247,6 +289,7 @@ export class LoopBuilder {
247
289
  maxIterations,
248
290
  ...(this._maxWallclockMs !== undefined && { maxWallclockMs: this._maxWallclockMs }),
249
291
  ...(this._until !== undefined && { until: this._until }),
292
+ ...(this._bodyTranslator !== undefined && { bodyTranslator: this._bodyTranslator }),
250
293
  });
251
294
  }
252
295
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Loop.js","sourceRoot":"","sources":["../../../src/core-flow/Loop.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Loop.js","sourceRoot":"","sources":["../../../src/core-flow/Loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EACL,iBAAiB,EACjB,SAAS,GAMV,MAAM,aAAa,CAAC;AAIrB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAsC3D,MAAM,kBAAkB,GAAG,GAAG,CAAC;AAM/B,MAAM,OAAO,IAAK,SAAQ,UAAiC;IAChD,IAAI,CAAS;IACb,EAAE,CAAS;IACH,IAAI,CAAY;IAChB,aAAa,CAAS;IACtB,cAAc,CAAqB;IACnC,KAAK,CAAyB;IAC9B,IAAI,CAAc;IACnC;0CACsC;IACrB,cAAc,CAA8B;IAErD,iBAAiB,GAAe;QACtC,UAAU,EAAE,CAAC;QACb,KAAK,EAAE,SAAS;QAChB,eAAe,EAAE,EAAE;KACpB,CAAC;IAEF,YACE,IAAiB,EACjB,IAAe,EACf,MAKC;QAED,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC;QAChC,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,IAAI,MAAM,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAC3D,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC5C,+DAA+D;QAC/D,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,OAAoB,EAAE;QAClC,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,oEAAoE;IAEpE,iEAAiE;IAC9C,kBAAkB;QACnC,OAAO,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC;IACnC,CAAC;IAED;;mCAE+B;IACZ,oBAAoB;QACrC,MAAM,OAAO,GAAkB;YAC7B;gBACE,QAAQ,EAAE,MAAM;gBAChB,MAAM,EAAE,IAAI,CAAC,IAAI;gBACjB,OAAO,EACL,IAAI,CAAC,cAAc,KAAK,SAAS;oBAC/B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,cAAc,CAAC;oBAC/C,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;aAC7B;SACF,CAAC;QACF,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO;YACP,KAAK,EAAE;gBACL,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,GAAG,CAAC,IAAI,CAAC,cAAc,KAAK,SAAS,IAAI;oBACvC,cAAc,EAAE,IAAI,CAAC,cAAc;iBACpC,CAAC;gBACF,aAAa,EAAE,IAAI,CAAC,KAAK,KAAK,SAAS;aACxC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAgB,EAAE,OAAoB;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACvC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC;YAChC,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE;YACjC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;SACnB,CAAC,CAAC;QACH,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,MAAM,CACV,UAA+B,EAC/B,KAAe,EACf,OAAoB;QAEpB,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAEO,cAAc;QACpB,IAAI,CAAC,iBAAiB,GAAG;YACvB,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE;YACtB,KAAK,EAAE,SAAS,EAAE;YAClB,eAAe,EAAE,CAAC,QAAQ,IAAI,CAAC,EAAE,EAAE,CAAC;SACrC,CAAC;QAEF,oDAAoD;QACpD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAEvD,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACxC,MAAM,SAAS,GAAG,GAAe,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC;QAE3D,QAAQ,CAAC,sBAAsB,CAAC,IAAI,eAAe,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC/F,QAAQ,CAAC,sBAAsB,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC1F,QAAQ,CAAC,sBAAsB,CAAC,aAAa,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QACzF,QAAQ,CAAC,sBAAsB,CAAC,mBAAmB,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;QAC/F,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,iBAAiB;YAAE,QAAQ,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,cAAc,CACpB,QAA2B,EAC3B,MAAe;QAEf,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,IAAI,MAAM,YAAY,KAAK;YAAE,MAAM,MAAM,CAAC;QAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAEO,UAAU;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACzC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,MAAM,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC;QAElC,MAAM,IAAI,GAAG,CAAC,KAA4B,EAAE,EAAE;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAa,CAAC;YACzC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC7B,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;YACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC3B,SAAS,CAAC,KAAK,EAAE,kCAAkC,EAAE;gBACnD,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,aAAa;gBACjB,IAAI,EAAE,eAAe;gBACrB,UAAU,EAAE,CAAC;aACd,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,cAAc,GAAG,CAAC,KAA4B,EAAE,EAAE;YACtD,MAAM,IAAI,GAAG,CAAE,KAAK,CAAC,SAAoB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACpD,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC;YACvB,SAAS,CAAC,KAAK,EAAE,4CAA4C,EAAE;gBAC7D,MAAM,EAAE,aAAa;gBACrB,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC;QACL,CAAC,CAAC;QAEF;;;;WAIG;QACH,MAAM,KAAK,GAAG,CAAC,KAA4B,EAAE,EAAE;YAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,SAAmB,CAAC;YAC5C,MAAM,YAAY,GAAI,KAAK,CAAC,OAAkB,IAAI,EAAE,CAAC;YACrD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAiB,CAAC;YAExC,IAAI,UAA4E,CAAC;YAEjF,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;gBAC/B,UAAU,GAAG,QAAQ,CAAC;YACxB,CAAC;iBAAM,IAAI,cAAc,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,cAAc,EAAE,CAAC;gBAClF,UAAU,GAAG,QAAQ,CAAC;YACxB,CAAC;iBAAM,IAAI,SAAS,IAAI,kBAAkB,EAAE,CAAC;gBAC3C,UAAU,GAAG,QAAQ,CAAC;YACxB,CAAC;iBAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC9E,UAAU,GAAG,aAAa,CAAC;YAC7B,CAAC;YAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,SAAS,CAAC,KAAK,EAAE,2CAA2C,EAAE;oBAC5D,MAAM,EAAE,aAAa;oBACrB,SAAS;oBACT,MAAM,EAAE,UAAU;iBACnB,CAAC,CAAC;gBACH,SAAS,CAAC,KAAK,EAAE,iCAAiC,EAAE;oBAClD,IAAI,EAAE,MAAM;oBACZ,EAAE,EAAE,aAAa;oBACjB,IAAI,EAAE,eAAe;oBACrB,MAAM,EAAE,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI;oBAC3D,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU;iBAC3D,CAAC,CAAC;gBACH,+DAA+D;gBAC/D,wDAAwD;gBACxD,KAAK,CAAC,MAAM,EAAE,CAAC;gBACf,OAAO,YAAY,CAAC;YACtB,CAAC;YAED,qEAAqE;YACrE,mEAAmE;YACnE,+BAA+B;YAC/B,SAAS,CAAC,KAAK,EAAE,2CAA2C,EAAE;gBAC5D,MAAM,EAAE,aAAa;gBACrB,SAAS;gBACT,MAAM,EAAE,eAAe;aACxB,CAAC,CAAC;YACH,OAAO,YAAY,CAAC;QACtB,CAAC,CAAC;QAEF,+DAA+D;QAC/D,8DAA8D;QAC9D,OAAO,SAAS,CAAY,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE;YAChD,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,KAAK,SAAS,IAAI;gBAChD,kBAAkB,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC;aACtD,CAAC;YACF,WAAW,EAAE,qBAAqB;SACnC,CAAC;aACC,WAAW,CAAC,gBAAgB,EAAE,cAAc,EAAE,iBAAiB,EAAE,uBAAuB,CAAC;aACzF,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE;YACnD,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAG,MAAM,CAAC,OAAkB,IAAI,EAAE,EAAE,CAAC;YACxE,qEAAqE;YACrE,YAAY,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC3B,OAAO,EAAE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;aACtD,CAAC;SACH,CAAC;aACD,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,2BAA2B,CAAC;aACjE,MAAM,CAAC,iBAAiB,CAAC;aACzB,KAAK,EAAE,CAAC;IACb,CAAC;CACF;AAoBD,MAAM,OAAO,WAAW;IACL,IAAI,CAAc;IAC3B,KAAK,CAAwB;IAC7B,eAAe,CAA8B;IAC7C,cAAc,CAAqB;IACnC,eAAe,CAAqB;IACpC,MAAM,CAAyB;IAEvC,YAAY,IAAiB;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,MAAiB,EAAE,IAAwB;QAChD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QACpB,IAAI,IAAI,EAAE,eAAe,KAAK,SAAS,EAAE,CAAC;YACxC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,CAAS;QACb,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,EAAU;QAClB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAiB;QACrB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,IAAI,EAAE,CAAC;QAChD,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE;YACrC,aAAa;YACb,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YACnF,GAAG,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACxD,GAAG,CAAC,IAAI,CAAC,eAAe,KAAK,SAAS,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;SACpF,CAAC,CAAC;IACL,CAAC;CACF;AAED,SAAS,eAAe,CAAC,CAAS;IAChC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACnE,IAAI,CAAC,GAAG,kBAAkB;QAAE,OAAO,kBAAkB,CAAC;IACtD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -10,7 +10,7 @@
10
10
  * composition.fork_start / branch_complete / merge_end
11
11
  * (via compositionRecorder).
12
12
  */
13
- import { FlowChartExecutor, flowChart, } from 'footprintjs';
13
+ import { FlowChartExecutor, flowChart, isFlowEvent, } from 'footprintjs';
14
14
  import { RunnerBase, makeRunId } from '../core/RunnerBase.js';
15
15
  import { ContextRecorder } from '../recorders/core/ContextRecorder.js';
16
16
  import { streamRecorder } from '../recorders/core/StreamRecorder.js';
@@ -22,13 +22,29 @@ export class Parallel extends RunnerBase {
22
22
  id;
23
23
  branches;
24
24
  merge;
25
+ opts;
25
26
  currentRunContext = {
26
27
  runStartMs: 0,
27
28
  runId: 'pending',
28
29
  compositionPath: [],
29
30
  };
31
+ /**
32
+ * Per-branch first-error messages captured during the current run.
33
+ *
34
+ * Filled by an internal CombinedRecorder attached in `createExecutor()`
35
+ * that observes footprintjs `FlowErrorEvent`s. Errors are keyed by the
36
+ * branch id (the first segment of `traversalContext.subflowPath`); only
37
+ * the first error per branch is kept so the surface mirrors the wrapper
38
+ * `try/catch` semantics that preceded the v0.x architectural refactor.
39
+ *
40
+ * Read by the Merge stage to populate strict-mode error messages and
41
+ * tolerant-mode `BranchOutcome.error` strings. Cleared at the start of
42
+ * every `run()` / `resume()`.
43
+ */
44
+ branchErrors = new Map();
30
45
  constructor(opts, branches, merge) {
31
46
  super();
47
+ this.opts = opts;
32
48
  this.name = opts.name ?? 'Parallel';
33
49
  this.id = opts.id ?? 'parallel';
34
50
  if (branches.length < 2) {
@@ -36,15 +52,53 @@ export class Parallel extends RunnerBase {
36
52
  }
37
53
  this.branches = branches;
38
54
  this.merge = merge;
55
+ // Eager chart construction — see `RunnerBase.initChart` JSDoc.
56
+ // Safe: the merge stage's closure captures `this.branchErrors`
57
+ // (an instance field initialized at declaration time, line 130),
58
+ // which is set BEFORE the constructor body runs.
59
+ this.initChart(() => this.buildChart());
39
60
  }
40
61
  static create(opts = {}) {
41
62
  return new ParallelBuilder(opts);
42
63
  }
43
- toFlowChart() {
44
- return this.buildChart();
64
+ // `getSpec()` inherited from RunnerBase — returns the cached chart.
65
+ // ─── UI group translation (L1b) ───────────────────────────────
66
+ getGroupTranslator() {
67
+ return this.opts.groupTranslator;
68
+ }
69
+ /**
70
+ * Build the Parallel's `GroupMetadata` — kind `'Parallel'`, with one
71
+ * `GroupMember` per branch. Each member exposes its `runner` plus
72
+ * the runner's own `getUIGroup()` output (when the consumer
73
+ * threaded the same translator through that branch's construction).
74
+ */
75
+ buildUIGroupMetadata() {
76
+ const members = this.branches.map((b) => ({
77
+ memberId: b.id,
78
+ runner: b.runner,
79
+ // Per-method override (L1c) takes precedence over the branch
80
+ // runner's own constructor-level translator. When present, the
81
+ // override runs against the branch runner's own GroupMetadata
82
+ // and its output becomes `member.uiGroup`. When absent, fall
83
+ // back to `branch.runner.getUIGroup()` which applies the
84
+ // runner's own translator (if any).
85
+ uiGroup: b.groupTranslator !== undefined
86
+ ? b.runner.getUIGroupWith(b.groupTranslator)
87
+ : b.runner.getUIGroup(),
88
+ }));
89
+ return {
90
+ kind: 'Parallel',
91
+ id: this.id,
92
+ name: this.name,
93
+ members,
94
+ extra: {
95
+ mergeStrategy: this.merge.kind,
96
+ },
97
+ };
45
98
  }
46
99
  async run(input, options) {
47
100
  const executor = this.createExecutor();
101
+ this.lastExecutor = executor;
48
102
  const result = await executor.run({
49
103
  input: { message: input.message },
50
104
  ...(options ?? {}),
@@ -63,18 +117,71 @@ export class Parallel extends RunnerBase {
63
117
  runId: makeRunId(),
64
118
  compositionPath: [`Parallel:${this.id}`],
65
119
  };
66
- const chart = this.buildChart();
67
- const executor = new FlowChartExecutor(chart);
120
+ // Reset per-run branch-error capture. Fork children now mount the
121
+ // branch runner's own chart (no try/catch wrapper); errors are
122
+ // captured via FlowRecorder.onError correlation by subflow path.
123
+ this.branchErrors.clear();
124
+ // Reuse the cached chart built at constructor time.
125
+ const executor = new FlowChartExecutor(this.getSpec());
68
126
  const dispatcher = this.getDispatcher();
69
127
  const getRunCtx = () => this.currentRunContext;
70
128
  executor.attachCombinedRecorder(new ContextRecorder({ dispatcher, getRunContext: getRunCtx }));
71
129
  executor.attachCombinedRecorder(streamRecorder({ dispatcher, getRunContext: getRunCtx }));
72
130
  executor.attachCombinedRecorder(agentRecorder({ dispatcher, getRunContext: getRunCtx }));
73
131
  executor.attachCombinedRecorder(compositionRecorder({ dispatcher, getRunContext: getRunCtx }));
132
+ executor.attachCombinedRecorder(this.makeBranchErrorRecorder());
74
133
  for (const r of this.attachedRecorders)
75
134
  executor.attachCombinedRecorder(r);
76
135
  return executor;
77
136
  }
137
+ /**
138
+ * Build the internal recorder that captures first-error-per-branch.
139
+ *
140
+ * footprintjs's `SubflowExecutor` swallows subflow errors into
141
+ * `parentContext.debug.addError(...)` and skips the `outputMapper`,
142
+ * so the failed branch's error message never lands in parent scope.
143
+ * To preserve the per-branch error surface the wrapper-based design
144
+ * provided, we observe `FlowRecorder.onError` and correlate by the
145
+ * first segment of `traversalContext.subflowPath`.
146
+ *
147
+ * Only the FIRST error per branch is kept. Errors fired outside any
148
+ * branch (e.g., a Merge-stage error) are ignored.
149
+ */
150
+ makeBranchErrorRecorder() {
151
+ const branchIds = new Set(this.branches.map((b) => b.id));
152
+ return {
153
+ id: 'parallel-branch-errors',
154
+ onError: (event) => {
155
+ if (!isFlowEvent(event))
156
+ return;
157
+ const ctx = event.traversalContext;
158
+ if (!ctx)
159
+ return;
160
+ // The branch id is the first segment of the engine-prefixed
161
+ // `stageId` (e.g. `bad/call-llm` → branch `bad`). `subflowPath`
162
+ // is sometimes empty for first-level subflows, and `subflowId`
163
+ // can be deeper than the branch when LLMCall/Agent mount their
164
+ // own internal subflows. The stageId prefix is the canonical
165
+ // origin path.
166
+ const stageId = ctx.stageId ?? '';
167
+ const slash = stageId.indexOf('/');
168
+ const branchId = slash >= 0 ? stageId.slice(0, slash) : undefined;
169
+ if (branchId === undefined || !branchIds.has(branchId))
170
+ return;
171
+ if (!this.branchErrors.has(branchId)) {
172
+ // Strip the leading "Error: " that `error.toString()` adds
173
+ // for standard `Error` instances so the captured message
174
+ // matches the original `throw new Error(msg)` reason exactly
175
+ // (consumers expect the bare message). Non-Error throws
176
+ // never carry this prefix, so the strip is a no-op there.
177
+ const m = event.message.startsWith('Error: ')
178
+ ? event.message.slice('Error: '.length)
179
+ : event.message;
180
+ this.branchErrors.set(branchId, m);
181
+ }
182
+ },
183
+ };
184
+ }
78
185
  finalizeResult(executor, result) {
79
186
  const paused = this.detectPause(executor, result);
80
187
  if (paused)
@@ -107,36 +214,67 @@ export class Parallel extends RunnerBase {
107
214
  };
108
215
  // Root description prefix `Parallel:` is the taxonomy marker — see
109
216
  // FlowchartRecorder.mapTopologyToSteps for the consumer side.
110
- let builder = flowChart('Seed', seed, 'seed', undefined, `Parallel: ${branches.length}-way fanout`);
111
- // Fork children each branch is wrapped in a chart that runs the
112
- // branch runner in try/catch. The wrapper always succeeds (no error
113
- // propagates up), so the outputMapper always fires and records a
114
- // typed `BranchOutcome` for the Merge stage to inspect.
217
+ // The 4th arg threads the consumer's `structureRecorders` (when set)
218
+ // into footprintjs's builder so every node in this chart is observed
219
+ // by them at construction time.
220
+ let builder = flowChart('Seed', seed, 'seed', {
221
+ ...(this.opts.structureRecorders !== undefined && {
222
+ structureRecorders: [...this.opts.structureRecorders],
223
+ }),
224
+ description: `Parallel: ${branches.length}-way fanout`,
225
+ });
226
+ // Fork children — each branch is mounted as a proper subflow via
227
+ // footprintjs's native fork mode. Multiple `addSubFlowChart` calls
228
+ // on the same builder cursor produce a fork node (`type: 'fork'`);
229
+ // `ChildrenExecutor` runs them concurrently via `Promise.allSettled`.
115
230
  //
116
- // Strict mode (default): Merge throws on any branch failure. Tolerant
117
- // mode: Merge passes the full outcomes map to the consumer's merge fn.
231
+ // The branch's OWN chart (its `getSpec()`) is mounted directly no
232
+ // wrapper. This preserves the parent's `runtimeStageId` address
233
+ // space across branch internals: every LLM call, tool execution,
234
+ // and commit inside a branch appears in the parent executor's
235
+ // commitLog with a globally-unique id. Recorder events flow
236
+ // naturally — no `scope.$emit` forwarding needed.
237
+ //
238
+ // Error handling: a failing branch's `outputMapper` does NOT fire
239
+ // (footprintjs convention: `subflowError` skips output mapping).
240
+ // The branch id is absent from `branchResults`. The merge stage
241
+ // detects this via `branches.map(b => b.id) \ keys(branchResults)`
242
+ // and either throws (strict mode) or synthesizes `BranchOutcome`
243
+ // entries for the tolerant `outcomes-fn` merge.
118
244
  for (const branch of branches) {
119
- builder = builder.addSubFlowChart(branch.id, buildBranchWrapperChart(branch), branch.name, {
245
+ builder = builder.addSubFlowChart(branch.id, branch.runner.getSpec(), branch.name, {
120
246
  inputMapper: (parent) => ({ message: parent.userMessage ?? '' }),
121
- // The wrapper's terminal stage returns a BranchOutcome. Stash it
122
- // under the branch id; shallow-merge across siblings produces
123
- // the full outcomes map.
124
247
  outputMapper: (sfOutput) => ({
125
- branchOutcomes: {
126
- [branch.id]: sfOutput,
248
+ branchResults: {
249
+ [branch.id]: typeof sfOutput === 'string' ? sfOutput : '',
127
250
  },
128
251
  }),
129
252
  });
130
253
  }
131
254
  // Merge stage — runs after all fork children complete (join point).
255
+ // Closes over `this.branchErrors` (populated by the internal
256
+ // `parallel-branch-errors` recorder) so per-branch error messages
257
+ // survive subflow boundary swallowing in footprintjs.
258
+ const branchErrors = this.branchErrors;
132
259
  const mergeStage = async (scope) => {
133
- const outcomes = scope.branchOutcomes ?? {};
134
- const failures = Object.entries(outcomes).filter(([, o]) => !o.ok);
260
+ const results = scope.branchResults ?? {};
261
+ // Detect failures by absence: any expected branch id missing
262
+ // from `branchResults` is a branch whose `outputMapper` didn't
263
+ // fire — i.e., one whose subflow errored. The specific error
264
+ // message comes from the recorder-captured `branchErrors` map.
265
+ //
266
+ // Caveat: footprintjs does NOT fire `FlowRecorder.onError` for
267
+ // errors thrown INSIDE `applyOutputMapping` (those are caught
268
+ // separately in `SubflowExecutor` and routed to
269
+ // `parentContext.addError('outputMapperError', ...)`). A branch
270
+ // whose subflow completed cleanly but whose outputMapper threw
271
+ // will therefore show up here as a missing id with no entry in
272
+ // `branchErrors` — strict-mode aggregation prints `unknown
273
+ // error` for it and tolerant-mode synthesizes the same string.
274
+ // This is a known gap; see `core-flow/README.md` Decision 8.
275
+ const failedIds = branches.map((b) => b.id).filter((id) => !(id in results));
135
276
  const isTolerant = merge.kind === 'outcomes-fn';
136
- if (failures.length > 0 && !isTolerant) {
137
- const details = failures
138
- .map(([id, o]) => ` ${id}: ${o.error}`)
139
- .join('\n');
277
+ if (failedIds.length > 0 && !isTolerant) {
140
278
  typedEmit(scope, 'agentfootprint.composition.exit', {
141
279
  kind: 'Parallel',
142
280
  id: compositionId,
@@ -144,34 +282,64 @@ export class Parallel extends RunnerBase {
144
282
  status: 'err',
145
283
  durationMs: Date.now() - this.currentRunContext.runStartMs,
146
284
  });
147
- throw new Error(`Parallel '${compositionId}': ${failures.length} branch(es) failed:\n${details}\n` +
285
+ const details = failedIds
286
+ .map((id) => ` ${id}: ${branchErrors.get(id) ?? 'unknown error'}`)
287
+ .join('\n');
288
+ throw new Error(`Parallel '${compositionId}': ${failedIds.length} branch(es) failed:\n${details}\n` +
148
289
  `(use .mergeOutcomesWithFn() for tolerant-mode partial-failure handling)`);
149
290
  }
291
+ // Run the merge strategy. Wrap in try/catch so that a merge-stage
292
+ // failure (e.g., merge LLM throws) still produces a
293
+ // `composition.exit` event with `status: 'err'` — without this the
294
+ // event stream would have a `composition.enter` without a matching
295
+ // `composition.exit`, breaking dashboards that pair the two.
150
296
  let merged;
151
- if (merge.kind === 'fn') {
152
- const results = {};
153
- for (const [id, o] of Object.entries(outcomes)) {
154
- if (o.ok)
155
- results[id] = o.value;
297
+ try {
298
+ if (merge.kind === 'fn') {
299
+ merged = merge.fn(results);
156
300
  }
157
- merged = merge.fn(results);
158
- }
159
- else if (merge.kind === 'llm') {
160
- const results = {};
161
- for (const [id, o] of Object.entries(outcomes)) {
162
- if (o.ok)
163
- results[id] = o.value;
301
+ else if (merge.kind === 'llm') {
302
+ merged = await mergeWithLLM(scope, merge.opts, results);
303
+ }
304
+ else {
305
+ // Tolerant-mode: synthesize BranchOutcome map for the consumer.
306
+ const outcomes = {};
307
+ for (const b of branches) {
308
+ if (b.id in results) {
309
+ outcomes[b.id] = { ok: true, value: results[b.id] };
310
+ }
311
+ else {
312
+ outcomes[b.id] = {
313
+ ok: false,
314
+ error: branchErrors.get(b.id) ?? 'unknown error',
315
+ };
316
+ }
317
+ }
318
+ merged = merge.fn(outcomes);
164
319
  }
165
- merged = await mergeWithLLM(scope, merge.opts, results);
166
320
  }
167
- else {
168
- merged = merge.fn(outcomes);
321
+ catch (err) {
322
+ typedEmit(scope, 'agentfootprint.composition.exit', {
323
+ kind: 'Parallel',
324
+ id: compositionId,
325
+ name: compositionName,
326
+ status: 'err',
327
+ durationMs: Date.now() - this.currentRunContext.runStartMs,
328
+ });
329
+ throw err;
169
330
  }
331
+ const succeededCount = Object.keys(results).length;
170
332
  typedEmit(scope, 'agentfootprint.composition.merge_end', {
171
333
  parentId: compositionId,
172
- strategy: merge.kind === 'outcomes-fn' ? 'fn' : merge.kind,
334
+ // Emit the merge.kind verbatim so consumers can distinguish
335
+ // tolerant (`outcomes-fn`) from strict (`fn` / `llm`).
336
+ strategy: merge.kind,
173
337
  resultSummary: truncate(merged, 80),
174
- mergedBranchCount: branches.length,
338
+ // Number of branches that actually contributed a result to the
339
+ // merge. Equals `totalBranchCount` on full success; smaller in
340
+ // tolerant-mode runs where some branches failed.
341
+ mergedBranchCount: succeededCount,
342
+ totalBranchCount: branches.length,
175
343
  });
176
344
  typedEmit(scope, 'agentfootprint.composition.exit', {
177
345
  kind: 'Parallel',
@@ -186,54 +354,6 @@ export class Parallel extends RunnerBase {
186
354
  return builder.build();
187
355
  }
188
356
  }
189
- /**
190
- * Build a wrapper chart that runs a branch Runner in a try/catch and
191
- * emits its events to the Parallel's dispatcher. The chart's terminal
192
- * stage returns a `BranchOutcome` — never throws up to the traverser.
193
- *
194
- * Event forwarding: the branch runner has its own EventDispatcher. We
195
- * subscribe to the wildcard `'*'` during run() and re-dispatch each
196
- * event on Parallel's dispatcher so consumers who attach listeners at
197
- * the Parallel level see the branch's llm/context/agent events.
198
- */
199
- function buildBranchWrapperChart(branch) {
200
- const runBranch = async (scope) => {
201
- const args = scope.$getArgs();
202
- // Forward every branch-runner event via `scope.$emit` so it flows
203
- // through footprintjs's emit channel. That channel reaches every
204
- // EmitBridge attached to the CURRENT executor — including bridges
205
- // belonging to outer compositions when this Parallel is nested
206
- // (e.g., `Loop(Parallel(...))`). Forwarding directly to the
207
- // Parallel's own dispatcher would be invisible to outer layers.
208
- const unsubscribe = branch.runner.on('*', (e) => {
209
- // `e.payload` is the typed payload union for the specific event;
210
- // $emit accepts `unknown`, so no cast is needed — let it pass
211
- // through structurally.
212
- scope.$emit(e.type, e.payload);
213
- });
214
- try {
215
- const result = await branch.runner.run({ message: args.message ?? '' });
216
- if (typeof result === 'string') {
217
- return { ok: true, value: result };
218
- }
219
- // Paused outcome: surface as "ok" with empty value — pauses from
220
- // nested runners aren't failures, but Parallel doesn't yet propagate
221
- // them through the merge. Consumers who need pause-inside-Parallel
222
- // should set up nested pause handling at their own layer.
223
- return { ok: true, value: '' };
224
- }
225
- catch (err) {
226
- return {
227
- ok: false,
228
- error: err instanceof Error ? err.message : String(err),
229
- };
230
- }
231
- finally {
232
- unsubscribe();
233
- }
234
- };
235
- return flowChart('RunBranch', runBranch, 'run-branch', undefined, `Parallel branch '${branch.id}' — catches failures`).build();
236
- }
237
357
  /** Fluent builder. Requires at least 2 branches + one merge strategy. */
238
358
  export class ParallelBuilder {
239
359
  opts;
@@ -243,13 +363,40 @@ export class ParallelBuilder {
243
363
  constructor(opts) {
244
364
  this.opts = opts;
245
365
  }
246
- /** Add a branch. All branches run concurrently with the same input. */
247
- branch(id, runner, name) {
366
+ /**
367
+ * Add a branch. All branches run concurrently with the same input.
368
+ *
369
+ * Third arg accepts EITHER a legacy bare `name` string (back-compat
370
+ * with pre-L1c callers) OR a `ParallelBranchOptions` bag containing
371
+ * `name` and/or a per-method `groupTranslator` override. The
372
+ * override applies ONLY to this branch's `member.uiGroup` and does
373
+ * not affect any other branch or the runner's own translator.
374
+ */
375
+ branch(id, runner, nameOrOpts) {
248
376
  if (this.seenIds.has(id)) {
249
377
  throw new Error(`Parallel.branch(): duplicate branch id '${id}'`);
250
378
  }
379
+ // Branch errors are correlated back to the originating branch by the
380
+ // first `/`-separated segment of footprintjs's engine-prefixed
381
+ // `traversalContext.stageId` (e.g., `legal/call-llm` → branch
382
+ // `legal`). A branch id containing `/` would silently shadow that
383
+ // mapping and drop the error message into 'unknown error' fallback.
384
+ if (id.includes('/')) {
385
+ throw new Error(`Parallel.branch(): id '${id}' must not contain '/' — it collides with footprintjs's subflow-path separator used for per-branch error correlation`);
386
+ }
251
387
  this.seenIds.add(id);
252
- this.branches.push({ id, runner, name: name ?? id });
388
+ const opts = typeof nameOrOpts === 'string'
389
+ ? ({ name: nameOrOpts })
390
+ : nameOrOpts ?? {};
391
+ const entry = {
392
+ id,
393
+ runner,
394
+ name: opts.name ?? id,
395
+ ...(opts.groupTranslator !== undefined && {
396
+ groupTranslator: opts.groupTranslator,
397
+ }),
398
+ };
399
+ this.branches.push(entry);
253
400
  return this;
254
401
  }
255
402
  /**