Flexibles KI Prompt System #48
|
|
@ -856,6 +856,19 @@ async def execute_unified_prompt(
|
||||||
elif result['type'] == 'pipeline':
|
elif result['type'] == 'pipeline':
|
||||||
# Pipeline: collect from all stages
|
# Pipeline: collect from all stages
|
||||||
stages_debug = result['debug'].get('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 stage_debug in stages_debug:
|
||||||
for prompt_debug in stage_debug.get('prompts', []):
|
for prompt_debug in stage_debug.get('prompts', []):
|
||||||
resolved_keys = []
|
resolved_keys = []
|
||||||
|
|
@ -867,20 +880,25 @@ async def execute_unified_prompt(
|
||||||
|
|
||||||
for key in resolved_keys:
|
for key in resolved_keys:
|
||||||
if key not in metadata['placeholders']: # Avoid duplicates
|
if key not in metadata['placeholders']: # Avoid duplicates
|
||||||
# Get full untruncated value
|
# Get value: first try stage outputs, then cleaned_values
|
||||||
value = cleaned_values.get(key, '')
|
value = stage_outputs.get(key, cleaned_values.get(key, ''))
|
||||||
|
|
||||||
# Find description in catalog
|
# For stage output placeholders, add special description
|
||||||
desc = None
|
if key.startswith('stage_'):
|
||||||
for cat_items in catalog.values():
|
desc = f"Output aus Stage {key.split('_')[1]} (Basis-Analyse)"
|
||||||
matching = [item for item in cat_items if item['key'] == key]
|
else:
|
||||||
if matching:
|
# Find description in catalog
|
||||||
desc = matching[0].get('description', '')
|
desc = None
|
||||||
break
|
for cat_items in catalog.values():
|
||||||
|
matching = [item for item in cat_items if item['key'] == key]
|
||||||
|
if matching:
|
||||||
|
desc = matching[0].get('description', '')
|
||||||
|
break
|
||||||
|
desc = desc or ''
|
||||||
|
|
||||||
metadata['placeholders'][key] = {
|
metadata['placeholders'][key] = {
|
||||||
'value': value,
|
'value': value if isinstance(value, str) else json.dumps(value, ensure_ascii=False),
|
||||||
'description': desc or ''
|
'description': desc
|
||||||
}
|
}
|
||||||
|
|
||||||
# Save to database with metadata
|
# 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 showOnlyValues = isBasePrompt && isJsonOutput && Object.keys(placeholdersRaw).length > 0
|
||||||
|
|
||||||
const [showValues, setShowValues] = useState(showOnlyValues) // Auto-expand for base prompts with JSON
|
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
|
// Find matching prompt to get display_name
|
||||||
const prompt = prompts.find(p => p.slug === ins.scope)
|
const prompt = prompts.find(p => p.slug === ins.scope)
|
||||||
|
|
@ -31,8 +32,20 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
||||||
|
|
||||||
// Use already-parsed metadata
|
// Use already-parsed metadata
|
||||||
const metadata = metadataRaw
|
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 placeholderCount = Object.keys(placeholders).length
|
||||||
|
const hiddenCount = Object.keys(allPlaceholders).length - placeholderCount
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card section-gap" style={{borderLeft:`3px solid var(--accent)`}}>
|
<div className="card section-gap" style={{borderLeft:`3px solid var(--accent)`}}>
|
||||||
|
|
@ -83,20 +96,45 @@ function InsightCard({ ins, onDelete, defaultOpen=false, prompts=[] }) {
|
||||||
{/* Value Table */}
|
{/* Value Table */}
|
||||||
{placeholderCount > 0 && (
|
{placeholderCount > 0 && (
|
||||||
<div style={{ marginTop: 16, borderTop: '1px solid var(--border)', paddingTop: 12 }}>
|
<div style={{ marginTop: 16, borderTop: '1px solid var(--border)', paddingTop: 12 }}>
|
||||||
<div
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||||
onClick={() => setShowValues(!showValues)}
|
<div
|
||||||
style={{
|
onClick={() => setShowValues(!showValues)}
|
||||||
cursor: 'pointer',
|
style={{
|
||||||
fontSize: 12,
|
cursor: 'pointer',
|
||||||
color: 'var(--text2)',
|
fontSize: 12,
|
||||||
fontWeight: 600,
|
color: 'var(--text2)',
|
||||||
display: 'flex',
|
fontWeight: 600,
|
||||||
alignItems: 'center',
|
display: 'flex',
|
||||||
gap: 6
|
alignItems: 'center',
|
||||||
}}
|
gap: 6
|
||||||
>
|
}}
|
||||||
{showValues ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
|
>
|
||||||
📊 Verwendete Werte ({placeholderCount})
|
{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>
|
</div>
|
||||||
|
|
||||||
{showValues && (
|
{showValues && (
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user