File size: 3,035 Bytes
1c0c94d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | import { useEffect, useState } from 'react'
export default function TraceLog({ status, result }) {
const [steps, setSteps] = useState([])
useEffect(() => {
// Reset if starting fresh
if (!status && !result) {
setSteps([])
return
}
if (status && steps.length === 0) {
setSteps([{ msg: 'Ingesting image and running Quality Gate...', state: 'spin' }])
}
if (status === 'status: processing (analysing…)' && steps.length < 2) {
setSteps((s) => [
{ msg: 'Quality Gate passed. Image accepted.', state: 'ok' },
{ msg: 'Running YOLO11 Object Detection...', state: 'spin' }
])
// Simulate subsequent steps based on time since we are polling
setTimeout(() => {
setSteps((s) => [
s[0],
{ msg: 'YOLO11 Detection complete. Objects found.', state: 'ok' },
{ msg: 'Constructing Evidence Graph & Evaluating Deterministic Rules...', state: 'spin' }
])
}, 1500)
setTimeout(() => {
setSteps((s) => [
s[0], s[1],
{ msg: 'Rules evaluated. Candidates identified.', state: 'ok' },
{ msg: 'Routing candidates & querying Gemini VLM for verification...', state: 'spin' }
])
}, 3500)
}
if (result) {
if (result.status === 'completed') {
const v = result.violations || []
setSteps([
{ msg: 'Quality Gate passed. Image accepted.', state: 'ok' },
{ msg: 'YOLO11 Detection complete.', state: 'ok' },
{ msg: 'Rules evaluated. Candidates identified.', state: 'ok' },
{ msg: `VLM Verification complete. Confirmed ${v.length} violation(s).`, state: 'ok' },
{ msg: 'Evidence hashed and stored. Analysis complete.', state: 'ok' }
])
} else if (result.status === 'undeterminable') {
setSteps([
{ msg: 'Quality Gate: FAILED. Image too blurry/dark.', state: 'warn' },
{ msg: 'Agent Abstained to prevent false positive.', state: 'warn' }
])
}
}
}, [status, result])
if (!status && !result) return null
return (
<div className="card" style={{ background: 'var(--card2)', borderColor: 'var(--blue)' }}>
<h3 className="sec" style={{ color: 'var(--blue)', marginBottom: 12 }}>Agent Observability Trace</h3>
<ul style={{ listStyle: 'none', margin: 0, padding: 0, fontSize: 14 }}>
{steps.map((step, i) => (
<li key={i} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 0' }}>
{step.state === 'spin' && <span className="spinner" style={{ width: 14, height: 14, borderWidth: 2 }} />}
{step.state === 'ok' && <span style={{ color: 'var(--ok)' }}>✅</span>}
{step.state === 'warn' && <span style={{ color: 'var(--warn)' }}>⚠️</span>}
<span style={{ color: step.state === 'spin' ? 'var(--txt)' : 'var(--mut)' }}>
{step.msg}
</span>
</li>
))}
</ul>
</div>
)
}
|