@ai-setting/roy-agent-core 1.5.43 → 1.5.45

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 (73) hide show
  1. package/dist/config/index.js +5 -5
  2. package/dist/env/agent/index.js +5 -5
  3. package/dist/env/commands/index.js +5 -5
  4. package/dist/env/context/index.js +4 -1
  5. package/dist/env/debug/index.js +5 -5
  6. package/dist/env/event-source/index.js +7 -7
  7. package/dist/env/hook/index.js +3 -3
  8. package/dist/env/index.js +24 -20
  9. package/dist/env/llm/index.js +5 -5
  10. package/dist/env/log-trace/index.js +5 -5
  11. package/dist/env/mcp/index.js +20 -6
  12. package/dist/env/memory/index.js +5 -5
  13. package/dist/env/plugin/index.js +5 -5
  14. package/dist/env/prompt/index.js +5 -5
  15. package/dist/env/session/index.js +6 -6
  16. package/dist/env/session/storage/index.js +1 -1
  17. package/dist/env/skill/index.js +5 -5
  18. package/dist/env/task/delegate/index.js +3 -3
  19. package/dist/env/task/index.js +6 -6
  20. package/dist/env/task/plugins/index.js +2 -2
  21. package/dist/env/tool/built-in/index.js +1 -1
  22. package/dist/env/tool/index.js +6 -6
  23. package/dist/env/workflow/decorators/index.js +1 -1
  24. package/dist/env/workflow/engine/index.js +10 -4
  25. package/dist/env/workflow/index.js +42 -24
  26. package/dist/env/workflow/nodes/index.js +5 -1
  27. package/dist/env/workflow/tools/index.js +14 -0
  28. package/dist/env/workflow/types/index.js +16 -2
  29. package/dist/env/workflow/utils/index.js +15 -196
  30. package/dist/index.js +35 -31
  31. package/dist/shared/@ai-setting/{roy-agent-core-kajktp3d.js → roy-agent-core-20fm423j.js} +47 -26
  32. package/dist/shared/@ai-setting/{roy-agent-core-ffb9fq4v.js → roy-agent-core-2vhsccvz.js} +54 -12
  33. package/dist/shared/@ai-setting/{roy-agent-core-69jskqjg.js → roy-agent-core-44g4dhzg.js} +75 -7
  34. package/dist/shared/@ai-setting/{roy-agent-core-e9fdm13a.js → roy-agent-core-4gmxjdhn.js} +4 -2
  35. package/dist/shared/@ai-setting/{roy-agent-core-b4wd9tn6.js → roy-agent-core-4k9a823d.js} +1 -1
  36. package/dist/shared/@ai-setting/roy-agent-core-68qy97r3.js +31 -0
  37. package/dist/shared/@ai-setting/roy-agent-core-6atd905e.js +42 -0
  38. package/dist/shared/@ai-setting/{roy-agent-core-4jqq077c.js → roy-agent-core-6e3wz81d.js} +2 -2
  39. package/dist/shared/@ai-setting/{roy-agent-core-pwkk12p4.js → roy-agent-core-6mcb7nqa.js} +60 -0
  40. package/dist/shared/@ai-setting/roy-agent-core-6vxg2gmr.js +321 -0
  41. package/dist/shared/@ai-setting/{roy-agent-core-9p43ap7h.js → roy-agent-core-8y804aat.js} +4 -2
  42. package/dist/shared/@ai-setting/{roy-agent-core-0rtxwr28.js → roy-agent-core-9bmtxmp6.js} +77 -120
  43. package/dist/shared/@ai-setting/{roy-agent-core-r6rwsr54.js → roy-agent-core-9p604xjf.js} +29 -9
  44. package/dist/shared/@ai-setting/{roy-agent-core-z1xf2fdk.js → roy-agent-core-a67e90d1.js} +6 -4
  45. package/dist/shared/@ai-setting/{roy-agent-core-xkb264a8.js → roy-agent-core-bp3xggmb.js} +192 -26
  46. package/dist/shared/@ai-setting/{roy-agent-core-zrja5v78.js → roy-agent-core-ce9w0j8n.js} +10 -2
  47. package/dist/shared/@ai-setting/{roy-agent-core-bmr6bdfb.js → roy-agent-core-cr8xer31.js} +15 -8
  48. package/dist/shared/@ai-setting/roy-agent-core-dbxm76wf.js +190 -0
  49. package/dist/shared/@ai-setting/{roy-agent-core-nj8yerg9.js → roy-agent-core-eftqdsy5.js} +1 -1
  50. package/dist/shared/@ai-setting/{roy-agent-core-7fgf85wc.js → roy-agent-core-h0x19xgn.js} +6 -7
  51. package/dist/shared/@ai-setting/{roy-agent-core-psvwzdhj.js → roy-agent-core-hdszq729.js} +9 -5
  52. package/dist/shared/@ai-setting/{roy-agent-core-dxbsc1zy.js → roy-agent-core-ja9qhg6d.js} +1 -1
  53. package/dist/shared/@ai-setting/{roy-agent-core-cevpwnq7.js → roy-agent-core-mjbfgqen.js} +5 -3
  54. package/dist/shared/@ai-setting/roy-agent-core-nhfy3p8q.js +132 -0
  55. package/dist/shared/@ai-setting/{roy-agent-core-2jnzv9at.js → roy-agent-core-nn9dmffw.js} +629 -288
  56. package/dist/shared/@ai-setting/roy-agent-core-qnrf2aw6.js +441 -0
  57. package/dist/shared/@ai-setting/{roy-agent-core-ee6nnnqw.js → roy-agent-core-r9hq4cjx.js} +8 -1
  58. package/dist/shared/@ai-setting/{roy-agent-core-jqy2mdyq.js → roy-agent-core-rgj6hq15.js} +52 -41
  59. package/dist/shared/@ai-setting/{roy-agent-core-z33en0cz.js → roy-agent-core-rm3hay00.js} +15 -2
  60. package/dist/shared/@ai-setting/{roy-agent-core-e130w7mv.js → roy-agent-core-rx74rye7.js} +5 -3
  61. package/dist/shared/@ai-setting/{roy-agent-core-pxcrzyv9.js → roy-agent-core-sk535ft2.js} +1 -1
  62. package/dist/shared/@ai-setting/roy-agent-core-v002ynpa.js +435 -0
  63. package/dist/shared/@ai-setting/{roy-agent-core-2dhd60aw.js → roy-agent-core-vdwvamre.js} +10 -0
  64. package/dist/shared/@ai-setting/{roy-agent-core-1zq3p19q.js → roy-agent-core-w64zachx.js} +8 -4
  65. package/dist/shared/@ai-setting/roy-agent-core-ye0z728h.js +18 -0
  66. package/dist/shared/@ai-setting/{roy-agent-core-rsybkb38.js → roy-agent-core-ysvh8er9.js} +36 -39
  67. package/dist/shared/@ai-setting/{roy-agent-core-9yxb3ty9.js → roy-agent-core-z5sxe4p7.js} +5 -1
  68. package/dist/shared/@ai-setting/{roy-agent-core-eg6nv09z.js → roy-agent-core-ztx5eh72.js} +1 -1
  69. package/dist/shared/@ai-setting/{roy-agent-core-nqgrjja0.js → roy-agent-core-zwq6vhpj.js} +1 -1
  70. package/package.json +1 -1
  71. package/dist/shared/@ai-setting/roy-agent-core-5x94xmt6.js +0 -350
  72. package/dist/shared/@ai-setting/roy-agent-core-dh9d7a3m.js +0 -11
  73. package/dist/shared/@ai-setting/roy-agent-core-jvatggbb.js +0 -603
