Skip to content

Commit

Permalink
ChatMode - extract as store, to persist between top-levels
Browse files Browse the repository at this point in the history
Not sure it belongs here, maybe should be part of a Chat Store instead.
  • Loading branch information
enricoros committed Oct 29, 2023
1 parent 33e1f7e commit 6b51a9f
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 45 deletions.
35 changes: 5 additions & 30 deletions src/apps/chat/AppChat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ChatDrawerItems } from './components/applayout/ChatDrawerItems';
import { ChatDropdowns } from './components/applayout/ChatDropdowns';
import { ChatMenuItems } from './components/applayout/ChatMenuItems';
import { ChatMessageList } from './components/ChatMessageList';
import { ChatModeId, useChatModeStore } from './store-chatmode';
import { CmdAddRoleMessage, extractCommands } from './commands';
import { Composer } from './components/composer/Composer';
import { Ephemerals } from './components/Ephemerals';
Expand All @@ -26,37 +27,10 @@ import { runReActUpdatingState } from './editors/react-tangent';

const SPECIAL_ID_ALL_CHATS = 'all-chats';

// definition of chat modes
export type ChatModeId = 'immediate' | 'immediate-follow-up' | 'write-user' | 'react' | 'draw-imagine';
export const ChatModeItems: { [key in ChatModeId]: { label: string; description: string | React.JSX.Element; experimental?: boolean } } = {
'immediate': {
label: 'Chat',
description: 'Persona answers',
},
'immediate-follow-up': {
label: 'Augmented Chat',
description: 'Chat with follow-up questions',
experimental: true,
},
'write-user': {
label: 'Write',
description: 'Just append a message',
},
'react': {
label: 'Reason+Act',
description: 'Answer your questions with ReAct and search',
},
'draw-imagine': {
label: 'Draw',
description: 'AI Image Generation',
},
};


