import { useEffect, useMemo, useState } from "react"; import { Interrupt } from "@langchain/langgraph-sdk"; import { cn } from "@/lib/utils"; import { useStreamContext } from "@/providers/Stream"; import { HITLRequest } from "./types"; import { StateView } from "./components/state-view"; import { ThreadActionsView } from "./components/thread-actions-view"; interface ThreadViewProps { interrupt: Interrupt | Interrupt[]; } export function ThreadView({ interrupt }: ThreadViewProps) { const thread = useStreamContext(); const interrupts = useMemo( () => (Array.isArray(interrupt) ? interrupt : [interrupt]).filter( (item): item is Interrupt => !!item, ), [interrupt], ); const [activeInterruptIndex, setActiveInterruptIndex] = useState(0); const [showDescription, setShowDescription] = useState(false); const [showState, setShowState] = useState(false); const showSidePanel = showDescription || showState; useEffect(() => { setActiveInterruptIndex(0); }, [interrupts.length]); const activeInterrupt = interrupts[activeInterruptIndex]; const activeDescription = activeInterrupt?.value?.action_requests?.[0]?.description ?? ""; const handleShowSidePanel = ( showStateFlag: boolean, showDescriptionFlag: boolean, ) => { if (showStateFlag && showDescriptionFlag) { console.error("Cannot show both state and description"); return; } if (showStateFlag) { setShowDescription(false); setShowState(true); } else if (showDescriptionFlag) { setShowState(false); setShowDescription(true); } else { setShowState(false); setShowDescription(false); } }; if (!activeInterrupt) { return null; } return (
{showSidePanel ? ( ) : (
{interrupts.length > 1 && (
{interrupts.map((it, idx) => { const title = it.value?.action_requests?.[0]?.name ?? `Interrupt ${idx + 1}`; return ( ); })}
)}
)}
); }