+
ChatGPT Clone
diff --git a/client/src/routes/Chat.jsx b/client/src/routes/Chat.jsx
index e9a30b71a8..58aa0500d3 100644
--- a/client/src/routes/Chat.jsx
+++ b/client/src/routes/Chat.jsx
@@ -1,13 +1,13 @@
-import React, { useEffect } from "react";
-import { useNavigate, useParams } from "react-router-dom";
-import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
+import React, { useEffect } from 'react';
+import { useNavigate, useParams } from 'react-router-dom';
+import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
-import Landing from "../components/ui/Landing";
-import Messages from "../components/Messages";
-import TextChat from "../components/Input";
+import Landing from '../components/ui/Landing';
+import Messages from '../components/Messages';
+import TextChat from '../components/Input';
-import store from "~/store";
-import manualSWR from "~/utils/fetchers";
+import store from '~/store';
+import manualSWR from '~/utils/fetchers';
// import TextChat from './components/Main/TextChat';
// {/* */}
@@ -20,28 +20,22 @@ export default function Chat() {
const { conversationId } = useParams();
const navigate = useNavigate();
- const { trigger: messagesTrigger } = manualSWR(
- `/api/messages/${conversation?.conversationId}`,
- "get"
- );
+ const { trigger: messagesTrigger } = manualSWR(`/api/messages/${conversation?.conversationId}`, 'get');
- const { trigger: conversationTrigger } = manualSWR(
- `/api/convos/${conversationId}`,
- "get"
- );
+ const { trigger: conversationTrigger } = manualSWR(`/api/convos/${conversationId}`, 'get');
// when conversation changed or conversationId (in url) changed
useEffect(() => {
if (conversation === null) {
// no current conversation, we need to do something
- if (conversationId == "new") {
+ if (conversationId == 'new') {
// create new
newConversation();
} else {
// fetch it from server
conversationTrigger().then(setConversation);
setMessages(null);
- console.log("NEED TO FETCH DATA");
+ console.log('NEED TO FETCH DATA');
}
} else if (conversation?.conversationId !== conversationId)
// conversationId (in url) should always follow conversation?.conversationId, unless conversation is null
@@ -60,7 +54,7 @@ export default function Chat() {
return (
<>
- {conversationId == "new" ? : }
+ {conversationId == 'new' ? : }
>
);
diff --git a/client/src/store/conversation.js b/client/src/store/conversation.js
index 0a68a40cf9..07a16e5f18 100644
--- a/client/src/store/conversation.js
+++ b/client/src/store/conversation.js
@@ -1,5 +1,13 @@
import models from './models';
-import { atom, selector, useRecoilValue, useSetRecoilState, useResetRecoilState } from 'recoil';
+import {
+ atom,
+ selector,
+ useRecoilValue,
+ useSetRecoilState,
+ useResetRecoilState,
+ useRecoilCallback,
+ useRecoilState
+} from 'recoil';
import buildTree from '~/utils/buildTree';
// current conversation, can be null (need to be fetched from server)
@@ -44,19 +52,45 @@ const latestMessage = atom({
});
const useConversation = () => {
- const modelsFilter = useRecoilValue(models.modelsFilter);
const setConversation = useSetRecoilState(conversation);
const setMessages = useSetRecoilState(messages);
const resetLatestMessage = useResetRecoilState(latestMessage);
- const newConversation = ({ model = null, chatGptLabel = null, promptPrefix = null } = {}) => {
+ const switchToConversation = useRecoilCallback(
+ ({ snapshot }) =>
+ async (_conversation, messages = null) => {
+ const prevConversation = await snapshot.getPromise(conversation);
+ const prevModelsFilter = await snapshot.getPromise(models.modelsFilter);
+ _switchToConversation(_conversation, messages, { prevModelsFilter, prevConversation });
+ },
+ []
+ );
+
+ const _switchToConversation = (
+ conversation,
+ messages = null,
+ { prevModelsFilter = {}, prev_conversation = {} }
+ ) => {
+ let { model = null, chatGptLabel = null, promptPrefix = null } = conversation;
const getDefaultModel = () => {
+ try {
+ // try to use current model
+ const { _model = null, _chatGptLabel = null, _promptPrefix = null } = prev_conversation || {};
+ console.log(_model, _chatGptLabel, _promptPrefix);
+ if (prevModelsFilter[_model]) {
+ model = _model;
+ chatGptLabel = _chatGptLabel;
+ promptPrefix = _promptPrefix;
+ return;
+ }
+ } catch (error) {}
+
try {
// try to read latest selected model from local storage
const lastSelected = JSON.parse(localStorage.getItem('model'));
const { model: _model, chatGptLabel: _chatGptLabel, promptPrefix: _promptPrefix } = lastSelected;
- if (modelsFilter[_model]) {
+ if (prevModelsFilter[_model]) {
model = _model;
chatGptLabel = _chatGptLabel;
promptPrefix = _promptPrefix;
@@ -65,9 +99,9 @@ const useConversation = () => {
} catch (error) {}
// if anything happens, reset to default model
- if (modelsFilter?.chatgpt) model = 'chatgpt';
- else if (modelsFilter?.bingai) model = 'bingai';
- else if (modelsFilter?.chatgptBrowser) model = 'chatgptBrowser';
+ if (prevModelsFilter?.chatgpt) model = 'chatgpt';
+ else if (prevModelsFilter?.bingai) model = 'bingai';
+ else if (prevModelsFilter?.chatgptBrowser) model = 'chatgptBrowser';
chatGptLabel = null;
promptPrefix = null;
};
@@ -77,24 +111,36 @@ const useConversation = () => {
getDefaultModel();
setConversation({
- conversationId: 'new',
- title: 'New Chat',
- jailbreakConversationId: null,
- conversationSignature: null,
- clientId: null,
- invocationId: null,
+ ...conversation,
model: model,
chatGptLabel: chatGptLabel,
- promptPrefix: promptPrefix,
- user: null,
- suggestions: [],
- toneStyle: null
+ promptPrefix: promptPrefix
});
- setMessages([]);
+ setMessages(messages);
resetLatestMessage();
};
- return { newConversation };
+ const newConversation = ({ model = null, chatGptLabel = null, promptPrefix = null } = {}) => {
+ switchToConversation(
+ {
+ conversationId: 'new',
+ title: 'New Chat',
+ jailbreakConversationId: null,
+ conversationSignature: null,
+ clientId: null,
+ invocationId: null,
+ model: model,
+ chatGptLabel: chatGptLabel,
+ promptPrefix: promptPrefix,
+ user: null,
+ suggestions: [],
+ toneStyle: null
+ },
+ []
+ );
+ };
+
+ return { newConversation, switchToConversation };
};
export default {
diff --git a/client/src/utils/buildTree.js b/client/src/utils/buildTree.js
index 7f9a4134e5..2929e1e7ce 100644
--- a/client/src/utils/buildTree.js
+++ b/client/src/utils/buildTree.js
@@ -4,6 +4,8 @@ const odd =
'w-full border-b border-black/10 bg-gray-50 dark:border-gray-900/50 text-gray-800 dark:text-gray-100 group bg-gray-100 dark:bg-[#444654] hover:bg-gray-100/40 hover:text-gray-700 dark:hover:bg-[#3b3d49] dark:hover:text-gray-200';
export default function buildTree(messages, groupAll = false) {
+ if (messages === null) return null;
+
let messageMap = {};
let rootMessages = [];
diff --git a/client/src/utils/createPayload.js b/client/src/utils/createPayload.js
index a1b0ff67bb..fb662b3d48 100644
--- a/client/src/utils/createPayload.js
+++ b/client/src/utils/createPayload.js
@@ -1,31 +1,50 @@
-export default function createPayload({ convo, message }) {
- const endpoint = `/api/ask`;
- let payload = { ...message };
- const { model } = message;
+export default function createPayload(submission) {
+ const { conversation, messages, message, initialResponse, isRegenerate = false } = submission;
- if (!payload.conversationId)
- if (convo?.conversationId && convo?.parentMessageId) {
- payload = {
- ...payload,
- conversationId: convo.conversationId,
- parentMessageId: convo.parentMessageId || '00000000-0000-0000-0000-000000000000'
- };
+ const endpoint = `/api/ask`;
+ const {
+ model,
+ chatGptLabel,
+ promptPrefix,
+ jailbreakConversationId,
+ conversationId,
+ conversationSignature,
+ clientId,
+ invocationId,
+ toneStyle
+ } = conversation;
+
+ let payload = {
+ ...message,
+ ...{
+ model,
+ chatGptLabel,
+ promptPrefix,
+ conversationId
}
+ };
+
+ // if (!payload.conversationId)
+ // if (convo?.conversationId && convo?.parentMessageId) {
+ // payload = {
+ // ...payload,
+ // conversationId: convo.conversationId,
+ // parentMessageId: convo.parentMessageId || '00000000-0000-0000-0000-000000000000'
+ // };
+ // }
const isBing = model === 'bingai' || model === 'sydney';
- if (isBing && !convo?.conversationId) {
- payload.toneStyle = convo.toneStyle || 'fast';
+ if (isBing && !conversationId) {
+ payload.toneStyle = toneStyle || 'fast';
}
-
- if (isBing && convo?.conversationId) {
+
+ if (isBing && conversationId) {
payload = {
...payload,
- jailbreakConversationId: convo.jailbreakConversationId,
- conversationId: convo.conversationId,
- conversationSignature: convo.conversationSignature,
- clientId: convo.clientId,
- invocationId: convo.invocationId,
- toneStyle: convo.toneStyle,
+ jailbreakConversationId,
+ conversationSignature,
+ clientId,
+ invocationId
};
}