diff --git a/src/components/thread/index.tsx b/src/components/thread/index.tsx index 28c270f..4c62e5b 100644 --- a/src/components/thread/index.tsx +++ b/src/components/thread/index.tsx @@ -1,5 +1,5 @@ import { v4 as uuidv4 } from "uuid"; -import { ReactNode, useEffect, useRef, ChangeEvent } from "react"; +import { ReactNode, useEffect, useRef } from "react"; import { motion } from "framer-motion"; import { cn } from "@/lib/utils"; import { useStreamContext } from "@/providers/Stream"; @@ -20,9 +20,9 @@ import { PanelRightOpen, PanelRightClose, SquarePen, + XIcon, Plus, CircleX, - XIcon, } from "lucide-react"; import { useQueryState, parseAsBoolean } from "nuqs"; import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom"; @@ -113,10 +113,10 @@ function OpenGitHubRepo() { } export function Thread() { - const [_threadId, _setThreadId] = useQueryState("threadId"); - const [artifactContext, setArtifactContext] = useArtifactContext(); const [artifactOpen, closeArtifact] = useArtifactOpen(); + + const [threadId, _setThreadId] = useQueryState("threadId"); const [chatHistoryOpen, setChatHistoryOpen] = useQueryState( "chatHistoryOpen", parseAsBoolean.withDefault(false), @@ -143,6 +143,14 @@ export function Thread() { const lastError = useRef(undefined); + const setThreadId = (id: string | null) => { + _setThreadId(id); + + // close artifact and reset artifact context + closeArtifact(); + setArtifactContext({}); + }; + useEffect(() => { if (!stream.error) { lastError.current = undefined; @@ -154,6 +162,7 @@ export function Thread() { // Message has already been logged. do not modify ref, return early. return; } + // Message is defined, and it has not been logged yet. Save it, and send the error lastError.current = message; toast.error("An error occurred. Please try again.", { @@ -200,16 +209,17 @@ export function Thread() { }; const toolMessages = ensureToolCallsHaveResponses(stream.messages); + + const context = + Object.keys(artifactContext).length > 0 ? artifactContext : undefined; + stream.submit( - { - messages: [...toolMessages, newHumanMessage], - context: artifactContext, - }, + { messages: [...toolMessages, newHumanMessage], context }, { streamMode: ["values"], optimisticValues: (prev) => ({ ...prev, - context: artifactContext, + context, messages: [ ...(prev.messages ?? []), ...toolMessages, @@ -223,7 +233,6 @@ export function Thread() { setContentBlocks([]); }; - // Restore handleRegenerate const handleRegenerate = ( parentCheckpoint: Checkpoint | null | undefined, ) => { @@ -236,13 +245,6 @@ export function Thread() { }); }; - const setThreadId = (id: string | null) => { - _setThreadId(id); - // close artifact and reset artifact context - closeArtifact(); - setArtifactContext({}); - }; - const threadId = _threadId; const chatStarted = !!threadId || !!messages.length; const hasNoAIOrToolMessages = !messages.find( (m) => m.type === "ai" || m.type === "tool", @@ -274,52 +276,36 @@ export function Thread() { - - {!chatStarted && ( -
-
- {(!chatHistoryOpen || !isLargeScreen) && ( - - )} -
-
- -
-
- )} - {chatStarted && ( -
-
-
+ + {!chatStarted && ( +
+
{(!chatHistoryOpen || !isLargeScreen) && (
- setThreadId(null)} - animate={{ - marginLeft: !chatHistoryOpen ? 48 : 0, - }} - transition={{ - type: "spring", - stiffness: 300, - damping: 30, - }} - > - - - Agent Chat - - -
- -
-
+
- setThreadId(null)} - > - -
- -
-
- )} - - - - {messages - .filter((m) => !m.id?.startsWith(DO_NOT_RENDER_ID_PREFIX)) - .map((message, index) => - message.type === "human" ? ( - - ) : ( - - ), + )} + {chatStarted && ( +
+
+
+ {(!chatHistoryOpen || !isLargeScreen) && ( + )} - {/* Special rendering case where there are no AI/tool messages, but there is an interrupt. - We need to render it outside of the messages list, since there are no messages to render */} - {hasNoAIOrToolMessages && !!stream.interrupt && ( - - )} - {isLoading && !firstTokenReceived && ( - - )} - - } - footer={ -
- {!chatStarted && ( -
- -

- Agent Chat -

-
- )} - - - -
+ setThreadId(null)} + animate={{ + marginLeft: !chatHistoryOpen ? 48 : 0, + }} + transition={{ + type: "spring", + stiffness: 300, + damping: 30, + }} > -
- + + Agent Chat + + +
+ +
+
+ +
+ setThreadId(null)} + > + + +
+ +
+
+ )} + + + + {messages + .filter((m) => !m.id?.startsWith(DO_NOT_RENDER_ID_PREFIX)) + .map((message, index) => + message.type === "human" ? ( + + ) : ( + + ), + )} + {/* Special rendering case where there are no AI/tool messages, but there is an interrupt. + We need to render it outside of the messages list, since there are no messages to render */} + {hasNoAIOrToolMessages && !!stream.interrupt && ( + + )} + {isLoading && !firstTokenReceived && ( + + )} + + } + footer={ +
+ {!chatStarted && ( +
+ +

+ Agent Chat +

+
+ )} + + + +
+ + -