diff --git a/backend/routers/prompts.py b/backend/routers/prompts.py index 814c126..35b0f59 100644 --- a/backend/routers/prompts.py +++ b/backend/routers/prompts.py @@ -858,17 +858,41 @@ async def execute_unified_prompt( stages_debug = result['debug'].get('stages', []) # First, collect stage outputs (outputs from base prompts in each stage) - stage_outputs = {} + stage_outputs = {} # Raw stage outputs (for expert mode) + extracted_values = {} # Individual values extracted from JSON outputs (for normal mode) + for stage_debug in stages_debug: stage_num = stage_debug.get('stage', 0) stage_output = stage_debug.get('output', {}) if isinstance(stage_output, dict): for output_key, output_value in stage_output.items(): - # Store stage outputs (e.g., stage_1_body) + # Store raw stage output (for expert mode) placeholder_key = f"stage_{stage_num}_{output_key}" stage_outputs[placeholder_key] = output_value - # Collect all resolved placeholders from prompts + # If output is a dict/object, extract individual fields + if isinstance(output_value, dict): + for field_key, field_value in output_value.items(): + # Store individual field (for normal mode) + # Use just the field name as key (e.g., "bmi" instead of "stage_1_body.bmi") + # This allows deduplication if multiple stages have the same field + if field_key not in extracted_values: + extracted_values[field_key] = { + 'value': field_value if isinstance(field_value, str) else json.dumps(field_value, ensure_ascii=False), + 'source_stage': stage_num, + 'source_output': output_key + } + + # Add extracted values from stage outputs (individual fields) + for field_key, field_data in extracted_values.items(): + if field_key not in metadata['placeholders']: + metadata['placeholders'][field_key] = { + 'value': field_data['value'], + 'description': f"Aus Stage {field_data['source_stage']} ({field_data['source_output']})", + 'is_extracted': True # Mark as extracted for filtering + } + + # Collect all resolved placeholders from prompts (input placeholders) for stage_debug in stages_debug: for prompt_debug in stage_debug.get('prompts', []): resolved_keys = [] @@ -883,9 +907,10 @@ async def execute_unified_prompt( # Get value: first try stage outputs, then cleaned_values value = stage_outputs.get(key, cleaned_values.get(key, '')) - # For stage output placeholders, add special description + # For stage output placeholders (raw JSON), add special description if key.startswith('stage_'): - desc = f"Output aus Stage {key.split('_')[1]} (Basis-Analyse)" + desc = f"Rohdaten Stage {key.split('_')[1]} (Basis-Analyse JSON)" + is_stage_raw = True else: # Find description in catalog desc = None @@ -895,10 +920,12 @@ async def execute_unified_prompt( desc = matching[0].get('description', '') break desc = desc or '' + is_stage_raw = False metadata['placeholders'][key] = { 'value': value if isinstance(value, str) else json.dumps(value, ensure_ascii=False), - 'description': desc + 'description': desc, + 'is_stage_raw': is_stage_raw # Mark raw stage outputs for expert mode } # Save to database with metadata diff --git a/frontend/src/pages/Analysis.jsx b/frontend/src/pages/Analysis.jsx index 90dd29f..cb9021c 100644 --- a/frontend/src/pages/Analysis.jsx +++ b/frontend/src/pages/Analysis.jsx @@ -34,11 +34,15 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) { const metadata = metadataRaw const allPlaceholders = placeholdersRaw - // Filter placeholders: In normal mode, hide empty values + // Filter placeholders: In normal mode, hide empty values and raw stage outputs const placeholders = expertMode ? allPlaceholders : Object.fromEntries( Object.entries(allPlaceholders).filter(([key, data]) => { + // Hide raw stage outputs (JSON) in normal mode + if (data.is_stage_raw) return false + + // Hide empty values const val = data.value || '' return val.trim() !== '' && val !== 'nicht verfügbar' && val !== '[Nicht verfügbar]' }) @@ -148,36 +152,50 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) { - {Object.entries(placeholders).map(([key, data]) => ( - - { + const isExtracted = data.is_extracted + const isStageRaw = data.is_stage_raw + + return ( + - {key} - - - {data.value} - - - {data.description || '—'} - - - ))} + + {isExtracted && '↳ '} + {isStageRaw && '🔬 '} + {key} + + + {data.value} + + + {data.description || '—'} + + + ) + })}