@@ -841,9 +841,8 @@ def __init__(
841841 self .target = target
842842 self .metadata = metadata or {}
843843 self .condition = condition
844- # Resolved once, so fires() never has to probe by catching TypeError —
845- # a predicate that raises TypeError internally would otherwise be
846- # called a second time with a different signature.
844+ # Resolved once: probing by catching TypeError would call a predicate
845+ # that raises TypeError internally a second time.
847846 self ._condition_wants_context = _accepts_two_args (condition )
848847
849848 def fires (self , output : Any , outputs : Dict [str , Any ]) -> bool :
@@ -921,9 +920,8 @@ def from_nodes(
921920 tgt = target_node
922921
923922 # Put all kwargs into metadata dict
924- # condition is a real constructor argument, not free-form metadata —
925- # leaving it in kwargs would bury the predicate in the visualization
926- # labels and silently drop the routing behaviour.
923+ # A real argument, not metadata: left in kwargs it lands in the
924+ # visualization labels and the routing is dropped.
927925 condition = kwargs .pop ("condition" , None )
928926 metadata = kwargs if kwargs else None
929927 return cls (
@@ -1184,10 +1182,8 @@ def compile(self) -> None:
11841182 for node_id , parents in pred .items ()
11851183 }
11861184
1187- # Index inbound edges per target so the run loop can evaluate
1188- # routing without scanning self.edges once per node. _has_conditions
1189- # lets a graph with no conditions skip the gating pass entirely,
1190- # keeping the existing execution path free of added work.
1185+ # Indexed so the run loop does not scan self.edges per node;
1186+ # _has_conditions lets an unconditional graph skip gating entirely.
11911187 inbound : Dict [str , List ["Edge" ]] = {}
11921188 has_conditions = False
11931189 for edge in self .edges :
@@ -2038,8 +2034,7 @@ def _node_is_eligible(
20382034 if edge .source in skipped :
20392035 continue
20402036 if edge .source not in prev_outputs :
2041- # Predecessor hasn't run yet (first layer of a later loop, or
2042- # a cycle edge). Don't let an unevaluated edge prune the node.
2037+ # Unevaluated edge (later loop, cycle): must not prune.
20432038 return True
20442039 if edge .fires (prev_outputs [edge .source ], prev_outputs ):
20452040 return True
@@ -2076,10 +2071,8 @@ def _build_prompt(
20762071
20772072 try :
20782073 preds = self ._get_predecessors (node_id )
2079- # Keep the id paired with its own output. Filtering the outputs
2080- # while zipping against the unfiltered predecessor tuple shifted
2081- # the labels, so a node with a skipped or missing predecessor
2082- # attributed each output to the wrong agent.
2074+ # Filtering outputs while zipping against the unfiltered
2075+ # predecessor tuple shifted every label by one.
20832076 pred_outputs = [
20842077 (pred , prev_outputs [pred ])
20852078 for pred in preds
@@ -2299,8 +2292,7 @@ def _get_executor() -> ContextThreadPoolExecutor:
22992292
23002293 execution_results = {}
23012294 prev_outputs = {}
2302- # Reset per loop: a node skipped on one iteration may well be
2303- # the one that runs on the next, once upstream output changes.
2295+ # Reset per loop: a skipped node may run on the next one.
23042296 skipped_nodes : Set [str ] = set ()
23052297
23062298 # Derive a deterministic key for this task so checkpoints
@@ -2378,10 +2370,8 @@ def _get_executor() -> ContextThreadPoolExecutor:
23782370 f"with { len (layer )} nodes: { [n [0 ] for n in layer ]} "
23792371 )
23802372
2381- # Conditional routing: drop nodes this layer whose inbound
2382- # edges all declined to fire. Entry points and nodes in
2383- # graphs without conditions are never gated, so an
2384- # unconditional graph takes the same path it always did.
2373+ # Drop nodes whose inbound edges all declined to fire.
2374+ # Entry points and unconditional graphs are never gated.
23852375 if self ._has_conditions :
23862376 eligible_layer = []
23872377 for entry in layer :
@@ -3423,11 +3413,8 @@ def node_to_dict(node: Node) -> Dict[str, Any]:
34233413 return node_data
34243414
34253415 def edge_to_dict (edge : Edge ) -> Dict [str , Any ]:
3426- # A predicate is a Python callable and cannot round-trip
3427- # through JSON. Flag it in the payload and warn, so a
3428- # deserialized graph is never silently missing its routing:
3429- # loading this JSON gives an unconditional graph, where every
3430- # branch fires.
3416+ # A callable cannot round-trip through JSON, so flag it:
3417+ # loading this back gives an unconditional graph.
34313418 d = {
34323419 "source" : edge .source ,
34333420 "target" : edge .target ,
0 commit comments