Skip to content

Commit

Permalink
added prisma, next-auth and tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
JHM69 committed Jul 13, 2023
1 parent c2fa56e commit 1331e53
Show file tree
Hide file tree
Showing 22 changed files with 7,565 additions and 1,421 deletions.
22 changes: 21 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,24 @@ OPENAI_API_ORG_ID=org-VawbJTMFvW9nwKniLZhA7gVx
# [Optional] Enables ElevenLabs credentials on the server side - for optional text-to-speech
ELEVENLABS_API_KEY=a945205a98cf786964be46a41439ba64
ELEVENLABS_API_HOST=https://api.elevenlabs.io
ELEVENLABS_VOICE_ID=
ELEVENLABS_VOICE_ID=

# This was inserted by `prisma init`:
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL=mysql://root:@localhost:3306/MeghBuzzDatabase

JWT_SECRET=ecb9cb92dfce1f2b357aca2d1c5ee39e

NEXTAUTH_SECRET=d/jWP/kaagPylVaEiPnio2DPGBbQNwCUkLohGsGsaKA=
NEXTAUTH_URL=http://localhost:3000

GOOGLE_ID=923437817359-hq564rl7am6t3eao445npqb55sunaopu.apps.googleusercontent.com
GOOGLE_SECRET=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


NODE_ENV=production
74 changes: 19 additions & 55 deletions components/ApplicationBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import { StyledDropdownWithSymbol } from '@/components/util/StyledDropdownWithSy
import { useChatStore } from '@/lib/store-chats';
import { useSettingsStore } from '@/lib/store-settings';
import Link from 'next/link';
import { Login } from '@mui/icons-material';
import { signOut } from 'next-auth/react';

/**
* The top bar of the application, with the model and purpose selection, and menu/settings icons
Expand Down Expand Up @@ -87,16 +89,14 @@ export function ApplicationBar(props: {
shallow,
);

const handleConversationClear = (e: React.MouseEvent<HTMLDivElement>) => {
const handleLogut = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
setClearConfirmationId(props.conversationId);
};

const handleConfirmedClearConversation = () => {
const handleSignOut = () => {
if (clearConfirmationId) {
setMessages(clearConfirmationId, []);
setAutoTitle(clearConfirmationId, '');
setClearConfirmationId(null);
signOut({ redirect: true, callbackUrl: '/' });
}
};

Expand Down Expand Up @@ -145,10 +145,12 @@ export function ApplicationBar(props: {
) : (
<StyledDropdownWithSymbol items={SystemPurposes} value={systemPurposeId} onChange={handleSystemPurposeChange} />
))}

<Link href="/bookvarse" target="_blank">
<button>MeghBuzz Bookvarse</button>
</Link>
<button>
{' '}
<Link href="/bookvarse" target="_blank">
MeghBuzz Bookvarse
</Link>{' '}
</button>
</Stack>

<IconButton variant="plain" onClick={(event) => setActionsMenuAnchor(event.currentTarget)}>
Expand Down Expand Up @@ -179,66 +181,28 @@ export function ApplicationBar(props: {
<Switch checked={colorMode === 'dark'} onChange={handleDarkModeToggle} sx={{ ml: 'auto' }} />
</MenuItem>

<MenuItem>
<ListItemDecorator>
<SettingsSuggestIcon />
</ListItemDecorator>
System text
<Switch checked={showSystemMessages} onChange={handleSystemMessagesToggle} sx={{ ml: 'auto' }} />
</MenuItem>

<MenuItem>
<ListItemDecorator>
<SwapVertIcon />
</ListItemDecorator>
Free scroll
<Switch checked={freeScroll} onChange={handleScrollModeToggle} sx={{ ml: 'auto' }} />
</MenuItem>

<MenuItem onClick={handleActionShowSettings}>
{/* <MenuItem onClick={handleActionShowSettings}>
<ListItemDecorator>
<SettingsOutlinedIcon />
</ListItemDecorator>
Settings
</MenuItem>

<ListDivider />

<MenuItem disabled={!props.conversationId || isConversationEmpty} onClick={handleConversationDownload}>
<ListItemDecorator>
{/*<Badge size='sm' color='danger'>*/}
<FileDownloadIcon />
{/*</Badge>*/}
</ListItemDecorator>
Download JSON
</MenuItem>

