Simplify the share chat page. Don't need it to maintain its own conversation history

- When chatting on a shared page, fork and redirect to a new conversation page
This commit is contained in:
sabaimran 2024-11-07 17:14:11 -08:00
parent 4b8be55958
commit 33498d876b
2 changed files with 21 additions and 126 deletions

View file

@ -95,7 +95,7 @@ function ChatBodyData(props: ChatBodyDataProps) {
}); });
} }
props.setUploadedFiles(uploadedFiles); props.setUploadedFiles(uploadedFiles);
}, [setQueryToProcess, props.setImages]); }, [setQueryToProcess, props.setImages, conversationId]);
useEffect(() => { useEffect(() => {
if (message) { if (message) {

View file

@ -5,23 +5,25 @@ import React, { Suspense, useEffect, useRef, useState } from "react";
import SidePanel from "../../components/sidePanel/chatHistorySidePanel"; import SidePanel from "../../components/sidePanel/chatHistorySidePanel";
import ChatHistory from "../../components/chatHistory/chatHistory"; import ChatHistory from "../../components/chatHistory/chatHistory";
import NavMenu from "../../components/navMenu/navMenu";
import Loading from "../../components/loading/loading"; import Loading from "../../components/loading/loading";
import "katex/dist/katex.min.css"; import "katex/dist/katex.min.css";
import { useIPLocationData, useIsMobileWidth, welcomeConsole } from "../../common/utils"; import { useIsMobileWidth, welcomeConsole } from "../../common/utils";
import { useAuthenticatedData } from "@/app/common/auth"; import { useAuthenticatedData } from "@/app/common/auth";
import { ChatInputArea, ChatOptions } from "@/app/components/chatInputArea/chatInputArea"; import {
AttachedFileText,
ChatInputArea,
ChatOptions,
} from "@/app/components/chatInputArea/chatInputArea";
import { StreamMessage } from "@/app/components/chatMessage/chatMessage"; import { StreamMessage } from "@/app/components/chatMessage/chatMessage";
import { processMessageChunk } from "@/app/common/chatFunctions";
import { AgentData } from "@/app/agents/page"; import { AgentData } from "@/app/agents/page";
interface ChatBodyDataProps { interface ChatBodyDataProps {
chatOptionsData: ChatOptions | null; chatOptionsData: ChatOptions | null;
setTitle: (title: string) => void; setTitle: (title: string) => void;
setUploadedFiles: (files: string[]) => void; setUploadedFiles: (files: AttachedFileText[]) => void;
isMobileWidth?: boolean; isMobileWidth?: boolean;
publicConversationSlug: string; publicConversationSlug: string;
streamedMessages: StreamMessage[]; streamedMessages: StreamMessage[];
@ -50,23 +52,6 @@ function ChatBodyData(props: ChatBodyDataProps) {
} }
}, [images, props.setImages]); }, [images, props.setImages]);
useEffect(() => {
const storedImages = localStorage.getItem("images");
if (storedImages) {
const parsedImages: string[] = JSON.parse(storedImages);
setImages(parsedImages);
const encodedImages = parsedImages.map((img: string) => encodeURIComponent(img));
props.setImages(encodedImages);
localStorage.removeItem("images");
}
const storedMessage = localStorage.getItem("message");
if (storedMessage) {
setProcessingMessage(true);
setQueryToProcess(storedMessage);
}
}, [setQueryToProcess, props.setImages]);
useEffect(() => { useEffect(() => {
if (message) { if (message) {
setProcessingMessage(true); setProcessingMessage(true);
@ -130,14 +115,10 @@ export default function SharedChat() {
const [conversationId, setConversationID] = useState<string | undefined>(undefined); const [conversationId, setConversationID] = useState<string | undefined>(undefined);
const [messages, setMessages] = useState<StreamMessage[]>([]); const [messages, setMessages] = useState<StreamMessage[]>([]);
const [queryToProcess, setQueryToProcess] = useState<string>(""); const [queryToProcess, setQueryToProcess] = useState<string>("");
const [processQuerySignal, setProcessQuerySignal] = useState(false); const [uploadedFiles, setUploadedFiles] = useState<AttachedFileText[] | null>(null);
const [uploadedFiles, setUploadedFiles] = useState<string[]>([]);
const [paramSlug, setParamSlug] = useState<string | undefined>(undefined); const [paramSlug, setParamSlug] = useState<string | undefined>(undefined);
const [images, setImages] = useState<string[]>([]); const [images, setImages] = useState<string[]>([]);
const locationData = useIPLocationData() || {
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
};
const authenticatedData = useAuthenticatedData(); const authenticatedData = useAuthenticatedData();
const isMobileWidth = useIsMobileWidth(); const isMobileWidth = useIsMobileWidth();
@ -161,6 +142,12 @@ export default function SharedChat() {
setParamSlug(window.location.pathname.split("/").pop() || ""); setParamSlug(window.location.pathname.split("/").pop() || "");
}, []); }, []);
useEffect(() => {
if (uploadedFiles) {
localStorage.setItem("uploadedFiles", JSON.stringify(uploadedFiles));
}
}, [uploadedFiles]);
useEffect(() => { useEffect(() => {
if (queryToProcess && !conversationId) { if (queryToProcess && !conversationId) {
// If the user has not yet started conversing in the chat, create a new conversation // If the user has not yet started conversing in the chat, create a new conversation
@ -173,6 +160,11 @@ export default function SharedChat() {
.then((response) => response.json()) .then((response) => response.json())
.then((data) => { .then((data) => {
setConversationID(data.conversation_id); setConversationID(data.conversation_id);
localStorage.setItem("message", queryToProcess);
if (images.length > 0) {
localStorage.setItem("images", JSON.stringify(images));
}
window.location.href = `/chat?conversationId=${data.conversation_id}`;
}) })
.catch((err) => { .catch((err) => {
console.error(err); console.error(err);
@ -180,105 +172,8 @@ export default function SharedChat() {
}); });
return; return;
} }
if (queryToProcess) {
// Add a new object to the state
const newStreamMessage: StreamMessage = {
rawResponse: "",
trainOfThought: [],
context: [],
onlineContext: {},
codeContext: {},
completed: false,
timestamp: new Date().toISOString(),
rawQuery: queryToProcess || "",
images: images,
};
setMessages((prevMessages) => [...prevMessages, newStreamMessage]);
setProcessQuerySignal(true);
}
}, [queryToProcess, conversationId, paramSlug]); }, [queryToProcess, conversationId, paramSlug]);
useEffect(() => {
if (processQuerySignal) {
chat();
}
}, [processQuerySignal]);
async function readChatStream(response: Response) {
if (!response.ok) throw new Error(response.statusText);
if (!response.body) throw new Error("Response body is null");
const reader = response.body.getReader();
const decoder = new TextDecoder();
const eventDelimiter = "␃🔚␗";
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
setQueryToProcess("");
setProcessQuerySignal(false);
setImages([]);
break;
}
const chunk = decoder.decode(value, { stream: true });
buffer += chunk;
let newEventIndex;
while ((newEventIndex = buffer.indexOf(eventDelimiter)) !== -1) {
const event = buffer.slice(0, newEventIndex);
buffer = buffer.slice(newEventIndex + eventDelimiter.length);
if (event) {
const currentMessage = messages.find((message) => !message.completed);
if (!currentMessage) {
console.error("No current message found");
return;
}
processMessageChunk(event, currentMessage);
setMessages([...messages]);
}
}
}
}
async function chat() {
if (!queryToProcess || !conversationId) return;
const chatAPI = "/api/chat?client=web";
const chatAPIBody = {
q: queryToProcess,
conversation_id: conversationId,
stream: true,
...(locationData && {
region: locationData.region,
country: locationData.country,
city: locationData.city,
country_code: locationData.countryCode,
timezone: locationData.timezone,
}),
...(images.length > 0 && { image: images }),
};
const response = await fetch(chatAPI, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(chatAPIBody),
});
try {
await readChatStream(response);
} catch (error) {
console.error(error);
}
}
if (isLoading) { if (isLoading) {
return <Loading />; return <Loading />;
} }
@ -293,7 +188,7 @@ export default function SharedChat() {
<div className={styles.sidePanel}> <div className={styles.sidePanel}>
<SidePanel <SidePanel
conversationId={conversationId ?? null} conversationId={conversationId ?? null}
uploadedFiles={uploadedFiles} uploadedFiles={[]}
isMobileWidth={isMobileWidth} isMobileWidth={isMobileWidth}
/> />
</div> </div>