import { isHumanMessageSDK } from "@/lib/langchain-messages"; import { UseStream, useStream } from "@langchain/langgraph-sdk/react"; import { AssistantMessage } from "../thread/messages/ai"; import { Dispatch, SetStateAction, useEffect, useRef } from "react"; import { ManagerGraphState } from "@open-swe/shared/open-swe/manager/types"; import { PlannerGraphState } from "@open-swe/shared/open-swe/planner/types"; import { GraphState } from "@open-swe/shared/open-swe/types"; interface ActionsRendererProps { graphId: string; threadId: string; runId?: string; setProgrammerSession?: ( session: ManagerGraphState["programmerSession"], ) => void; programmerSession?: ManagerGraphState["programmerSession"]; setSelectedTab?: Dispatch>; } export function ActionsRenderer({ graphId, threadId, runId, setProgrammerSession, programmerSession, setSelectedTab, }: ActionsRendererProps) { const stream = useStream({ apiUrl: process.env.NEXT_PUBLIC_API_URL, assistantId: graphId, reconnectOnMount: true, threadId, }); const streamJoined = useRef(false); useEffect(() => { if (!streamJoined.current && runId) { streamJoined.current = true; stream.joinStream(runId).catch(console.error); } }, [runId]); const nonHumanMessages = stream.messages?.filter( (m) => !isHumanMessageSDK(m), ); // TODO: Need a better way to handle this. Not great like this... useEffect(() => { if ( "programmerSession" in stream.values && stream.values.programmerSession && (stream.values.programmerSession.runId !== programmerSession?.runId || stream.values.programmerSession.threadId !== programmerSession?.threadId) ) { setProgrammerSession?.(stream.values.programmerSession); setSelectedTab?.("programmer"); } }, [stream.values]); return (
{nonHumanMessages?.map((m) => ( >} message={m} isLoading={false} handleRegenerate={() => {}} /> ))}
); }