import { useState, useCallback } from "react"; import type { ContractWithRelations } from "../../lib/api"; import { getSupervisorStatus, startSupervisor, stopSupervisor, resumeSupervisor, type SupervisorStatus, } from "../../lib/api"; interface AutopilotPanelProps { contract: ContractWithRelations; onUpdate: () => void; } const statusConfig: Record< SupervisorStatus["status"], { label: string; color: string; bgColor: string } > = { not_configured: { label: "Not Configured", color: "text-[#555]", bgColor: "bg-[#555]/10", }, pending: { label: "Ready", color: "text-yellow-400", bgColor: "bg-yellow-400/10", }, starting: { label: "Starting...", color: "text-blue-400", bgColor: "bg-blue-400/10", }, running: { label: "Running", color: "text-green-400", bgColor: "bg-green-400/10", }, paused: { label: "Paused", color: "text-orange-400", bgColor: "bg-orange-400/10", }, done: { label: "Completed", color: "text-blue-400", bgColor: "bg-blue-400/10", }, failed: { label: "Failed", color: "text-red-400", bgColor: "bg-red-400/10", }, }; export function AutopilotPanel({ contract, onUpdate }: AutopilotPanelProps) { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const supervisorStatus = getSupervisorStatus(contract); const config = statusConfig[supervisorStatus.status]; const handleStart = useCallback(async () => { if (!supervisorStatus.supervisorTaskId) return; setLoading(true); setError(null); try { await startSupervisor(supervisorStatus.supervisorTaskId); onUpdate(); } catch (e) { setError(e instanceof Error ? e.message : "Failed to start autopilot"); } finally { setLoading(false); } }, [supervisorStatus.supervisorTaskId, onUpdate]); const handleStop = useCallback(async () => { if (!supervisorStatus.supervisorTaskId) return; setLoading(true); setError(null); try { await stopSupervisor(supervisorStatus.supervisorTaskId); onUpdate(); } catch (e) { setError(e instanceof Error ? e.message : "Failed to stop autopilot"); } finally { setLoading(false); } }, [supervisorStatus.supervisorTaskId, onUpdate]); const handleResume = useCallback(async () => { setLoading(true); setError(null); try { await resumeSupervisor(contract.id, { resumeMode: "continue" }); // After resuming, we need to start the task if (supervisorStatus.supervisorTaskId) { await startSupervisor(supervisorStatus.supervisorTaskId); } onUpdate(); } catch (e) { setError(e instanceof Error ? e.message : "Failed to resume autopilot"); } finally { setLoading(false); } }, [contract.id, supervisorStatus.supervisorTaskId, onUpdate]); // Don't show panel for task-type contracts (they don't have supervisors) if (contract.contractType === "task") { return null; } return (

Autopilot Mode

{config.label}

{supervisorStatus.status === "not_configured" ? ( "This contract does not have an autopilot supervisor configured." ) : supervisorStatus.status === "running" ? ( "Autopilot is actively working on this contract, spawning tasks and managing progress." ) : supervisorStatus.status === "pending" ? ( "Autopilot is ready to start. Click 'Enable' to begin autonomous work." ) : supervisorStatus.status === "paused" ? ( "Autopilot is paused. Click 'Resume' to continue work." ) : supervisorStatus.status === "failed" ? ( "Autopilot encountered an error. You can resume to retry." ) : supervisorStatus.status === "done" ? ( "Autopilot has completed its work on this contract." ) : ( "Autopilot is initializing..." )}

{error && (
{error}
)}
{supervisorStatus.canStart && ( )} {supervisorStatus.canResume && ( )} {supervisorStatus.canStop && ( )}
{/* Show running indicator when active */} {supervisorStatus.status === "running" && (
Autopilot is actively working
)} {supervisorStatus.status === "starting" && (
Initializing autopilot...
)}
); }