- workflow_executor.py: Generate node_label from prompt_slug or node.type (WorkflowNode has no label attribute)
- prompts.py: Fix INSERT statement - use 'created' column instead of 'created_at'
SSE endpoint now works correctly for workflow execution streaming.
Backend:
- workflow_executor.py: Add progress_callback parameter, emit events for execution_started, node_complete, execution_complete, execution_failed
- prompt_executor.py: Thread progress_callback through execute chain
- routers/prompts.py: New /execute-stream endpoint with asyncio Queue for SSE
Frontend:
- utils/api.js: New executeUnifiedPromptStream() function with EventSource
- pages/Analysis.jsx: Use SSE with live progress display (X/Y Nodes)
Fixes:
- No more gateway timeouts for complex workflows (10+ nodes)
- Live progress feedback for users
- Unlimited workflow complexity
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Bug: debug=true in URL was ignored because FastAPI expected it in
request body (POST without Query() expects body params by default).
Result: node_states were never returned, even with ?debug=true
Fix: Changed debug and save to Query parameters:
- debug: bool = Query(False, ...)
- save: bool = Query(False, ...)
Now ?debug=true in URL correctly enables debug output with node_states.
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 handled hasattr() but didn't check for None values.
Now explicitly checks that operator/expression is not None before using it.
Error was: "'NoneType' object has no attribute 'operator'"
Clearer error message: "condition is None or missing"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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>
Problem: Logic nodes without logic_expression defined caused AttributeError
"'NoneType' object has no attribute 'operator'" when evaluating condition.
Solution: Check both node.condition AND node.condition.expression before
calling evaluate_logic_expression(). Return clear FAILED state with error
message instead of crashing.
Impact: Workflows with incomplete logic node definitions now fail gracefully
with clear error message instead of cryptic AttributeError.