Skip to content

Commit 94fe814

Browse files
committed
address blip of empty state
1 parent 48eeeae commit 94fe814

File tree

2 files changed

+169
-157
lines changed

2 files changed

+169
-157
lines changed

frontend/app/components/ChatWindow.tsx

Lines changed: 164 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,12 @@ export function ChatWindow() {
8585
areThreadsLoading,
8686
} = useThreadList(userId);
8787
const { streamState, startStream, stopStream } = useStreamState();
88-
const { refreshMessages, messages, setMessages, next } = useThreadMessages(
89-
currentThread?.thread_id ?? null,
90-
streamState,
91-
stopStream,
92-
);
88+
const { refreshMessages, messages, setMessages, next, areMessagesLoading } =
89+
useThreadMessages(
90+
currentThread?.thread_id ?? null,
91+
streamState,
92+
stopStream,
93+
);
9394

9495
const setLanggraphInfo = async () => {
9596
try {
@@ -255,7 +256,6 @@ export function ChatWindow() {
255256
window.location.pathname,
256257
);
257258
};
258-
259259
return (
260260
<>
261261
<div className="flex items-center rounded grow max-h-full">
@@ -282,174 +282,181 @@ export function ChatWindow() {
282282
marginX={"12px"}
283283
height={"100%"}
284284
>
285-
<Flex
286-
direction={"column"}
287-
alignItems={"center"}
288-
flexGrow={"1"}
289-
margin={"24px"}
290-
height={"100%"}
291-
>
285+
{areMessagesLoading ? (
286+
<Spinner className="my-2"/>
287+
) : (
292288
<Flex
293289
direction={"column"}
294290
alignItems={"center"}
295-
marginTop={messages.length > 0 ? "" : "64px"}
291+
flexGrow={"1"}
292+
margin={"24px"}
293+
height={"100%"}
296294
>
297-
<Heading
298-
fontSize={messages.length > 0 ? "2xl" : "3xl"}
299-
fontWeight={"medium"}
300-
mb={1}
301-
color={"white"}
295+
<Flex
296+
direction={"column"}
297+
alignItems={"center"}
298+
marginTop={messages.length > 0 ? "" : "64px"}
302299
>
303-
Chat LangChain 🦜🔗
304-
</Heading>
305-
{messages.length > 0 ? (
306300
<Heading
307-
fontSize="md"
308-
fontWeight={"normal"}
301+
fontSize={messages.length > 0 ? "2xl" : "3xl"}
302+
fontWeight={"medium"}
309303
mb={1}
310304
color={"white"}
311305
>
312-
We appreciate feedback!
306+
Chat LangChain 🦜🔗
313307
</Heading>
314-
) : (
315-
<Heading
316-
fontSize="xl"
317-
fontWeight={"normal"}
318-
color={"white"}
319-
marginTop={"10px"}
320-
textAlign={"center"}
321-
>
322-
Ask me anything about LangChain&apos;s{" "}
323-
<Link href="https://python.langchain.com/" color={"blue.200"}>
324-
Python documentation!
325-
</Link>
326-
</Heading>
327-
)}
328-
<div className="text-white flex flex-wrap items-center mt-4">
329-
<div className="flex items-center mb-2">
330-
<span className="shrink-0 mr-2">Powered by</span>
331-
{llmIsLoading ? (
332-
<Spinner className="my-2"></Spinner>
333-
) : (
334-
<Select
335-
value={llm}
336-
onChange={(e) => {
337-
insertUrlParam("llm", e.target.value);
338-
setLlm(e.target.value);
339-
}}
340-
width={"240px"}
308+
{messages.length > 0 ? (
309+
<Heading
310+
fontSize="md"
311+
fontWeight={"normal"}
312+
mb={1}
313+
color={"white"}
314+
>
315+
We appreciate feedback!
316+
</Heading>
317+
) : (
318+
<Heading
319+
fontSize="xl"
320+
fontWeight={"normal"}
321+
color={"white"}
322+
marginTop={"10px"}
323+
textAlign={"center"}
324+
>
325+
Ask me anything about LangChain&apos;s{" "}
326+
<Link
327+
href="https://python.langchain.com/"
328+
color={"blue.200"}
341329
>
342-
<option value="openai_gpt_3_5_turbo">
343-
GPT-3.5-Turbo
344-
</option>
345-
<option value="anthropic_claude_3_haiku">
346-
Claude 3 Haiku
347-
</option>
348-
<option value="google_gemini_pro">
349-
Google Gemini Pro
350-
</option>
351-
<option value="fireworks_mixtral">
352-
Mixtral (via Fireworks.ai)
353-
</option>
354-
<option value="cohere_command">Cohere</option>
355-
</Select>
356-
)}
357-
</div>
358-
</div>
359-
</Flex>
360-
<div
361-
className="flex flex-col-reverse w-full mb-2 overflow-auto max-h-[75vh]"
362-
ref={messageContainerRef}
363-
>
364-
{messages.length > 0 ? (
365-
<>
366-
{next.length > 0 &&
367-
streamState?.status !== "inflight" &&
368-
currentThread != null && (
369-
<Button
370-
key={"continue-button"}
371-
backgroundColor={"rgb(58, 58, 61)"}
372-
_hover={{ backgroundColor: "rgb(78,78,81)" }}
373-
onClick={() =>
374-
continueStream(currentThread["thread_id"])
375-
}
330+
Python documentation!
331+
</Link>
332+
</Heading>
333+
)}
334+
<div className="text-white flex flex-wrap items-center mt-4">
335+
<div className="flex items-center mb-2">
336+
<span className="shrink-0 mr-2">Powered by</span>
337+
{llmIsLoading ? (
338+
<Spinner className="my-2"></Spinner>
339+
) : (
340+
<Select
341+
value={llm}
342+
onChange={(e) => {
343+
insertUrlParam("llm", e.target.value);
344+
setLlm(e.target.value);
345+
}}
346+
width={"240px"}
376347
>
377-
<ArrowDownIcon color={"white"} marginRight={"4px"} />
378-
<Text color={"white"}>Click to continue</Text>
379-
</Button>
348+
<option value="openai_gpt_3_5_turbo">
349+
GPT-3.5-Turbo
350+
</option>
351+
<option value="anthropic_claude_3_haiku">
352+
Claude 3 Haiku
353+
</option>
354+
<option value="google_gemini_pro">
355+
Google Gemini Pro
356+
</option>
357+
<option value="fireworks_mixtral">
358+
Mixtral (via Fireworks.ai)
359+
</option>
360+
<option value="cohere_command">Cohere</option>
361+
</Select>
380362
)}
381-
{[...messages].reverse().map((m, index) => (
382-
<ChatMessageBubble
383-
key={m.id}
384-
message={{ ...m }}
385-
feedbackUrls={streamState?.feedbackUrls}
386-
aiEmoji="🦜"
387-
isMostRecent={index === 0}
388-
messageCompleted={!isLoading}
389-
/>
390-
))}
391-
</>
392-
) : (
393-
<EmptyState onChoice={sendInitialQuestion} />
394-
)}
395-
</div>
396-
<InputGroup
397-
size="md"
398-
alignItems={"center"}
399-
maxWidth={messages.length === 0 ? "1024px" : "100%"}
400-
marginY={"12px"}
401-
>
402-
<AutoResizeTextarea
403-
value={input}
404-
maxRows={5}
405-
marginRight={"56px"}
406-
placeholder="What does RunnablePassthrough.assign() do?"
407-
textColor={"white"}
408-
borderColor={"rgb(58, 58, 61)"}
409-
onChange={(e) => setInput(e.target.value)}
410-
onKeyDown={(e) => {
411-
if (e.key === "Enter" && !e.shiftKey) {
412-
e.preventDefault();
413-
sendMessage();
414-
} else if (e.key === "Enter" && e.shiftKey) {
415-
e.preventDefault();
416-
setInput(input + "\n");
417-
}
418-
}}
419-
/>
420-
<InputRightElement h="full">
421-
<IconButton
422-
colorScheme="blue"
423-
rounded={"full"}
424-
aria-label="Send"
425-
icon={isLoading ? <SmallCloseIcon /> : <ArrowUpIcon />}
426-
type="submit"
427-
onClick={(e) => {
428-
e.preventDefault();
429-
if (isLoading) {
430-
stopStream?.();
431-
} else {
363+
</div>
364+
</div>
365+
</Flex>
366+
<div
367+
className="flex flex-col-reverse w-full mb-2 overflow-auto max-h-[75vh]"
368+
ref={messageContainerRef}
369+
>
370+
{messages.length > 0 ? (
371+
<>
372+
{next.length > 0 &&
373+
streamState?.status !== "inflight" &&
374+
currentThread != null && (
375+
<Button
376+
key={"continue-button"}
377+
backgroundColor={"rgb(58, 58, 61)"}
378+
_hover={{ backgroundColor: "rgb(78,78,81)" }}
379+
onClick={() =>
380+
continueStream(currentThread["thread_id"])
381+
}
382+
>
383+
<ArrowDownIcon color={"white"} marginRight={"4px"} />
384+
<Text color={"white"}>Click to continue</Text>
385+
</Button>
386+
)}
387+
{[...messages].reverse().map((m, index) => (
388+
<ChatMessageBubble
389+
key={m.id}
390+
message={{ ...m }}
391+
feedbackUrls={streamState?.feedbackUrls}
392+
aiEmoji="🦜"
393+
isMostRecent={index === 0}
394+
messageCompleted={!isLoading}
395+
/>
396+
))}
397+
</>
398+
) : (
399+
<EmptyState onChoice={sendInitialQuestion} />
400+
)}
401+
</div>
402+
<InputGroup
403+
size="md"
404+
alignItems={"center"}
405+
maxWidth={messages.length === 0 ? "1024px" : "100%"}
406+
marginY={"12px"}
407+
>
408+
<AutoResizeTextarea
409+
value={input}
410+
maxRows={5}
411+
marginRight={"56px"}
412+
placeholder="What does RunnablePassthrough.assign() do?"
413+
textColor={"white"}
414+
borderColor={"rgb(58, 58, 61)"}
415+
onChange={(e) => setInput(e.target.value)}
416+
onKeyDown={(e) => {
417+
if (e.key === "Enter" && !e.shiftKey) {
418+
e.preventDefault();
432419
sendMessage();
420+
} else if (e.key === "Enter" && e.shiftKey) {
421+
e.preventDefault();
422+
setInput(input + "\n");
433423
}
434424
}}
435425
/>
436-
</InputRightElement>
437-
</InputGroup>
438-
{messages.length === 0 ? (
439-
<footer className="flex justify-center mt-auto h-4 fixed bottom-4">
440-
<a
441-
href="https://github.com/langchain-ai/chat-langchain"
442-
target="_blank"
443-
className="text-white flex items-center"
444-
>
445-
<img src="/images/github-mark.svg" className="h-4 mr-1" />
446-
<span>View Source</span>
447-
</a>
448-
</footer>
449-
) : (
450-
""
451-
)}
452-
</Flex>
426+
<InputRightElement h="full">
427+
<IconButton
428+
colorScheme="blue"
429+
rounded={"full"}
430+
aria-label="Send"
431+
icon={isLoading ? <SmallCloseIcon /> : <ArrowUpIcon />}
432+
type="submit"
433+
onClick={(e) => {
434+
e.preventDefault();
435+
if (isLoading) {
436+
stopStream?.();
437+
} else {
438+
sendMessage();
439+
}
440+
}}
441+
/>
442+
</InputRightElement>
443+
</InputGroup>
444+
{messages.length === 0 ? (
445+
<footer className="flex justify-center mt-auto h-4 fixed bottom-4">
446+
<a
447+
href="https://github.com/langchain-ai/chat-langchain"
448+
target="_blank"
449+
className="text-white flex items-center"
450+
>
451+
<img src="/images/github-mark.svg" className="h-4 mr-1" />
452+
<span>View Source</span>
453+
</a>
454+
</footer>
455+
) : (
456+
""
457+
)}
458+
</Flex>
459+
)}
453460
</Flex>
454461
</div>
455462
</>

frontend/app/hooks/useThreadMessages.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,12 @@ export function useThreadMessages(
4040
const client = useLangGraphClient();
4141
const [messages, setMessages] = useState<Message[]>([]);
4242
const [next, setNext] = useState<string[]>([]);
43+
const [areMessagesLoading, setAreMessagesLoading] = useState(false);
4344
const prevStreamStatus = usePrevious(streamState?.status);
4445

4546
const refreshMessages = useCallback(async () => {
4647
if (threadId) {
48+
setAreMessagesLoading(true);
4749
const { values, next } = await client.threads.getState<{
4850
messages: Message[];
4951
documents: Document[];
@@ -54,6 +56,7 @@ export function useThreadMessages(
5456
);
5557
setMessages(messages);
5658
setNext(next);
59+
setAreMessagesLoading(false);
5760
}
5861
}, [threadId]);
5962

@@ -100,13 +103,15 @@ export function useThreadMessages(
100103
),
101104
setMessages,
102105
next,
106+
areMessagesLoading,
103107
}),
104108
[
105109
messages,
106110
streamState?.messages,
107111
streamState?.documents,
108112
next,
109113
refreshMessages,
114+
areMessagesLoading,
110115
],
111116
);
112117
}

0 commit comments

Comments
 (0)