Flexibles KI Prompt System #48

Merged
Lars merged 56 commits from develop into main 2026-03-26 14:49:48 +01:00
2 changed files with 81 additions and 36 deletions
Showing only changes of commit da803da816 - Show all commits

View File

@ -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

View File

@ -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=[] }) {
</tr>
</thead>
<tbody>
{Object.entries(placeholders).map(([key, data]) => (
<tr key={key} style={{ borderBottom: '1px solid var(--border)' }}>
<td style={{
padding: '6px 8px',
fontFamily: 'monospace',
color: 'var(--accent)',
whiteSpace: 'nowrap',
verticalAlign: 'top'
{Object.entries(placeholders).map(([key, data]) => {
const isExtracted = data.is_extracted
const isStageRaw = data.is_stage_raw
return (
<tr key={key} style={{
borderBottom: '1px solid var(--border)',
background: isStageRaw && expertMode ? 'var(--surface)' : 'transparent'
}}>
{key}
</td>
<td style={{
padding: '6px 8px',
fontFamily: 'monospace',
wordBreak: 'break-word',
maxWidth: '400px',
verticalAlign: 'top'
}}>
{data.value}
</td>
<td style={{
padding: '6px 8px',
color: 'var(--text3)',
fontSize: 10,
verticalAlign: 'top'
}}>
{data.description || '—'}
</td>
</tr>
))}
<td style={{
padding: '6px 8px',
fontFamily: 'monospace',
color: isStageRaw ? 'var(--text3)' : (isExtracted ? '#6B8E23' : 'var(--accent)'),
whiteSpace: 'nowrap',
verticalAlign: 'top',
fontSize: isStageRaw ? 10 : 11
}}>
{isExtracted && '↳ '}
{isStageRaw && '🔬 '}
{key}
</td>
<td style={{
padding: '6px 8px',
fontFamily: 'monospace',
wordBreak: 'break-word',
maxWidth: '400px',
verticalAlign: 'top',
fontSize: isStageRaw ? 9 : 11,
color: isStageRaw ? 'var(--text3)' : 'var(--text1)'
}}>
{data.value}
</td>
<td style={{
padding: '6px 8px',
color: 'var(--text3)',
fontSize: 10,
verticalAlign: 'top',
fontStyle: isExtracted ? 'italic' : 'normal'
}}>
{data.description || '—'}
</td>
</tr>
)
})}
</tbody>
</table>
</div>