export function AppChat() {

// state
const [chatModeId, setChatModeId] = React.useState<ChatModeId>('immediate');
const [isMessageSelectionMode, setIsMessageSelectionMode] = React.useState(false);
const [tradeConfig, setTradeConfig] = React.useState<TradeConfig | null>(null);
const [clearConfirmationId, setClearConfirmationId] = React.useState<string | null>(null);
Expand Down Expand Up @@ -144,12 +118,14 @@ export function AppChat() {

const handleSendUserMessage = async (conversationId: string, userText: string) => {
const conversation = _findConversation(conversationId);
if (conversation)
if (conversation) {
const chatModeId = useChatModeStore.getState().chatModeId;
return await handleExecuteConversation(chatModeId, conversationId, [...conversation.messages, createDMessage('user', userText)]);
}
};

const handleExecuteChatHistory = async (conversationId: string, history: DMessage[]) =>
await handleExecuteConversation(chatModeId, conversationId, history);
await handleExecuteConversation('immediate', conversationId, history);

const handleImagineFromText = async (conversationId: string, messageText: string) => {
const conversation = _findConversation(conversationId);
Expand Down Expand Up @@ -246,7 +222,6 @@ export function AppChat() {

<Composer
conversationId={activeConversationId} messageId={null}
chatModeId={chatModeId} setChatModeId={setChatModeId}
isDeveloperMode={systemPurposeId === 'Developer'}
onSendMessage={handleSendUserMessage}
sx={{
Expand Down
2 changes: 1 addition & 1 deletion src/apps/chat/components/composer/ChatModeMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as React from 'react';

import { Box, MenuItem, Radio, Typography } from '@mui/joy';

import { ChatModeId, ChatModeItems } from '../../AppChat';
import { ChatModeId, ChatModeItems } from '../../store-chatmode';

import { CloseableMenu } from '~/common/components/CloseableMenu';

Expand Down
28 changes: 14 additions & 14 deletions src/apps/chat/components/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { useGlobalShortcut } from '~/common/components/useGlobalShortcut';
import { useUIPreferencesStore, useUIStateStore } from '~/common/state/store-ui';

import { CameraCaptureButton } from './CameraCaptureButton';
import { ChatModeId } from '../../AppChat';
import { ChatModeId, useChatModeStore } from '../../store-chatmode';
import { ChatModeMenu } from './ChatModeMenu';
import { TokenBadge } from './TokenBadge';
import { TokenProgressbar } from './TokenProgressbar';
Expand Down Expand Up @@ -109,12 +109,12 @@ const CallButtonDesktop = (props: { disabled?: boolean, onClick: () => void, sx?
Call
</Button>;

const DrawButtonMobile = (props: { onClick: () => void, sx?: SxProps }) =>
const DrawOptionsButtonMobile = (props: { onClick: () => void, sx?: SxProps }) =>
<IconButton variant='soft' color='warning' onClick={props.onClick} sx={props.sx}>
<FormatPaintIcon />
</IconButton>;

const DrawButtonDesktop = (props: { onClick: () => void, sx?: SxProps }) =>
const DrawOptionsButtonDesktop = (props: { onClick: () => void, sx?: SxProps }) =>
<Button variant='soft' color='warning' onClick={props.onClick} endDecorator={<FormatPaintIcon />} sx={props.sx}>
Options
</Button>;
Expand All @@ -132,7 +132,6 @@ const DrawButtonDesktop = (props: { onClick: () => void, sx?: SxProps }) =>
*/
export function Composer(props: {
conversationId: string | null; messageId: string | null;
chatModeId: ChatModeId, setChatModeId: (chatModeId: ChatModeId) => void;
isDeveloperMode: boolean;
onSendMessage: (conversationId: string, text: string) => void;
sx?: SxProps;
Expand All @@ -148,6 +147,7 @@ export function Composer(props: {

// external state
const theme = useTheme();
const [chatModeId, setChatModeId] = useChatModeStore(state => [state.chatModeId, state.setChatModeId], shallow);
const { enterToSend, experimentalLabs } = useUIPreferencesStore(state => ({
enterToSend: state.enterToSend,
experimentalLabs: state.experimentalLabs,
Expand Down Expand Up @@ -201,9 +201,9 @@ export function Composer(props: {

const handleHideChatMode = () => setChatModeMenuAnchor(null);

const handleSetChatModeId = (chatModeId: ChatModeId) => {
const handleSetChatModeId = (_chatModeId: ChatModeId) => {
handleHideChatMode();
props.setChatModeId(chatModeId);
setChatModeId(_chatModeId);
};

const handleStopClicked = () => props.conversationId && stopTyping(props.conversationId);
Expand Down Expand Up @@ -397,12 +397,12 @@ export function Composer(props: {
console.log('Unhandled Drop event. Contents: ', e.dataTransfer.types.map(t => `${t}: ${e.dataTransfer.getData(t)}`));
};

const isImmediate = props.chatModeId === 'immediate';
const isWriteUser = props.chatModeId === 'write-user';
const isImmediate = chatModeId === 'immediate';
const isWriteUser = chatModeId === 'write-user';
const isChat = isImmediate || isWriteUser;
const isFollowUp = props.chatModeId === 'immediate-follow-up';
const isReAct = props.chatModeId === 'react';
const isDraw = props.chatModeId === 'draw-imagine';
const isFollowUp = chatModeId === 'immediate-follow-up';
const isReAct = chatModeId === 'react';
const isDraw = chatModeId === 'draw-imagine';

const textPlaceholder: string =
isDraw
Expand Down Expand Up @@ -572,7 +572,7 @@ export function Composer(props: {
/>}

{/* [mobile] [corner] Draw button */}
{isDraw && <DrawButtonMobile
{isDraw && <DrawOptionsButtonMobile
onClick={handleDrawOptionsClicked}
sx={{ ...hideOnDesktop, mr: { xs: 1, md: 2 } }}
/>}
Expand Down Expand Up @@ -609,7 +609,7 @@ export function Composer(props: {

{APP_CALL_ENABLED && isChat && <CallButtonDesktop disabled={!props.conversationId || !chatLLM} onClick={handleCallClicked} />}

{isDraw && <DrawButtonDesktop onClick={handleDrawOptionsClicked} />}
{isDraw && <DrawOptionsButtonDesktop onClick={handleDrawOptionsClicked} />}
</Box>

</Box>
Expand All @@ -621,7 +621,7 @@ export function Composer(props: {
<ChatModeMenu
anchorEl={chatModeMenuAnchor} onClose={handleHideChatMode}
experimental={experimentalLabs}
chatModeId={props.chatModeId} onSetChatModeId={handleSetChatModeId}
chatModeId={chatModeId} onSetChatModeId={handleSetChatModeId}
/>
)}

Expand Down
49 changes: 49 additions & 0 deletions src/apps/chat/store-chatmode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import * as React from 'react';
import { create } from 'zustand';


export type ChatModeId = 'immediate' | 'immediate-follow-up' | 'write-user' | 'react' | 'draw-imagine';

/// Describe the chat modes
export const ChatModeItems: { [key in ChatModeId]: { label: string; description: string | React.JSX.Element; experimental?: boolean } } = {
'immediate': {
label: 'Chat',
description: 'Persona answers',
},
'immediate-follow-up': {
label: 'Augmented Chat',
description: 'Chat with follow-up questions',
experimental: true,
},
'write-user': {
label: 'Write',
description: 'Just append a message',
},
'react': {
label: 'Reason+Act',
description: 'Answer your questions with ReAct and search',
},
'draw-imagine': {
label: 'Draw',
description: 'AI Image Generation',
},
};


/// Store

interface ChatModeData {

chatModeId: ChatModeId;
setChatModeId: (chatModeId: ChatModeId) => void;

}

export const useChatModeStore = create<ChatModeData>()(
(set) => ({

chatModeId: 'immediate',
setChatModeId: (chatModeId) => set({ chatModeId }),

}),
);

1 comment on commit 6b51a9f

@vercel
Copy link

@vercel vercel bot commented on 6b51a9f Oct 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

big-agi – ./

big-agi-git-main-enricoros.vercel.app
get.big-agi.com
big-agi-enricoros.vercel.app

Please sign in to comment.