Skip to content

Commit

Permalink
Chore/refactor code (#31)
Browse files Browse the repository at this point in the history
* fix: add useMemo useCallback to refactor code

* feat: playground and debug view thread delete

* chore: delete unused import and add useEffect for navigate
  • Loading branch information
Onelevenvy authored Sep 12, 2024
1 parent e84b491 commit 49ef90f
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 97 deletions.
2 changes: 1 addition & 1 deletion web/src/app/(applayout)/playground/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const ChatPlayground = () => {
transition="width 0.1s, visibility 0.1s"
>
<Box maxH="full" h="full">
<ChatHistoryList teamId={teamId!} />
<ChatHistoryList teamId={teamId!} isPlayground={true} />
</Box>
</Box>
</Flex>
Expand Down
68 changes: 35 additions & 33 deletions web/src/components/Playground/ChatHistoryList.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import {
Flex,
Spinner,
Container,
useColorModeValue,
IconButton,
Menu,
MenuButton,
MenuList,
MenuItem,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
ModalCloseButton,
useDisclosure,
Icon,
Box,
Text,
Expand All @@ -27,20 +14,15 @@ import useCustomToast from "../../hooks/useCustomToast";
import { useRouter } from "next/navigation";
import { useTranslation } from "react-i18next";
import React, { useEffect, useState } from "react";
import {
EllipsisVerticalIcon,
StarIcon,
Trash,
Trash2Icon,
} from "lucide-react";
import { StarIcon, Trash2Icon } from "lucide-react";
import useChatMessageStore from "@/store/chatMessageStore";
import { FaTrashCan } from "react-icons/fa6";

interface ChatHistoryProps {
teamId: string;
isPlayground?: boolean;
}

const ChatHistoryList = ({ teamId }: ChatHistoryProps) => {
const ChatHistoryList = ({ teamId, isPlayground }: ChatHistoryProps) => {
const queryClient = useQueryClient();

const navigate = useRouter();
Expand Down Expand Up @@ -86,39 +68,57 @@ const ChatHistoryList = ({ teamId }: ChatHistoryProps) => {
const deleteThreadMutation = useMutation(deleteThread, {
onError: (err: ApiError) => {
const errDetail = err.body?.detail;
showToast("Unable to delete thread.", `${errDetail}`, "error");
// showToast("Unable to delete thread.", `${errDetail}`, "error");
console.log("error", errDetail);
},
onSettled: () => {
queryClient.invalidateQueries(["threads", teamId]);
// queryClient.invalidateQueries(["threads", threadId]);
queryClient.invalidateQueries(["threads", selectedThreadId]);
},
});
const [selectedThreadId, setSelectedThreadId] = useState<string | null>(null);
const onClickRowHandler = (threadId: string) => {
navigate.push(`/playground?teamId=${teamId}&threadId=${threadId}`);
setSelectedThreadId(threadId);
if (isPlayground) {
navigate.push(`/playground?teamId=${teamId}&threadId=${threadId}`);
} else {
navigate.push(`/teams/${teamId}?threadId=${threadId}`);
}
};

const { setMessages } = useChatMessageStore();
const [shouldNavigate, setShouldNavigate] = useState(false);

const handleDeleteThread = () => {
if (selectedThreadId) {
deleteThreadMutation.mutate(selectedThreadId);

setMessages([]);
navigate.push(`/playground?teamId=${teamId}`);
setShouldNavigate(true);
}
};

if (isError) {
const errDetail = (error as ApiError).body?.detail;
useEffect(() => {
if (shouldNavigate) {
if (isPlayground) {
navigate.push(`/playground?teamId=${teamId}`);
} else {
navigate.push(`/steamsS/${teamId}`);
}
setShouldNavigate(false);
}
}, [shouldNavigate, isPlayground, teamId, navigate]);

if (isError || membersIsError) {
const errors = error || membersError;
const errDetail = (errors as ApiError).body?.detail;

showToast("Something went wrong.", `${errDetail}`, "error");
}
const [showMenu, setShowMenu] = useState(false);
const { t } = useTranslation();
return (
<>
{isLoading ? (
{isLoading && membersLoading ? (
<Flex justify="center" align="center" height="100vh" width="full">
<Spinner size="xl" color="ui.main" />
</Flex>
Expand Down Expand Up @@ -175,7 +175,7 @@ const ChatHistoryList = ({ teamId }: ChatHistoryProps) => {
{thread.query}
</Text>
</Box>
<Box mr={2} minW={"30%"} maxW={"30%"}>
<Box mr={2} minW={"40%"} maxW={"40%"}>
<Text
fontFamily="Arial, sans-serif"
fontSize={"sm"}
Expand All @@ -189,16 +189,18 @@ const ChatHistoryList = ({ teamId }: ChatHistoryProps) => {
<Box
display="flex"
position={"absolute"}
right={2}
right={1}
ml={1}
>
{/* <Menu> */}
<Button
as={IconButton}
size={"sm"}
aria-label="Options"
icon={<Icon as={Trash2Icon} w="4" h="4" />}
variant="ghost"
onClick={handleDeleteThread}
onClick={() => {
handleDeleteThread();
}}
/>
</Box>
)}
Expand Down
114 changes: 52 additions & 62 deletions web/src/components/Playground/ChatMain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
useQueryClient,
} from "react-query";
import useCustomToast from "../../hooks/useCustomToast";
import { useRef, useState } from "react";
import { useCallback, useRef, useState } from "react";
import {
getQueryString,
getRequestBody,
Expand Down Expand Up @@ -61,7 +61,9 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
const { t } = useTranslation();
const { teamId } = useChatTeamIdStore() as { teamId: string };

const [currentThreadId, setCurrentThreadId] = useState<string | null>(null);
const [currentThreadId, setCurrentThreadId] = useState<string | null>(
searchParams.get("threadId")
);
const showToast = useCustomToast();
const [input, setInput] = useState("");
const { messages, setMessages } = useChatMessageStore();
Expand Down Expand Up @@ -139,9 +141,7 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
id: threadId,
requestBody: data,
});

cancelablePromise.then((thread) => resolve(thread.id)).catch(reject);

cancelUpdateRef.current = () => cancelablePromise.cancel();
});
};
Expand All @@ -162,26 +162,21 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {

const processMessage = (response: ChatResponse) => {
setMessages((prevMessages: ChatResponse[]) => {
const updatedMessages = [...prevMessages];

const messageIndex = updatedMessages.findIndex(
const messageIndex = prevMessages.findIndex(
(msg) => msg.id === response.id
);

if (messageIndex !== -1) {
const currentMessage = updatedMessages[messageIndex];
updatedMessages[messageIndex] = {
...currentMessage,
// only content is streamable in chunks
content: currentMessage.content
? currentMessage.content + (response.content || "")
: null,
tool_output: response.tool_output,
};
} else {
updatedMessages.push(response);
return prevMessages.map((msg, index) =>
index === messageIndex
? {
...msg,
content: (msg.content ?? "") + (response.content ?? ""),
tool_output: response.tool_output,
}
: msg
);
}
return updatedMessages;
return [...prevMessages, response];
});
};

Expand Down Expand Up @@ -218,10 +213,9 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
},
});

// 从 TeamChat 数据中提取适合 ThreadUpdate 的信息

const threadUpdateData: ThreadUpdate = {
query: data.messages[0].content, // 假设第一条消息是查询
// 如果需要,可以添加其他 ThreadUpdate 所需的字段
query: data.messages[0].content,
};

const updatePromise = updateThreadMutation.mutateAsync(threadUpdateData);
Expand All @@ -235,17 +229,12 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
}
};

const interruptStreamAndUpdate = () => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
if (cancelUpdateRef.current) {
cancelUpdateRef.current();
}
const interruptStreamAndUpdate = useCallback(() => {
abortControllerRef.current?.abort();
cancelUpdateRef.current?.();
setIsInterruptible(false);

// 添加中断消息
setMessages((prev: ChatResponse[]) => [
setMessages((prev) => [
...prev,
{
type: "ai",
Expand All @@ -254,7 +243,7 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
name: "system",
},
]);
};
}, [setMessages, t]);

const chatTeam = async (data: TeamChat) => {
// Create a new thread or update current thread with most recent user query
Expand Down Expand Up @@ -312,39 +301,40 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
},
});

const onSubmit = async (e: React.FormEvent) => {
e.preventDefault();
mutation.mutate({ messages: [{ type: "human", content: input }] });
setInput("");
};
const onSubmit = useCallback(
async (e: React.FormEvent) => {
e.preventDefault();
mutation.mutate({ messages: [{ type: "human", content: input }] });
setInput("");
},
[input, mutation]
);

const newChatHandler = () => {
if (isPlayground) {
navigate.push(`/playground?teamId=${teamId}`);
setMessages([]);
} else {
navigate.push(`/teams/${teamId}`);
setMessages([]);
}
};
const newChatHandler = useCallback(() => {
const path = isPlayground
? `/playground?teamId=${teamId}`
: `/teams/${teamId}`;
navigate.push(path);
setMessages([]);
}, [isPlayground, teamId, navigate, setMessages]);

/**
* Submit the interrupt decision and optional tool message
*/
const onResumeHandler = (
decision: InterruptDecision,
tool_message?: string | null
) => {
mutation.mutate({
messages: [
{
type: "human",
content: tool_message || decision,
},
],
interrupt: { decision, tool_message },
});
};
const onResumeHandler = useCallback(
(decision: InterruptDecision, tool_message?: string | null) => {
mutation.mutate({
messages: [
{
type: "human",
content: tool_message || decision,
},
],
interrupt: { decision, tool_message },
});
},
[mutation]
);

return (
<Box
Expand Down Expand Up @@ -384,7 +374,7 @@ const ChatMain = ({ isPlayground }: { isPlayground?: boolean }) => {
borderRadius={"lg"}
size={"sm"}
>
{ t(`chat.chatMain.abort`)}
{t(`chat.chatMain.abort`)}
</Button>
)}
</Box>
Expand Down
2 changes: 1 addition & 1 deletion web/src/components/Teams/DebugPreview/head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function DebugPreviewHead({
<Box
// zIndex="1001"
>
<ChatHistoryList teamId={teamId} />
<ChatHistoryList teamId={teamId} isPlayground={false} />
</Box>
</PopoverBody>
<PopoverFooter />
Expand Down

0 comments on commit 49ef90f

Please sign in to comment.