AG-UI React Multi-step agent progress with live duration timers, ETA estimates, failure states, and skip support. Compact pill row or expanded vertical timeline. Progress bars that don't lie.
// Controlled mode — pass steps array directly import { ProgressTracker } from './ProgressTracker.jsx'; const steps = [ { id: 'fetch', label: 'Fetch data', status: 'done', startedAt: t0, completedAt: t0+1200 }, { id: 'parse', label: 'Parse results', status: 'running', startedAt: Date.now() }, { id: 'validate', label: 'Validate schema', status: 'pending' }, { id: 'save', label: 'Save to DB', status: 'pending' }, ]; // Expanded vertical timeline (default) return <ProgressTracker steps={steps} variant="expanded" theme="light" showETA={true} />; // Compact horizontal pill row return <ProgressTracker steps={steps} variant="compact" theme="dark" />; // AG-UI stream mode — auto-wired to event bus import { ProgressTrackerContainer } from './ProgressTracker.jsx'; const bus = new EventTarget(); // Your agent runtime dispatches these events: bus.dispatchEvent(new CustomEvent('STEP_STARTED', { detail: { stepId: 'fetch', label: 'Fetch data' } })); bus.dispatchEvent(new CustomEvent('PROGRESS_UPDATE', { detail: { stepId: 'fetch', description: 'Retrieved 240 records' } })); bus.dispatchEvent(new CustomEvent('STEP_COMPLETED', { detail: { stepId: 'fetch' } })); bus.dispatchEvent(new CustomEvent('STEP_FAILED', { detail: { stepId: 'save', error: 'Connection timeout' } })); bus.dispatchEvent(new CustomEvent('STEP_SKIPPED', { detail: { stepId: 'cache' } })); return <ProgressTrackerContainer eventSource={bus} initialSteps={[ { id: 'fetch', label: 'Fetch data', status: 'pending' }, { id: 'parse', label: 'Parse results', status: 'pending' }, { id: 'save', label: 'Save to DB', status: 'pending' }, { id: 'cache', label: 'Warm cache', status: 'pending' }, ]} variant="expanded" theme="light" showETA={true} />; // Step status values: // 'pending' → gray dot (not started) // 'running' → animated spinner + live elapsed timer // 'done' → green check + completion duration // 'failed' → red × + inline error message // 'skipped' → dashed circle + strikethrough label