import "./WorkflowPipeline.css"; const STAGES = [ { key: "EXTRACTION", label: "Extract" }, { key: "CHUNKING", label: "Chunk" }, { key: "EMBEDDING", label: "Embed" }, { key: "CLASSIFICATION", label: "Classify" }, { key: "KNOWLEDGE_EXTRACTION", label: "Knowledge" }, { key: "RECONCILIATION", label: "Reconcile" }, { key: "VALIDATION", label: "Validate" }, { key: "DECISION", label: "Decide" }, { key: "HUMAN_REVIEW", label: "Review" }, { key: "COMPLETED", label: "Complete" }, ]; // Map stage keys to metric stage names const METRIC_MAP = { EXTRACTION: "extraction", CHUNKING: "chunking", EMBEDDING: "embedding", KNOWLEDGE_EXTRACTION: "knowledge_extraction", RECONCILIATION: "reconciliation", VALIDATION: "validation", }; function getStageStatus(stage, currentNode, workflowStatus) { if (workflowStatus === "COMPLETED") return "done"; if (workflowStatus === "FAILED") { const currentIdx = STAGES.findIndex((s) => s.key === currentNode); const stageIdx = STAGES.findIndex((s) => s.key === stage.key); if (stageIdx < currentIdx) return "done"; if (stageIdx === currentIdx) return "failed"; return "pending"; } const currentIdx = STAGES.findIndex((s) => s.key === currentNode); const stageIdx = STAGES.findIndex((s) => s.key === stage.key); if (currentIdx < 0) return "pending"; if (stageIdx < currentIdx) return "done"; if (stageIdx === currentIdx) { if (workflowStatus === "WAITING_FOR_REVIEW" && stage.key === "HUMAN_REVIEW") return "active"; if (workflowStatus === "RUNNING") return "active"; return "done"; } return "pending"; } function formatMs(ms) { if (!ms || ms <= 0) return null; if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`; return `${Math.round(ms)}ms`; } /** * @param {object} props * @param {string} props.currentNode * @param {string} props.workflowStatus * @param {Array} [props.stageMetrics] - Array of {name, elapsed_ms, input_tokens, output_tokens} */ export function WorkflowPipeline({ currentNode, workflowStatus, stageMetrics }) { // Build metrics lookup const metricsMap = {}; if (stageMetrics) { for (const m of stageMetrics) { metricsMap[m.name] = m; } } return (