<MenuItem disabled={!props.conversationId || isConversationEmpty} onClick={handleConversationPublish}>
<ListItemDecorator>
{/*<Badge size='sm' color='primary'>*/}
<ExitToAppIcon />
{/*</Badge>*/}
</ListItemDecorator>
Share via paste.gg
</MenuItem>

<ListDivider />
</MenuItem> */}

<MenuItem disabled={!props.conversationId || isConversationEmpty} onClick={handleConversationClear}>
<MenuItem onClick={handleLogut}>
<ListItemDecorator>
<ClearIcon />
<Login />
</ListItemDecorator>
Clear conversation
Log Out
</MenuItem>
</Menu>

{/* Confirmations */}
<ConfirmationModal
open={!!clearConfirmationId}
onClose={() => setClearConfirmationId(null)}
onPositive={handleConfirmedClearConversation}
confirmationText={'Are you sure you want to discard all the messages?'}
positiveActionText={'Clear conversation'}
onPositive={handleSignOut}
confirmationText={'Are you sure you want to log out ?'}
positiveActionText={'Log Out'}
/>
</>
);
Expand Down
97 changes: 58 additions & 39 deletions components/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,24 @@ import { publishConversation } from '@/lib/publish';
import { speakIfFirstLine } from '@/lib/text-to-speech';
import { streamAssistantMessage, updateAutoConversationTitle } from '@/lib/ai';
import { useSettingsStore } from '@/lib/store-settings';

import { useSession } from 'next-auth/react';
import { useRouter } from 'next/router';

