clear all convos in progress, async code refactored in debugging warning

This commit is contained in:
Daniel Avila 2023-02-07 19:07:48 -05:00
parent 053368646d
commit 511ac948b4
10 changed files with 84 additions and 65 deletions

1
.gitignore vendored
View file

@ -23,6 +23,7 @@ build/
dist/ dist/
public/main.js public/main.js
public/main.js.map public/main.js.map
public/main.js.LICENSE.txt
# Dependency directorys # Dependency directorys
# Deployed apps should consider commenting these lines out: # Deployed apps should consider commenting these lines out:

14
package-lock.json generated
View file

@ -11,7 +11,7 @@
"dependencies": { "dependencies": {
"@keyv/mongo": "^2.1.8", "@keyv/mongo": "^2.1.8",
"@reduxjs/toolkit": "^1.9.2", "@reduxjs/toolkit": "^1.9.2",
"chatgpt": "^4.1.1", "chatgpt": "^4.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",
@ -5233,9 +5233,9 @@
} }
}, },
"node_modules/chatgpt": { "node_modules/chatgpt": {
"version": "4.1.1", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/chatgpt/-/chatgpt-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chatgpt/-/chatgpt-4.2.0.tgz",
"integrity": "sha512-2Hn9kjSSndvmLiRLYK1xHXxf436xwby3vmLBlLayxFFErQHW2+47zjGlaanhrFzb89MfWsf+1GPwl/qKklDUeA==", "integrity": "sha512-HYQ65GCa8PGtmmUB+XSAa17/IKTy/EEj8QU9HGU8UAsGBtKZushiozC0JpNcTyG+ivpuwzdduXJyL6ELnqkY4A==",
"dependencies": { "dependencies": {
"eventsource-parser": "^0.0.5", "eventsource-parser": "^0.0.5",
"gpt-3-encoder": "^1.1.4", "gpt-3-encoder": "^1.1.4",
@ -16406,9 +16406,9 @@
} }
}, },
"chatgpt": { "chatgpt": {
"version": "4.1.1", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/chatgpt/-/chatgpt-4.1.1.tgz", "resolved": "https://registry.npmjs.org/chatgpt/-/chatgpt-4.2.0.tgz",
"integrity": "sha512-2Hn9kjSSndvmLiRLYK1xHXxf436xwby3vmLBlLayxFFErQHW2+47zjGlaanhrFzb89MfWsf+1GPwl/qKklDUeA==", "integrity": "sha512-HYQ65GCa8PGtmmUB+XSAa17/IKTy/EEj8QU9HGU8UAsGBtKZushiozC0JpNcTyG+ivpuwzdduXJyL6ELnqkY4A==",
"requires": { "requires": {
"eventsource-parser": "^0.0.5", "eventsource-parser": "^0.0.5",
"gpt-3-encoder": "^1.1.4", "gpt-3-encoder": "^1.1.4",

View file

@ -23,7 +23,7 @@
"dependencies": { "dependencies": {
"@keyv/mongo": "^2.1.8", "@keyv/mongo": "^2.1.8",
"@reduxjs/toolkit": "^1.9.2", "@reduxjs/toolkit": "^1.9.2",
"chatgpt": "^4.1.1", "chatgpt": "^4.2.0",
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-browserify": "^3.12.0", "crypto-browserify": "^3.12.0",
"dotenv": "^16.0.3", "dotenv": "^16.0.3",

View file

@ -33,7 +33,6 @@ app.get('/messages/:conversationId', async (req, res) => {
app.post('/clear_convos', async (req, res) => { app.post('/clear_convos', async (req, res) => {
let filter = {}; let filter = {};
const { conversationId } = req.body.arg; const { conversationId } = req.body.arg;
console.log('conversationId', conversationId);
if (!!conversationId) { if (!!conversationId) {
filter = { conversationId }; filter = { conversationId };
} }
@ -77,19 +76,24 @@ app.post('/ask', async (req, res) => {
res.write(`event: message\ndata: ${data}\n\n`); res.write(`event: message\ndata: ${data}\n\n`);
}; };
let gptResponse = await ask(text, progressCallback, { parentMessageId, conversationId }); try {
if (!!parentMessageId) { let gptResponse = await ask(text, progressCallback, { parentMessageId, conversationId });
gptResponse = { ...gptResponse, parentMessageId }; if (!!parentMessageId) {
} else { gptResponse = { ...gptResponse, parentMessageId };
gptResponse.title = await titleConversation(text, gptResponse.text); } else {
gptResponse.title = await titleConversation(text, gptResponse.text);
}
gptResponse.sender = 'GPT';
await saveMessage(gptResponse);
await saveConvo(gptResponse);
res.write(`event: message\ndata: ${JSON.stringify(gptResponse)}\n\n`);
res.end();
} catch (error) {
console.error(error);
res.status(500).send(error);
} }
gptResponse.sender = 'GPT';
await saveMessage(gptResponse);
await saveConvo(gptResponse);
res.write(`event: message\ndata: ${JSON.stringify(gptResponse)}\n\n`);
res.end();
}); });
app.listen(port, () => { app.listen(port, () => {

View file

@ -11,17 +11,14 @@ export default function Conversation({ id, parentMessageId, title = 'New convers
const conversationId = useSelector((state) => state.convo.conversationId); const conversationId = useSelector((state) => state.convo.conversationId);
const { trigger, isMutating } = manualSWR( const { trigger, isMutating } = manualSWR(
`http://localhost:3050/messages/${id}`, `http://localhost:3050/messages/${id}`,
'get', 'get'
(res) => dispatch(setMessages(res))
); );
const clickHandler = () => { const clickHandler = async () => {
if (conversationId === id) {
return;
}
dispatch(setConversation({ conversationId: id, parentMessageId })); dispatch(setConversation({ conversationId: id, parentMessageId }));
trigger(); const data = await trigger();
dispatch(setMessages(data));
}; };
return ( return (

View file

@ -0,0 +1,30 @@
import React from 'react';
import NavLink from './NavLink';
import TrashIcon from '../svg/TrashIcon';
import manualSWR from '~/utils/fetchers';
import { useDispatch } from 'react-redux';
import { setConversation } from '~/store/convoSlice';
import { setMessages } from '~/store/messageSlice';
export default function ClearConvos() {
const dispatch = useDispatch();
const { trigger, isMutating } = manualSWR(
'http://localhost:3050/clear_convos',
'post',
() => {
dispatch(setMessages([]));
dispatch(setConversation({ conversationId: null, parentMessageId: null }));
}
);
const clickHandler = () => trigger({});
return (
<NavLink
svg={TrashIcon}
text="Clear conversations"
onClick={clickHandler}
/>
);
}

View file

@ -1,14 +1,19 @@
import React from 'react'; import React from 'react';
export default function NavLink({ svg, text, clickHandler}) { export default function NavLink({ svg, text, clickHandler }) {
// const props const props = {
// if (clickHandler) { className:
'flex cursor-pointer items-center gap-3 rounded-md py-3 px-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10'
};
// } if (clickHandler) {
// return ( props.onClick = clickHandler;
// <a {clickHandler && onClick={clickHandler}} className="flex cursor-pointer items-center gap-3 rounded-md py-3 px-3 text-sm text-white transition-colors duration-200 hover:bg-gray-500/10"> }
// {svg()}
// {text} return (
// </a> <a {...props}>
// ); {svg()}
{text}
</a>
);
} }

View file

@ -1,34 +1,13 @@
import React from 'react'; import React from 'react';
import ClearConvos from './ClearConvos';
import NavLink from './NavLink'; import NavLink from './NavLink';
import TrashIcon from '../svg/TrashIcon';
import DarkModeIcon from '../svg/DarkModeIcon'; import DarkModeIcon from '../svg/DarkModeIcon';
import LogOutIcon from '../svg/LogOutIcon'; import LogOutIcon from '../svg/LogOutIcon';
import manualSWR from '~/utils/fetchers';
import { useDispatch } from 'react-redux';
import { setConversation } from '~/store/convoSlice';
import { setMessages } from '~/store/messageSlice';
export default function NavLinks() { export default function NavLinks() {
const dispatch = useDispatch();
const { trigger, isMutating } = manualSWR(
'http://localhost:3050/clear_convos',
'post',
() => {
dispatch(setMessages([]));
dispatch(setConversation({ conversationId: null, parentMessageId: null }));
}
);
const clickHandler = () => trigger({});
return ( return (
<> <>
<NavLink <ClearConvos />
svg={TrashIcon}
text="Clear conversations"
onClick={clickHandler}
/>
<NavLink <NavLink
svg={DarkModeIcon} svg={DarkModeIcon}
text="Dark mode" text="Dark mode"

View file

@ -9,7 +9,7 @@ const currentSlice = createSlice({
initialState, initialState,
reducers: { reducers: {
setMessages: (state, action) => { setMessages: (state, action) => {
state.messages = [...action.payload]; state.messages = action.payload;
}, },
} }
}); });

View file

@ -11,8 +11,11 @@ const postRequest = async (url, { arg }) => {
export const swr = (path) => useSWR(path, fetcher); export const swr = (path) => useSWR(path, fetcher);
export default function manualSWR(path, type, successCallback) { export default function manualSWR(path, type, successCallback) {
const options = {};
if (successCallback) {
options.onSuccess = successCallback;
}
const fetchFunction = type === 'get' ? fetcher : postRequest; const fetchFunction = type === 'get' ? fetcher : postRequest;
return useSWRMutation(path, fetchFunction, { return useSWRMutation(path, fetchFunction, options);
onSuccess: successCallback
});
}; };