@@ -1,7 +1,13 @@
1
+ import {
2
+ buildWorkflowNodeMetadata,
3
+ getWorkflowNodeIdFromMetadata,
4
+ init_workflow_message_metadata,
5
+ patchAgentSessionIdOnMessage
6
+ } from "./roy-agent-core-6atd905e.js";
1
7
  import {
2
8
  AgentComponentAdapter,
3
9
  init_agent_component_adapter
4
- } from "./roy-agent-core-69jskqjg.js";
10
+ } from "./roy-agent-core-44g4dhzg.js";
5
11
  import {
6
12
  SkillNode,
7
13
  ToolNode,
@@ -9,12 +15,26 @@ import {
9
15
  init_skill_node,
10
16
  init_tool_node,
11
17
  init_workflow_node
12
- } from "./roy-agent-core-jvatggbb.js";
18
+ } from "./roy-agent-core-6vxg2gmr.js";
19
+ import {
20
+ WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
21
+ init_json_schema_to_zod,
22
+ init_submit_json_output_tool,
23
+ jsonSchemaToZod,
24
+ parseWorkflowJsonOutput,
25
+ validateJsonOutputSchema
26
+ } from "./roy-agent-core-nhfy3p8q.js";
27
+ import {
28
+ TemplateResolver,
29
+ init_template_resolver
30
+ } from "./roy-agent-core-v002ynpa.js";
13
31
  import {
32
+ WorkflowError,
14
33
  createWorkflowEvent,
15
34
  init_event,
16
- init_types
17
- } from "./roy-agent-core-5x94xmt6.js";
35
+ init_types,
36
+ init_workflow_error
37
+ } from "./roy-agent-core-qnrf2aw6.js";
18
38
  import {
19
39
  AskUserError,
20
40
  createNodeInterruptEvent,
@@ -129,12 +149,14 @@ class DAGManager {
129
149
  nodeMap;
130
150
  extendedDefinition = null;
131
151
  cachedAnalysis = null;
132
- constructor(workflow) {
152
+ allowCycles;
153
+ constructor(workflow, options) {
133
154
  if (!workflow.nodes || workflow.nodes.length === 0) {
134
155
  throw new Error("At least one node is required");
135
156
  }
136
157
  this.workflow = workflow;
137
158
  this.nodeMap = new Map;
159
+ this.allowCycles = options?.allowCycles ?? false;
138
160
  for (const node of workflow.nodes) {
139
161
  if (node.id === "") {
140
162
  throw new Error("Node ID cannot be empty");
@@ -386,7 +408,7 @@ class DAGManager {
386
408
  }
387
409
  return result;
388
410
  }
389
- validate() {
411
+ validate(options) {
390
412
  const errors = [];
391
413
  const nodeIds = new Set;
392
414
  for (const node of this.workflow.nodes) {
@@ -407,7 +429,7 @@ class DAGManager {
407
429
  }
408
430
  }
409
431
  }
410
- if (this.isCyclic()) {
432
+ if (!this.allowCycles && !options?.skipCycleCheck && this.isCyclic()) {
411
433
  errors.push("Workflow contains a cycle");
412
434
  }
413
435
  return {
@@ -455,6 +477,27 @@ class DAGManager {
455
477
  const analysis = this.analyze();
456
478
  return analysis.dependents.get(nodeId) || [];
457
479
  }
480
+ getDownstreamUntil(fromNodeId, untilNodeId) {
481
+ const result = [];
482
+ const visited = new Set;
483
+ const queue = [...this.getDependents(fromNodeId)];
484
+ while (queue.length > 0) {
485
+ const nodeId = queue.shift();
486
+ if (visited.has(nodeId))
487
+ continue;
488
+ visited.add(nodeId);
489
+ result.push(nodeId);
490
+ if (nodeId === untilNodeId) {
491
+ continue;
492
+ }
493
+ for (const dependent of this.getDependents(nodeId)) {
494
+ if (!visited.has(dependent)) {
495
+ queue.push(dependent);
496
+ }
497
+ }
498
+ }
499
+ return result;
500
+ }
458
501
  getDefinition() {
459
502
  return this.workflow;
460
503
  }
@@ -467,6 +510,20 @@ class DAGManager {
467
510
  getNodeCount() {
468
511
  return this.nodeMap.size;
469
512
  }
513
+ buildEdges(explicitEdges = []) {
514
+ const derivedEdges = [];
515
+ const explicitEdgeSet = new Set(explicitEdges.map((e) => `${e.from}->${e.to}`));
516
+ for (const node of this.workflow.nodes) {
517
+ const deps = node.depends_on || [];
518
+ for (const dep of deps) {
519
+ const edgeKey = `${dep}->${node.id}`;
520
+ if (!explicitEdgeSet.has(edgeKey)) {
521
+ derivedEdges.push({ from: dep, to: node.id });
522
+ }
523
+ }
524
+ }
525
+ return [...explicitEdges, ...derivedEdges];
526
+ }
470
527
  }
471
528
  var init_dag_manager = () => {};
472
529
 
@@ -542,6 +599,10 @@ class Scheduler {
542
599
  return this.ready.has(nodeId);
543
600
  }
544
601
  markCompleted(nodeId) {
602
+ if (nodeId === "__end__" || nodeId === "__END__") {
603
+ logger.debug(`[Scheduler] Workflow marked as completed via __end__`);
604
+ return;
605
+ }
545
606
  this.running.delete(nodeId);
546
607
  this.ready.delete(nodeId);
547
608
  this.pending.delete(nodeId);
@@ -569,6 +630,21 @@ class Scheduler {
569
630
  }
570
631
  this.skipped.add(nodeId);
571
632
  }
633
+ unmarkSkipped(nodeId) {
634
+ if (!this.skipped.has(nodeId)) {
635
+ return;
636
+ }
637
+ this.skipped.delete(nodeId);
638
+ this.pending.add(nodeId);
639
+ }
640
+ resetNodeForReEntry(nodeId) {
641
+ this.running.delete(nodeId);
642
+ this.completed.delete(nodeId);
643
+ this.failed.delete(nodeId);
644
+ this.skipped.delete(nodeId);
645
+ this.ready.delete(nodeId);
646
+ this.pending.add(nodeId);
647
+ }
572
648
  reset() {
573
649
  this.running.clear();
574
650
  this.completed.clear();
@@ -593,6 +669,11 @@ class Scheduler {
593
669
  skipped: Array.from(this.skipped).sort()
594
670
  };
595
671
  }
672
+ markCompletedFromRestore(nodeIds) {
673
+ for (const nodeId of nodeIds) {
674
+ this.markCompleted(nodeId);
675
+ }
676
+ }
596
677
  updateReadyNodes(completedNodes) {
597
678
  const allCompleted = new Set(completedNodes);
598
679
  for (const nodeId of this.completed) {
@@ -616,8 +697,70 @@ class Scheduler {
616
697
  setParallelLimit(limit) {
617
698
  this.options.parallelLimit = limit;
618
699
  }
700
+ getOutgoingEdges(nodeId, edges) {
701
+ return edges.filter((edge) => edge.from === nodeId);
702
+ }
703
+ processEdgesAfterCompletion(completedNodeId, edges, templateResolver, loopEnabled) {
704
+ const result = {
705
+ toStart: [],
706
+ reEntries: [],
707
+ skipped: [],
708
+ resetNodes: []
709
+ };
710
+ const completedNode = this.dagManager.getNode(completedNodeId);
711
+ if (completedNode?.condition) {
712
+ const conditionMet = templateResolver.evaluateCondition(completedNode.condition);
713
+ if (!conditionMet) {
714
+ for (const edge of this.getOutgoingEdges(completedNodeId, edges)) {
715
+ this.markSkipped(edge.to);
716
+ result.skipped.push({
717
+ nodeId: edge.to,
718
+ reason: `Inline condition false on node "${completedNodeId}"`
719
+ });
720
+ }
721
+ return result;
722
+ }
723
+ }
724
+ const outgoingEdges = this.getOutgoingEdges(completedNodeId, edges);
725
+ for (const edge of outgoingEdges) {
726
+ const conditionMet = !edge.when || templateResolver.evaluateCondition(edge.when);
727
+ if (conditionMet) {
728
+ if (this.skipped.has(edge.to)) {
729
+ this.unmarkSkipped(edge.to);
730
+ }
731
+ const isReEntry = loopEnabled && this.completed.has(edge.to);
732
+ const canStart = loopEnabled ? !this.running.has(edge.to) && !this.failed.has(edge.to) : !this.completed.has(edge.to) && !this.running.has(edge.to) && !this.failed.has(edge.to);
733
+ if (canStart) {
734
+ if (isReEntry) {
735
+ const downstream = this.dagManager.getDownstreamUntil(edge.to, completedNodeId);
736
+ for (const nodeId of downstream) {
737
+ this.resetNodeForReEntry(nodeId);
738
+ result.resetNodes.push(nodeId);
739
+ }
740
+ this.resetNodeForReEntry(edge.to);
741
+ result.resetNodes.push(edge.to);
742
+ result.reEntries.push(edge.to);
743
+ }
744
+ result.toStart.push(edge.to);
745
+ }
746
+ } else {
747
+ if (!this.skipped.has(edge.to)) {
748
+ result.skipped.push({
749
+ nodeId: edge.to,
750
+ reason: edge.when ? `Edge condition false: ${edge.when}` : "Edge condition false"
751
+ });
752
+ }
753
+ this.markSkipped(edge.to);
754
+ }
755
+ }
756
+ return result;
757
+ }
619
758
  }
620
- var init_scheduler = () => {};
759
+ var logger;
760
+ var init_scheduler = __esm(() => {
761
+ init_logger();
762
+ logger = createLogger("workflow.scheduler");
763
+ });
621
764
 
622
765
  // src/env/workflow/engine/executor.ts
623
766
  var Executor;
@@ -625,6 +768,7 @@ var init_executor = __esm(() => {
625
768
  init_event();
626
769
  init_types();
627
770
  init_decorator();
771
+ init_workflow_message_metadata();
628
772
  Executor = class Executor {
629
773
  nodeRegistry;
630
774
  eventBus;
@@ -817,15 +961,33 @@ var init_executor = __esm(() => {
817
961
  role: "workflow.node.start",
818
962
  content: contentSummary,
819
963
  parts: [part],
820
- metadata: {
821
- _workflowNodeMetadata: true,
822
- type: "workflow.node.start",
823
- workflowNodeId: nodeId,
824
- workflowNodeType: nodeType,
964
+ metadata: buildWorkflowNodeMetadata("workflow.node.start", nodeId, nodeType, {
825
965
  ...agentSessionId ? { agentSessionId } : {}
826
- }
966
+ })
827
967
  });
828
968
  }
969
+ async attachAgentSessionToLastStart(sessionId, nodeId, agentSessionId) {
970
+ if (!this.sessionComponent?.getMessages || !this.sessionComponent.updateMessage) {
971
+ return;
972
+ }
973
+ const messages = await this.sessionComponent.getMessages(sessionId);
974
+ for (let i = messages.length - 1;i >= 0; i--) {
975
+ const msg = messages[i];
976
+ const meta = msg.metadata;
977
+ if (meta?.type !== "workflow.node.start") {
978
+ continue;
979
+ }
980
+ if (getWorkflowNodeIdFromMetadata(meta) !== nodeId) {
981
+ continue;
982
+ }
983
+ if (meta.agentSessionId) {
984
+ return;
985
+ }
986
+ const patched = patchAgentSessionIdOnMessage(meta, msg.parts, agentSessionId);
987
+ await this.sessionComponent.updateMessage(sessionId, msg.id, patched);
988
+ return;
989
+ }
990
+ }
829
991
  summarizeCall(nodeType, nodeId, input) {
830
992
  if (input === undefined || input === null) {
831
993
  return `[${nodeType}] ${nodeId} started`;
@@ -857,14 +1019,11 @@ var init_executor = __esm(() => {
857
1019
  role: "workflow.node.interrupt",
858
1020
  content: query,
859
1021
  parts: [part],
860
- metadata: {
861
- _workflowNodeMetadata: true,
862
- type: "workflow.node.interrupt",
863
- workflowNodeId: nodeId,
864
- workflowNodeType: nodeType,
1022
+ metadata: buildWorkflowNodeMetadata("workflow.node.interrupt", nodeId, nodeType, {
865
1023
  query,
866
- agentSessionId
867
- }
1024
+ ...agentSessionId ? { agentSessionId } : {},
1025
+ timestamp
1026
+ })
868
1027
  });
869
1028
  }
870
1029
  async writeNodeEnd(sessionId, nodeId, nodeType, output, error, durationMs, agentSessionId) {
@@ -884,14 +1043,10 @@ var init_executor = __esm(() => {
884
1043
  role: "workflow.node.end",
885
1044
  content: contentSummary,
886
1045
  parts: [part],
887
- metadata: {
888
- _workflowNodeMetadata: true,
889
- type: "workflow.node.end",
890
- workflowNodeId: nodeId,
891
- workflowNodeType: nodeType,
1046
+ metadata: buildWorkflowNodeMetadata("workflow.node.end", nodeId, nodeType, {
892
1047
  success: !error,
893
1048
  ...agentSessionId ? { agentSessionId } : {}
894
- }
1049
+ })
895
1050
  });
896
1051
  }
897
1052
  summarizeResult(nodeId, output, error, durationMs) {
@@ -913,7 +1068,7 @@ var init_executor = __esm(() => {
913
1068
  const truncated = strOutput.length > 100 ? strOutput.substring(0, 100) + "..." : strOutput;
914
1069
  return `✅ ${nodeId}: ${truncated} (${durationMs}ms)`;
915
1070
  }
916
- async writeNodeResume(sessionId, nodeId, response, agentSessionId) {
1071
+ async writeNodeResume(sessionId, nodeId, nodeType, response, agentSessionId) {
917
1072
  if (!this.sessionComponent)
918
1073
  return;
919
1074
  const timestamp = Date.now();
@@ -928,12 +1083,11 @@ var init_executor = __esm(() => {
928
1083
  role: "workflow.node.resume",
929
1084
  content: response,
930
1085
  parts: [part],
931
- metadata: {
932
- _workflowNodeMetadata: true,
933
- type: "workflow.node.resume",
934
- workflowNodeId: nodeId,
935
- ...agentSessionId ? { agentSessionId } : {}
936
- }
1086
+ metadata: buildWorkflowNodeMetadata("workflow.node.resume", nodeId, nodeType, {
1087
+ response,
1088
+ ...agentSessionId ? { agentSessionId } : {},
1089
+ timestamp
1090
+ })
937
1091
  });
938
1092
  }
939
1093
  };
@@ -943,6 +1097,9 @@ var init_executor = __esm(() => {
943
1097
  __legacyDecorateClassTS([
944
1098
  TracedAs("workflow.executor.writeNodeStart", { recordParams: true, recordResult: true, log: true })
945
1099
  ], Executor.prototype, "writeNodeStart", null);
1100
+ __legacyDecorateClassTS([
1101
+ TracedAs("workflow.executor.attachAgentSessionToLastStart", { log: true })
1102
+ ], Executor.prototype, "attachAgentSessionToLastStart", null);
946
1103
  __legacyDecorateClassTS([
947
1104
  TracedAs("workflow.executor.writeNodeInterrupt", { recordParams: true, recordResult: true, log: true })
948
1105
  ], Executor.prototype, "writeNodeInterrupt", null);
@@ -954,11 +1111,139 @@ var init_executor = __esm(() => {
954
1111
  ], Executor.prototype, "writeNodeResume", null);
955
1112
  });
956
1113
 
1114
+ // src/env/workflow/utils/parse-agent-output-config.ts
1115
+ function parseAgentOutputConfig(config) {
1116
+ const output = config.output;
1117
+ if (!output) {
1118
+ return { mode: "string" };
1119
+ }
1120
+ const mode = output.mode === "json" ? "json" : "string";
1121
+ if (mode === "json") {
1122
+ if (output.schema === undefined) {
1123
+ throw new Error("AgentNode output.mode=json requires output.schema");
1124
+ }
1125
+ const schema = validateJsonOutputSchema(output.schema);
1126
+ return { mode, schema };
1127
+ }
1128
+ return { mode: "string" };
1129
+ }
1130
+ var init_parse_agent_output_config = __esm(() => {
1131
+ init_json_schema_to_zod();
1132
+ });
1133
+
1134
+ // src/env/workflow/utils/extract-agent-json-output.ts
1135
+ function extractAgentJsonOutput(agentResult, schema) {
1136
+ const candidates = [
1137
+ agentResult.structuredOutput,
1138
+ asRecord(agentResult.output),
1139
+ extractFromToolCalls(agentResult),
1140
+ extractFromMessages(agentResult.messages)
1141
+ ];
1142
+ for (const candidate of candidates) {
1143
+ const validated = validateAgainstSchema(candidate, schema);
1144
+ if (validated) {
1145
+ return validated;
1146
+ }
1147
+ }
1148
+ return;
1149
+ }
1150
+ function asRecord(value) {
1151
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1152
+ return value;
1153
+ }
1154
+ return;
1155
+ }
1156
+ function extractFromToolCalls(agentResult) {
1157
+ const toolCalls = agentResult.metadata?.toolCallsDetail;
1158
+ if (!toolCalls?.length) {
1159
+ return;
1160
+ }
1161
+ for (let i = toolCalls.length - 1;i >= 0; i--) {
1162
+ const tc = toolCalls[i];
1163
+ if (tc.name === WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME && tc.arguments) {
1164
+ return tc.arguments;
1165
+ }
1166
+ }
1167
+ return;
1168
+ }
1169
+ function extractFromMessages(messages) {
1170
+ if (!messages?.length) {
1171
+ return;
1172
+ }
1173
+ for (let i = messages.length - 1;i >= 0; i--) {
1174
+ const msg = messages[i];
1175
+ if (msg.toolName !== WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME || !msg.content) {
1176
+ continue;
1177
+ }
1178
+ const fromMarker = parseWorkflowJsonOutput(msg.content);
1179
+ if (fromMarker) {
1180
+ return fromMarker;
1181
+ }
1182
+ try {
1183
+ const parsed = JSON.parse(msg.content);
1184
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1185
+ return parsed;
1186
+ }
1187
+ } catch {}
1188
+ }
1189
+ return;
1190
+ }
1191
+ function validateAgainstSchema(data, schema) {
1192
+ if (!data) {
1193
+ return;
1194
+ }
1195
+ if (!schema) {
1196
+ return data;
1197
+ }
1198
+ try {
1199
+ return jsonSchemaToZod(schema).parse(data);
1200
+ } catch {
1201
+ return;
1202
+ }
1203
+ }
1204
+ var init_extract_agent_json_output = __esm(() => {
1205
+ init_submit_json_output_tool();
1206
+ init_json_schema_to_zod();
1207
+ });
1208
+
1209
+ // src/env/workflow/utils/build-agent-node-output.ts
1210
+ function buildAgentNodeOutput(agentResult, outputConfig) {
1211
+ const base = {
1212
+ metadata: agentResult.metadata,
1213
+ workflowHistory: agentResult.messages
1214
+ };
1215
+ if (outputConfig.mode === "json") {
1216
+ const schema = outputConfig.schema;
1217
+ const jsonData = extractAgentJsonOutput(agentResult, schema);
1218
+ if (!jsonData) {
1219
+ throw new Error("AgentNode json output mode requires structured JSON from workflow_submit_output");
1220
+ }
1221
+ return {
1222
+ result: jsonData,
1223
+ ...jsonData,
1224
+ metadata: {
1225
+ ...agentResult.metadata,
1226
+ outputMode: "json"
1227
+ },
1228
+ workflowHistory: agentResult.messages
1229
+ };
1230
+ }
1231
+ return {
1232
+ result: agentResult.output,
1233
+ ...base
1234
+ };
1235
+ }
1236
+ var init_build_agent_node_output = __esm(() => {
1237
+ init_extract_agent_json_output();
1238
+ });
1239
+
957
1240
  // src/env/workflow/nodes/agent-node.ts
958
1241
  var AgentNode;
959
1242
  var init_agent_node = __esm(() => {
960
1243
  init_workflow_hil();
961
1244
  init_decorator();
1245
+ init_parse_agent_output_config();
1246
+ init_build_agent_node_output();
962
1247
  AgentNode = class AgentNode {
963
1248
  definition;
964
1249
  agentRunner;
@@ -972,11 +1257,17 @@ var init_agent_node = __esm(() => {
972
1257
  async execute(context) {
973
1258
  const startTime = Date.now();
974
1259
  try {
975
- const config = this.definition.config || {};
1260
+ const config = context.resolvedConfig ?? this.definition.config ?? {};
976
1261
  const agentType = config.agent_type || "general";
977
- const promptTemplate = config.prompt || "";
978
1262
  const options = config.options || {};
979
- const resolvedPrompt = this.resolveTemplate(promptTemplate, context);
1263
+ const outputConfig = parseAgentOutputConfig(config);
1264
+ let resolvedPrompt;
1265
+ if (context.resolvedConfig && context.templateResolver) {
1266
+ resolvedPrompt = config.prompt || "";
1267
+ } else {
1268
+ const promptTemplate = config.prompt || "";
1269
+ resolvedPrompt = context.templateResolver?.resolveValue(promptTemplate) ?? promptTemplate;
1270
+ }
980
1271
  if (this.agentRunner.registerAgent && this.agentRunner.hasAgent) {
981
1272
  if (!this.agentRunner.hasAgent(agentType)) {
982
1273
  this.agentRunner.registerAgent(agentType, {
@@ -986,19 +1277,30 @@ var init_agent_node = __esm(() => {
986
1277
  });
987
1278
  }
988
1279
  }
989
- const userQuery = context.input?.userQuery;
1280
+ const userQuery = context.input?.userQuery ?? context.workflowInput?.userQuery;
990
1281
  let agentSessionId = context.agentSessionId;
1282
+ if (!agentSessionId && context.sessionComponent) {
1283
+ agentSessionId = await this.resolveAgentSessionIdFromWorkflow(context);
1284
+ if (agentSessionId) {
1285
+ context.agentSessionId = agentSessionId;
1286
+ }
1287
+ }
991
1288
  if (!agentSessionId && context.sessionComponent) {
992
1289
  agentSessionId = await this.createAgentSubSession(context);
993
1290
  context.agentSessionId = agentSessionId;
1291
+ if (context.attachAgentSessionToLastStart) {
1292
+ await context.attachAgentSessionToLastStart(this.definition.id, agentSessionId);
1293
+ }
994
1294
  }
1295
+ const allowedTools = ["ask_user"];
995
1296
  const agentConfig = {
996
1297
  type: agentType,
997
1298
  prompt: resolvedPrompt,
998
1299
  options: {
999
1300
  timeout: options.timeout,
1000
1301
  model: options.model,
1001
- allowedTools: ["ask_user"]
1302
+ allowedTools,
1303
+ outputSchema: outputConfig.schema
1002
1304
  },
1003
1305
  workflowHistory: context.workflowHistory,
1004
1306
  nodeId: this.definition.id,
@@ -1011,11 +1313,7 @@ var init_agent_node = __esm(() => {
1011
1313
  const result = await this.agentRunner.run(agentConfig, resumeOptions);
1012
1314
  const duration = Date.now() - startTime;
1013
1315
  return {
1014
- output: {
1015
- result: result.output,
1016
- metadata: result.metadata,
1017
- workflowHistory: result.messages
1018
- },
1316
+ output: buildAgentNodeOutput(result, outputConfig),
1019
1317
  error: undefined,
1020
1318
  duration
1021
1319
  };
@@ -1036,6 +1334,18 @@ var init_agent_node = __esm(() => {
1036
1334
  };
1037
1335
  }
1038
1336
  }
1337
+ async resolveAgentSessionIdFromWorkflow(context) {
1338
+ const sessionComponent = context.sessionComponent;
1339
+ if (!sessionComponent) {
1340
+ return;
1341
+ }
1342
+ const workflowSession = await sessionComponent.get(context.sessionId);
1343
+ const agentSessions = workflowSession?.metadata?.agentSessions;
1344
+ if (!agentSessions?.length) {
1345
+ return;
1346
+ }
1347
+ return agentSessions.find((ref) => ref.nodeId === this.definition.id)?.sessionId;
1348
+ }
1039
1349
  async createAgentSubSession(context) {
1040
1350
  const sessionComponent = context.sessionComponent;
1041
1351
  if (!sessionComponent) {
@@ -1082,142 +1392,9 @@ var init_agent_node = __esm(() => {
1082
1392
  }
1083
1393
  return agentSessionId;
1084
1394
  }
1085
- resolveTemplate(template, context) {
1086
- if (!template) {
1087
- return "";
1088
- }
1089
- let resolved = template;
1090
- resolved = resolved.replace(/\{\{input\.([^}]+)\}\}/g, (match, path) => {
1091
- let value = this.getNestedValue(context.input, path);
1092
- if (value === undefined && context.workflowInput) {
1093
- value = this.getNestedValue(context.workflowInput, path);
1094
- }
1095
- return this.stringifyValue(value, match);
1096
- });
1097
- resolved = resolved.replace(/\{\{inputs\.([^}]+)\}\}/g, (match, path) => {
1098
- let value = this.getNestedValue(context.input, path);
1099
- if (value === undefined && context.workflowInput) {
1100
- value = this.getNestedValue(context.workflowInput, path);
1101
- }
1102
- return this.stringifyValue(value, match);
1103
- });
1104
- resolved = resolved.replace(/\{\{nodes\.([^}]+)\}\}/g, (match, path) => {
1105
- const segments = path.split(".");
1106
- const nodeId = segments[0];
1107
- let nodeOutput = context.previousOutputs.get(nodeId);
1108
- if (nodeOutput === undefined) {
1109
- const normalizedUnderscore = nodeId.replace(/-/g, "_");
1110
- const normalizedHyphen = nodeId.replace(/_/g, "-");
1111
- if (normalizedUnderscore !== nodeId) {
1112
- nodeOutput = context.previousOutputs.get(normalizedUnderscore);
1113
- }
1114
- if (nodeOutput === undefined && normalizedHyphen !== nodeId) {
1115
- nodeOutput = context.previousOutputs.get(normalizedHyphen);
1116
- }
1117
- }
1118
- if (nodeOutput === undefined) {
1119
- return match;
1120
- }
1121
- nodeOutput = this.extractFromWrapper(nodeOutput);
1122
- if (segments.length === 1) {
1123
- return this.stringifyValue(nodeOutput, match);
1124
- }
1125
- let value = nodeOutput;
1126
- let startIndex = 1;
1127
- if (segments.length > 1 && (segments[1] === "output" || segments[1] === "result" || segments[1] === "metadata")) {
1128
- startIndex = 2;
1129
- }
1130
- for (let i = startIndex;i < segments.length; i++) {
1131
- if (value === null || value === undefined) {
1132
- return match;
1133
- }
1134
- value = value[segments[i]];
1135
- }
1136
- return this.stringifyValue(value, match);
1137
- });
1138
- resolved = resolved.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
1139
- if (path.startsWith("input.") || path.startsWith("nodes.")) {
1140
- return match;
1141
- }
1142
- const segments = path.split(".");
1143
- const nodeId = segments[0];
1144
- let nodeOutput = context.previousOutputs.get(nodeId);
1145
- if (nodeOutput === undefined) {
1146
- const normalizedUnderscore = nodeId.replace(/-/g, "_");
1147
- const normalizedHyphen = nodeId.replace(/_/g, "-");
1148
- if (normalizedUnderscore !== nodeId) {
1149
- nodeOutput = context.previousOutputs.get(normalizedUnderscore);
1150
- }
1151
- if (nodeOutput === undefined && normalizedHyphen !== nodeId) {
1152
- nodeOutput = context.previousOutputs.get(normalizedHyphen);
1153
- }
1154
- }
1155
- if (nodeOutput === undefined) {
1156
- return match;
1157
- }
1158
- nodeOutput = this.extractFromWrapper(nodeOutput);
1159
- if (segments.length === 1) {
1160
- return this.stringifyValue(nodeOutput, match);
1161
- }
1162
- let value = nodeOutput;
1163
- let startIndex = 1;
1164
- if (segments.length > 1 && (segments[1] === "output" || segments[1] === "result" || segments[1] === "metadata")) {
1165
- startIndex = 2;
1166
- }
1167
- for (let i = startIndex;i < segments.length; i++) {
1168
- if (value === null || value === undefined) {
1169
- return match;
1170
- }
1171
- value = value[segments[i]];
1172
- }
1173
- return this.stringifyValue(value, match);
1174
- });
1175
- return resolved;
1176
- }
1177
- stringifyValue(value, originalTemplate) {
1178
- if (value === undefined) {
1179
- return originalTemplate;
1180
- }
1181
- if (value === null) {
1182
- return "null";
1183
- }
1184
- if (typeof value === "string") {
1185
- return value;
1186
- }
1187
- return JSON.stringify(value);
1188
- }
1189
- extractFromWrapper(value) {
1190
- if (value === null || value === undefined) {
1191
- return value;
1192
- }
1193
- if (typeof value !== "object") {
1194
- return value;
1195
- }
1196
- if ("result" in value && "metadata" in value) {
1197
- return value.result;
1198
- }
1199
- if ("output" in value) {
1200
- return value.output;
1201
- }
1202
- return value;
1203
- }
1204
- getNestedValue(obj, path) {
1205
- if (!obj) {
1206
- return;
1207
- }
1208
- if ("input" in obj && path in obj["input"]) {
1209
- return obj["input"][path];
1210
- }
1211
- return path.split(".").reduce((current, key) => {
1212
- if (current && typeof current === "object") {
1213
- return current[key];
1214
- }
1215
- return;
1216
- }, obj);
1217
- }
1218
1395
  };
1219
1396
  __legacyDecorateClassTS([
1220
- TracedAs("agent.node.execute", { recordParams: true, recordResult: true, log: true })
1397
+ TracedAs("workflow.agent.execute", { log: true })
1221
1398
  ], AgentNode.prototype, "execute", null);
1222
1399
  __legacyDecorateClassTS([
1223
1400
  TracedAs("agent.node.createAgentSubSession", { recordParams: true, recordResult: true, log: true })
@@ -1226,16 +1403,17 @@ var init_agent_node = __esm(() => {
1226
1403
 
1227
1404
  // src/env/workflow/nodes/ask-user-node.ts
1228
1405
  class AskUserNode {
1406
+ definition;
1229
1407
  type = "ask_user";
1230
1408
  id;
1231
- config;
1232
1409
  constructor(definition) {
1410
+ this.definition = definition;
1233
1411
  this.id = definition.id;
1234
- this.config = definition.config || {};
1235
1412
  }
1236
1413
  async execute(context) {
1237
- const query = this.config.query || "确认继续吗?";
1238
- const options = this.config.options;
1414
+ const config = context.resolvedConfig ?? this.definition.config ?? {};
1415
+ const query = config.query || "确认继续吗?";
1416
+ const options = config.options;
1239
1417
  const fullQuery = options ? `${query} (选项: ${options.join(", ")})` : query;
1240
1418
  await context.eventBus.publish(createNodeInterruptEvent(context.runId, this.id, this.type, fullQuery));
1241
1419
  throw new AskUserError(context.runId, context.sessionId, this.id, this.type, query);
@@ -1264,7 +1442,8 @@ class NodeRegistry {
1264
1442
  agentComponent,
1265
1443
  agentRunner,
1266
1444
  workflowRunner,
1267
- sessionComponent
1445
+ sessionComponent,
1446
+ llmComponent
1268
1447
  } = options ?? {};
1269
1448
  this.toolRegistry = toolRegistry;
1270
1449
  this.skillRegistry = skillRegistry;
@@ -1275,8 +1454,11 @@ class NodeRegistry {
1275
1454
  if (agentRunner.setSessionComponent && sessionComponent) {
1276
1455
  agentRunner.setSessionComponent(sessionComponent);
1277
1456
  }
1457
+ if (llmComponent && "setLLMComponent" in agentRunner && typeof agentRunner.setLLMComponent === "function") {
1458
+ agentRunner.setLLMComponent(llmComponent);
1459
+ }
1278
1460
  } else if (agentComponent) {
1279
- this.agentComponentAdapter = new AgentComponentAdapter(agentComponent, {}, sessionComponent);
1461
+ this.agentComponentAdapter = new AgentComponentAdapter(agentComponent, {}, sessionComponent, llmComponent);
1280
1462
  this.agentRunner = this.agentComponentAdapter;
1281
1463
  }
1282
1464
  this.registerBuiltInTypes();
@@ -1346,9 +1528,24 @@ var init_node_registry = __esm(() => {
1346
1528
  init_ask_user_node();
1347
1529
  });
1348
1530
 
1531
+ // src/env/workflow/utils/agent-session-metadata.ts
1532
+ function updateAgentSessionStatus(agentSessions, nodeId, status) {
1533
+ if (!agentSessions?.length) {
1534
+ return agentSessions ?? [];
1535
+ }
1536
+ return agentSessions.map((ref) => ref.nodeId === nodeId ? { ...ref, status } : ref);
1537
+ }
1538
+ function markAllAgentSessionsCompleted(agentSessions) {
1539
+ if (!agentSessions?.length) {
1540
+ return agentSessions ?? [];
1541
+ }
1542
+ return agentSessions.map((ref) => ref.status === "active" || ref.status === "paused" ? { ...ref, status: "completed" } : ref);
1543
+ }
1544
+ var init_agent_session_metadata = () => {};
1545
+
1349
1546
  // src/env/workflow/engine/engine.ts
1350
1547
  import { EventEmitter } from "events";
1351
- var logger, WorkflowEngine;
1548
+ var logger2, WorkflowEngine;
1352
1549
  var init_engine = __esm(() => {
1353
1550
  init_event();
1354
1551
  init_workflow_hil();
@@ -1357,9 +1554,12 @@ var init_engine = __esm(() => {
1357
1554
  init_scheduler();
1358
1555
  init_executor();
1359
1556
  init_node_registry();
1557
+ init_agent_session_metadata();
1360
1558
  init_logger();
1361
1559
  init_decorator();
1362
- logger = createLogger("workflow:engine");
1560
+ init_template_resolver();
1561
+ init_workflow_error();
1562
+ logger2 = createLogger("workflow:engine");
1363
1563
  WorkflowEngine = class WorkflowEngine extends EventEmitter {
1364
1564
  activeSessions = new Map;
1365
1565
  sessionIdCounter = 0;
@@ -1375,10 +1575,12 @@ var init_engine = __esm(() => {
1375
1575
  static async create(options) {
1376
1576
  const agentComponent = options.env?.getComponent("agent");
1377
1577
  const sessionComponent = options.sessionComponent;
1578
+ const llmComponent = options.env?.getComponent("llm");
1378
1579
  const nodeRegistry = new NodeRegistry({
1379
1580
  toolRegistry: options.toolRegistry,
1380
1581
  skillRegistry: options.skillRegistry,
1381
1582
  agentComponent,
1583
+ llmComponent,
1382
1584
  workflowRunner: options.workflowRunner,
1383
1585
  sessionComponent
1384
1586
  });
@@ -1406,6 +1608,8 @@ var init_engine = __esm(() => {
1406
1608
  workflowName,
1407
1609
  workflowVersion: definition.version,
1408
1610
  status: "running",
1611
+ runId,
1612
+ startedAt: Date.now(),
1409
1613
  input: options?.input,
1410
1614
  agentSessions: []
1411
1615
  };
@@ -1416,7 +1620,7 @@ var init_engine = __esm(() => {
1416
1620
  metadata
1417
1621
  });
1418
1622
  }
1419
- logger.info(`[WorkflowEngine] Created session: ${sessionId}`);
1623
+ logger2.info(`[WorkflowEngine] Created session: ${sessionId}`);
1420
1624
  return sessionId;
1421
1625
  }
1422
1626
  async run(sessionId, options) {
@@ -1486,24 +1690,32 @@ var init_engine = __esm(() => {
1486
1690
  }
1487
1691
  });
1488
1692
  metadata.input = { ...existingInput, ...newInput };
1489
- logger.info(`[WorkflowEngine] Updated session ${sessionId} input with resume user input`);
1693
+ logger2.info(`[WorkflowEngine] Updated session ${sessionId} input with resume user input`);
1490
1694
  }
1491
1695
  }
1492
1696
  const messages = this.sessionComponent ? await this.sessionComponent.getMessages(sessionId) : [];
1493
- const { inferNextNode } = await import("./roy-agent-core-ffb9fq4v.js");
1697
+ const {
1698
+ inferNextNode,
1699
+ extractResumeInfo,
1700
+ enrichResumeInfoWithAgentSessions,
1701
+ enrichResumePointWithAgentSessions
1702
+ } = await import("./roy-agent-core-2vhsccvz.js");
1494
1703
  const entry = workflowDef.entry;
1495
1704
  const entryNode = Array.isArray(entry) ? entry[0] : entry;
1496
- const resumePoint = inferNextNode(messages, {
1705
+ const agentSessions = metadata.agentSessions ?? [];
1706
+ const resumeInfo = enrichResumeInfoWithAgentSessions(extractResumeInfo(messages), agentSessions);
1707
+ const resumePoint = enrichResumePointWithAgentSessions(inferNextNode(messages, {
1497
1708
  entryNode: entryNode !== "__default_entry__" ? entryNode : undefined,
1498
1709
  edges: undefined
1499
- });
1710
+ }), agentSessions);
1500
1711
  const sessionState = await this.initializeSessionState(sessionId, workflowDef, workflowId, workflowName, options);
1501
1712
  this.activeSessions.set(sessionId, sessionState);
1502
- return this.runWithResume(sessionId, resumePoint, options);
1713
+ return this.runWithResume(sessionId, resumePoint, resumeInfo, options);
1503
1714
  }
1504
1715
  async initializeSessionState(sessionId, definition, workflowId, workflowName, options) {
1505
- const dagManager = new DAGManager(definition);
1506
- const validation = dagManager.validate();
1716
+ const loopEnabled = options?.loopEnabled ?? definition.config?.loopEnabled ?? false;
1717
+ const dagManager = new DAGManager(definition, { allowCycles: loopEnabled });
1718
+ const validation = dagManager.validate({ skipCycleCheck: loopEnabled });
1507
1719
  if (!validation.valid) {
1508
1720
  throw new Error(`Invalid workflow: ${validation.errors.join(", ")}`);
1509
1721
  }
@@ -1516,10 +1728,28 @@ var init_engine = __esm(() => {
1516
1728
  debug: options?.debug ?? definition.config?.debug ?? false
1517
1729
  };
1518
1730
  const executor = new Executor(this.nodeRegistry, eventBus, executorOptions, this.sessionComponent);
1731
+ const rawRuntimeInput = options?.workflowInput ?? options?.input;
1732
+ let persistedInput = {};
1733
+ if (this.sessionComponent) {
1734
+ const existingSession = await this.sessionComponent.get(sessionId);
1735
+ const metaInput = existingSession?.metadata?.input;
1736
+ if (metaInput) {
1737
+ const { userQuery: _omit, ...rest } = metaInput;
1738
+ persistedInput = rest;
1739
+ }
1740
+ }
1741
+ const { stripEphemeralResumeInput } = await import("./roy-agent-core-2vhsccvz.js");
1742
+ const { workflowInput: runtimeInput } = stripEphemeralResumeInput(rawRuntimeInput);
1743
+ const mergedWorkflowInput = { ...persistedInput, ...runtimeInput };
1744
+ const workflowInput = Object.keys(mergedWorkflowInput).length > 0 ? mergedWorkflowInput : undefined;
1519
1745
  const config = {
1520
1746
  parallelLimit,
1521
1747
  timeout: options?.timeout ?? definition.config?.timeout ?? null,
1522
- debug: options?.debug ?? definition.config?.debug ?? false
1748
+ debug: options?.debug ?? definition.config?.debug ?? false,
1749
+ strict: options?.strict ?? definition.config?.strict ?? false,
1750
+ maxIterations: options?.maxIterations ?? definition.config?.maxIterations ?? 100,
1751
+ loopEnabled,
1752
+ workflowInput
1523
1753
  };
1524
1754
  const abortController = new AbortController;
1525
1755
  let resolveCompleted;
@@ -1546,12 +1776,14 @@ var init_engine = __esm(() => {
1546
1776
  resolveCompleted,
1547
1777
  rejectCompleted,
1548
1778
  workflowHistory: [],
1549
- agentSessions: new Map
1779
+ agentSessions: new Map,
1780
+ edges: dagManager.buildEdges(definition.edges || []),
1781
+ loopIterationCount: 0
1550
1782
  };
1551
1783
  this.setupEventHandlers(sessionState);
1552
1784
  return sessionState;
1553
1785
  }
1554
- async runWithResume(sessionId, resumePoint, options) {
1786
+ async runWithResume(sessionId, resumePoint, resumeInfo, options) {
1555
1787
  const sessionState = this.activeSessions.get(sessionId);
1556
1788
  if (!sessionState) {
1557
1789
  throw new Error(`Session not found: ${sessionId}`);
@@ -1580,12 +1812,17 @@ var init_engine = __esm(() => {
1580
1812
  } else if (options?.input && typeof options.input === "object") {
1581
1813
  inputForExecution = options.input;
1582
1814
  }
1815
+ if (resumeInfo?.nodeOutputs) {
1816
+ const completedNodeIds = Array.from(resumeInfo.nodeOutputs.keys());
1817
+ sessionState.scheduler.markCompletedFromRestore(completedNodeIds);
1818
+ }
1583
1819
  this.scheduleAndExecute(sessionState, {
1584
1820
  input: inputForExecution,
1585
1821
  pendingNodeId,
1586
- agentSessionId
1822
+ agentSessionId,
1823
+ restoredOutputs: resumeInfo?.nodeOutputs
1587
1824
  }).catch((error) => {
1588
- logger.error(`Workflow ${sessionId} scheduling error:`, error);
1825
+ logger2.error(`Workflow ${sessionId} scheduling error:`, error);
1589
1826
  this.failWorkflow(sessionState, error);
1590
1827
  });
1591
1828
  if (options?.sync !== false) {
@@ -1600,7 +1837,7 @@ var init_engine = __esm(() => {
1600
1837
  const sessionId = await this.createSession(workflow, options);
1601
1838
  const sessionState = await this.initializeSessionState(sessionId, definition, workflowId, workflowName, options);
1602
1839
  this.activeSessions.set(sessionId, sessionState);
1603
- return this.runWithResume(sessionId, { type: "entry_node" }, options);
1840
+ return this.runWithResume(sessionId, { type: "entry_node" }, undefined, options);
1604
1841
  }
1605
1842
  async pause(sessionId) {
1606
1843
  const sessionState = this.activeSessions.get(sessionId);
@@ -1620,7 +1857,7 @@ var init_engine = __esm(() => {
1620
1857
  });
1621
1858
  }
1622
1859
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.paused", this.getRunIdFromSessionId(sessionId), {}));
1623
- logger.info(`[WorkflowEngine] Workflow paused: ${sessionId}`);
1860
+ logger2.info(`[WorkflowEngine] Workflow paused: ${sessionId}`);
1624
1861
  }
1625
1862
  async stop(sessionId, reason) {
1626
1863
  const sessionState = this.activeSessions.get(sessionId);
@@ -1659,15 +1896,12 @@ var init_engine = __esm(() => {
1659
1896
  eventBus.on("node.completed", async (event) => {
1660
1897
  if (event.type !== "node.completed")
1661
1898
  return;
1662
- sessionState.nodeOutputs.set(event.node_id, event.output);
1663
- scheduler.markCompleted(event.node_id);
1664
1899
  if (event.output && typeof event.output === "object" && "workflowHistory" in event.output) {
1665
1900
  const messages = event.output.workflowHistory;
1666
1901
  if (Array.isArray(messages)) {
1667
1902
  sessionState.workflowHistory.push(...messages);
1668
1903
  }
1669
1904
  }
1670
- this.checkAndFinalize(sessionState);
1671
1905
  });
1672
1906
  eventBus.on("node.failed", async (event) => {
1673
1907
  if (event.type !== "node.failed")
@@ -1678,20 +1912,27 @@ var init_engine = __esm(() => {
1678
1912
  eventBus.on("node.interrupt", async (event) => {
1679
1913
  if (event.type !== "node.interrupt")
1680
1914
  return;
1681
- logger.info(`Workflow paused at node "${event.node_id}" - ask_user pending`);
1915
+ logger2.info(`Workflow paused at node "${event.node_id}" - ask_user pending`);
1682
1916
  sessionState.status = "paused";
1683
1917
  sessionState.abortController.abort();
1684
1918
  if (this.sessionComponent) {
1685
1919
  const metadata = await this.getSessionMetadata(sessionId);
1920
+ const agentSessions = updateAgentSessionStatus(metadata.agentSessions, event.node_id, "paused");
1686
1921
  await this.sessionComponent.update(sessionId, {
1687
- metadata: { ...metadata, status: "paused" }
1922
+ metadata: {
1923
+ ...metadata,
1924
+ status: "paused",
1925
+ pendingNodeId: event.node_id,
1926
+ pauseReason: "ask_user",
1927
+ agentSessions
1928
+ }
1688
1929
  });
1689
1930
  }
1690
1931
  await eventBus.publish(createWorkflowEvent("workflow.paused", runId, {
1691
1932
  pendingNodeId: event.node_id,
1692
1933
  query: event.query
1693
1934
  }));
1694
- await this.writeNodeInterrupt(sessionId, event.node_id, event.node_type, event.query, event.agent_session_id);
1935
+ await sessionState.executor.writeNodeInterrupt(sessionId, event.node_id, event.node_type, event.query, event.agent_session_id);
1695
1936
  sessionState.resolveCompleted({
1696
1937
  runId,
1697
1938
  status: "paused",
@@ -1701,25 +1942,19 @@ var init_engine = __esm(() => {
1701
1942
  });
1702
1943
  });
1703
1944
  }
1704
- async writeNodeInterrupt(sessionId, nodeId, nodeType, query, agentSessionId) {
1705
- if (this.sessionComponent) {
1706
- await this.sessionComponent.addMessage(sessionId, {
1707
- role: "workflow.node.interrupt",
1708
- content: query,
1709
- metadata: {
1710
- type: "workflow.node.interrupt",
1711
- workflowNodeId: nodeId,
1712
- workflowNodeType: nodeType,
1713
- query,
1714
- agentSessionId,
1715
- timestamp: Date.now()
1716
- }
1717
- });
1718
- }
1719
- }
1720
1945
  async scheduleAndExecute(sessionState, options) {
1721
1946
  const { scheduler, executor, eventBus, abortController, nodeOutputs } = sessionState;
1722
1947
  const { input: globalInput, pendingNodeId, agentSessionId, restoredOutputs } = options || {};
1948
+ const { stripEphemeralResumeInput } = await import("./roy-agent-core-2vhsccvz.js");
1949
+ const { workflowInput: inputToPersist, userQuery: resumeUserQuery } = stripEphemeralResumeInput(globalInput);
1950
+ if (inputToPersist) {
1951
+ sessionState.config.workflowInput = {
1952
+ ...sessionState.config.workflowInput || {},
1953
+ ...inputToPersist
1954
+ };
1955
+ }
1956
+ sessionState.loopIterationCount = 0;
1957
+ const maxIterations = sessionState.config.maxIterations;
1723
1958
  if (restoredOutputs) {
1724
1959
  for (const [nodeId, output] of restoredOutputs) {
1725
1960
  nodeOutputs.set(nodeId, output);
@@ -1739,7 +1974,7 @@ var init_engine = __esm(() => {
1739
1974
  break;
1740
1975
  if (scheduled >= (sessionState.config.parallelLimit ?? Infinity))
1741
1976
  break;
1742
- await this.startNode(sessionState, nodeId, globalInput);
1977
+ await this.startNode(sessionState, nodeId, sessionState.config.workflowInput);
1743
1978
  scheduled++;
1744
1979
  }
1745
1980
  return true;
@@ -1747,7 +1982,7 @@ var init_engine = __esm(() => {
1747
1982
  if (pendingNodeId) {
1748
1983
  await this.resumeNode(sessionState, pendingNodeId, {
1749
1984
  agentSessionId,
1750
- userQuery: globalInput?.userQuery
1985
+ userQuery: resumeUserQuery
1751
1986
  });
1752
1987
  } else {
1753
1988
  await scheduleAvailableNodes();
@@ -1757,6 +1992,12 @@ var init_engine = __esm(() => {
1757
1992
  if (state.pending.length === 0 && state.running.length === 0) {
1758
1993
  break;
1759
1994
  }
1995
+ if (sessionState.config.loopEnabled && sessionState.loopIterationCount >= maxIterations) {
1996
+ logger2.error(`[WorkflowEngine] Max loop iterations ${maxIterations} exceeded`);
1997
+ sessionState.rejectCompleted(new WorkflowError(`Workflow exceeded maximum loop iterations: ${maxIterations}`));
1998
+ await this.stop(sessionState.sessionId, "Max iterations exceeded");
1999
+ return;
2000
+ }
1760
2001
  try {
1761
2002
  await this.waitForNextNodeEvent(sessionState, abortController.signal);
1762
2003
  } catch {
@@ -1809,15 +2050,8 @@ var init_engine = __esm(() => {
1809
2050
  scheduler.markFailed(nodeId);
1810
2051
  return;
1811
2052
  }
1812
- await this.writeNodeStart(sessionId, nodeId, nodeDef.type, input);
1813
- const context = this.createExecutionContext(sessionState, nodeId, input);
1814
- executor.executeNode(nodeDef, context).catch(async (error) => {
1815
- if (error instanceof AskUserError) {
1816
- await eventBus.publish(createNodeInterruptEvent(runId, nodeId, nodeDef.type, error.query, error.agentSessionId));
1817
- return;
1818
- }
1819
- scheduler.markFailed(nodeId);
1820
- });
2053
+ const context = this.buildNodeContext(sessionState, nodeId, input);
2054
+ await this.validateAndExecute(nodeDef, context, sessionState);
1821
2055
  }
1822
2056
  async writeNodeStart(sessionId, nodeId, nodeType, input) {
1823
2057
  if (this.sessionComponent) {
@@ -1833,66 +2067,143 @@ var init_engine = __esm(() => {
1833
2067
  });
1834
2068
  }
1835
2069
  }
1836
- async writeNodeResume(sessionId, nodeId, userResponse) {
1837
- if (this.sessionComponent && userResponse) {
1838
- await this.sessionComponent.addMessage(sessionId, {
1839
- role: "workflow.node.resume",
1840
- content: JSON.stringify({ userResponse }),
1841
- metadata: {
1842
- type: "workflow.node.resume",
1843
- workflowNodeId: nodeId,
1844
- timestamp: Date.now()
1845
- }
1846
- });
1847
- }
1848
- }
1849
2070
  async resumeNode(sessionState, nodeId, options) {
1850
2071
  const { scheduler, executor, eventBus, dagManager } = sessionState;
1851
2072
  const sessionId = sessionState.sessionId;
1852
2073
  const runId = this.getRunIdFromSessionId(sessionId);
1853
2074
  scheduler.markStarted(nodeId);
1854
- await this.writeNodeResume(sessionId, nodeId, options?.userQuery);
2075
+ const nodeDef = dagManager.getNode(nodeId);
2076
+ if (!nodeDef) {
2077
+ scheduler.markFailed(nodeId);
2078
+ return;
2079
+ }
2080
+ let agentSessionId = options?.agentSessionId;
2081
+ if (!agentSessionId && this.sessionComponent) {
2082
+ const session = await this.sessionComponent.get(sessionId);
2083
+ const agentSessions = session?.metadata?.agentSessions;
2084
+ const { resolveAgentSessionId } = await import("./roy-agent-core-2vhsccvz.js");
2085
+ agentSessionId = resolveAgentSessionId(nodeId, undefined, agentSessions);
2086
+ }
2087
+ await sessionState.executor.writeNodeResume(sessionId, nodeId, nodeDef.type, options?.userQuery ?? "", agentSessionId);
1855
2088
  await eventBus.publish(createWorkflowEvent("node.started", runId, {
1856
2089
  node_id: nodeId,
1857
- agentSessionId: options?.agentSessionId,
2090
+ agentSessionId,
1858
2091
  userQuery: options?.userQuery
1859
2092
  }));
1860
- const nodeDef = dagManager.getNode(nodeId);
2093
+ const context = this.buildNodeContext(sessionState, nodeId, sessionState.config.workflowInput);
2094
+ if (options?.userQuery !== undefined) {
2095
+ context.input.userQuery = options.userQuery;
2096
+ }
2097
+ if (agentSessionId) {
2098
+ context.agentSessionId = agentSessionId;
2099
+ }
2100
+ await this.validateAndExecute(nodeDef, context, sessionState);
2101
+ }
2102
+ async preExecuteValidation(nodeId, nodeDef, context, options) {
1861
2103
  if (!nodeDef) {
1862
- scheduler.markFailed(nodeId);
2104
+ logger2.warn(`Node ${nodeId} has no configuration`);
1863
2105
  return;
1864
2106
  }
1865
- const context = this.createExecutionContext(sessionState, nodeId, { userQuery: options?.userQuery }, true);
1866
- if (options?.agentSessionId) {
1867
- context.agentSessionId = options.agentSessionId;
1868
- }
1869
- if (nodeDef.type === "agent" && options?.agentSessionId) {
1870
- const agentAdapter = this.nodeRegistry.getAgentAdapter?.();
1871
- if (agentAdapter?.resumeAgent) {
1872
- const agentConfig = {
1873
- type: nodeDef.config?.agent_type || "general",
1874
- prompt: nodeDef.config?.prompt || "",
1875
- nodeId,
1876
- runId,
1877
- workflowSessionId: sessionId
1878
- };
1879
- try {
1880
- await agentAdapter.resumeAgent(options.agentSessionId, options.userQuery || "", agentConfig);
1881
- } catch (error) {
1882
- console.error(`Failed to resume agent node ${nodeId}:`, error);
2107
+ const config = nodeDef.config || {};
2108
+ if (context.debug) {
2109
+ logger2.debug(`Pre-execute validation for node ${nodeId}`, {
2110
+ workflowInput: context.workflowInput,
2111
+ previousOutputs: Array.from(context.previousOutputs.keys()),
2112
+ hasTemplateResolver: !!context.templateResolver
2113
+ });
2114
+ }
2115
+ if (context.templateResolver) {
2116
+ const { unresolved } = context.templateResolver.resolveAndValidate(config);
2117
+ if (unresolved.length > 0) {
2118
+ if (options?.strict) {
2119
+ context.templateResolver.resolveStrict(config, nodeId);
1883
2120
  }
2121
+ logger2.warn(`[WorkflowEngine] Node "${nodeId}" has unresolved templates:`, unresolved);
1884
2122
  }
1885
2123
  }
1886
- executor.executeNode(nodeDef, context).catch((error) => {
2124
+ }
2125
+ async validateAndExecute(nodeDef, context, sessionState) {
2126
+ const { scheduler, executor, eventBus } = sessionState;
2127
+ const { nodeId } = context;
2128
+ const strictMode = sessionState.config?.strict ?? false;
2129
+ try {
2130
+ await this.preExecuteValidation(nodeId, nodeDef, context, { strict: strictMode });
2131
+ } catch (err) {
2132
+ logger2.error(`[WorkflowEngine] Strict validation failed for node ${nodeId}:`, err);
2133
+ scheduler.markFailed(nodeId);
2134
+ return;
2135
+ }
2136
+ try {
2137
+ const result = await executor.executeNode(nodeDef, context);
2138
+ if (result.error) {
2139
+ return;
2140
+ }
2141
+ sessionState.nodeOutputs.set(nodeId, result.output);
2142
+ scheduler.markCompleted(nodeId);
2143
+ if (result.output && typeof result.output === "object" && "workflowHistory" in result.output) {
2144
+ const messages = result.output.workflowHistory;
2145
+ if (Array.isArray(messages)) {
2146
+ sessionState.workflowHistory.push(...messages);
2147
+ }
2148
+ }
2149
+ await this.processConditionalEdgesAfterCompletion(sessionState, nodeId);
2150
+ this.checkAndFinalize(sessionState);
2151
+ } catch (error) {
1887
2152
  if (error instanceof AskUserError) {
1888
- const event = createNodeInterruptEvent(runId, nodeId, nodeDef.type, error.query, error.agentSessionId);
1889
- eventBus.publish(event);
2153
+ await eventBus.publish(createNodeInterruptEvent(context.runId, nodeId, nodeDef.type, error.query, error.agentSessionId));
1890
2154
  return;
1891
2155
  }
1892
2156
  scheduler.markFailed(nodeId);
2157
+ }
2158
+ }
2159
+ async processConditionalEdgesAfterCompletion(sessionState, completedNodeId) {
2160
+ if (!sessionState.edges || sessionState.edges.length === 0) {
2161
+ return;
2162
+ }
2163
+ const { scheduler, eventBus } = sessionState;
2164
+ const runId = this.getRunIdFromSessionId(sessionState.sessionId);
2165
+ const templateResolver = new TemplateResolver({
2166
+ input: sessionState.config.workflowInput || {},
2167
+ previousOutputs: new Map(sessionState.nodeOutputs)
1893
2168
  });
2169
+ logger2.debug(`[WorkflowEngine] Processing edges after "${completedNodeId}" completed. edges=${JSON.stringify(sessionState.edges)}`);
2170
+ const edgeResult = scheduler.processEdgesAfterCompletion(completedNodeId, sessionState.edges, templateResolver, sessionState.config.loopEnabled);
2171
+ logger2.debug(`[WorkflowEngine] Edge processing result: ${JSON.stringify(edgeResult)}`);
2172
+ for (const nodeId of edgeResult.resetNodes) {
2173
+ sessionState.nodeOutputs.delete(nodeId);
2174
+ }
2175
+ for (const { nodeId, reason } of edgeResult.skipped) {
2176
+ await eventBus.publish(createWorkflowEvent("node.skipped", runId, {
2177
+ node_id: nodeId,
2178
+ reason
2179
+ }));
2180
+ }
2181
+ if (edgeResult.reEntries.length > 0) {
2182
+ if (sessionState.config.loopEnabled) {
2183
+ const nextCount = sessionState.loopIterationCount + edgeResult.reEntries.length;
2184
+ if (nextCount > sessionState.config.maxIterations) {
2185
+ logger2.error(`[WorkflowEngine] Max loop iterations ${sessionState.config.maxIterations} exceeded (next=${nextCount})`);
2186
+ await this.failWorkflow(sessionState, new WorkflowError(`Workflow exceeded maximum loop iterations: ${sessionState.config.maxIterations}`));
2187
+ return;
2188
+ }
2189
+ sessionState.loopIterationCount = nextCount;
2190
+ } else {
2191
+ sessionState.loopIterationCount += edgeResult.reEntries.length;
2192
+ }
2193
+ logger2.debug(`[WorkflowEngine] Loop iteration #${sessionState.loopIterationCount}: re-entering ${edgeResult.reEntries.join(", ")}`);
2194
+ }
2195
+ const workflowInput = sessionState.config.workflowInput || {};
2196
+ for (const targetId of edgeResult.toStart) {
2197
+ if (targetId === "__end__" || targetId === "__END__") {
2198
+ logger2.info(`[WorkflowEngine] Workflow terminated via __end__ edge from node "${completedNodeId}"`);
2199
+ scheduler.markCompleted("__end__");
2200
+ await this.completeWorkflow(sessionState);
2201
+ } else {
2202
+ await this.startNode(sessionState, targetId, workflowInput);
2203
+ }
2204
+ }
1894
2205
  }
1895
- createExecutionContext(sessionState, nodeId, globalInput, forceGlobalInput) {
2206
+ buildNodeContext(sessionState, nodeId, globalInput) {
1896
2207
  const nodeDef = sessionState.dagManager.getNode(nodeId);
1897
2208
  const runId = this.getRunIdFromSessionId(sessionState.sessionId);
1898
2209
  const deps = nodeDef.depends_on || [];
@@ -1903,15 +2214,16 @@ var init_engine = __esm(() => {
1903
2214
  input[depId] = depOutput;
1904
2215
  }
1905
2216
  }
1906
- const analysis = sessionState.dagManager.analyze();
1907
- const isEntryNode = analysis.entryNodes.includes(nodeId);
1908
- if ((isEntryNode || forceGlobalInput) && globalInput) {
1909
- Object.assign(input, globalInput);
1910
- }
2217
+ const rawWorkflowInput = globalInput ?? sessionState.config.workflowInput ?? {};
2218
+ const { userQuery: _ephemeral, ...workflowInput } = rawWorkflowInput;
2219
+ const templateResolver = new TemplateResolver({
2220
+ input: workflowInput,
2221
+ previousOutputs: new Map(sessionState.nodeOutputs)
2222
+ });
1911
2223
  const askUser = (query) => {
1912
2224
  throw new AskUserError(runId, sessionState.sessionId, nodeId, nodeDef.type, query);
1913
2225
  };
1914
- return {
2226
+ const context = {
1915
2227
  runId,
1916
2228
  sessionId: sessionState.sessionId,
1917
2229
  workflowName: sessionState.workflowName,
@@ -1924,8 +2236,15 @@ var init_engine = __esm(() => {
1924
2236
  nodeOutputs: sessionState.nodeOutputs,
1925
2237
  workflowHistory: sessionState.workflowHistory,
1926
2238
  sessionComponent: this.sessionComponent,
1927
- askUser
2239
+ askUser,
2240
+ attachAgentSessionToLastStart: async (targetNodeId, agentSessionId) => {
2241
+ await sessionState.executor.attachAgentSessionToLastStart(sessionState.sessionId, targetNodeId, agentSessionId);
2242
+ },
2243
+ workflowInput,
2244
+ templateResolver,
2245
+ resolvedConfig: templateResolver.resolveValue(nodeDef.config ?? {})
1928
2246
  };
2247
+ return context;
1929
2248
  }
1930
2249
  checkAndFinalize(sessionState) {
1931
2250
  const state = sessionState.scheduler.getState();
@@ -1938,6 +2257,10 @@ var init_engine = __esm(() => {
1938
2257
  }
1939
2258
  }
1940
2259
  async completeWorkflow(sessionState) {
2260
+ if (sessionState.status !== "running") {
2261
+ return;
2262
+ }
2263
+ sessionState.status = "completed";
1941
2264
  const durationMs = Date.now() - sessionState.startedAt.getTime();
1942
2265
  const sessionId = sessionState.sessionId;
1943
2266
  const runId = this.getRunIdFromSessionId(sessionId);
@@ -1948,7 +2271,16 @@ var init_engine = __esm(() => {
1948
2271
  if (this.sessionComponent) {
1949
2272
  const metadata = await this.getSessionMetadata(sessionId);
1950
2273
  await this.sessionComponent.update(sessionId, {
1951
- metadata: { ...metadata, status: "completed" }
2274
+ metadata: {
2275
+ ...metadata,
2276
+ status: "completed",
2277
+ completedAt: Date.now(),
2278
+ durationMs,
2279
+ output,
2280
+ pendingNodeId: undefined,
2281
+ pauseReason: undefined,
2282
+ agentSessions: markAllAgentSessionsCompleted(metadata.agentSessions)
2283
+ }
1952
2284
  });
1953
2285
  }
1954
2286
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.completed", runId, {
@@ -1964,6 +2296,10 @@ var init_engine = __esm(() => {
1964
2296
  this.cleanupSession(sessionState);
1965
2297
  }
1966
2298
  async failWorkflow(sessionState, error) {
2299
+ if (sessionState.status !== "running") {
2300
+ return;
2301
+ }
2302
+ sessionState.status = "failed";
1967
2303
  const durationMs = Date.now() - sessionState.startedAt.getTime();
1968
2304
  const sessionId = sessionState.sessionId;
1969
2305
  const runId = this.getRunIdFromSessionId(sessionId);
@@ -1971,7 +2307,12 @@ var init_engine = __esm(() => {
1971
2307
  if (this.sessionComponent) {
1972
2308
  const metadata = await this.getSessionMetadata(sessionId);
1973
2309
  await this.sessionComponent.update(sessionId, {
1974
- metadata: { ...metadata, status: "failed" }
2310
+ metadata: {
2311
+ ...metadata,
2312
+ status: "failed",
2313
+ failedAt: Date.now(),
2314
+ durationMs
2315
+ }
1975
2316
  });
1976
2317
  }
1977
2318
  await sessionState.eventBus.publish(createWorkflowEvent("workflow.failed", runId, {
@@ -2044,9 +2385,6 @@ var init_engine = __esm(() => {
2044
2385
  __legacyDecorateClassTS([
2045
2386
  TracedAs("workflow.engine.stop", { recordParams: true, recordResult: true, log: true })
2046
2387
  ], WorkflowEngine.prototype, "stop", null);
2047
- __legacyDecorateClassTS([
2048
- TracedAs("workflow.engine.writeNodeInterrupt", { recordParams: true, recordResult: true, log: true })
2049
- ], WorkflowEngine.prototype, "writeNodeInterrupt", null);
2050
2388
  __legacyDecorateClassTS([
2051
2389
  TracedAs("workflow.engine.scheduleAndExecute", { recordParams: true, recordResult: true, log: true })
2052
2390
  ], WorkflowEngine.prototype, "scheduleAndExecute", null);
@@ -2059,12 +2397,15 @@ var init_engine = __esm(() => {
2059
2397
  __legacyDecorateClassTS([
2060
2398
  TracedAs("workflow.engine.writeNodeStart", { recordParams: true, recordResult: true, log: true })
2061
2399
  ], WorkflowEngine.prototype, "writeNodeStart", null);
2062
- __legacyDecorateClassTS([
2063
- TracedAs("workflow.engine.writeNodeResume", { recordParams: true, recordResult: true, log: true })
2064
- ], WorkflowEngine.prototype, "writeNodeResume", null);
2065
2400
  __legacyDecorateClassTS([
2066
2401
  TracedAs("workflow.engine.resumeNode", { recordParams: true, recordResult: true, log: true })
2067
2402
  ], WorkflowEngine.prototype, "resumeNode", null);
2403
+ __legacyDecorateClassTS([
2404
+ TracedAs("workflow.engine.preExecuteValidation", { log: true })
2405
+ ], WorkflowEngine.prototype, "preExecuteValidation", null);
2406
+ __legacyDecorateClassTS([
2407
+ TracedAs("workflow.engine.buildNodeContext", { log: true })
2408
+ ], WorkflowEngine.prototype, "buildNodeContext", null);
2068
2409
  __legacyDecorateClassTS([
2069
2410
  TracedAs("workflow.engine.checkAndFinalize", { recordParams: true, recordResult: true, log: true })
2070
2411
  ], WorkflowEngine.prototype, "checkAndFinalize", null);