fix: Show debug_prompt and debug_raw_response in WorkflowResultViewer
RICHTIGE ANALYSE: - Problem: WorkflowResultViewer zeigte nur output/error/metadata - Backend liefert bereits debug_prompt/debug_raw_response (wenn debug=true) - Lösung: Display für alle Debug-Felder hinzufügen Änderungen: - Zeige debug_prompt (vollständiger Prompt an KI) - Zeige debug_raw_response (rohe KI-Antwort) - Zeige analysis_core (geparste Ergebnisse) - Zeige normalized_signals (Signale mit Status) - Failed Nodes: Rote Border + roter Background - Node-Namen: debug_prompt_slug statt node_id - Bessere Struktur: Error zuerst, dann Debug-Info, dann Ergebnisse Fixes: User request 'pro Node deutliche Informationen zu Debug, Prompt und Ergebnis'
This commit is contained in:
parent
9a13bc43ac
commit
680269e971
|
|
@ -192,13 +192,18 @@ export function WorkflowResultViewer({ result, onClose }) {
|
||||||
Node States (Debug)
|
Node States (Debug)
|
||||||
</h3>
|
</h3>
|
||||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
||||||
{nodeStates.map((node) => (
|
{nodeStates.map((node) => {
|
||||||
|
const hasFailed = node.status === 'failed'
|
||||||
|
const hasError = node.error != null
|
||||||
|
return (
|
||||||
<div
|
<div
|
||||||
key={node.node_id}
|
key={node.node_id}
|
||||||
style={{
|
style={{
|
||||||
border: '1px solid var(--border)',
|
border: hasFailed ? '2px solid #D85A30' : '1px solid var(--border)',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
overflow: 'hidden'
|
background: hasFailed ? '#D85A3010' : 'transparent',
|
||||||
|
overflow: 'hidden',
|
||||||
|
boxShadow: hasFailed ? '0 0 0 2px #D85A3020' : 'none'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Node Header */}
|
{/* Node Header */}
|
||||||
|
|
@ -216,13 +221,13 @@ export function WorkflowResultViewer({ result, onClose }) {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
{node.node_type === 'start' && '🚀'}
|
{node.debug_node_type === 'start' && '🚀'}
|
||||||
{node.node_type === 'analysis' && '🤖'}
|
{node.debug_node_type === 'analysis' && '🤖'}
|
||||||
{node.node_type === 'logic' && '⚡'}
|
{node.debug_node_type === 'logic' && '⚡'}
|
||||||
{node.node_type === 'join' && '🔀'}
|
{node.debug_node_type === 'join' && '🔀'}
|
||||||
{node.node_type === 'end' && '🏁'}
|
{node.debug_node_type === 'end' && '🏁'}
|
||||||
{' '}
|
{' '}
|
||||||
{node.node_label || node.node_id}
|
{node.debug_prompt_slug || node.node_label || (node.debug_node_type ? `${node.debug_node_type}-${node.node_id.substring(0, 8)}` : node.node_id)}
|
||||||
{node.status === 'skipped' && (
|
{node.status === 'skipped' && (
|
||||||
<span style={{ color: 'var(--text3)', marginLeft: '8px' }}>
|
<span style={{ color: 'var(--text3)', marginLeft: '8px' }}>
|
||||||
(skipped)
|
(skipped)
|
||||||
|
|
@ -237,45 +242,91 @@ export function WorkflowResultViewer({ result, onClose }) {
|
||||||
{/* Node Details */}
|
{/* Node Details */}
|
||||||
{expandedNodes[node.node_id] && (
|
{expandedNodes[node.node_id] && (
|
||||||
<div style={{ padding: '12px', fontSize: '12px' }}>
|
<div style={{ padding: '12px', fontSize: '12px' }}>
|
||||||
{node.output && (
|
{/* Error (show first if present) */}
|
||||||
<div style={{ marginBottom: '8px' }}>
|
{node.error && (
|
||||||
<strong>Output:</strong>
|
<div style={{ marginBottom: '12px', padding: '12px', background: '#D85A3015', border: '1px solid #D85A30', borderRadius: '6px' }}>
|
||||||
<pre
|
<div style={{ fontSize: '12px', fontWeight: 600, color: '#D85A30', marginBottom: '6px' }}>
|
||||||
style={{
|
Error:
|
||||||
marginTop: '4px',
|
</div>
|
||||||
padding: '8px',
|
<pre style={{ margin: 0, fontSize: '12px', color: '#D85A30', whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>
|
||||||
background: 'var(--bg)',
|
{node.error}
|
||||||
borderRadius: '4px',
|
|
||||||
fontSize: '11px',
|
|
||||||
overflowX: 'auto',
|
|
||||||
maxHeight: '200px',
|
|
||||||
overflowY: 'auto'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{typeof node.output === 'string'
|
|
||||||
? node.output
|
|
||||||
: JSON.stringify(node.output, null, 2)}
|
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{node.error && (
|
|
||||||
<div style={{ color: 'var(--danger)', marginBottom: '8px' }}>
|
{/* Debug Prompt (vollständiger Prompt) */}
|
||||||
<strong>Error:</strong> {node.error}
|
{node.debug_prompt && (
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text2)', marginBottom: '6px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
|
||||||
|
Prompt:
|
||||||
|
</div>
|
||||||
|
<pre style={{ margin: 0, padding: '12px', background: 'var(--surface2)', borderRadius: '6px', fontSize: '12px', lineHeight: '1.6', color: 'var(--text1)', whiteSpace: 'pre-wrap', wordBreak: 'break-word', maxHeight: '400px', overflowY: 'auto', border: '1px solid var(--border)' }}>
|
||||||
|
{node.debug_prompt}
|
||||||
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Debug Raw Response (rohe KI-Antwort) */}
|
||||||
|
{node.debug_raw_response && (
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text2)', marginBottom: '6px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
|
||||||
|
Rohe Antwort:
|
||||||
|
</div>
|
||||||
|
<pre style={{ margin: 0, padding: '12px', background: 'var(--surface2)', borderRadius: '6px', fontSize: '12px', lineHeight: '1.6', color: 'var(--text1)', whiteSpace: 'pre-wrap', wordBreak: 'break-word', maxHeight: '400px', overflowY: 'auto', border: '1px solid var(--border)' }}>
|
||||||
|
{node.debug_raw_response}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Analysis Core (geparste Ergebnisse) */}
|
||||||
|
{node.analysis_core && (
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text2)', marginBottom: '6px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
|
||||||
|
Geparste Ergebnisse:
|
||||||
|
</div>
|
||||||
|
<pre style={{ margin: 0, padding: '12px', background: 'var(--surface2)', borderRadius: '6px', fontSize: '12px', lineHeight: '1.6', color: 'var(--text1)', whiteSpace: 'pre-wrap', wordBreak: 'break-word', maxHeight: '300px', overflowY: 'auto', border: '1px solid var(--border)' }}>
|
||||||
|
{node.analysis_core}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Normalized Signals */}
|
||||||
|
{node.normalized_signals && node.normalized_signals.length > 0 && (
|
||||||
|
<div style={{ marginBottom: '12px' }}>
|
||||||
|
<div style={{ fontSize: '12px', fontWeight: 600, color: 'var(--text2)', marginBottom: '6px', textTransform: 'uppercase', letterSpacing: '0.5px' }}>
|
||||||
|
Signale ({node.normalized_signals.length}):
|
||||||
|
</div>
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}>
|
||||||
|
{node.normalized_signals.map((sig, i) => (
|
||||||
|
<div key={i} style={{ padding: '8px', background: 'var(--surface2)', borderRadius: '4px', fontSize: '12px', border: '1px solid var(--border)' }}>
|
||||||
|
<span style={{ color: 'var(--text2)' }}>{sig.question_type}:</span>{' '}
|
||||||
|
<span style={{ fontWeight: 500, color: 'var(--text1)' }}>
|
||||||
|
"{sig.raw_value}" → "{sig.normalized_value}"
|
||||||
|
</span>{' '}
|
||||||
|
<span style={{ fontSize: '11px', padding: '2px 6px', borderRadius: '3px', background: sig.status === 'valid' ? '#1D9E7520' : '#D85A3020', color: sig.status === 'valid' ? '#1D9E75' : '#D85A30' }}>
|
||||||
|
{sig.status}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Output (fallback) */}
|
||||||
|
{node.output && !node.analysis_core && (
|
||||||
|
<div style={{ marginBottom: '8px' }}>
|
||||||
|
<strong>Output:</strong>
|
||||||
|
<pre style={{ marginTop: '4px', padding: '8px', background: 'var(--bg)', borderRadius: '4px', fontSize: '11px', overflowX: 'auto', maxHeight: '200px', overflowY: 'auto' }}>
|
||||||
|
{typeof node.output === 'string' ? node.output : JSON.stringify(node.output, null, 2)}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Metadata */}
|
||||||
{node.metadata && (
|
{node.metadata && (
|
||||||
<div style={{ marginTop: '8px' }}>
|
<div style={{ marginTop: '8px' }}>
|
||||||
<strong>Metadata:</strong>
|
<strong>Metadata:</strong>
|
||||||
<pre
|
<pre style={{ marginTop: '4px', padding: '8px', background: 'var(--bg)', borderRadius: '4px', fontSize: '11px', overflowX: 'auto' }}>
|
||||||
style={{
|
|
||||||
marginTop: '4px',
|
|
||||||
padding: '8px',
|
|
||||||
background: 'var(--bg)',
|
|
||||||
borderRadius: '4px',
|
|
||||||
fontSize: '11px',
|
|
||||||
overflowX: 'auto'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{JSON.stringify(node.metadata, null, 2)}
|
{JSON.stringify(node.metadata, null, 2)}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -283,7 +334,7 @@ export function WorkflowResultViewer({ result, onClose }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
))}
|
)})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user