import React, { useState, useEffect } from 'react'; import { supabase } from '../services/supabase'; import { MessageSquare, Play, CheckCircle2, AlertCircle } from 'lucide-react'; import { motion } from 'framer-motion'; import { getApiUrl } from '../services/runtimeConfig'; interface DebateAgent { id: string; name: string; model: string; } interface DebateTask { id: string; title: string; status: string; } const renderContent = (content: any) => { if (!content) return null; if (typeof content === 'string') return content; if (Array.isArray(content) && content.length > 0 && typeof content[0] === 'object' && !Array.isArray(content[0])) { const keys = Object.keys(content[0]); const isTableCandidate = content.every(item => item && typeof item === 'object' && Object.keys(item).length === keys.length && keys.every(k => Object.keys(item).includes(k)) ); if (isTableCandidate && keys.length <= 6) { return (
{keys.map(k => ( ))} {content.map((item, i) => ( {keys.map(k => ( ))} ))}
{k.replace(/_/g, ' ')}
{typeof item[k] === 'object' ? JSON.stringify(item[k]) : String(item[k])}
); } } if (Array.isArray(content)) { return ( ); } if (typeof content === 'object') { return (
{Object.entries(content).map(([key, value]) => (
{key.replace(/_/g, ' ').replace(/-/g, ' ')}
{typeof value === 'object' ? renderContent(value) : String(value)}
))}
); } return String(content); }; const DebateView: React.FC = () => { const [agents, setAgents] = useState([]); const [tasks, setTasks] = useState([]); const [selectedTask, setSelectedTask] = useState(''); const [agentA, setAgentA] = useState(''); const [agentB, setAgentB] = useState(''); const [loading, setLoading] = useState(false); const [status, setStatus] = useState(null); const [debateResult, setDebateResult] = useState(null); useEffect(() => { const fetchData = async () => { const { data: agentsData } = await supabase.from('agents').select('id,name,model'); const { data: tasksData } = await supabase.from('tasks') .select('id,title,status') .in('status', ['todo', 'awaiting_approval']); if (agentsData) setAgents(agentsData); if (tasksData) setTasks(tasksData); }; fetchData(); }, []); useEffect(() => { let interval: number; if (loading && selectedTask) { interval = window.setInterval(async () => { const { data } = await supabase.from('tasks').select('status, output_data').eq('id', selectedTask).single(); if (data && data.status !== 'in_progress') { setLoading(false); setStatus(data.status === 'awaiting_approval' ? 'Debate completed successfully!' : `Debate finished with status: ${data.status}`); if (data.status === 'awaiting_approval' && data.output_data?.debate_history) { setDebateResult(data.output_data.debate_history); } window.clearInterval(interval); } }, 3000); } return () => window.clearInterval(interval); }, [loading, selectedTask]); const handleStartDebate = async () => { if (!selectedTask || !agentA || !agentB) { alert('Please select a task and two different agents.'); return; } if (agentA === agentB) { alert('Agents must be different for a debate.'); return; } setDebateResult(null); setLoading(true); setStatus('Initializing debate flow...'); try { const response = await fetch(`${getApiUrl()}/orchestrator/debate`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ task_id: selectedTask, agent_a_id: agentA, agent_b_id: agentB }) }); if (response.ok) { setStatus('Debate started! Monitor the agent console for progress.'); // We keep loading=true, the useEffect will poll until completion } else { setStatus('Failed to start debate.'); setLoading(false); } } catch { setStatus('Error connecting to backend.'); setLoading(false); } }; return (

Multi-Agent Debate

Two agents collaborate to refine a task's output.

{status && (
{status.includes('Error') || status.includes('Failed') ? : } {status}
)} {debateResult && (

Debate Results: Before & After

Initial Proposal
{renderContent(debateResult.initial)}
Refined Final Result
{renderContent(debateResult.final)}
{debateResult.critique && (
Critique Context
{renderContent(debateResult.critique)}
)}
)}
); }; export default DebateView;