diff --git a/backend/workflow_executor.py b/backend/workflow_executor.py index d585bae..a516727 100644 --- a/backend/workflow_executor.py +++ b/backend/workflow_executor.py @@ -893,6 +893,37 @@ async def load_prompt_template(node: WorkflowNode, context: Dict[str, Any]) -> s except Exception as e: logger.error(f"❌ CRITICAL: Failed to load placeholders for workflow: {e}", exc_info=True) + # Add workflow node outputs as placeholders (Part 3: Inline Prompts) + # Format: node_id.analysis_core, node_id.signal_xyz, node_id.question_xyz + node_results = context.get("node_results", {}) + if node_results: + logger.info(f"🔍 DEBUG: Adding {len(node_results)} node outputs as placeholders") + for node_id, node_state in node_results.items(): + # analysis_core + if hasattr(node_state, 'analysis_core') and node_state.analysis_core: + key = f"{node_id}.analysis_core" + variables[key] = node_state.analysis_core + logger.debug(f" Added placeholder: {key} = {node_state.analysis_core[:50]}...") + + # decision_signals (keyed by question ID) + if hasattr(node_state, 'decision_signals') and node_state.decision_signals: + for signal_id, signal_value in node_state.decision_signals.items(): + # Signal placeholder: node_id.signal_question_id + signal_key = f"{node_id}.signal_{signal_id}" + variables[signal_key] = signal_value + logger.debug(f" Added placeholder: {signal_key} = {signal_value}") + + # Question texts (from graph metadata if available) + # NOTE: Question text placeholders are populated from graph in PlaceholderPicker + # Here we only add if available in node_state metadata + if hasattr(node_state, 'metadata') and isinstance(node_state.metadata, dict): + questions = node_state.metadata.get('questions', []) + for q in questions: + if isinstance(q, dict) and 'id' in q and 'question' in q: + question_key = f"{node_id}.question_{q['id']}" + variables[question_key] = q['question'] + logger.debug(f" Added placeholder: {question_key}") + # Load catalog for |d modifier support try: catalog = get_placeholder_catalog(profile_id)