generated from amosproj/amos202Xss0Y-projname
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #212 from amosproj/204-query-and-display-multiple-…
…llm-responses-simultaneously---frontend Multiple llm selection menu & chat UI integration Wrong linting comes from code that is not ours
- Loading branch information
Showing
23 changed files
with
405 additions
and
281 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
103 changes: 0 additions & 103 deletions
103
src/frontend/TO INTEGRATE - Chat UI/components/ChatUI.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import React, { type ReactNode, createContext, useState, useContext, type Dispatch, type SetStateAction } from 'react'; | ||
|
||
// Define the shape of the context value | ||
interface ChatContextValue { | ||
activeChatId: string; | ||
setActiveChatId: Dispatch<SetStateAction<string>>; | ||
} | ||
|
||
// Define the default context value | ||
const defaultContextValue: ChatContextValue = { | ||
activeChatId: 'default', | ||
setActiveChatId: () => {}, | ||
}; | ||
|
||
// Create a context with the default value | ||
export const ChatContext = createContext<ChatContextValue>(defaultContextValue); | ||
|
||
type ActiveChatProviderProps = { | ||
children: ReactNode; | ||
}; | ||
|
||
// Create a provider component | ||
export const ActiveChatProvider = (props: ActiveChatProviderProps ) => { | ||
const [activeChatId, setActiveChatId] = useState<string>('default'); // initial active chat id is -1 | ||
const { children } = props; | ||
|
||
return ( | ||
<ChatContext.Provider value={{ activeChatId, setActiveChatId }}> | ||
{children} | ||
</ChatContext.Provider> | ||
); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,78 @@ | ||
import { type RouteProp, useRoute } from '@react-navigation/native'; | ||
import React, { useMemo, useState } from 'react'; | ||
import { Button, Menu } from 'react-native-paper'; | ||
import { useGetChat, useUpdateChat } from 'src/frontend/hooks'; | ||
import React, { useEffect, useState } from 'react'; | ||
import { Button, Menu, Checkbox, List } from 'react-native-paper'; | ||
import type { MainDrawerParams } from 'src/frontend/routes/MainRoutes'; | ||
import { useLLMs } from 'src/frontend/hooks/useLLMs'; | ||
import { View } from 'react-native'; | ||
import { Style } from './style'; | ||
import { useActiveChatId, useGetAllChat, useGetChat} from 'src/frontend/hooks'; | ||
import type { Chat } from 'src/frontend/types'; | ||
import type { ChatItemProps } from 'src/frontend/components/ChatItem' | ||
|
||
|
||
export const DropdownMenu = () => { | ||
const router = useRoute<RouteProp<MainDrawerParams>>(); | ||
const chatId = router.params?.chatId; | ||
// get chatID after opening app copilot help | ||
const route = useRoute<RouteProp<MainDrawerParams>>(); | ||
const chatId = route.params?.chatId; | ||
const [isVisible, setIsVisible] = useState(false); | ||
const { chat, status } = useGetChat(chatId || 'default'); | ||
const { updateChat, isUpdating } = useUpdateChat(chatId || 'default'); | ||
const { activeLLMs, toggleLLM } = useLLMs(chatId || 'default'); | ||
|
||
const { activeChatId, setActiveChatId } = useActiveChatId(); | ||
const { chat, status, error } = useGetChat(activeChatId); | ||
|
||
const activeLLMsCount = Object.values(activeLLMs).filter(llm => llm.active).length; | ||
const activeLLMsNames = Object.values(activeLLMs).filter(llm => llm.active).map(llm => llm.name); | ||
let buttonLabel = activeLLMsCount === 1 ? activeLLMsNames[0] : `${activeLLMsCount} LLMs`; | ||
|
||
const llmModels: { [key: string]: string } = useMemo(() => { | ||
return { | ||
'gpt-4': 'OpenAi', | ||
'google-gemini': 'Gemini', | ||
'mistral-ai': 'Mistral', | ||
'claude-ai': 'Claude' | ||
}; | ||
}, []); | ||
// If no chatId is selected, set button label to "SELECT" | ||
if (chat === undefined) { | ||
buttonLabel = ""; | ||
} | ||
|
||
const handleLLMModelChange = async (model: string) => { | ||
setIsVisible(false); | ||
try { | ||
await updateChat({ model: model }); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
}; | ||
// Determine if the button should be disabled | ||
const isButtonDisabled = chat === undefined || activeLLMsCount === 0; | ||
|
||
return ( | ||
<Menu | ||
visible={isVisible} | ||
onDismiss={() => setIsVisible(false)} | ||
anchorPosition='bottom' | ||
anchor={ | ||
<Button | ||
mode='outlined' | ||
onPress={() => setIsVisible(true)} | ||
icon={'brain'} | ||
loading={status === 'loading' || isUpdating} | ||
> | ||
{llmModels[chat?.model || 'gpt-4']} | ||
</Button> | ||
} | ||
> | ||
{Object.entries(llmModels).map((model) => { | ||
const [key, value] = model; | ||
return ( | ||
<Menu | ||
visible={isVisible} | ||
onDismiss={() => setIsVisible(false)} | ||
anchor={ | ||
<Button | ||
mode="outlined" | ||
onPress={() => setIsVisible(true)} | ||
icon="brain" | ||
loading={status === 'loading'} | ||
disabled={isButtonDisabled} | ||
> | ||
{buttonLabel} | ||
</Button> | ||
} | ||
> | ||
<List.Section> | ||
{Object.entries(activeLLMs).map(([key, llm]) => ( | ||
<Menu.Item | ||
key={key} | ||
onPress={async () => { | ||
await handleLLMModelChange(key); | ||
onPress={() => { | ||
if (activeLLMsCount > 1 || !llm.active) { | ||
toggleLLM(key); | ||
} | ||
}} | ||
title={value} | ||
title={ | ||
<View style={Style.menuItem}> | ||
<List.Item | ||
title={llm.name} | ||
style={{ flex: 1 }} | ||
/> | ||
<Checkbox | ||
status={llm.active ? 'checked' : 'unchecked'} | ||
disabled={activeLLMsCount === 1 && llm.active} | ||
/> | ||
</View> | ||
} | ||
/> | ||
); | ||
})} | ||
))} | ||
</List.Section> | ||
</Menu> | ||
); | ||
}; |
Oops, something went wrong.