import React, { useState, useEffect, useMemo } from "react"; import { ExampleTraceLite, ExampleTrace } from "@/types"; import { api } from "@/lib/api"; import { Button } from "@/components/ui/button"; import { useToast } from "@/hooks/use-toast"; import { useAgentGraph } from "@/context/AgentGraphContext"; import { CheckCircle, AlertTriangle } from "lucide-react"; import ExampleTraceDetailModal from "./ExampleTraceDetailModal"; import { AgentMultiSelect } from "@/components/ui/agent-multi-select"; interface Props { data?: any; onClose: () => void; } // Remove subset concept - load all traces as "Who_and_When" const SUBSETS = ["Who_and_When"] as const; type CountFilter = 1 | 2 | 3 | null; export const ExampleTraceModal: React.FC = ({ onClose: _onClose }) => { const [subset, setSubset] = useState<(typeof SUBSETS)[number]>(SUBSETS[0]); const [examples, setExamples] = useState([]); const [loading, setLoading] = useState(false); const [selectedAgents, setSelectedAgents] = useState([]); const [countFilter, setCountFilter] = useState(null); const [detailOpen, setDetailOpen] = useState(false); const [selectedExample, setSelectedExample] = useState( null ); const { toast } = useToast(); const { actions } = useAgentGraph(); const load = async (s: string) => { setLoading(true); try { // For "Who_and_When", load all traces (no subset filter) const subsetParam = s === "Who_and_When" ? undefined : s; const list = await api.exampleTraces.list(subsetParam); setExamples(list); } catch (e: any) { toast({ title: "Error", description: e.message }); } finally { setLoading(false); } }; useEffect(() => { load(subset); }, [subset]); // Unique agent options for current examples const agentOptions = useMemo(() => { const set = new Set(); examples.forEach((ex) => ex.agents?.forEach((a) => set.add(a))); return Array.from(set).sort(); }, [examples]); // Apply filters const filteredExamples = useMemo(() => { return examples.filter((ex) => { // agent multi-select filter if (selectedAgents.length) { const hasAll = selectedAgents.every((a) => ex.agents?.includes(a)); if (!hasAll) return false; } // count filter if (countFilter) { const c = ex.agents?.length || 0; if (countFilter === 3) { if (c < 3) return false; } else if (c !== countFilter) { return false; } } return true; }); }, [examples, selectedAgents, countFilter]); const handleImport = async (ex: ExampleTrace) => { setLoading(true); try { await api.exampleTraces.import(ex.subset, ex.id); toast({ title: "Imported", description: "Trace added to workspace" }); const tracesData = await api.traces.list(); actions.setTraces(Array.isArray(tracesData) ? tracesData : []); } catch (e: any) { toast({ title: "Import failed", description: e.message }); } finally { setLoading(false); } }; const clearFilters = () => { setSelectedAgents([]); setCountFilter(null); }; // UI helpers const countBtnVariant = (val: CountFilter) => val === countFilter ? "default" : "outline"; return (
{/* Toolbar */}
{/* Subset buttons */}
{SUBSETS.map((s) => ( ))}
{/* Agent multiselect */} {/* Count filter */}
Agents: {[1, 2, 3].map((n) => ( ))} {(selectedAgents.length > 0 || countFilter) && ( )}
{/* Content */}
{loading ? (

Loading...

) : filteredExamples.length === 0 ? (

No examples found

) : (
{filteredExamples.map((ex) => (
{ try { const full = await api.exampleTraces.get(ex.subset, ex.id); setSelectedExample(full); setDetailOpen(true); } catch (err: any) { toast({ title: "Error", description: err.message }); } }} > {/* Header with correctness indicator */}
{ex.question}
{ex.is_correct === true && ( )}
{/* Agent info */}
agents: {ex.agents?.map((agent, index) => ( {agent} {agent === ex.mistake_agent ? " ⚠️" : ""} {index < (ex.agents?.length || 0) - 1 ? "," : ""} )) || ?}
{/* Failure reason preview */} {ex.mistake_reason && (

{ex.mistake_reason}

)}
))}
)}
{/* Detail Drawer */} {selectedExample && ( setDetailOpen(o)} onImport={() => handleImport(selectedExample)} /> )}
); }; export default ExampleTraceModal;