From 057df0afc8931810731cd737cdd3dfe1d8e5189d Mon Sep 17 00:00:00 2001 From: Lars Date: Mon, 13 Apr 2026 09:07:50 +0200 Subject: [PATCH] fix: Support UI-format edge routing with sourceHandle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Logic-Nodes evaluated correctly but activated_edges was empty because _get_edges_by_label() only checked e.label, which is null in UI format. UI format uses: - sourceHandle: "true" / "false" (instead of label: "then" / "else") - targetHandle: "in" / "path_1" / etc. Changes: 1. Added source_handle/target_handle fields to WorkflowEdge model - With aliases sourceHandle/targetHandle for camelCase JSON 2. Updated _get_edges_by_label() to check both formats: - Legacy: e.label == "then" / "else" - UI: e.source_handle == "true" / "false" Now Logic-Nodes correctly activate outgoing edges → Join-Node receives completed paths → End-Node executes → Workflow completes! Co-Authored-By: Claude Opus 4.6 --- backend/workflow_executor.py | 18 ++++++++++++++++-- backend/workflow_models.py | 4 ++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/backend/workflow_executor.py b/backend/workflow_executor.py index dbc398b..ad25033 100644 --- a/backend/workflow_executor.py +++ b/backend/workflow_executor.py @@ -816,17 +816,31 @@ def _get_edges_by_label(node_id: str, label: str, graph: WorkflowGraph) -> List[ """ Findet alle ausgehenden Edges mit bestimmtem Label. + Unterstützt beide Formate: + - Legacy: e.label == label (z.B. "then", "else") + - UI: e.source_handle == label (z.B. "true", "false") + Args: node_id: Node-ID - label: Edge-Label (z.B. "then", "else", "uncertainty") + label: Edge-Label oder sourceHandle (z.B. "then"/"true", "else"/"false") graph: WorkflowGraph Returns: Liste von Edge-IDs """ + # Map label to sourceHandle equivalents + label_to_handle = { + "then": "true", + "else": "false" + } + handle_equivalent = label_to_handle.get(label, label) + matching_edges = [ e.id for e in graph.edges - if e.from_node == node_id and e.label == label + if e.from_node == node_id and ( + e.label == label or # Legacy format + (hasattr(e, 'source_handle') and e.source_handle == handle_equivalent) # UI format + ) ] return matching_edges diff --git a/backend/workflow_models.py b/backend/workflow_models.py index 0b98ef2..0467285 100644 --- a/backend/workflow_models.py +++ b/backend/workflow_models.py @@ -230,6 +230,10 @@ class WorkflowEdge(BaseModel): to_node: str = Field(..., alias="to", description="Ziel-Knoten-ID") label: Optional[str] = Field(None, description="Label für visuelle Darstellung (z.B. 'then', 'else')") + # UI-Format fields (React Flow) + source_handle: Optional[str] = Field(None, alias="sourceHandle", description="Source handle ID (UI format: 'true', 'false', 'out')") + target_handle: Optional[str] = Field(None, alias="targetHandle", description="Target handle ID (UI format: 'in', 'path_1', etc.)") + class WorkflowGraph(BaseModel): """