mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-10-02 08:50:11 +02:00
- toned down chat copy,thumbs up and down icons
- refactored Dynamic Input Component to encapsulate all dynamic input logic, gate and controllers
This commit is contained in:
parent
fd1df23ff9
commit
40de9d7bd5
@ -57,11 +57,11 @@ function FeedbackButton({
|
|||||||
onClick={handleFeedback}
|
onClick={handleFeedback}
|
||||||
data-tooltip-id={tooltipId}
|
data-tooltip-id={tooltipId}
|
||||||
data-tooltip-content={tooltipContent}
|
data-tooltip-content={tooltipContent}
|
||||||
className="text-zinc-300"
|
className="text-white/40"
|
||||||
>
|
>
|
||||||
<IconComponent
|
<IconComponent
|
||||||
size={18}
|
size={18}
|
||||||
className="mb-1"
|
className={`mb-1 hover:text-white/80 ${isSelected ? "text-white" : "text-white/40"}`}
|
||||||
weight={isSelected ? "fill" : "regular"}
|
weight={isSelected ? "fill" : "regular"}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
@ -85,10 +85,10 @@ function CopyMessage({ message }) {
|
|||||||
onClick={() => copyText(message)}
|
onClick={() => copyText(message)}
|
||||||
data-tooltip-id="copy-assistant-text"
|
data-tooltip-id="copy-assistant-text"
|
||||||
data-tooltip-content="Copy"
|
data-tooltip-content="Copy"
|
||||||
className="text-zinc-300"
|
className="text-white/40 hover:text-white/80"
|
||||||
>
|
>
|
||||||
{copied ? (
|
{copied ? (
|
||||||
<Check size={18} className="mb-1" />
|
<Check size={18} className="mb-1 text-white/80" />
|
||||||
) : (
|
) : (
|
||||||
<ClipboardText size={18} className="mb-1" />
|
<ClipboardText size={18} className="mb-1" />
|
||||||
)}
|
)}
|
||||||
@ -97,7 +97,7 @@ function CopyMessage({ message }) {
|
|||||||
id="copy-assistant-text"
|
id="copy-assistant-text"
|
||||||
place="bottom"
|
place="bottom"
|
||||||
delayShow={300}
|
delayShow={300}
|
||||||
className="tooltip !text-xs"
|
className="tooltip !text-xs "
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@ -1,37 +1,61 @@
|
|||||||
const OptionSelect = ({ data, settings }) => {
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
const OptionSelect = ({ data, settings, submit, message, setMessage }) => {
|
||||||
|
const [submitMessage, setSubmitMessage] = useState(false);
|
||||||
|
useEffect(() => {
|
||||||
|
if (submitMessage) {
|
||||||
|
submit();
|
||||||
|
setSubmitMessage(false);
|
||||||
|
}
|
||||||
|
}, [message]);
|
||||||
|
|
||||||
const handleSelection = (value) => {
|
const handleSelection = (value) => {
|
||||||
// Implement your logic to handle selection
|
setMessage(value);
|
||||||
console.log(value);
|
setSubmitMessage(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Grid of Buttons
|
// Grid of Buttons
|
||||||
if (settings.displayType === "buttons") {
|
if (settings.displayType === "buttons") {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-2 text-white/60 text-xs mt-10 w-full justify-center">
|
<div className=" mb-2 w-full p-4 backdrop-blur-sm rounded-t-xl overflow-hidden py-4 px-6 border-l border-t border-r border-[#2f3238]">
|
||||||
|
<Label label={data?.label} />
|
||||||
|
<div className=" pb-0 mt-2 grid grid-cols-1 md:grid-cols-2 gap-4 text-white/80 text-xs ">
|
||||||
{data.options.map((option, index) => (
|
{data.options.map((option, index) => (
|
||||||
<button
|
<button
|
||||||
key={index}
|
key={index}
|
||||||
className="shadow-lg hover:shadow-sm transition-all duration-200 hover:animate-shine ease-in-out text-left p-2.5 border rounded-xl border-white/20 bg-sidebar hover:bg-workspace-item-selected-gradient"
|
className="group relative shadow-lg hover:shadow-sm transition-all duration-200 ease-in-out text-left p-2.5 border rounded-xl border-white/20 bg-sidebar hover:bg-sidebar/50 overflow-hidden "
|
||||||
onClick={() => handleSelection(option.value)}
|
onClick={() => handleSelection(option.value)}
|
||||||
>
|
>
|
||||||
<p className="">{option.label}</p>
|
<p className="truncate max-w-xl group-hover:max-w-xl group-hover:truncate-0">
|
||||||
|
<span style={{ color: "grey" }}>{index + 1}.</span>{" "}
|
||||||
|
{option.label}
|
||||||
|
</p>
|
||||||
|
<span className="absolute invisible group-hover:visible bg-black text-white text-xs rounded-lg p-2 left-0 bottom-full mb-2">
|
||||||
|
<span style={{ color: "grey" }}>{index + 1}.</span>{" "}
|
||||||
|
{option.label}
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal List with Hyperlinks
|
// Normal List with Hyperlinks
|
||||||
if (settings.displayType === "list") {
|
if (settings.displayType === "list") {
|
||||||
return (
|
return (
|
||||||
<div className="mt-10 text-white/60 text-xs w-full">
|
<div className=" text-white/70 text-xs w-full backdrop-blur-sm rounded-t-xl overflow-hidden py-4 px-6 border-l border-t border-r border-[#2f3238]">
|
||||||
|
<Label {...data} />
|
||||||
{data.options.map((option, index) => (
|
{data.options.map((option, index) => (
|
||||||
<a
|
<a
|
||||||
key={index}
|
key={index}
|
||||||
href={option.href} // assuming `href` is available in your option object
|
href={option.href} // assuming `href` is available in your option object
|
||||||
className="block p-2.5 border-b border-white/20 last:border-0 hover:bg-workspace-item-selected-gradient"
|
className="block p-2.5 border-b border-white/10 last:border-0 hover:bg-sidebar/50 cursor-pointer"
|
||||||
|
onClick={() => handleSelection(option.value)}
|
||||||
>
|
>
|
||||||
<p className="font-semibold">{option.label}</p>
|
<p className="">
|
||||||
|
<span style={{ color: "grey" }}>{index + 1}.</span> {option.label}
|
||||||
|
</p>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@ -40,18 +64,8 @@ const OptionSelect = ({ data, settings }) => {
|
|||||||
|
|
||||||
// Dropdown Menu
|
// Dropdown Menu
|
||||||
return (
|
return (
|
||||||
<div className="mt-5 w-full">
|
<div className="mt-5 mb-5 w-full backdrop-blur-sm rounded-t-xl overflow-hidden py-4 px-6 border-l border-t border-r border-[#2f3238]">
|
||||||
<div className="flex flex-col">
|
<Label {...data} />
|
||||||
<label
|
|
||||||
htmlFor="chatModel"
|
|
||||||
className="block input-label text-white text-opacity-60 text-xs font-medium py-1.5"
|
|
||||||
>
|
|
||||||
{data?.label}
|
|
||||||
</label>
|
|
||||||
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
|
||||||
{data?.description}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<select
|
<select
|
||||||
name="optionSelect"
|
name="optionSelect"
|
||||||
id="optionSelect"
|
id="optionSelect"
|
||||||
@ -59,7 +73,11 @@ const OptionSelect = ({ data, settings }) => {
|
|||||||
required={true}
|
required={true}
|
||||||
disabled={settings.disabled}
|
disabled={settings.disabled}
|
||||||
className="shadow-xl bg-sidebar text-white text-xs rounded-xl p-2.5 w-full border border-white/20 focus:ring-blue-500 focus:border-blue-500"
|
className="shadow-xl bg-sidebar text-white text-xs rounded-xl p-2.5 w-full border border-white/20 focus:ring-blue-500 focus:border-blue-500"
|
||||||
|
onChange={(e) => handleSelection(e.target.value)}
|
||||||
>
|
>
|
||||||
|
<option value="placeholder" disabled selected>
|
||||||
|
Select an option
|
||||||
|
</option>
|
||||||
{settings.waitingForModels ? (
|
{settings.waitingForModels ? (
|
||||||
<option disabled={true} selected={true}>
|
<option disabled={true} selected={true}>
|
||||||
-- waiting for models --
|
-- waiting for models --
|
||||||
@ -67,7 +85,7 @@ const OptionSelect = ({ data, settings }) => {
|
|||||||
) : (
|
) : (
|
||||||
data.options.map((option, index) => (
|
data.options.map((option, index) => (
|
||||||
<option key={index} value={option.value}>
|
<option key={index} value={option.value}>
|
||||||
{option.label}
|
<span style={{ color: "grey" }}>{index + 1}.</span> {option.label}
|
||||||
</option>
|
</option>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
@ -76,4 +94,24 @@ const OptionSelect = ({ data, settings }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Label = ({ label, description }) => {
|
||||||
|
return (
|
||||||
|
<div className="hidden md:flex flex-col">
|
||||||
|
{label && (
|
||||||
|
<label
|
||||||
|
htmlFor="chatModel"
|
||||||
|
className="block input-label text-white text-opacity-60 text-xs font-medium py-1.5"
|
||||||
|
>
|
||||||
|
{label}
|
||||||
|
</label>
|
||||||
|
)}
|
||||||
|
{description && (
|
||||||
|
<p className="text-white text-opacity-60 text-xs font-medium py-1.5">
|
||||||
|
{description}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default OptionSelect;
|
export default OptionSelect;
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
// import TextInput from './TextInput';
|
// import TextInput from './TextInput';
|
||||||
import OptionSelect from "@/components/WorkspaceChat/ChatContainer/DynamicInput/OptionSelect";
|
import OptionSelect from "@/components/WorkspaceChat/ChatContainer/DynamicInput/OptionSelect";
|
||||||
import { ArrowUUpLeft, Keyboard } from "@phosphor-icons/react";
|
import { Cursor, Keyboard } from "@phosphor-icons/react";
|
||||||
|
import PromptInput from "../PromptInput";
|
||||||
// import RangeSlider from './RangeSlider';
|
// import RangeSlider from './RangeSlider';
|
||||||
// import DatePicker from './DatePicker';
|
// import DatePicker from './DatePicker';
|
||||||
// import TimePicker from './TimePicker';
|
// import TimePicker from './TimePicker';
|
||||||
@ -25,31 +26,75 @@ const inputComponents = {
|
|||||||
const DynamicInput = ({
|
const DynamicInput = ({
|
||||||
inputs,
|
inputs,
|
||||||
isDynamicInput,
|
isDynamicInput,
|
||||||
isForcedTextInput,
|
submit,
|
||||||
setIsForcedTextInput,
|
setMessage,
|
||||||
|
workspace,
|
||||||
|
message,
|
||||||
|
onChange,
|
||||||
|
inputDisabled,
|
||||||
|
buttonDisabled,
|
||||||
|
sendCommand,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [isForcedTextInput, setIsForcedTextInput] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (inputs?.type !== "text") {
|
||||||
|
setIsForcedTextInput(false);
|
||||||
|
}
|
||||||
|
}, [inputs]);
|
||||||
|
|
||||||
const InputComponent = inputComponents[inputs?.type] || null;
|
const InputComponent = inputComponents[inputs?.type] || null;
|
||||||
if (!InputComponent) {
|
if (!InputComponent) {
|
||||||
return null; // or any fallback UI
|
return null; // or any fallback UI
|
||||||
}
|
}
|
||||||
|
const renderPromptInput = () => {
|
||||||
|
if (inputs?.type === "text" || inputs === undefined || isForcedTextInput) {
|
||||||
return (
|
return (
|
||||||
<div className="w-full px-4 fixed md:absolute bottom-10 left-0 z-10 md:z-0 flex justify-center items-center">
|
<PromptInput
|
||||||
|
className={
|
||||||
|
inputs !== undefined ? "bottom-8 md:-bottom-5" : "-bottom-2"
|
||||||
|
}
|
||||||
|
workspace={workspace}
|
||||||
|
message={message}
|
||||||
|
submit={submit}
|
||||||
|
onChange={onChange}
|
||||||
|
inputDisabled={inputDisabled}
|
||||||
|
buttonDisabled={buttonDisabled}
|
||||||
|
sendCommand={sendCommand}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<div className="w-full md:px-4 fixed md:absolute bottom-10 left-0 z-10 md:z-0 flex justify-center items-center">
|
||||||
<div className="w-[600px]">
|
<div className="w-[600px]">
|
||||||
<InputComponent {...inputs} />
|
{inputs?.type !== "text" &&
|
||||||
|
isDynamicInput &&
|
||||||
|
inputs !== undefined &&
|
||||||
|
!isForcedTextInput ? (
|
||||||
|
<InputComponent
|
||||||
|
submit={submit}
|
||||||
|
setMessage={setMessage}
|
||||||
|
message={message}
|
||||||
|
{...inputs}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
renderPromptInput()
|
||||||
|
)}
|
||||||
{isDynamicInput && inputs != undefined && (
|
{isDynamicInput && inputs != undefined && (
|
||||||
<div className="flex justify-end">
|
<div className="w-full fixed absolute -bottom-8 left-0 z-10 md:z-0 flex justify-center items-center">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="pb-5 transition-all w-fit duration-300 px-5 py-2.5 rounded-lg text-white/50 text-xs items-center flex gap-x-2 hover:text-white focus:ring-gray-800"
|
className="transition-all w-fit duration-300 px-5 py-2.5 rounded-lg text-white/40 text-xs items-center flex gap-x-2 shadow-sm hover:text-white/60 focus:ring-gray-800"
|
||||||
onClick={() => setIsForcedTextInput(!isForcedTextInput)}
|
onClick={() => setIsForcedTextInput(!isForcedTextInput)}
|
||||||
>
|
>
|
||||||
{isForcedTextInput ? (
|
{isForcedTextInput ? (
|
||||||
<>
|
<>
|
||||||
<ArrowUUpLeft className="h-5 w-5" /> back to options
|
<Cursor className="h-5 w-5" /> Select an option
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Keyboard className="h-5 w-5" /> Type another answer
|
<Keyboard className="h-5 w-5" /> Type a response
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
@ -8,7 +8,7 @@ import { isMobile } from "react-device-detect";
|
|||||||
import debounce from "lodash.debounce";
|
import debounce from "lodash.debounce";
|
||||||
|
|
||||||
export default function PromptInput({
|
export default function PromptInput({
|
||||||
className,
|
className = "bottom-0",
|
||||||
workspace,
|
workspace,
|
||||||
message,
|
message,
|
||||||
submit,
|
submit,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Workspace from "@/models/workspace";
|
import Workspace from "@/models/workspace";
|
||||||
import handleChat from "@/utils/chat";
|
import handleChat from "@/utils/chat";
|
||||||
import { extractMetaData } from "@/utils/chat/extractMetaData";
|
import { extractMetaData } from "@/utils/chat/extractMetaData";
|
||||||
import { CursorClick, Keyboard } from "@phosphor-icons/react";
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
@ -21,16 +20,14 @@ export default function ChatContainer({
|
|||||||
const [message, setMessage] = useState("");
|
const [message, setMessage] = useState("");
|
||||||
const [loadingResponse, setLoadingResponse] = useState(false);
|
const [loadingResponse, setLoadingResponse] = useState(false);
|
||||||
const [chatHistory, setChatHistory] = useState(knownHistory);
|
const [chatHistory, setChatHistory] = useState(knownHistory);
|
||||||
const [finalizedChatHistory, setFinalizedChatHistory] =
|
const [finalizedChatHistory, setFinalizedChatHistory] = useState(knownHistory);
|
||||||
useState(knownHistory);
|
|
||||||
const [isForcedTextInput, setIsForcedTextInput] = useState(false);
|
|
||||||
|
|
||||||
const handleMessageChange = (event) => {
|
const handleMessageChange = (event) => {
|
||||||
setMessage(event.target.value);
|
setMessage(event.target.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (event) => {
|
const handleSubmit = async (event) => {
|
||||||
event.preventDefault();
|
event?.preventDefault();
|
||||||
if (!message || message === "") return false;
|
if (!message || message === "") return false;
|
||||||
|
|
||||||
const prevChatHistory = [
|
const prevChatHistory = [
|
||||||
@ -122,7 +119,6 @@ export default function ChatContainer({
|
|||||||
_chatHistory[_chatHistory.length - 1].content = remainingText;
|
_chatHistory[_chatHistory.length - 1].content = remainingText;
|
||||||
setFinalizedChatHistory(_chatHistory);
|
setFinalizedChatHistory(_chatHistory);
|
||||||
setCurrentInputMeta(metaData);
|
setCurrentInputMeta(metaData);
|
||||||
console.log("metaData", metaData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -130,32 +126,6 @@ export default function ChatContainer({
|
|||||||
loadingResponse === true && fetchReply();
|
loadingResponse === true && fetchReply();
|
||||||
}, [loadingResponse, chatHistory, workspace]);
|
}, [loadingResponse, chatHistory, workspace]);
|
||||||
|
|
||||||
const renderInputComponent = () => {
|
|
||||||
if (
|
|
||||||
!isDynamicInput ||
|
|
||||||
currentInputMeta?.inputs?.type === "text" ||
|
|
||||||
currentInputMeta?.inputs === undefined ||
|
|
||||||
isForcedTextInput
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<PromptInput
|
|
||||||
className={isDynamicInput && currentInputMeta?.inputs !== undefined ? "bottom-4" : "-bottom-2"}
|
|
||||||
workspace={workspace}
|
|
||||||
message={message}
|
|
||||||
submit={handleSubmit}
|
|
||||||
onChange={handleMessageChange}
|
|
||||||
inputDisabled={loadingResponse}
|
|
||||||
buttonDisabled={loadingResponse}
|
|
||||||
sendCommand={sendCommand}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentInputMeta?.inputs?.type !== "text") {
|
|
||||||
return <DynamicInput {...currentInputMeta} />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||||
@ -168,25 +138,29 @@ export default function ChatContainer({
|
|||||||
workspace={workspace}
|
workspace={workspace}
|
||||||
sendCommand={sendCommand}
|
sendCommand={sendCommand}
|
||||||
/>
|
/>
|
||||||
{renderInputComponent()}
|
{isDynamicInput && currentInputMeta?.inputs?.type !== undefined ? (
|
||||||
{isDynamicInput && currentInputMeta?.inputs != undefined && (
|
<DynamicInput
|
||||||
<div className="w-full fixed md:absolute -bottom-1 left-0 z-10 md:z-0 flex justify-center items-center">
|
inputs={currentInputMeta?.inputs}
|
||||||
<button
|
isDynamicInput={isDynamicInput}
|
||||||
type="button"
|
submit={handleSubmit}
|
||||||
className="transition-all w-fit duration-300 px-5 py-2.5 rounded-lg text-white/50 text-xs items-center flex gap-x-2 hover:text-white focus:ring-gray-800"
|
setMessage={setMessage}
|
||||||
onClick={() => setIsForcedTextInput(!isForcedTextInput)}
|
workspace={workspace}
|
||||||
>
|
message={message}
|
||||||
{isForcedTextInput ? (
|
onChange={handleMessageChange}
|
||||||
<>
|
inputDisabled={loadingResponse}
|
||||||
<CursorClick className="h-5 w-5" /> use dynamic input
|
buttonDisabled={loadingResponse}
|
||||||
</>
|
sendCommand={sendCommand}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<PromptInput
|
||||||
<Keyboard className="h-5 w-5" /> use keyboard input
|
workspace={workspace}
|
||||||
</>
|
message={message}
|
||||||
)}
|
submit={handleSubmit}
|
||||||
</button>
|
onChange={handleMessageChange}
|
||||||
</div>
|
inputDisabled={loadingResponse}
|
||||||
|
buttonDisabled={loadingResponse}
|
||||||
|
sendCommand={sendCommand}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
|
||||||
import Workspace from "@/models/workspace";
|
import Workspace from "@/models/workspace";
|
||||||
import LoadingChat from "./LoadingChat";
|
|
||||||
import ChatContainer from "./ChatContainer";
|
|
||||||
import paths from "@/utils/paths";
|
|
||||||
import ModalWrapper from "../ModalWrapper";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { extractMetaData } from "@/utils/chat/extractMetaData";
|
import { extractMetaData } from "@/utils/chat/extractMetaData";
|
||||||
|
import paths from "@/utils/paths";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import ModalWrapper from "../ModalWrapper";
|
||||||
|
import ChatContainer from "./ChatContainer";
|
||||||
|
import LoadingChat from "./LoadingChat";
|
||||||
|
|
||||||
export default function WorkspaceChat({ loading, workspace }) {
|
export default function WorkspaceChat({ loading, workspace }) {
|
||||||
const { threadSlug = null } = useParams();
|
const { threadSlug = null } = useParams();
|
||||||
|
@ -97,7 +97,6 @@ export default function handleChat(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
setChatHistory([..._chatHistory]);
|
setChatHistory([..._chatHistory]);
|
||||||
console.log("chunk: ", [..._chatHistory]);
|
|
||||||
} else if (type === "finalizeResponseStream") {
|
} else if (type === "finalizeResponseStream") {
|
||||||
const chatIdx = _chatHistory.findIndex((chat) => chat.uuid === uuid);
|
const chatIdx = _chatHistory.findIndex((chat) => chat.uuid === uuid);
|
||||||
if (chatIdx !== -1) {
|
if (chatIdx !== -1) {
|
||||||
@ -109,7 +108,6 @@ export default function handleChat(
|
|||||||
_chatHistory[chatIdx] = updatedHistory;
|
_chatHistory[chatIdx] = updatedHistory;
|
||||||
}
|
}
|
||||||
setChatHistory([..._chatHistory]);
|
setChatHistory([..._chatHistory]);
|
||||||
console.log("final: ", [..._chatHistory]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user