Spaces:
Running
Running
File size: 7,098 Bytes
f1fb638 aecda56 f1fb638 aecda56 f1fb638 aecda56 f1fb638 aecda56 f1fb638 | 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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
import React, { useState, useEffect } from 'react';
import { Wrench, X, Bug, HardHat, CheckCircle2, Play, AlertTriangle } from 'lucide-react';
import { fixArchitectureErrors, AgentStatus } from '../services/geminiService';
import { Node, Edge } from 'reactflow';
import { NodeData } from '../types';
interface FixerModalProps {
isOpen: boolean;
onClose: () => void;
onApply: (nodes: any[], edges: any[], logMsg?: string) => void;
errorMsg: string;
nodes: Node<NodeData>[];
edges: Edge[];
}
const FixerModal: React.FC<FixerModalProps> = ({ isOpen, onClose, onApply, errorMsg, nodes, edges }) => {
const [isFixing, setIsFixing] = useState(false);
const [agentStatus, setAgentStatus] = useState<AgentStatus>('idle');
const [agentMessage, setAgentMessage] = useState('');
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (isOpen) {
setAgentStatus('idle');
setAgentMessage('');
setError(null);
setIsFixing(false);
}
}, [isOpen]);
const handleStartFix = async () => {
setIsFixing(true);
setAgentStatus('debugger');
setAgentMessage('Initializing debugging protocols...');
try {
const result = await fixArchitectureErrors(nodes, edges, errorMsg, (status, msg) => {
setAgentStatus(status);
setAgentMessage(msg);
});
if (result && result.nodes && result.edges) {
// Post-process to ensure compatibility and safe access
const processedNodes = result.nodes.map((n: any) => {
const data = n.data || {};
const type = data.type || n.type || 'Identity'; // Fallback
return {
...n,
type: 'custom',
data: {
...data,
type: type,
label: data.label || n.label || type, // Safe access
params: data.params || {}
}
};
});
const processedEdges = result.edges.map((e: any) => ({
...e, animated: true, style: { stroke: '#94a3b8' }
}));
setTimeout(() => {
onApply(processedNodes, processedEdges, "Auto-Fixer agents applied corrections.");
onClose();
}, 1000);
}
} catch (err) {
setError(err instanceof Error ? err.message : "Failed to fix architecture");
setAgentStatus('error');
setIsFixing(false);
}
};
const renderAgentStep = (step: AgentStatus, icon: React.ReactNode, label: string) => {
const order = ['idle', 'debugger', 'architect', 'patcher', 'complete'];
const stepIdx = order.indexOf(step);
const currentIdx = order.indexOf(agentStatus);
const isCurrent = agentStatus === step;
const isDone = currentIdx > stepIdx && agentStatus !== 'error';
const isPending = currentIdx < stepIdx;
let statusColor = 'text-slate-600';
if (isDone) statusColor = 'text-emerald-400';
if (isCurrent) statusColor = 'text-amber-400 animate-pulse';
if (agentStatus === 'error') statusColor = 'text-red-400';
return (
<div className={`flex items-center gap-3 p-3 rounded-lg border transition-all duration-300 ${isCurrent ? 'bg-slate-800 border-amber-500/30' : 'bg-slate-900 border-slate-800'}`}>
<div className={`${statusColor}`}>
{isDone ? <CheckCircle2 size={24} /> : icon}
</div>
<div className="flex-1">
<div className={`font-semibold text-sm ${isCurrent ? 'text-amber-200' : isDone ? 'text-emerald-200' : 'text-slate-400'}`}>
{label}
</div>
{isCurrent && (
<div className="text-xs text-slate-500 mt-1">{agentMessage}</div>
)}
</div>
{isCurrent && <div className="w-2 h-2 rounded-full bg-amber-400 animate-ping" />}
</div>
);
}
if (!isOpen) return null;
return (
<div className="absolute inset-0 z-50 flex items-center justify-center bg-black/80 backdrop-blur-sm p-4">
<div className="bg-slate-950 w-full max-w-lg rounded-xl border border-red-500/30 shadow-2xl flex flex-col overflow-hidden animate-in fade-in zoom-in duration-200">
<div className="flex items-center justify-between px-6 py-4 border-b border-slate-800 bg-gradient-to-r from-slate-900 to-slate-800">
<h2 className="text-lg font-bold text-white flex items-center gap-2">
<Wrench className="text-red-400" size={20} />
Auto-Fixer
</h2>
<button onClick={onClose} className="text-slate-400 hover:text-white transition-colors">
<X size={20} />
</button>
</div>
<div className="p-6 space-y-6">
{!isFixing && agentStatus !== 'complete' ? (
<>
<div className="bg-red-500/10 border border-red-500/20 rounded-lg p-4 flex gap-3 items-start">
<AlertTriangle className="text-red-400 shrink-0 mt-0.5" size={18} />
<div>
<h3 className="text-sm font-bold text-red-200 mb-1">Detected Issues</h3>
<p className="text-xs text-red-300/80 font-mono leading-relaxed max-h-32 overflow-y-auto">
{errorMsg}
</p>
</div>
</div>
<div className="text-sm text-slate-400">
Deploy AI debugging agents to analyze the graph structure and apply corrections automatically.
</div>
<div className="flex justify-end pt-2">
<button
onClick={handleStartFix}
className="flex items-center gap-2 px-6 py-2.5 rounded-lg font-medium text-white bg-red-600 hover:bg-red-500 transition-all shadow-lg shadow-red-900/20"
>
<Play size={18} fill="currentColor" />
Run Diagnostics & Fix
</button>
</div>
</>
) : (
<div className="space-y-3">
{renderAgentStep('debugger', <Bug size={24} />, "Debugger: Identifying Root Cause")}
{renderAgentStep('architect', <HardHat size={24} />, "Architect: Planning Structural Fix")}
{renderAgentStep('patcher', <Wrench size={24} />, "Patcher: Applying Fixes to Graph")}
{agentStatus === 'complete' && (
<div className="text-center text-emerald-400 font-bold mt-6 animate-pulse">
Fixes Applied Successfully!
</div>
)}
{agentStatus === 'error' && (
<div className="text-center text-red-400 font-bold mt-6">
{error || "An error occurred during fixing."}
</div>
)}
</div>
)}
</div>
</div>
</div>
);
};
export default FixerModal;
|