diff --git a/README.md b/README.md index ea406e7fff..4aca1aa208 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- + @@ -9,7 +9,7 @@

- + @@ -20,10 +20,7 @@ ## All AI Conversations under One Roof. ## Assistant AIs are the future and OpenAI revolutionized this movement with ChatGPT. While numerous UIs exist, this app commemorates the original styling of ChatGPT, with the ability to integrate any current/future AI models, while integrating and improving upon original client features, such as conversation/message search and prompt templates (currently WIP). Through this clone, you can avoid ChatGPT Plus in favor of free or pay-per-call APIs. I will soon deploy a demo of this app. Feel free to contribute, clone, or fork. Currently dockerized. -

-
- + ![clone3](https://user-images.githubusercontent.com/110412045/230538752-9b99dc6e-cd02-483a-bff0-6c6e780fa7ae.gif) ### Features diff --git a/api/server/routes/ask/askBingAI.js b/api/server/routes/ask/askBingAI.js index 6a1fe8d770..9f18fd9d01 100644 --- a/api/server/routes/ask/askBingAI.js +++ b/api/server/routes/ask/askBingAI.js @@ -35,21 +35,21 @@ router.post('/', async (req, res) => { let endpointOption = {}; if (req.body?.jailbreak) endpointOption = { - jailbreak: req.body?.jailbreak ?? false, - jailbreakConversationId: req.body?.jailbreakConversationId ?? null, - systemMessage: req.body?.systemMessage ?? null, - context: req.body?.context ?? null, - toneStyle: req.body?.toneStyle ?? 'fast' + jailbreak: req.body?.jailbreak || false, + jailbreakConversationId: req.body?.jailbreakConversationId || null, + systemMessage: req.body?.systemMessage || null, + context: req.body?.context || null, + toneStyle: req.body?.toneStyle || 'fast' }; else endpointOption = { - jailbreak: req.body?.jailbreak ?? false, - systemMessage: req.body?.systemMessage ?? null, - context: req.body?.context ?? null, - conversationSignature: req.body?.conversationSignature ?? null, - clientId: req.body?.clientId ?? null, - invocationId: req.body?.invocationId ?? null, - toneStyle: req.body?.toneStyle ?? 'fast' + jailbreak: req.body?.jailbreak || false, + systemMessage: req.body?.systemMessage || null, + context: req.body?.context || null, + conversationSignature: req.body?.conversationSignature || null, + clientId: req.body?.clientId || null, + invocationId: req.body?.invocationId || null, + toneStyle: req.body?.toneStyle || 'fast' }; console.log('ask log', { @@ -122,23 +122,31 @@ const ask = async ({ console.log('BING RESPONSE', response); - const newConversationId = endpointOption?.jailbreak - ? response.jailbreakConversationId - : response.conversationId || conversationId; - const newUserMassageId = response.parentMessageId || userMessageId; - const newResponseMessageId = response.parentMessageId || response.details.requestId || userMessageId; - // STEP1 generate response message response.text = response.response || response.details.spokenText || '**Bing refused to answer.**'; let responseMessage = { - conversationId: newConversationId, - messageId: newResponseMessageId, - parentMessageId: overrideParentMessageId || newUserMassageId, - sender: endpointOption?.jailbreak ? 'Sydney' : 'BingAI', text: await handleText(response, true), - suggestions: response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text) + suggestions: + response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text), + jailbreak: endpointOption?.jailbreak }; + // // response.text = await handleText(response, true); + // response.suggestions = + // response.details.suggestedResponses && response.details.suggestedResponses.map(s => s.text); + + if (endpointOption?.jailbreak) { + responseMessage.conversationId = response.jailbreakConversationId; + responseMessage.messageId = response.messageId || response.details.messageId; + responseMessage.parentMessageId = overrideParentMessageId || response.parentMessageId || userMessageId; + responseMessage.sender = 'Sydney'; + } else { + responseMessage.conversationId = response.conversationId; + responseMessage.messageId = response.messageId || response.details.messageId; + responseMessage.parentMessageId = + overrideParentMessageId || response.parentMessageId || response.details.requestId || userMessageId; + responseMessage.sender = 'BingAI'; + } await saveMessage(responseMessage); @@ -151,22 +159,14 @@ const ask = async ({ // Attition: the api will also create new conversationId while using invalid userMessage.parentMessageId, // but in this situation, don't change the conversationId, but create new convo. - let conversationUpdate = { conversationId: newConversationId, endpoint: 'bingAI' }; - if (conversationId != newConversationId) - if (isNewConversation) { - // change the conversationId to new one - conversationUpdate = { - ...conversationUpdate, - conversationId: conversationId, - newConversationId: newConversationId - }; - } else { - // create new conversation - conversationUpdate = { - ...conversationUpdate, - ...endpointOption - }; - } + let conversationUpdate = { conversationId, endpoint: 'bingAI' }; + if (conversationId != responseMessage.conversationId && isNewConversation) + conversationUpdate = { + ...conversationUpdate, + conversationId: conversationId, + newConversationId: responseMessage.conversationId || conversationId + }; + conversationId = responseMessage.conversationId || conversationId; if (endpointOption?.jailbreak) { conversationUpdate.jailbreak = true; @@ -179,16 +179,17 @@ const ask = async ({ } await saveConvo(req?.session?.user?.username, conversationUpdate); - conversationId = newConversationId; // STEP3 update the user message - userMessage.conversationId = newConversationId; - userMessage.messageId = newUserMassageId; + userMessage.conversationId = conversationId; + userMessage.messageId = responseMessage.parentMessageId; // If response has parentMessageId, the fake userMessage.messageId should be updated to the real one. - if (!overrideParentMessageId) - await saveMessage({ ...userMessage, messageId: userMessageId, newMessageId: newUserMassageId }); - userMessageId = newUserMassageId; + if (!overrideParentMessageId) { + const oldUserMessageId = userMessageId; + await saveMessage({ ...userMessage, messageId: oldUserMessageId, newMessageId: userMessage.messageId }); + } + userMessageId = userMessage.messageId; sendMessage(res, { title: await getConvoTitle(req?.session?.user?.username, conversationId), @@ -222,4 +223,4 @@ const ask = async ({ } }; -module.exports = router; +module.exports = router; \ No newline at end of file diff --git a/client/package.json b/client/package.json index 290d52500c..9e2ff4fb07 100644 --- a/client/package.json +++ b/client/package.json @@ -67,7 +67,6 @@ "tailwindcss-animate": "^1.0.5", "tailwindcss-radix": "^2.8.0", "url": "^0.11.0", - "use-react-screenshot": "github:danny-avila/use-react-screenshot#master", "uuidv4": "^6.2.13", "@tanstack/react-query": "^4.28.0" }, diff --git a/client/src/components/Nav/ExportConversation/ExportModel.jsx b/client/src/components/Nav/ExportConversation/ExportModel.jsx index 7a02dc96db..61e9916132 100644 --- a/client/src/components/Nav/ExportConversation/ExportModel.jsx +++ b/client/src/components/Nav/ExportConversation/ExportModel.jsx @@ -23,7 +23,6 @@ export default function ExportModel({ open, onOpenChange }) { const [includeOptions, setIncludeOptions] = useState(true); const [exportBranches, setExportBranches] = useState(false); - const [exportBranchesSupport, setExportBranchesSupport] = useState(false); const [recursive, setRecursive] = useState(true); const conversation = useRecoilValue(store.conversation) || {}; @@ -37,30 +36,34 @@ export default function ExportModel({ open, onOpenChange }) { [] ); - const typeOptions = ['text', 'markdown', 'csv', 'json', 'screenshot']; //,, 'webpage']; + const typeOptions = [ + { value: 'text', display: 'text (.txt)' }, + { value: 'markdown', display: 'markdown (.md)' }, + { value: 'csv', display: 'csv (.csv)' }, + { value: 'json', display: 'json (.json)' }, + { value: 'screenshot', display: 'screenshot (.png)' } + ]; //,, 'webpage']; useEffect(() => { - setFileName( - filenamify(String(conversation?.title || 'file')) - ); + setFileName(filenamify(String(conversation?.title || 'file'))); setType('text'); setIncludeOptions(true); setExportBranches(false); - setExportBranchesSupport(false); setRecursive(true); }, [open]); const _setType = newType => { - if (newType === 'json' || newType === 'csv' || newType === 'webpage') { - setExportBranches(true); - setExportBranchesSupport(true); - } else { - setExportBranches(false); - setExportBranchesSupport(false); - } + const exportBranchesSupport = newType === 'json' || newType === 'csv' || newType === 'webpage'; + const exportOptionsSupport = newType !== 'csv' && newType !== 'screenshot'; + + setExportBranches(exportBranchesSupport); + setIncludeOptions(exportOptionsSupport); setType(newType); }; + const exportBranchesSupport = type === 'json' || type === 'csv' || type === 'webpage'; + const exportOptionsSupport = type !== 'csv' && type !== 'screenshot'; + // return an object or an array based on branches and recursive option // messageId is used to get siblindIdx from recoil snapshot const buildMessageTree = async ({ messageId, message, messages, branches = false, recursive = false }) => { @@ -320,57 +323,54 @@ export default function ExportModel({ open, onOpenChange }) {
- {type !== 'csv' && type !== 'screenshot' ? ( -
-
- -
- - -
-
-
- ) : null} - {type !== 'screenshot' ? ( +
- ) : null} +
+
+ +
+ + +
+
{type === 'json' ? (