'use client'; import React, { useState, useEffect } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Progress } from '@/components/ui/progress'; import { Input } from '@/components/ui/input'; import { SafeTimestamp } from './ClientTimeStampProvider'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { Activity, CheckCircle, AlertCircle, Clock, Zap, Filter, Search, RefreshCw, Eye, Trash2, TrendingUp, Brain } from 'lucide-react'; interface WorkflowStatus { workflow_id: string; status: string; current_stage: number; stages: Array<{ name: string; status: string; description: string; started_at?: string; completed_at?: string; error?: string; }>; progress_percentage: number; created_at: string; metrics?: { consciousness_scores?: number[]; accuracy_scores?: number[]; total_time?: number; error_count?: number; }; error?: string; } interface WorkflowMonitorProps { workflows?: WorkflowStatus[]; } export default function WorkflowMonitor({ workflows: propWorkflows }: WorkflowMonitorProps) { const [workflows, setWorkflows] = useState(propWorkflows || []); const [filteredWorkflows, setFilteredWorkflows] = useState([]); const [statusFilter, setStatusFilter] = useState('all'); const [searchTerm, setSearchTerm] = useState(''); const [isLoading, setIsLoading] = useState(false); const [selectedWorkflow, setSelectedWorkflow] = useState(null); // Fetch workflows on component mount and periodically useEffect(() => { fetchWorkflows(); const interval = setInterval(fetchWorkflows, 5000); // Refresh every 5 seconds return () => clearInterval(interval); }, []); // Update filtered workflows when filters change useEffect(() => { let filtered = workflows; // Apply status filter if (statusFilter !== 'all') { filtered = filtered.filter(w => w.status === statusFilter); } // Apply search filter if (searchTerm) { filtered = filtered.filter(w => w.workflow_id.toLowerCase().includes(searchTerm.toLowerCase()) || w.stages.some(stage => stage.name.toLowerCase().includes(searchTerm.toLowerCase())) ); } setFilteredWorkflows(filtered); }, [workflows, statusFilter, searchTerm]); const fetchWorkflows = async () => { if (propWorkflows) return; // Don't fetch if workflows are provided as props setIsLoading(true); try { const response = await fetch('/api/ai-architect/workflows'); if (response.ok) { const data = await response.json(); setWorkflows(data); } } catch (error) { console.error('Failed to fetch workflows:', error); } finally { setIsLoading(false); } }; const getStatusIcon = (status: string) => { switch (status) { case 'completed': return ; case 'running': return ; case 'failed': return ; case 'initializing': return ; default: return ; } }; const getStatusBadge = (status: string) => { const variants = { completed: 'border-green-500 text-green-400', running: 'border-blue-500 text-blue-400 animate-pulse', failed: 'border-red-500 text-red-400', initializing: 'border-yellow-500 text-yellow-400' }; return ( {status.toUpperCase()} ); }; const formatDuration = (startTime: string, endTime?: string) => { const start = new Date(startTime); const end = endTime ? new Date(endTime) : new Date(); const duration = Math.round((end.getTime() - start.getTime()) / 1000 / 60); // minutes if (duration < 60) { return `${duration}m`; } else { const hours = Math.floor(duration / 60); const minutes = duration % 60; return `${hours}h ${minutes}m`; } }; const deleteWorkflow = async (workflowId: string) => { if (!confirm('Are you sure you want to delete this workflow?')) return; try { // This would be an actual delete endpoint setWorkflows(prev => prev.filter(w => w.workflow_id !== workflowId)); } catch (error) { console.error('Failed to delete workflow:', error); } }; const getOverallStats = () => { const total = workflows.length; const completed = workflows.filter(w => w.status === 'completed').length; const running = workflows.filter(w => w.status === 'running').length; const failed = workflows.filter(w => w.status === 'failed').length; const avgConsciousness = workflows.length > 0 ? workflows.reduce((sum, w) => { const scores = w.metrics?.consciousness_scores || []; return sum + (scores.length > 0 ? scores[0] : 0); }, 0) / workflows.length : 0; const avgAccuracy = workflows.length > 0 ? workflows.reduce((sum, w) => { const scores = w.metrics?.accuracy_scores || []; return sum + (scores.length > 0 ? scores[0] : 0); }, 0) / workflows.length : 0; return { total, completed, running, failed, avgConsciousness, avgAccuracy }; }; const stats = getOverallStats(); return (
{/* Stats Overview */}
{stats.total}
Total Workflows
{stats.completed}
Completed
{stats.running}
Running
{stats.failed}
Failed
{(stats.avgConsciousness * 100).toFixed(1)}%
Avg Consciousness
{(stats.avgAccuracy * 100).toFixed(1)}%
Avg Accuracy
{/* Filters and Controls */}
Workflow Monitor {filteredWorkflows.length} workflows
setSearchTerm(e.target.value)} className="w-64" />
{/* Workflows List */}
{filteredWorkflows.length === 0 ? (

No workflows found

{workflows.length === 0 ? "No workflows have been created yet. Create your first workflow in the AI Architect panel." : "No workflows match your current filters. Try adjusting the search or filter criteria." }

) : ( filteredWorkflows.map((workflow) => (
{/* Header */}
{getStatusIcon(workflow.status)} {workflow.workflow_id} {getStatusBadge(workflow.status)} Created {formatDuration(workflow.created_at)} ago
{/* Progress */}
{Math.round(workflow.progress_percentage)}% Stage {workflow.current_stage + 1}/{workflow.stages.length}
{/* Current Stage */} {workflow.stages.length > 0 && workflow.current_stage < workflow.stages.length && (
Current: {workflow.stages[workflow.current_stage]?.name.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase())}
)} {/* Metrics */} {workflow.metrics && (
{workflow.metrics.consciousness_scores && workflow.metrics.consciousness_scores.length > 0 && (
Consciousness: {(workflow.metrics.consciousness_scores[0] * 100).toFixed(1)}%
)} {workflow.metrics.accuracy_scores && workflow.metrics.accuracy_scores.length > 0 && (
Accuracy: {(workflow.metrics.accuracy_scores[0] * 100).toFixed(1)}%
)} {workflow.metrics.total_time && (
Duration: {Math.round(workflow.metrics.total_time / 60)}m
)}
)} {/* Error Display */} {workflow.error && (
Error:

{workflow.error}

)}
{/* Actions */}
)) )}
{/* Detailed View Modal (Simple version) */} {selectedWorkflow && (
Workflow Details: {selectedWorkflow.workflow_id}
{/* Status and Progress */}
{getStatusBadge(selectedWorkflow.status)}
{Math.round(selectedWorkflow.progress_percentage)}%
{/* All Stages */}

Workflow Stages

{selectedWorkflow.stages.map((stage, index) => (
{getStatusIcon(stage.status)} {stage.name.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase())} {getStatusBadge(stage.status)}

{stage.description}

{stage.error && (

Error: {stage.error}

)}
{stage.started_at && ( Started: )} {stage.completed_at && ( Completed: )}
))}
{/* Detailed Metrics */} {selectedWorkflow.metrics && (

Performance Metrics

{selectedWorkflow.metrics.consciousness_scores && (
Consciousness Score: {(selectedWorkflow.metrics.consciousness_scores[0] * 100).toFixed(2)}%
)} {selectedWorkflow.metrics.accuracy_scores && (
Model Accuracy: {(selectedWorkflow.metrics.accuracy_scores[0] * 100).toFixed(2)}%
)} {selectedWorkflow.metrics.total_time && (
Total Time: {Math.round(selectedWorkflow.metrics.total_time / 60)} minutes
)}

System Metrics

Error Count: {selectedWorkflow.metrics.error_count || 0}
Created:
)}
)}
); }