Merge remote-tracking branch 'origin/websocket' into chat_and_cache

This commit is contained in:
Gabriel Almeida 2023-04-25 23:43:16 -03:00
commit e58a2d2104
5 changed files with 120 additions and 93 deletions

View file

@ -61,5 +61,5 @@
"last 1 safari version" "last 1 safari version"
] ]
}, },
"proxy": "http://backend:7860" "proxy": "http://127.0.0.1:5003"
} }

View file

@ -10,6 +10,7 @@ import { FlowType } from "../types/flow";
import { TabsContextType } from "../types/tabs"; import { TabsContextType } from "../types/tabs";
import { normalCaseToSnakeCase } from "../utils"; import { normalCaseToSnakeCase } from "../utils";
import { alertContext } from "./alertContext"; import { alertContext } from "./alertContext";
const { v4: uuidv4 } = require('uuid');
const TabsContextInitialValue: TabsContextType = { const TabsContextInitialValue: TabsContextType = {
save: () => {}, save: () => {},
@ -33,8 +34,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
const { setNoticeData } = useContext(alertContext); const { setNoticeData } = useContext(alertContext);
const [tabIndex, setTabIndex] = useState(0); const [tabIndex, setTabIndex] = useState(0);
const [flows, setFlows] = useState<Array<FlowType>>([]); const [flows, setFlows] = useState<Array<FlowType>>([]);
const [id, setId] = useState(0); const [id, setId] = useState("");
const [lockChat, setLockChat] = useState(false);
const newNodeId = useRef(0); const newNodeId = useRef(0);
function incrementNodeId() { function incrementNodeId() {
@ -68,7 +68,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
newNodeId.current = 0; newNodeId.current = 0;
setTabIndex(0); setTabIndex(0);
setFlows([]); setFlows([]);
setId(0); setId(uuidv4());
} }
/** /**
@ -157,7 +157,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
}; };
// Increment the ID counter. // Increment the ID counter.
setId((old) => old + 1); setId(uuidv4());
// Add the new flow to the list of flows. // Add the new flow to the list of flows.
setFlows((prevState) => { setFlows((prevState) => {

View file

@ -19,12 +19,12 @@ export default function ChatMessage({ chat }: { chat: ChatMessageType }) {
> >
<div <div
className={classNames( className={classNames(
"rounded-full w-9 h-9 flex items-center my-3 justify-center", "rounded-full w-8 h-8 flex items-center my-3 justify-center",
chat.isSend ? "bg-gray-200" : "bg-gray-200" chat.isSend ? "bg-gray-900" : "bg-gray-200"
)} )}
> >
{!chat.isSend && <img className="scale-150" src={AiIcon} />} {!chat.isSend && <img className="scale-150" src={AiIcon} />}
{chat.isSend && <UserIcon />} {chat.isSend && <UserIcon className="w-6 h-6 -mb-1 text-gray-200" />}
</div> </div>
{!chat.isSend ? ( {!chat.isSend ? (
<div className="w-full text-start flex items-center"> <div className="w-full text-start flex items-center">
@ -49,20 +49,24 @@ export default function ChatMessage({ chat }: { chat: ChatMessageType }) {
)} )}
{chat.thought && chat.thought !== "" && !hidden && <br></br>} {chat.thought && chat.thought !== "" && !hidden && <br></br>}
<div className="w-full px-4 pb-3 pt-3 pr-8"> <div className="w-full px-4 pb-3 pt-3 pr-8">
{chat.file ? ( <span>
<div></div> {chat.message}
) : ( {chat.files && (
<span>
{chat.message}
<div className="my-2 w-full"> <div className="my-2 w-full">
<FileCard {chat.files.map((file) => {
fileName={"FileType"} return (
fileType={"jpeg"} <div className="my-2 w-full">
content={""} <FileCard
/> fileName={"File"}
fileType={file.type}
content={file.data}
/>
</div>
);
})}
</div> </div>
</span> )}
)} </span>
</div> </div>
</div> </div>
</div> </div>

View file

@ -35,14 +35,13 @@ export default function ChatModal({
message: string, message: string,
isSend: boolean, isSend: boolean,
thought?: string, thought?: string,
file?:Blob files?: Array<any>
) => { ) => {
setChatHistory((old) => { setChatHistory((old) => {
let newChat = _.cloneDeep(old); let newChat = _.cloneDeep(old);
if(file){ if (files) {
newChat.push({ message, isSend,file }); newChat.push({ message, isSend, files });
} } else if (thought) {
else if (thought) {
newChat.push({ message, isSend, thought }); newChat.push({ message, isSend, thought });
} else { } else {
newChat.push({ message, isSend }); newChat.push({ message, isSend });
@ -51,69 +50,96 @@ export default function ChatModal({
}); });
}; };
useEffect(() => { function connectWS(){
const newWs = new WebSocket(`ws://localhost:7860/chat/${flow.id}`); const newWs = new WebSocket(`ws://127.0.0.1:5003/chat/${flow.id}`);
newWs.onopen = () => { newWs.onopen = () => {
console.log("WebSocket connection established!"); console.log("WebSocket connection established!");
}; };
newWs.onmessage = (event) => { newWs.onmessage = (event) => {
const data = JSON.parse(event.data); try {
console.log("Received data:", data); const data = JSON.parse(event.data);
//get chat history console.log("Received data:", data);
if (Array.isArray(data)) { //get chat history
console.log(data); if (Array.isArray(data)) {
console.log(data);
setChatHistory((_) => { setChatHistory((_) => {
let newChatHistory: ChatMessageType[] = []; let newChatHistory: ChatMessageType[] = [];
data.forEach( data.forEach(
(chatItem: { (chatItem: {
intermediate_steps?: "string"; intermediate_steps?: "string";
is_bot: boolean; is_bot: boolean;
message: string; message: string;
type: string; type: string;
data?:string; files?: Array<any>;
}) => { }) => {
if(chatItem.type==="file"){ if (chatItem.message) {
newChatHistory.push({ newChatHistory.push(
isSend: !chatItem.is_bot, chatItem.files
message: chatItem.message, ? {
thought: chatItem.intermediate_steps, isSend: !chatItem.is_bot,
file:chatItem.data message: chatItem.message,
}); thought: chatItem.intermediate_steps,
files: chatItem.files,
}
: {
isSend: !chatItem.is_bot,
message: chatItem.message,
thought: chatItem.intermediate_steps,
}
);
}
} }
newChatHistory.push({ );
isSend: !chatItem.is_bot, return newChatHistory;
message: chatItem.message, });
thought: chatItem.intermediate_steps, }
}); if (data.type === "end") {
} if (data.files) {
); addChatHistory(
return newChatHistory; data.message,
}); false,
data.intermediate_steps,
data.files
);
} else {
addChatHistory(data.message, false, data.intermediate_steps);
}
setLockChat(false);
}
if (data.type == "file") {
console.log(data);
}
} catch (error) {
setErrorData({title:event.data})
if(newWs.readyState===newWs.CLOSED){
window.alert(error)
}
}
};
newWs.onclose = (_) => {
if(open){
setLockChat(false);
setTimeout(() => {
connectWS()
}, 100);
} }
if (data.type === "end") {
addChatHistory(data.message, false, data.intermediate_steps);
setLockChat(false)
}
if (data.type=="file"){
console.log(data)
}
// Do something with the data received from the WebSocket
}; };
newWs.onclose=(e)=>{console.log(e.reason)}
setWs(newWs); setWs(newWs);
return newWs
}
useEffect(() => {
let newWs = connectWS()
return () => { return () => {
newWs.close(); newWs.close();
}; };
}, []); }, []);
useEffect(()=>{
if(ws && ws.CLOSED){
setLockChat(false)
}
},[lockChat])
async function sendAll(data: sendAllProps) { async function sendAll(data: sendAllProps) {
if (ws) { if (ws) {
ws.send(JSON.stringify(data)); ws.send(JSON.stringify(data));
@ -124,6 +150,12 @@ export default function ChatModal({
if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" }); if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
}, [chatHistory]); }, [chatHistory]);
useEffect(() => {
if (ws && ws.readyState === ws.CLOSED) {
setLockChat(false);
}
}, [lockChat]);
function validateNode(n: NodeType): Array<string> { function validateNode(n: NodeType): Array<string> {
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) { if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
setNoticeData({ setNoticeData({
@ -187,20 +219,6 @@ export default function ChatModal({
chatHistory, chatHistory,
name: flow.name, name: flow.name,
description: flow.description, description: flow.description,
}).catch((error) => {
setErrorData({
title: error.message ?? "Unknown Error",
list: [error.response.data.detail],
});
setLockChat(false);
let lastMessage;
setChatHistory((chatHistory) => {
let newChat = chatHistory;
lastMessage = newChat.pop().message;
return newChat;
});
setChatValue(lastMessage);
}); });
} else { } else {
setErrorData({ setErrorData({
@ -217,7 +235,7 @@ export default function ChatModal({
} }
function clearChat() { function clearChat() {
setChatHistory([]); setChatHistory([]);
updateFlow({ ..._.cloneDeep(flow), chat: [] }); ws.send(JSON.stringify({ clear_history: true }));
} }
const { closePopUp } = useContext(PopUpContext); const { closePopUp } = useContext(PopUpContext);

View file

@ -1,5 +1,10 @@
import { ReactFlowInstance } from 'reactflow'; import { ReactFlowInstance } from "reactflow";
import { FlowType } from "../flow"; import { FlowType } from "../flow";
export type ChatType = {flow:FlowType,reactFlowInstance:ReactFlowInstance} export type ChatType = { flow: FlowType; reactFlowInstance: ReactFlowInstance };
export type ChatMessageType = { message: string; isSend: boolean, thought?:string,file?:string } export type ChatMessageType = {
message: string;
isSend: boolean;
thought?: string;
files?: Array<{data:string,type:string}>;
};