fixed duplicated message
This commit is contained in:
parent
bb5dae166f
commit
4ca064ebdc
3 changed files with 374 additions and 358 deletions
|
|
@ -0,0 +1,8 @@
|
||||||
|
export default function codeBlock() {
|
||||||
|
// a html custom element for code blocks in markdown texts, it will allow to download the code as a file or copy it to the clipboard
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Code Block</h1>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -65,6 +65,14 @@ export default function ChatMessage({ chat }: { chat: ChatMessageType }) {
|
||||||
remarkPlugins={[remarkGfm, remarkMath]}
|
remarkPlugins={[remarkGfm, remarkMath]}
|
||||||
rehypePlugins={[rehypeMathjax]}
|
rehypePlugins={[rehypeMathjax]}
|
||||||
className="markdown prose"
|
className="markdown prose"
|
||||||
|
// components={{
|
||||||
|
// code: (props) => (
|
||||||
|
// <code
|
||||||
|
// className="bg-pink-600 dark:bg-gray-700 rounded-md p-1"
|
||||||
|
// {...props}
|
||||||
|
// />
|
||||||
|
// ),
|
||||||
|
// }}
|
||||||
>
|
>
|
||||||
{message}
|
{message}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
|
|
|
||||||
|
|
@ -14,383 +14,383 @@ import ChatInput from "./chatInput";
|
||||||
const _ = require("lodash");
|
const _ = require("lodash");
|
||||||
|
|
||||||
export default function ChatModal({
|
export default function ChatModal({
|
||||||
flow,
|
flow,
|
||||||
open,
|
open,
|
||||||
setOpen,
|
setOpen,
|
||||||
}: {
|
}: {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
setOpen: Function;
|
setOpen: Function;
|
||||||
flow: FlowType;
|
flow: FlowType;
|
||||||
}) {
|
}) {
|
||||||
const [chatValue, setChatValue] = useState("");
|
const [chatValue, setChatValue] = useState("");
|
||||||
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
|
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
|
||||||
const { reactFlowInstance } = useContext(typesContext);
|
const { reactFlowInstance } = useContext(typesContext);
|
||||||
const { setErrorData, setNoticeData } = useContext(alertContext);
|
const { setErrorData, setNoticeData } = useContext(alertContext);
|
||||||
const ws = useRef<WebSocket | null>(null);
|
const ws = useRef<WebSocket | null>(null);
|
||||||
const [lockChat, setLockChat] = useState(false);
|
const [lockChat, setLockChat] = useState(false);
|
||||||
const isOpen = useRef(open);
|
const isOpen = useRef(open);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
isOpen.current = open;
|
isOpen.current = open;
|
||||||
}, [open]);
|
}, [open]);
|
||||||
var isStream = false;
|
var isStream = false;
|
||||||
|
|
||||||
const addChatHistory = (
|
const addChatHistory = (
|
||||||
message: string,
|
message: string,
|
||||||
isSend: boolean,
|
isSend: boolean,
|
||||||
thought?: string,
|
thought?: string,
|
||||||
files?: Array<any>
|
files?: Array<any>
|
||||||
) => {
|
) => {
|
||||||
setChatHistory((old) => {
|
setChatHistory((old) => {
|
||||||
let newChat = _.cloneDeep(old);
|
let newChat = _.cloneDeep(old);
|
||||||
if (files) {
|
if (files) {
|
||||||
newChat.push({ message, isSend, files, thought });
|
newChat.push({ message, isSend, files, thought });
|
||||||
} 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 });
|
||||||
}
|
}
|
||||||
return newChat;
|
return newChat;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//add proper type signature for function
|
//add proper type signature for function
|
||||||
|
|
||||||
function updateLastMessage({
|
function updateLastMessage({
|
||||||
str,
|
str,
|
||||||
thought,
|
thought,
|
||||||
end = false,
|
end = false,
|
||||||
}: {
|
}: {
|
||||||
str?: string;
|
str?: string;
|
||||||
thought?: string;
|
thought?: string;
|
||||||
// end param default is false
|
// end param default is false
|
||||||
end?: boolean;
|
end?: boolean;
|
||||||
}) {
|
}) {
|
||||||
setChatHistory((old) => {
|
setChatHistory((old) => {
|
||||||
let newChat = [...old];
|
let newChat = [...old];
|
||||||
if (str) {
|
if (str) {
|
||||||
if (end && !newChat[newChat.length - 1].message) {
|
if (end) {
|
||||||
newChat[newChat.length - 1].message = str;
|
newChat[newChat.length - 1].message = str;
|
||||||
}
|
} else {
|
||||||
newChat[newChat.length - 1].message =
|
newChat[newChat.length - 1].message =
|
||||||
newChat[newChat.length - 1].message + str;
|
newChat[newChat.length - 1].message + str;
|
||||||
}
|
}
|
||||||
if (thought) {
|
}
|
||||||
newChat[newChat.length - 1].thought = thought;
|
if (thought) {
|
||||||
}
|
newChat[newChat.length - 1].thought = thought;
|
||||||
return newChat;
|
}
|
||||||
});
|
return newChat;
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function handleOnClose(event: CloseEvent) {
|
function handleOnClose(event: CloseEvent) {
|
||||||
if (isOpen.current) {
|
if (isOpen.current) {
|
||||||
setLockChat(false);
|
setLockChat(false);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
connectWS();
|
connectWS();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleWsMessage(data: any) {
|
function handleWsMessage(data: any) {
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
//set chat history
|
//set chat history
|
||||||
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;
|
||||||
files?: Array<any>;
|
files?: Array<any>;
|
||||||
}) => {
|
}) => {
|
||||||
if (chatItem.message) {
|
if (chatItem.message) {
|
||||||
newChatHistory.push(
|
newChatHistory.push(
|
||||||
chatItem.files
|
chatItem.files
|
||||||
? {
|
? {
|
||||||
isSend: !chatItem.is_bot,
|
isSend: !chatItem.is_bot,
|
||||||
message: chatItem.message,
|
message: chatItem.message,
|
||||||
thought: chatItem.intermediate_steps,
|
thought: chatItem.intermediate_steps,
|
||||||
files: chatItem.files,
|
files: chatItem.files,
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
isSend: !chatItem.is_bot,
|
isSend: !chatItem.is_bot,
|
||||||
message: chatItem.message,
|
message: chatItem.message,
|
||||||
thought: chatItem.intermediate_steps,
|
thought: chatItem.intermediate_steps,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return newChatHistory;
|
return newChatHistory;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (data.type === "start") {
|
if (data.type === "start") {
|
||||||
console.log("start");
|
console.log("start");
|
||||||
addChatHistory("", false);
|
addChatHistory("", false);
|
||||||
isStream = true;
|
isStream = true;
|
||||||
}
|
}
|
||||||
if (data.type === "end") {
|
if (data.type === "end") {
|
||||||
if (data.intermediate_steps) {
|
if (data.intermediate_steps) {
|
||||||
updateLastMessage({
|
updateLastMessage({
|
||||||
str: data.message,
|
str: data.message,
|
||||||
thought: data.intermediate_steps,
|
thought: data.intermediate_steps,
|
||||||
end: true,
|
end: true,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
setLockChat(false);
|
||||||
|
isStream = false;
|
||||||
|
}
|
||||||
|
if (data.type === "file") {
|
||||||
|
console.log(data);
|
||||||
|
}
|
||||||
|
if (data.type === "stream" && isStream) {
|
||||||
|
updateLastMessage({ str: data.message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
function connectWS() {
|
||||||
setLockChat(false);
|
try {
|
||||||
isStream = false;
|
const urlWs =
|
||||||
}
|
process.env.NODE_ENV === "development"
|
||||||
if (data.type === "file") {
|
? `ws://localhost:7860/chat/${flow.id}`
|
||||||
console.log(data);
|
: `${window.location.protocol === "https:" ? "wss" : "ws"}://${
|
||||||
}
|
window.location.host
|
||||||
if (data.type === "stream" && isStream) {
|
}/chat/${flow.id}`;
|
||||||
updateLastMessage({ str: data.message });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function connectWS() {
|
const newWs = new WebSocket(urlWs);
|
||||||
try {
|
newWs.onopen = () => {
|
||||||
const urlWs =
|
console.log("WebSocket connection established!");
|
||||||
process.env.NODE_ENV === "development"
|
};
|
||||||
? `ws://localhost:7860/chat/${flow.id}`
|
console.log(flow.id);
|
||||||
: `${window.location.protocol === "https:" ? "wss" : "ws"}://${
|
newWs.onmessage = (event) => {
|
||||||
window.location.host
|
const data = JSON.parse(event.data);
|
||||||
}/chat/${flow.id}`;
|
console.log("Received data:", data);
|
||||||
|
handleWsMessage(data);
|
||||||
|
//get chat history
|
||||||
|
};
|
||||||
|
newWs.onclose = (event) => {
|
||||||
|
handleOnClose(event);
|
||||||
|
};
|
||||||
|
newWs.onerror = (ev) => {
|
||||||
|
console.log(ev, "error");
|
||||||
|
setErrorData({
|
||||||
|
title: "There was an error on web connection, please: ",
|
||||||
|
list: [
|
||||||
|
"Refresh the page",
|
||||||
|
"Use a new flow tab",
|
||||||
|
"Check if the backend is up",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
ws.current = newWs;
|
||||||
|
} catch {
|
||||||
|
setErrorData({
|
||||||
|
title: "There was an error on web connection, please: ",
|
||||||
|
list: [
|
||||||
|
"Refresh the page",
|
||||||
|
"Use a new flow tab",
|
||||||
|
"Check if the backend is up",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const newWs = new WebSocket(urlWs);
|
useEffect(() => {
|
||||||
newWs.onopen = () => {
|
connectWS();
|
||||||
console.log("WebSocket connection established!");
|
return () => {
|
||||||
};
|
console.log("unmount");
|
||||||
console.log(flow.id);
|
console.log(ws);
|
||||||
newWs.onmessage = (event) => {
|
if (ws) {
|
||||||
const data = JSON.parse(event.data);
|
ws.current.close();
|
||||||
console.log("Received data:", data);
|
}
|
||||||
handleWsMessage(data);
|
};
|
||||||
//get chat history
|
}, []);
|
||||||
};
|
|
||||||
newWs.onclose = (event) => {
|
|
||||||
handleOnClose(event);
|
|
||||||
};
|
|
||||||
newWs.onerror = (ev) => {
|
|
||||||
console.log(ev, "error");
|
|
||||||
setErrorData({
|
|
||||||
title: "There was an error on web connection, please: ",
|
|
||||||
list: [
|
|
||||||
"Refresh the page",
|
|
||||||
"Use a new flow tab",
|
|
||||||
"Check if the backend is up",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
};
|
|
||||||
ws.current = newWs;
|
|
||||||
} catch {
|
|
||||||
setErrorData({
|
|
||||||
title: "There was an error on web connection, please: ",
|
|
||||||
list: [
|
|
||||||
"Refresh the page",
|
|
||||||
"Use a new flow tab",
|
|
||||||
"Check if the backend is up",
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
async function sendAll(data: sendAllProps) {
|
||||||
connectWS();
|
try {
|
||||||
return () => {
|
if (ws) {
|
||||||
console.log("unmount");
|
ws.current.send(JSON.stringify(data));
|
||||||
console.log(ws);
|
}
|
||||||
if (ws) {
|
} catch (error) {
|
||||||
ws.current.close();
|
setErrorData({
|
||||||
}
|
title: "There was an erro sending the message",
|
||||||
};
|
list: [error.message],
|
||||||
}, []);
|
});
|
||||||
|
setChatValue(data.message);
|
||||||
|
connectWS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function sendAll(data: sendAllProps) {
|
useEffect(() => {
|
||||||
try {
|
if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
|
||||||
if (ws) {
|
}, [chatHistory]);
|
||||||
ws.current.send(JSON.stringify(data));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
setErrorData({
|
|
||||||
title: "There was an erro sending the message",
|
|
||||||
list: [error.message],
|
|
||||||
});
|
|
||||||
setChatValue(data.message);
|
|
||||||
connectWS();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
function validateNode(n: NodeType): Array<string> {
|
||||||
if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
|
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
|
||||||
}, [chatHistory]);
|
setNoticeData({
|
||||||
|
title:
|
||||||
|
"We've noticed a potential issue with a node in the flow. Please review it and, if necessary, submit a bug report with your exported flow file. Thank you for your help!",
|
||||||
|
});
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
function validateNode(n: NodeType): Array<string> {
|
const {
|
||||||
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
|
type,
|
||||||
setNoticeData({
|
node: { template },
|
||||||
title:
|
} = n.data;
|
||||||
"We've noticed a potential issue with a node in the flow. Please review it and, if necessary, submit a bug report with your exported flow file. Thank you for your help!",
|
|
||||||
});
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
return Object.keys(template).reduce(
|
||||||
type,
|
(errors: Array<string>, t) =>
|
||||||
node: { template },
|
errors.concat(
|
||||||
} = n.data;
|
template[t].required &&
|
||||||
|
template[t].show &&
|
||||||
|
(!template[t].value || template[t].value === "") &&
|
||||||
|
!reactFlowInstance
|
||||||
|
.getEdges()
|
||||||
|
.some(
|
||||||
|
(e) =>
|
||||||
|
e.targetHandle.split("|")[1] === t &&
|
||||||
|
e.targetHandle.split("|")[2] === n.id
|
||||||
|
)
|
||||||
|
? [
|
||||||
|
`${type} is missing ${
|
||||||
|
template.display_name
|
||||||
|
? template.display_name
|
||||||
|
: toNormalCase(template[t].name)
|
||||||
|
}.`,
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
),
|
||||||
|
[] as string[]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return Object.keys(template).reduce(
|
function validateNodes() {
|
||||||
(errors: Array<string>, t) =>
|
return reactFlowInstance
|
||||||
errors.concat(
|
.getNodes()
|
||||||
template[t].required &&
|
.flatMap((n: NodeType) => validateNode(n));
|
||||||
template[t].show &&
|
}
|
||||||
(!template[t].value || template[t].value === "") &&
|
|
||||||
!reactFlowInstance
|
|
||||||
.getEdges()
|
|
||||||
.some(
|
|
||||||
(e) =>
|
|
||||||
e.targetHandle.split("|")[1] === t &&
|
|
||||||
e.targetHandle.split("|")[2] === n.id
|
|
||||||
)
|
|
||||||
? [
|
|
||||||
`${type} is missing ${
|
|
||||||
template.display_name
|
|
||||||
? template.display_name
|
|
||||||
: toNormalCase(template[t].name)
|
|
||||||
}.`,
|
|
||||||
]
|
|
||||||
: []
|
|
||||||
),
|
|
||||||
[] as string[]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateNodes() {
|
const ref = useRef(null);
|
||||||
return reactFlowInstance
|
|
||||||
.getNodes()
|
|
||||||
.flatMap((n: NodeType) => validateNode(n));
|
|
||||||
}
|
|
||||||
|
|
||||||
const ref = useRef(null);
|
function sendMessage() {
|
||||||
|
if (chatValue !== "") {
|
||||||
|
let nodeValidationErrors = validateNodes();
|
||||||
|
if (nodeValidationErrors.length === 0) {
|
||||||
|
setLockChat(true);
|
||||||
|
let message = chatValue;
|
||||||
|
setChatValue("");
|
||||||
|
addChatHistory(message, true);
|
||||||
|
sendAll({
|
||||||
|
...reactFlowInstance.toObject(),
|
||||||
|
message,
|
||||||
|
chatHistory,
|
||||||
|
name: flow.name,
|
||||||
|
description: flow.description,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setErrorData({
|
||||||
|
title: "Oops! Looks like you missed some required information:",
|
||||||
|
list: nodeValidationErrors,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
setErrorData({
|
||||||
|
title: "Error sending message",
|
||||||
|
list: ["The message cannot be empty."],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function clearChat() {
|
||||||
|
setChatHistory([]);
|
||||||
|
ws.current.send(JSON.stringify({ clear_history: true }));
|
||||||
|
}
|
||||||
|
|
||||||
function sendMessage() {
|
function setModalOpen(x: boolean) {
|
||||||
if (chatValue !== "") {
|
setOpen(x);
|
||||||
let nodeValidationErrors = validateNodes();
|
}
|
||||||
if (nodeValidationErrors.length === 0) {
|
return (
|
||||||
setLockChat(true);
|
<Transition.Root show={open} appear={open} as={Fragment}>
|
||||||
let message = chatValue;
|
<Dialog
|
||||||
setChatValue("");
|
as="div"
|
||||||
addChatHistory(message, true);
|
className="relative z-10"
|
||||||
sendAll({
|
onClose={setModalOpen}
|
||||||
...reactFlowInstance.toObject(),
|
initialFocus={ref}
|
||||||
message,
|
>
|
||||||
chatHistory,
|
<Transition.Child
|
||||||
name: flow.name,
|
as={Fragment}
|
||||||
description: flow.description,
|
enter="ease-out duration-300"
|
||||||
});
|
enterFrom="opacity-0"
|
||||||
} else {
|
enterTo="opacity-100"
|
||||||
setErrorData({
|
leave="ease-in duration-200"
|
||||||
title: "Oops! Looks like you missed some required information:",
|
leaveFrom="opacity-100"
|
||||||
list: nodeValidationErrors,
|
leaveTo="opacity-0"
|
||||||
});
|
>
|
||||||
}
|
<div className="fixed inset-0 bg-black backdrop-blur-sm dark:bg-gray-600 dark:bg-opacity-80 bg-opacity-80 transition-opacity" />
|
||||||
} else {
|
</Transition.Child>
|
||||||
setErrorData({
|
|
||||||
title: "Error sending message",
|
|
||||||
list: ["The message cannot be empty."],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function clearChat() {
|
|
||||||
setChatHistory([]);
|
|
||||||
ws.current.send(JSON.stringify({ clear_history: true }));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setModalOpen(x: boolean) {
|
<div className="fixed inset-0 z-10 overflow-y-auto">
|
||||||
setOpen(x);
|
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
||||||
}
|
<Transition.Child
|
||||||
return (
|
as={Fragment}
|
||||||
<Transition.Root show={open} appear={open} as={Fragment}>
|
enter="ease-out duration-300"
|
||||||
<Dialog
|
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
as="div"
|
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
||||||
className="relative z-10"
|
leave="ease-in duration-200"
|
||||||
onClose={setModalOpen}
|
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
||||||
initialFocus={ref}
|
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
>
|
>
|
||||||
<Transition.Child
|
<Dialog.Panel className=" drop-shadow-2xl relative flex flex-col justify-between transform h-[95%] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[690px]">
|
||||||
as={Fragment}
|
<div className="relative w-full">
|
||||||
enter="ease-out duration-300"
|
<button
|
||||||
enterFrom="opacity-0"
|
onClick={() => clearChat()}
|
||||||
enterTo="opacity-100"
|
className="absolute top-2 right-2 hover:text-red-500 z-30"
|
||||||
leave="ease-in duration-200"
|
>
|
||||||
leaveFrom="opacity-100"
|
<FaEraser className="w-4 h-4" />
|
||||||
leaveTo="opacity-0"
|
</button>
|
||||||
>
|
</div>
|
||||||
<div className="fixed inset-0 bg-black backdrop-blur-sm dark:bg-gray-600 dark:bg-opacity-80 bg-opacity-80 transition-opacity" />
|
<div className="w-full h-full bg-white dark:bg-gray-800 border-t dark:border-t-gray-600 flex-col flex items-center overflow-scroll scrollbar-hide">
|
||||||
</Transition.Child>
|
{chatHistory.length > 0 ? (
|
||||||
|
chatHistory.map((c, i) => <ChatMessage chat={c} key={i} />)
|
||||||
<div className="fixed inset-0 z-10 overflow-y-auto">
|
) : (
|
||||||
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
|
<div className="flex flex-col h-full text-center justify-center w-full items-center align-middle ">
|
||||||
<Transition.Child
|
<span>
|
||||||
as={Fragment}
|
👋{" "}
|
||||||
enter="ease-out duration-300"
|
<span className="text-gray-600 text-lg">
|
||||||
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
LangFlow Chat
|
||||||
enterTo="opacity-100 translate-y-0 sm:scale-100"
|
</span>
|
||||||
leave="ease-in duration-200"
|
</span>
|
||||||
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
|
<br />
|
||||||
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
<div className="bg-gray-100 rounded-md w-2/4 px-6 py-8 border border-gray-200">
|
||||||
>
|
<span className="text-base text-gray-500">
|
||||||
<Dialog.Panel className=" drop-shadow-2xl relative flex flex-col justify-between transform h-[95%] overflow-hidden rounded-lg bg-white dark:bg-gray-800 text-left shadow-xl transition-all sm:my-8 w-[690px]">
|
Start a conversation and click the agent’s thoughts{" "}
|
||||||
<div className="relative w-full">
|
<span>
|
||||||
<button
|
<ChatBubbleOvalLeftEllipsisIcon className="w-6 h-6 inline animate-bounce " />
|
||||||
onClick={() => clearChat()}
|
</span>{" "}
|
||||||
className="absolute top-2 right-2 hover:text-red-500"
|
to inspect the chaining process.
|
||||||
>
|
</span>
|
||||||
<FaEraser className="w-4 h-4" />
|
</div>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
)}
|
||||||
<div className="w-full h-full bg-white dark:bg-gray-800 border-t dark:border-t-gray-600 flex-col flex items-center overflow-scroll scrollbar-hide">
|
<div ref={ref}></div>
|
||||||
{chatHistory.length > 0 ? (
|
</div>
|
||||||
chatHistory.map((c, i) => <ChatMessage chat={c} key={i} />)
|
<div className="w-full bg-white dark:bg-gray-800 border-t dark:border-t-gray-600 flex-col flex items-center justify-between p-3">
|
||||||
) : (
|
<div className="relative w-full mt-1 rounded-md shadow-sm">
|
||||||
<div className="flex flex-col h-full text-center justify-center w-full items-center align-middle ">
|
<ChatInput
|
||||||
<span>
|
chatValue={chatValue}
|
||||||
👋{" "}
|
lockChat={lockChat}
|
||||||
<span className="text-gray-600 text-lg">
|
sendMessage={sendMessage}
|
||||||
LangFlow Chat
|
setChatValue={setChatValue}
|
||||||
</span>
|
/>
|
||||||
</span>
|
</div>
|
||||||
<br />
|
</div>
|
||||||
<div className="bg-gray-100 rounded-md w-2/4 px-6 py-8 border border-gray-200">
|
</Dialog.Panel>
|
||||||
<span className="text-base text-gray-500">
|
</Transition.Child>
|
||||||
Start a conversation and click the agent’s thoughts{" "}
|
</div>
|
||||||
<span>
|
</div>
|
||||||
<ChatBubbleOvalLeftEllipsisIcon className="w-6 h-6 inline animate-bounce " />
|
</Dialog>
|
||||||
</span>{" "}
|
</Transition.Root>
|
||||||
to inspect the chaining process.
|
);
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div ref={ref}></div>
|
|
||||||
</div>
|
|
||||||
<div className="w-full bg-white dark:bg-gray-800 border-t dark:border-t-gray-600 flex-col flex items-center justify-between p-3">
|
|
||||||
<div className="relative w-full mt-1 rounded-md shadow-sm">
|
|
||||||
<ChatInput
|
|
||||||
chatValue={chatValue}
|
|
||||||
lockChat={lockChat}
|
|
||||||
sendMessage={sendMessage}
|
|
||||||
setChatValue={setChatValue}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Dialog.Panel>
|
|
||||||
</Transition.Child>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Dialog>
|
|
||||||
</Transition.Root>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue