Rolled back to v0.0.2

This commit is contained in:
Danny Avila 2023-03-10 12:55:45 -05:00
parent 57d3025717
commit 72ff47e204
20 changed files with 87 additions and 142 deletions

2
.gitignore vendored
View file

@ -48,7 +48,7 @@ bower_components/
cache.json cache.json
api/data/ api/data/
.eslintrc.js .eslintrc.js
owner*.yml owner.yml
archive archive
.vscode/settings.json .vscode/settings.json

View file

@ -110,7 +110,7 @@ Here are my recently completed and planned features:
^* ChatGPT can be 'customized' by setting a system message or prompt prefix and alternate 'role' to the API request ^* ChatGPT can be 'customized' by setting a system message or prompt prefix and alternate 'role' to the API request
[More info here](https://platform.openai.com/docs/guides/chat/instructing-chat-models). Here's an [example from this app.](#use-cases) [More info here](https://platform.openai.com/docs/guides/chat/instructing-chat-models). Here's an [example from this app.]()
### Tech Stack ### Tech Stack
@ -126,8 +126,8 @@ Here are my recently completed and planned features:
- Node.js >= 19.0.0 - Node.js >= 19.0.0
- MongoDB installed or [MongoDB Atlas](https://account.mongodb.com/account/login) (required if not using Docker) - MongoDB installed or [MongoDB Atlas](https://account.mongodb.com/account/login) (required if not using Docker)
- [Docker (optional)](https://www.docker.com/get-started/) - [Docker (optional)](https://www.docker.com/get-started/)
- [OpenAI API key](https://platform.openai.com/account/api-keys) (optional: chats will not be titled and only free models will work) - [OpenAI API key](https://platform.openai.com/account/api-keys)
- BingAI, ChatGPT access tokens (optional for free AI models) - BingAI, ChatGPT access tokens (optional, free AIs)
## Usage ## Usage
@ -136,7 +136,6 @@ Here are my recently completed and planned features:
git clone https://github.com/danny-avila/chatgpt-clone.git git clone https://github.com/danny-avila/chatgpt-clone.git
``` ```
- If using MongoDB Atlas, remove `&w=majority` from default connection string. - If using MongoDB Atlas, remove `&w=majority` from default connection string.
- You can configure proxy, host, and port environment variables as needed
### Local ### Local
- **Run npm** install in both the api and client directories - **Run npm** install in both the api and client directories
@ -162,7 +161,12 @@ Here are my recently completed and planned features:
<details> <details>
<summary><strong>ChatGPT Free Instructions</strong></summary> <summary><strong>ChatGPT Free Instructions</strong></summary>
To get your Access token For ChatGPT 'Free Version', login to chat.openai.com, then visit https://chat.openai.com/api/auth/session. Set it to `CHATGPT_TOKEN` in `.env` or `docker-compose.yml`
**This has been disabled as is no longer working as of 3-07-23**
To get your Access token For ChatGPT 'Free Version', login to chat.openai.com, then visit https://chat.openai.com/api/auth/session.
**Warning:** There may be a high chance of your account being banned with this method. Continue doing so at your own risk. **Warning:** There may be a high chance of your account being banned with this method. Continue doing so at your own risk.
@ -171,7 +175,7 @@ To get your Access token For ChatGPT 'Free Version', login to chat.openai.com, t
<details> <details>
<summary><strong>BingAI Instructions</strong></summary> <summary><strong>BingAI Instructions</strong></summary>
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. Set it in `.env` or `docker-compose.yml` to `BING_TOKEN`; if setting the user token doesn't work, try setting the entire cookie string from bing request header to `BING_COOKIES` 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 error handling and styling for this model is still in progress. **Note:** Specific error handling and styling for this model is still in progress.
</details> </details>

View file

@ -2,32 +2,27 @@ require('dotenv').config();
const { KeyvFile } = require('keyv-file'); const { KeyvFile } = require('keyv-file');
const askBing = async ({ text, progressCallback, convo }) => { const askBing = async ({ text, progressCallback, convo }) => {
const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api'); const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
const clientOptions = { const bingAIClient = new BingAIClient({
// "_U" cookie from bing.com
userToken: process.env.BING_TOKEN, userToken: process.env.BING_TOKEN,
// If the above doesn't work, provide all your cookies as a string instead
// cookies: '',
debug: false, debug: false,
cache: { store: new KeyvFile({ filename: './data/cache.json' }) } cache: { store: new KeyvFile({ filename: './data/cache.json' }) }
}; });
const cookies = process.env.BING_COOKIES;
if (cookies?.length > 0) {
clientOptions.cookies = cookies;
delete clientOptions.userToken;
}
const bingAIClient = new BingAIClient(clientOptions);
let options = { let options = {
onProgress: async (partialRes) => await progressCallback(partialRes) onProgress: async (partialRes) => await progressCallback(partialRes),
}; };
if (convo) { if (convo) {
options = { ...options, ...convo }; options = { ...options, ...convo };
} }
const res = await bingAIClient.sendMessage(text, options); const res = await bingAIClient.sendMessage(text, options
);
return res; return res;

View file

@ -7,7 +7,6 @@ const clientOptions = {
// Access token from https://chat.openai.com/api/auth/session // Access token from https://chat.openai.com/api/auth/session
accessToken: process.env.CHATGPT_TOKEN, accessToken: process.env.CHATGPT_TOKEN,
// debug: true // debug: true
proxy: process.env.PROXY || null,
}; };
const browserClient = async ({ text, progressCallback, convo }) => { const browserClient = async ({ text, progressCallback, convo }) => {

View file

@ -5,7 +5,6 @@ const clientOptions = {
modelOptions: { modelOptions: {
model: 'gpt-3.5-turbo' model: 'gpt-3.5-turbo'
}, },
proxy: process.env.PROXY || null,
debug: false debug: false
}; };

View file

@ -5,7 +5,6 @@ const clientOptions = {
modelOptions: { modelOptions: {
model: 'gpt-3.5-turbo' model: 'gpt-3.5-turbo'
}, },
proxy: process.env.PROXY || null,
debug: false debug: false
}; };

View file

@ -2,39 +2,30 @@ require('dotenv').config();
const { KeyvFile } = require('keyv-file'); const { KeyvFile } = require('keyv-file');
const askSydney = async ({ text, progressCallback, convo }) => { const askSydney = async ({ text, progressCallback, convo }) => {
const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api'); const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api'));
const clientOptions = { const sydneyClient = new BingAIClient({
// "_U" cookie from bing.com
userToken: process.env.BING_TOKEN, userToken: process.env.BING_TOKEN,
// If the above doesn't work, provide all your cookies as a string instead
// cookies: '',
debug: false, debug: false,
cache: { store: new KeyvFile({ filename: './data/cache.json' }) } cache: { store: new KeyvFile({ filename: './data/cache.json' }) }
}; });
const cookies = process.env.BING_COOKIES;
if (cookies?.length > 0) {
clientOptions.cookies = cookies;
delete clientOptions.userToken;
}
const sydneyClient = new BingAIClient(clientOptions);
let options = { let options = {
jailbreakConversationId: true, jailbreakConversationId: true,
onProgress: async (partialRes) => await progressCallback(partialRes) onProgress: async (partialRes) => await progressCallback(partialRes),
}; };
if (convo.parentMessageId) { if (convo.parentMessageId) {
options = { options = { ...options, jailbreakConversationId: convo.jailbreakConversationId, parentMessageId: convo.parentMessageId };
...options,
jailbreakConversationId: convo.jailbreakConversationId,
parentMessageId: convo.parentMessageId
};
} }
console.log('sydney options', options); console.log('sydney options', options);
const res = await sydneyClient.sendMessage(text, options); const res = await sydneyClient.sendMessage(text, options
);
return res; return res;

View file

@ -1,7 +1,6 @@
const { Configuration, OpenAIApi } = require('openai'); const { Configuration, OpenAIApi } = require('openai');
const titleConvo = async ({ message, response, model }) => { const titleConvo = async ({ message, response, model }) => {
try {
const configuration = new Configuration({ const configuration = new Configuration({
apiKey: process.env.OPENAI_KEY apiKey: process.env.OPENAI_KEY
}); });
@ -14,19 +13,12 @@ const titleConvo = async ({ message, response, model }) => {
content: content:
'You are a title-generator with one job: titling the conversation provided by a user in title case.' 'You are a title-generator with one job: titling the conversation provided by a user in title case.'
}, },
{ { role: 'user', content: `In 5 words or less, summarize the conversation below with a title in title case. Don't refer to the participants of the conversation by name. Do not include punctuation or quotation marks. Your response should be in title case, exclusively containing the title. Conversation:\n\nUser: "${message}"\n\n${model}: "${response}"\n\nTitle: ` },
role: 'user',
content: `In 5 words or less, summarize the conversation below with a title in title case. Don't refer to the participants of the conversation by name. Do not include punctuation or quotation marks. Your response should be in title case, exclusively containing the title. Conversation:\n\nUser: "${message}"\n\n${model}: "${response}"\n\nTitle: `
}
] ]
}); });
//eslint-disable-next-line //eslint-disable-next-line
return completion.data.choices[0].message.content.replace(/["\.]/g, ''); return completion.data.choices[0].message.content.replace(/["\.]/g, '');
} catch (error) {
console.log(error);
return 'New Chat';
}
}; };
module.exports = titleConvo; module.exports = titleConvo;

