From 6d757ff91f6a4f16dd54e14fd6fd841c362c5b15 Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Mon, 6 Mar 2023 21:12:36 -0500 Subject: [PATCH] improve custom model selection ux --- README.md | 12 +++---- api/.env.example | 3 +- api/models/CustomGpt.js | 2 -- client/src/components/Models/ModelDialog.jsx | 11 ++++-- client/src/components/Models/ModelMenu.jsx | 38 +++++++++++++++----- client/src/store/submitSlice.js | 3 +- 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 2ff1c33d6a..77ed51f432 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ Currently, this project is only functional with the `text-davinci-003` model. > **Warning** -> This is a work in progress. I'm building this in public. You can follow the progress here or on my [Linkedin](https://www.linkedin.com/in/danny-avila). +> This is a work in progress. I'm building this in public. FYI there is still a lot of tech debt to cleanup. You can follow the progress here or on my [Linkedin](https://www.linkedin.com/in/danny-avila). Here are my recently completed and planned features: @@ -153,9 +153,9 @@ Warning: There may be a high chance of your account being banned with this metho
BingAI Instructions +The Bing Access Token is the "_U" cookie from bing.com. Use dev tools or an extension while logged into the site to view it. - -Note: Specific Styling for this model is still in progress. +Note: Specific error handling and styling for this model is still in progress.
### Updating @@ -167,15 +167,15 @@ Note: Specific Styling for this model is still in progress. - Using the official API, you'd have to generate 7.5 million words to expense the same cost as ChatGPT Plus ($20). - ChatGPT/Google Bard/Bing AI conversations are lost in space or cannot be searched past a certain timeframe. - - Customize ChatGPT + - **Customize ChatGPT** ![use case example](./client/public/use_case3.png "Make a Custom GPT") - - API is not as limited as ChatGPT Free (at [chat.openai.com](https://chat.openai.com/chat)) + - **API is not as limited as ChatGPT Free (at [chat.openai.com](https://chat.openai.com/chat))** ![use case example](./client/public/use_case2.png "chat.openai.com is getting more limited by the day!") - - ChatGPT Free is down. + - **ChatGPT Free is down.** ![use case example](./client/public/use_case.png "GPT is down! Plus is too expensive!") diff --git a/api/.env.example b/api/.env.example index e20fa1fdc3..47576c119a 100644 --- a/api/.env.example +++ b/api/.env.example @@ -1,6 +1,7 @@ OPENAI_KEY= PORT=3080 NODE_ENV=development -MONGO_URI="mongodb://127.0.0.1:27017/chatgpt-client" +# Change this to your MongoDB URI if different and I recommend appending chatgpt-clone +MONGO_URI="mongodb://127.0.0.1:27017/chatgpt-clone" CHATGPT_TOKEN="" BING_TOKEN="" \ No newline at end of file diff --git a/api/models/CustomGpt.js b/api/models/CustomGpt.js index 67385904a0..7df5f45f5f 100644 --- a/api/models/CustomGpt.js +++ b/api/models/CustomGpt.js @@ -45,8 +45,6 @@ module.exports = { }, updateCustomGpt: async ({ value, ...update }) => { try { - console.log('updateCustomGpt', value, update); - const customGpt = await CustomGpt.findOne({ value }).exec(); if (!customGpt) { diff --git a/client/src/components/Models/ModelDialog.jsx b/client/src/components/Models/ModelDialog.jsx index 42daf05be0..87ee82fcb3 100644 --- a/client/src/components/Models/ModelDialog.jsx +++ b/client/src/components/Models/ModelDialog.jsx @@ -16,10 +16,11 @@ import { DialogTitle } from '../ui/Dialog.tsx'; -export default function ModelDialog({ mutate, modelMap }) { +export default function ModelDialog({ mutate, modelMap, setModelSave, handleSaveState }) { const dispatch = useDispatch(); const [chatGptLabel, setChatGptLabel] = useState(''); const [promptPrefix, setPromptPrefix] = useState(''); + const [saveText, setSaveText] = useState('Save'); const [required, setRequired] = useState(false); const inputRef = useRef(null); @@ -34,11 +35,13 @@ export default function ModelDialog({ mutate, modelMap }) { } dispatch(setCustomGpt({ chatGptLabel, promptPrefix })); dispatch(setModel('chatgptCustom')); + handleSaveState(chatGptLabel.toLowerCase()); // dispatch(setDisabled(false)); }; const saveHandler = (e) => { e.preventDefault(); + setModelSave(true); const value = chatGptLabel.toLowerCase(); if (chatGptLabel.length === 0) { @@ -60,7 +63,11 @@ export default function ModelDialog({ mutate, modelMap }) { // dispatch(setDisabled(false)); }; - if (modelMap[chatGptLabel.toLowerCase()] && saveText === 'Save') { + if ( + chatGptLabel !== 'chatgptCustom' && + modelMap[chatGptLabel.toLowerCase()] && + saveText === 'Save' + ) { setSaveText('Update'); } diff --git a/client/src/components/Models/ModelMenu.jsx b/client/src/components/Models/ModelMenu.jsx index cd36156b74..470ada15d4 100644 --- a/client/src/components/Models/ModelMenu.jsx +++ b/client/src/components/Models/ModelMenu.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useState, useEffect } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { setModel, setDisabled, setCustomGpt, setCustomModel } from '~/store/submitSlice'; import { setConversation } from '~/store/convoSlice'; @@ -23,6 +23,8 @@ import { Dialog } from '../ui/Dialog.tsx'; export default function ModelMenu() { const dispatch = useDispatch(); + const [modelSave, setModelSave] = useState(false); + // const [dialogOpen, setDialogOpen] = useState(false); const { model, customModel } = useSelector((state) => state.submit); const { models, modelMap, initial } = useSelector((state) => state.models); const { trigger } = manualSWR(`http://localhost:3080/api/customGpts`, 'get', (res) => { @@ -60,15 +62,15 @@ export default function ModelMenu() { } else if (initial[value]) { dispatch(setModel(value)); dispatch(setDisabled(false)); - setCustomModel(null); + dispatch(setCustomModel(null)); } else if (!initial[value]) { const chatGptLabel = modelMap[value]?.chatGptLabel; const promptPrefix = modelMap[value]?.promptPrefix; dispatch(setCustomGpt({ chatGptLabel, promptPrefix })); dispatch(setModel('chatgptCustom')); - setCustomModel(value); + dispatch(setCustomModel(value)); } else if (!modelMap[value]) { - setCustomModel(null); + dispatch(setCustomModel(null)); } // Set new conversation @@ -82,6 +84,21 @@ export default function ModelMenu() { ); }; + const onOpenChange = (open) => { + if (!open) { + setModelSave(false); + } + }; + + const handleSaveState = (value) => { + if (!modelSave) { + return; + } + + dispatch(setCustomModel(value)); + setModelSave(false); + }; + const defaultColorProps = [ 'text-gray-500', 'hover:bg-gray-100', @@ -107,8 +124,8 @@ export default function ModelMenu() { const icon = model === 'bingai' ? : ; return ( - - + + ); } diff --git a/client/src/store/submitSlice.js b/client/src/store/submitSlice.js index b659ddcc7d..464a96c5a5 100644 --- a/client/src/store/submitSlice.js +++ b/client/src/store/submitSlice.js @@ -6,7 +6,7 @@ const initialState = { model: 'chatgpt', promptPrefix: '', chatGptLabel: '', - customModel: null + customModel: '' }; const currentSlice = createSlice({ @@ -27,6 +27,7 @@ const currentSlice = createSlice({ state.chatGptLabel = action.payload.chatGptLabel; }, setCustomModel: (state, action) => { + console.log('setCustomModel', action.payload); state.customModel = action.payload; } }