/**
* The main "chat" function. TODO: this is here so we can soon move it to the data model.
*/
const runAssistantUpdatingState = async (conversationId: string, history: DMessage[], assistantModel: ChatModelId, assistantPurpose: SystemPurposeId) => {

// reference the state editing functions
const { startTyping, appendMessage, editMessage, setMessages } = useChatStore.getState();

// update the purpose of the system message (if not manually edited), and create if needed
{
const systemMessageIndex = history.findIndex(m => m.role === 'system');
const systemMessageIndex = history.findIndex((m) => m.role === 'system');
const systemMessage: DMessage = systemMessageIndex >= 0 ? history.splice(systemMessageIndex, 1)[0] : createDMessage('system', '');

if (!systemMessage.updated) {
systemMessage.purposeId = assistantPurpose;
systemMessage.text = SystemPurposes[assistantPurpose]?.systemMessage
.replaceAll('{{Today}}', new Date().toISOString().split('T')[0]);
systemMessage.text = SystemPurposes[assistantPurpose]?.systemMessage.replaceAll('{{Today}}', new Date().toISOString().split('T')[0]);
}

history.unshift(systemMessage);
Expand All @@ -58,7 +57,20 @@ const runAssistantUpdatingState = async (conversationId: string, history: DMessa
startTyping(conversationId, controller);

const { apiKey, apiHost, apiOrganizationId, modelTemperature, modelMaxResponseTokens } = useSettingsStore.getState();
await streamAssistantMessage(conversationId, assistantMessageId, history, apiKey, apiHost, apiOrganizationId, assistantModel, modelTemperature, modelMaxResponseTokens, editMessage, controller.signal, speakIfFirstLine);
await streamAssistantMessage(
conversationId,
assistantMessageId,
history,
apiKey,
apiHost,
apiOrganizationId,
assistantModel,
modelTemperature,
modelMaxResponseTokens,
editMessage,
controller.signal,
speakIfFirstLine,
);

// clear to send, again
startTyping(conversationId, null);
Expand All @@ -67,27 +79,26 @@ const runAssistantUpdatingState = async (conversationId: string, history: DMessa
await updateAutoConversationTitle(conversationId);
};


export function Chat(props: { onShowSettings: () => void, sx?: SxProps }) {
export function Chat(props: { onShowSettings: () => void; sx?: SxProps }) {
// state
const [publishConversationId, setPublishConversationId] = React.useState<string | null>(null);
const [publishResponse, setPublishResponse] = React.useState<ApiPublishResponse | null>(null);



// external state
const theme = useTheme();
const { activeConversationId, chatModelId, systemPurposeId } = useChatStore(state => {
const conversation = state.conversations.find(conversation => conversation.id === state.activeConversationId);
const { activeConversationId, chatModelId, systemPurposeId } = useChatStore((state) => {
const conversation = state.conversations.find((conversation) => conversation.id === state.activeConversationId);
return {
activeConversationId: state.activeConversationId,
chatModelId: conversation?.chatModelId ?? null,
systemPurposeId: conversation?.systemPurposeId ?? null,
};
}, shallow);


const _findConversation = (conversationId: string) =>
conversationId ? useChatStore.getState().conversations.find(c => c.id === conversationId) ?? null : null;

conversationId ? useChatStore.getState().conversations.find((c) => c.id === conversationId) ?? null : null;

const handleSendMessage = async (conversationId: string, userText: string) => {
const conversation = _findConversation(conversationId);
Expand All @@ -96,17 +107,14 @@ export function Chat(props: { onShowSettings: () => void, sx?: SxProps }) {
};

const handleRestartConversation = async (conversationId: string, history: DMessage[]) => {
if (conversationId && chatModelId && systemPurposeId)
await runAssistantUpdatingState(conversationId, history, chatModelId, systemPurposeId);
if (conversationId && chatModelId && systemPurposeId) await runAssistantUpdatingState(conversationId, history, chatModelId, systemPurposeId);
};


const handleDownloadConversationToJson = (conversationId: string) => {
const conversation = _findConversation(conversationId);
conversation && downloadConversationJson(conversation);
};


const handlePublishConversation = (conversationId: string) => setPublishConversationId(conversationId);

const handleConfirmedPublishConversation = async () => {
Expand All @@ -117,24 +125,27 @@ export function Chat(props: { onShowSettings: () => void, sx?: SxProps }) {
}
};


return (

<Box
sx={{
display: 'flex', flexDirection: 'column', minHeight: '100vh',
display: 'flex',
flexDirection: 'column',
minHeight: '100vh',
...(props.sx || {}),
}}>

}}
>
<ApplicationBar
conversationId={activeConversationId}
onDownloadConversationJSON={handleDownloadConversationToJson}
onPublishConversation={handlePublishConversation}
onShowSettings={props.onShowSettings}
sx={{
position: 'sticky', top: 0, zIndex: 20,
position: 'sticky',
top: 0,
zIndex: 20,
// ...(process.env.NODE_ENV === 'development' ? { background: theme.vars.palette.danger.solidBg } : {}),
}} />
}}
/>

<ChatMessageList
conversationId={activeConversationId}
Expand All @@ -144,35 +155,43 @@ export function Chat(props: { onShowSettings: () => void, sx?: SxProps }) {
background: theme.vars.palette.background.level2,
overflowY: 'hidden',
marginBottom: '-1px',
}} />
}}
/>

<Composer
conversationId={activeConversationId} messageId={null}
conversationId={activeConversationId}
messageId={null}
isDeveloperMode={systemPurposeId === 'Developer'}
onSendMessage={handleSendMessage}
sx={{
position: 'sticky', bottom: 0, zIndex: 21,
position: 'sticky',
bottom: 0,
zIndex: 21,
background: theme.vars.palette.background.surface,
borderTop: `1px solid ${theme.vars.palette.divider}`,
p: { xs: 1, md: 2 },
}} />
}}
/>

{/* Confirmation for Publishing */}
<ConfirmationModal
open={!!publishConversationId} onClose={() => setPublishConversationId(null)} onPositive={handleConfirmedPublishConversation}
confirmationText={<>
Share your conversation anonymously on <Link href='https://paste.gg' target='_blank'>paste.gg</Link>?
It will be unlisted and available to share and read for 30 days. Keep in mind, deletion may not be possible.
Are you sure you want to proceed?
</>} positiveActionText={'Understood, upload to paste.gg'}
open={!!publishConversationId}
onClose={() => setPublishConversationId(null)}
onPositive={handleConfirmedPublishConversation}
confirmationText={
<>
Share your conversation anonymously on{' '}
<Link href="https://paste.gg" target="_blank">
paste.gg
</Link>
? It will be unlisted and available to share and read for 30 days. Keep in mind, deletion may not be possible. Are you sure you want to proceed?
</>
}
positiveActionText={'Understood, upload to paste.gg'}
/>

{/* Show the Published details */}
{!!publishResponse && (
<PublishedModal open onClose={() => setPublishResponse(null)} response={publishResponse} />
)}

{!!publishResponse && <PublishedModal open onClose={() => setPublishResponse(null)} response={publishResponse} />}
</Box>

);
}
Loading

0 comments on commit 1331e53

Please sign in to comment.