View file

@ -5,7 +5,6 @@ const cors = require('cors');
const routes = require('./routes'); const routes = require('./routes');
const app = express(); const app = express();
const port = process.env.PORT || 3080; const port = process.env.PORT || 3080;
const host = process.env.HOST || 'localhost'
const projectPath = path.join(__dirname, '..', '..', 'client'); const projectPath = path.join(__dirname, '..', '..', 'client');
dbConnect().then(() => console.log('Connected to MongoDB')); dbConnect().then(() => console.log('Connected to MongoDB'));
@ -24,6 +23,6 @@ app.use('/api/convos', routes.convos);
app.use('/api/customGpts', routes.customGpts); app.use('/api/customGpts', routes.customGpts);
app.use('/api/prompts', routes.prompts); app.use('/api/prompts', routes.prompts);
app.listen(port, host, () => { app.listen(port, () => {
console.log(`Server listening at http://${host}:${port}`); console.log(`Server listening at http://localhost:${port}`);
}); });

View file

@ -23,8 +23,8 @@ export default function Conversation({
const { modelMap } = useSelector((state) => state.models); const { modelMap } = useSelector((state) => state.models);
const inputRef = useRef(null); const inputRef = useRef(null);
const dispatch = useDispatch(); const dispatch = useDispatch();
const { trigger } = manualSWR(`/api/messages/${id}`, 'get'); const { trigger } = manualSWR(`http://localhost:3080/api/messages/${id}`, 'get');
const rename = manualSWR(`/api/convos/update`, 'post'); const rename = manualSWR(`http://localhost:3080/api/convos/update`, 'post');
const clickHandler = async () => { const clickHandler = async () => {
if (conversationId === id) { if (conversationId === id) {

View file

@ -9,7 +9,7 @@ import { setMessages } from '~/store/messageSlice';
export default function DeleteButton({ conversationId, renaming, cancelHandler }) { export default function DeleteButton({ conversationId, renaming, cancelHandler }) {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { trigger } = manualSWR( const { trigger } = manualSWR(
`/api/convos/clear`, `http://localhost:3080/api/convos/clear`,
'post', 'post',
() => { () => {
dispatch(setMessages([])); dispatch(setMessages([]));

View file

@ -1,15 +0,0 @@
import React from 'react';
export default function TabLink(a) {
return (
<a
href={a.href}
title={a.title}
className={a.className}
target="_blank"
rel="noopener noreferrer"
>
{a.children}
</a>
);
}

View file

@ -2,22 +2,10 @@ import React from 'react';
import Markdown from 'markdown-to-jsx'; import Markdown from 'markdown-to-jsx';
import Embed from './Embed'; import Embed from './Embed';
import Highlight from './Highlight'; import Highlight from './Highlight';
import TabLink from './TabLink';
import regexSplit from '~/utils/regexSplit'; import regexSplit from '~/utils/regexSplit';
import { wrapperRegex } from '~/utils'; import { wrapperRegex } from '~/utils';
const { codeRegex, inLineRegex, markupRegex, languageMatch, newLineMatch } = wrapperRegex; const { codeRegex, inLineRegex, markupRegex, languageMatch, newLineMatch } = wrapperRegex;
const mdOptions = { const mdOptions = { wrapper: React.Fragment, forceWrapper: true };
wrapper: React.Fragment,
forceWrapper: true,
overrides: {
a: {
component: TabLink,
// props: {
// className: 'foo'
// }
}
}
};
const inLineWrap = (parts) => { const inLineWrap = (parts) => {
let previousElement = null; let previousElement = null;

View file

@ -25,7 +25,7 @@ export default function ModelDialog({ mutate, setModelSave, handleSaveState }) {
const [saveText, setSaveText] = useState('Save'); const [saveText, setSaveText] = useState('Save');
const [required, setRequired] = useState(false); const [required, setRequired] = useState(false);
const inputRef = useRef(null); const inputRef = useRef(null);
const updateCustomGpt = manualSWR(`/api/customGpts/`, 'post'); const updateCustomGpt = manualSWR(`http://localhost:3080/api/customGpts/`, 'post');
const submitHandler = (e) => { const submitHandler = (e) => {
if (chatGptLabel.length === 0) { if (chatGptLabel.length === 0) {

View file

@ -15,8 +15,8 @@ export default function ModelItem({ modelName, value, onSelect }) {
const [currentName, setCurrentName] = useState(modelName); const [currentName, setCurrentName] = useState(modelName);
const [modelInput, setModelInput] = useState(modelName); const [modelInput, setModelInput] = useState(modelName);
const inputRef = useRef(null); const inputRef = useRef(null);
const rename = manualSWR(`/api/customGpts`, 'post'); const rename = manualSWR(`http://localhost:3080/api/customGpts`, 'post');
const deleteCustom = manualSWR(`/api/customGpts/delete`, 'post'); const deleteCustom = manualSWR(`http://localhost:3080/api/customGpts/delete`, 'post');
if (value === 'chatgptCustom') { if (value === 'chatgptCustom') {
return ( return (

View file

@ -27,7 +27,7 @@ export default function ModelMenu() {
const [menuOpen, setMenuOpen] = useState(false); const [menuOpen, setMenuOpen] = useState(false);
const { model, customModel } = useSelector((state) => state.submit); const { model, customModel } = useSelector((state) => state.submit);
const { models, modelMap, initial } = useSelector((state) => state.models); const { models, modelMap, initial } = useSelector((state) => state.models);
const { trigger } = manualSWR(`/api/customGpts`, 'get', (res) => { const { trigger } = manualSWR(`http://localhost:3080/api/customGpts`, 'get', (res) => {
const fetchedModels = res.map((modelItem) => ({ const fetchedModels = res.map((modelItem) => ({
...modelItem, ...modelItem,
name: modelItem.chatGptLabel name: modelItem.chatGptLabel

View file

@ -10,10 +10,10 @@ export default function ClearConvos() {
const dispatch = useDispatch(); const dispatch = useDispatch();
const { mutate } = useSWRConfig(); const { mutate } = useSWRConfig();
const { trigger } = manualSWR(`/api/convos/clear`, 'post', () => { const { trigger } = manualSWR(`http://localhost:3080/api/convos/clear`, 'post', () => {
dispatch(setMessages([])); dispatch(setMessages([]));
dispatch(setNewConvo()); dispatch(setNewConvo());
mutate(`/api/convos`); mutate(`http://localhost:3080/api/convos`);
}); });
const clickHandler = () => { const clickHandler = () => {

View file

@ -17,7 +17,7 @@ export default function Nav() {
}; };
const { data, isLoading, mutate } = swr( const { data, isLoading, mutate } = swr(
`/api/convos?pageNumber=${pageNumber}`, `http://localhost:3080/api/convos?pageNumber=${pageNumber}`,
onSuccess onSuccess
); );
const containerRef = useRef(null); const containerRef = useRef(null);

View file

@ -11,7 +11,7 @@ export default function handleSubmit({
chatGptLabel, chatGptLabel,
promptPrefix promptPrefix
}) { }) {
const endpoint = `/api/ask`; const endpoint = `http://localhost:3080/api/ask`;
let payload = { model, text, chatGptLabel, promptPrefix }; let payload = { model, text, chatGptLabel, promptPrefix };
if (convo.conversationId && convo.parentMessageId) { if (convo.conversationId && convo.parentMessageId) {
payload = { payload = {

View file

@ -22,12 +22,6 @@ services:
- OPENAI_KEY="" - OPENAI_KEY=""
- CHATGPT_TOKEN="" - CHATGPT_TOKEN=""
- BING_TOKEN="" - BING_TOKEN=""
# if setting the user token doesn't work, try setting the entire cookie string from bing request header
- BING_COOKIES=""
# Change this to proxy any request.
- PROXY=""
# Change this if you need to configure host name, default: 'localhost'
- HOST=""
ports: ports:
- "9000:3080" - "9000:3080"
volumes: volumes: