feat: expert mode + stage outputs in value table (Issue #47)
FEATURE: Experten-Modus 🔬 - Toggle-Button in Wertetabelle - Normal: Nur gefüllte Werte anzeigen - Experten: Alle Platzhalter inkl. leere/technische - Anzeige: "(+X ausgeblendet)" wenn Werte gefiltert - Button-Style: Accent wenn aktiv FILTER: Leere Werte ausblenden (Normal-Modus) - Filtert: '', 'nicht verfügbar', '[Nicht verfügbar]' - Zeigt nur relevante Nutzer-Daten - Experten-Modus zeigt alles FEATURE: Stage-Outputs in Wertetabelle ✅ ROOT CAUSE: stage_N_key Platzhalter hatten keine Werte - Stage-Outputs (z.B. stage_1_body) sind Basis-Analysen-Ergebnisse - Wurden nicht in cleaned_values gefunden (nur statische Platzhalter) FIX: - Collect stage outputs aus result.debug.stages[].output - Store als stage_N_key dict - Lookup: erst stage_outputs, dann cleaned_values - Description: "Output aus Stage X (Basis-Analyse)" - JSON-Werte automatisch serialisiert BEISPIEL Pipeline-Wertetabelle: ┌──────────────────────────────────────────────┐ │ 📊 Verwendete Werte (8) (+3 ausgeblendet) 🔬│ │ ┌──────────────────────────────────────────┐ │ │ │ weight_aktuell │ 85.2 kg │ Gewicht │ │ │ │ stage_1_body │ {"bmi":...│ Output...│ │ ← Stage output! │ │ stage_1_nutr... │ {"kcal"...│ Output...│ │ │ └──────────────────────────────────────────┘ │ └──────────────────────────────────────────────┘ AKTIVIERUNG Experten-Modus: 1. Analyse öffnen 2. "📊 Verwendete Werte" aufklappen 3. Button "🔬 Experten-Modus" klicken 4. Zeigt alle Platzhalter (auch leere stage outputs) version: 9.8.0 (feature) module: prompts 2.3.0, insights 1.6.0
This commit is contained in:
parent
15bd6cddeb
commit
e799edbae4
|
|
@ -856,6 +856,19 @@ async def execute_unified_prompt(
|
|||
elif result['type'] == 'pipeline':
|
||||
# Pipeline: collect from all stages
|
||||
stages_debug = result['debug'].get('stages', [])
|
||||
|
||||
# First, collect stage outputs (outputs from base prompts in each stage)
|
||||
stage_outputs = {}
|
||||
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)
|
||||
placeholder_key = f"stage_{stage_num}_{output_key}"
|
||||
stage_outputs[placeholder_key] = output_value
|
||||
|
||||
# Collect all resolved placeholders from prompts
|
||||
for stage_debug in stages_debug:
|
||||
for prompt_debug in stage_debug.get('prompts', []):
|
||||
resolved_keys = []
|
||||
|
|
@ -867,9 +880,13 @@ async def execute_unified_prompt(
|
|||
|
||||
for key in resolved_keys:
|
||||
if key not in metadata['placeholders']: # Avoid duplicates
|
||||
# Get full untruncated value
|
||||
value = cleaned_values.get(key, '')
|
||||
# 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
|
||||
if key.startswith('stage_'):
|
||||
desc = f"Output aus Stage {key.split('_')[1]} (Basis-Analyse)"
|
||||
else:
|
||||
# Find description in catalog
|
||||
desc = None
|
||||
for cat_items in catalog.values():
|
||||
|
|
@ -877,10 +894,11 @@ async def execute_unified_prompt(
|
|||
if matching:
|
||||
desc = matching[0].get('description', '')
|
||||
break
|
||||
desc = desc or ''
|
||||
|
||||
metadata['placeholders'][key] = {
|
||||
'value': value,
|
||||
'description': desc or ''
|
||||
'value': value if isinstance(value, str) else json.dumps(value, ensure_ascii=False),
|
||||
'description': desc
|
||||
}
|
||||
|
||||
# Save to database with metadata
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
|||
const showOnlyValues = isBasePrompt && isJsonOutput && Object.keys(placeholdersRaw).length > 0
|
||||
|
||||
const [showValues, setShowValues] = useState(showOnlyValues) // Auto-expand for base prompts with JSON
|
||||
const [expertMode, setExpertMode] = useState(false) // Show empty/technical placeholders
|
||||
|
||||
// Find matching prompt to get display_name
|
||||
const prompt = prompts.find(p => p.slug === ins.scope)
|
||||
|
|
@ -31,8 +32,20 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
|||
|
||||
// Use already-parsed metadata
|
||||
const metadata = metadataRaw
|
||||
const placeholders = placeholdersRaw
|
||||
const allPlaceholders = placeholdersRaw
|
||||
|
||||
// Filter placeholders: In normal mode, hide empty values
|
||||
const placeholders = expertMode
|
||||
? allPlaceholders
|
||||
: Object.fromEntries(
|
||||
Object.entries(allPlaceholders).filter(([key, data]) => {
|
||||
const val = data.value || ''
|
||||
return val.trim() !== '' && val !== 'nicht verfügbar' && val !== '[Nicht verfügbar]'
|
||||
})
|
||||
)
|
||||
|
||||
const placeholderCount = Object.keys(placeholders).length
|
||||
const hiddenCount = Object.keys(allPlaceholders).length - placeholderCount
|
||||
|
||||
return (
|
||||
<div className="card section-gap" style={{borderLeft:`3px solid var(--accent)`}}>
|
||||
|
|
@ -83,6 +96,7 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
|||
{/* Value Table */}
|
||||
{placeholderCount > 0 && (
|
||||
<div style={{ marginTop: 16, borderTop: '1px solid var(--border)', paddingTop: 12 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<div
|
||||
onClick={() => setShowValues(!showValues)}
|
||||
style={{
|
||||
|
|
@ -97,6 +111,30 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
|||
>
|
||||
{showValues ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
|
||||
📊 Verwendete Werte ({placeholderCount})
|
||||
{hiddenCount > 0 && !expertMode && (
|
||||
<span style={{ fontSize: 10, color: 'var(--text3)', fontWeight: 400 }}>
|
||||
(+{hiddenCount} ausgeblendet)
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showValues && Object.keys(allPlaceholders).length > 0 && (
|
||||
<button
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
setExpertMode(!expertMode)
|
||||
}}
|
||||
className="btn"
|
||||
style={{
|
||||
fontSize: 10,
|
||||
padding: '4px 8px',
|
||||
background: expertMode ? 'var(--accent)' : 'var(--surface)',
|
||||
color: expertMode ? 'white' : 'var(--text2)'
|
||||
}}
|
||||
>
|
||||
🔬 Experten-Modus
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{showValues && (
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user