"use client"; import { useEffect, useState } from "react"; export interface AgentStatus { agentName: string; status: "pending" | "running" | "completed" | "failed"; durationMs?: number; outputSummary?: string; error?: string; } const AGENT_NAMES = [ "trend-scout", "marketing-research-agent", "script-writer", "ad-creative-designer", "video-ad-producer", "copywriter-agent", "distribution-agent", ]; export function usePipelineProgress(campaignId: string | null) { const [agents, setAgents] = useState( AGENT_NAMES.map((name) => ({ agentName: name, status: "pending" })) ); const [pipelineStatus, setPipelineStatus] = useState("idle"); useEffect(() => { if (!campaignId) return; const source = new EventSource(`/api/campaigns/${campaignId}/stream`); source.onmessage = (event) => { try { const data = JSON.parse(event.data); if (data.type === "pipeline_started") { setPipelineStatus("running"); } else if (data.type === "agent_started") { setAgents((prev) => prev.map((a) => a.agentName === data.agentName ? { ...a, status: "running" } : a ) ); } else if (data.type === "agent_completed") { setAgents((prev) => prev.map((a) => a.agentName === data.agentName ? { ...a, status: "completed", durationMs: data.durationMs, outputSummary: data.outputSummary, } : a ) ); } else if (data.type === "agent_failed") { setAgents((prev) => prev.map((a) => a.agentName === data.agentName ? { ...a, status: "failed", error: data.error } : a ) ); } else if (data.type === "pipeline_complete") { setPipelineStatus(data.status || "complete"); } } catch { // ignore parse errors } }; source.onerror = () => { source.close(); }; return () => source.close(); }, [campaignId]); return { agents, pipelineStatus }; }