"use client"; import { useEffect, useRef, useState } from "react"; import { formatDistanceToNow } from "date-fns"; import { BargeInInput } from "@/components/mission-control/BargeInInput"; import { Badge } from "@/components/ui/badge"; import type { BadgeVariant } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { PanelControls } from "@/components/mission-control/PanelControls"; import { ScrollArea } from "@/components/ui/scroll-area"; import { useSessionStream, useSessions, type MissionControlConnectionStatus, type MissionControlMessageRole, } from "@/hooks/useMissionControl"; const ROLE_BADGE_VARIANT: Record = { user: "badge-blue", assistant: "status-success", tool: "badge-amber", system: "badge-muted", }; const CONNECTION_DOT_CLASS: Record = { connected: "bg-emerald-500", connecting: "bg-amber-500", error: "bg-red-500", }; const CONNECTION_TEXT: Record = { connected: "Connected", connecting: "Connecting", error: "Error", }; export interface OrchestratorPanelProps { sessionId?: string; onClose?: () => void; closeDisabled?: boolean; onExpand?: () => void; expanded?: boolean; } interface PanelHeaderActionsProps { onClose?: () => void; closeDisabled?: boolean; onExpand?: () => void; expanded?: boolean; } function PanelHeaderActions({ onClose, closeDisabled = false, onExpand, expanded = false, }: PanelHeaderActionsProps): React.JSX.Element | null { if (!onClose && !onExpand) { return null; } return (
{onExpand ? ( ) : null} {onClose ? ( ) : null}
); } function formatRelativeTimestamp(timestamp: string): string { const parsedDate = new Date(timestamp); if (Number.isNaN(parsedDate.getTime())) { return "just now"; } return formatDistanceToNow(parsedDate, { addSuffix: true }); } export function OrchestratorPanel({ sessionId, onClose, closeDisabled, onExpand, expanded, }: OrchestratorPanelProps): React.JSX.Element { const { messages, status, error } = useSessionStream(sessionId ?? ""); const { sessions } = useSessions(); const bottomAnchorRef = useRef(null); const [optimisticStatus, setOptimisticStatus] = useState(null); const selectedSessionStatus = sessions.find((session) => session.id === sessionId)?.status; const controlsStatus = optimisticStatus ?? selectedSessionStatus ?? "unknown"; const panelHeaderActionProps = { ...(onClose !== undefined ? { onClose } : {}), ...(closeDisabled !== undefined ? { closeDisabled } : {}), ...(onExpand !== undefined ? { onExpand } : {}), ...(expanded !== undefined ? { expanded } : {}), }; useEffect(() => { bottomAnchorRef.current?.scrollIntoView({ block: "end" }); }, [messages.length]); useEffect(() => { setOptimisticStatus(null); }, [sessionId, selectedSessionStatus]); if (!sessionId) { return (
Orchestrator Panel
Select an agent to view its stream
); } return (
Orchestrator Panel

Session: {sessionId}

{messages.length === 0 ? (

{error ?? "Waiting for messages..."}

) : ( messages.map((message) => (
{message.role}

{message.content}

)) )}
); }