Async Workflow #82
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "develop"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Logic-Nodes were timing out because UI saves condition as: {operands: [...], operator: "and"} But Backend expected: {expression: {operands: [...], operator: "and"}} This caused node.condition.expression to be None, triggering: - Logic-Node failures - Join-Node wait_all timeout - 504 Gateway Timeout Fix: Accept both formats by checking for operator/operands attributes directly on condition, falling back to condition.expression. Fixes: 504 Gateway Timeout in Training-Tiefenanalyse workflow Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Root cause: UI saves LogicExpression directly as condition: {operands: [...], operator: "and"} But Pydantic model expected Condition with wrapped expression: {expression: {operands: [...], operator: "and"}} Result: Pydantic deserialized it as Condition with expression=None → Logic-Nodes failed with "'NoneType' object has no attribute 'operator'" Fix: 1. Changed WorkflowNode.condition type from Condition to Any 2. Executor now handles both dict and Pydantic model formats 3. Detects UI format (operator+operands) vs legacy format (expression wrapper) 4. Converts dict to LogicExpression before evaluation Fixes: Logic-Node execution failures in Training-Tiefenanalyse workflow Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Previous fix used Any type, breaking type safety and only handling simple cases. This is the correct implementation: Changes: 1. LogicExpression.operands: List[Any] → List['LogicExpression'] - Enables recursive/nested expressions - Proper type checking for all operator combinations 2. WorkflowNode.condition: Any → Union[LogicExpression, Condition] - Type-safe deserialization - Supports both UI format (direct LogicExpression) and legacy (Condition wrapper) - Pydantic automatically tries LogicExpression first, then Condition 3. Executor: Simplified with isinstance() checks - Clean type detection without dict manipulation - Fallback for edge cases This now correctly handles: - Simple conditions: {operator: "eq", ref: "...", value: "..."} - Combined: {operator: "and", operands: [...]} - Nested: {operator: "or", operands: [{operator: "and", ...}, ...]} - All operators: eq, neq, in, not_in, gt, lt, gte, lte, contains, and, or, not - Legacy format: {expression: {...}, then_path: "...", else_path: "..."} Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>Critical fix: Without extra='forbid', Pydantic accepted UI format {operator: "and", operands: [...]} as valid Condition by ignoring unknown fields, resulting in Condition(expression=None). With extra='forbid': - Condition rejects unknown fields → fails - Union tries next type → LogicExpression → success Test Results (9/9 passed): - Simple comparisons (eq, neq, gt, lt, in) ✅ - AND/OR combinations ✅ - Deep nesting (3+ levels) ✅ - NOT operator ✅ - All operators (eq, neq, in, not_in, gt, lt, gte, lte, and, or, not) ✅ - Legacy format (Condition wrapper) ✅ - Complex real-world scenarios ✅ Added comprehensive test suite in: - test_condition_parsing.py (9 test cases) - test_condition_union.py (Union resolution verification) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>