import { Fragment } from 'react' import ScrollToBottom from 'react-scroll-to-bottom' import { ChatCompletionRole, ConversationalExtension, ExtensionType, InferenceEngine, MessageStatus, } from '@janhq/core' import { Button } from '@janhq/uikit' import { useAtomValue, useSetAtom } from 'jotai' import { RefreshCcw } from 'lucide-react' import LogoMark from '@/containers/Brand/Logo/Mark' import { MainViewState } from '@/constants/screens' import { useGetDownloadedModels } from '@/hooks/useGetDownloadedModels' import { useMainViewState } from '@/hooks/useMainViewState' import useSendChatMessage from '@/hooks/useSendChatMessage' import ChatItem from '../ChatItem' import { extensionManager } from '@/extension' import { deleteMessageAtom, getCurrentChatMessagesAtom, } from '@/helpers/atoms/ChatMessage.atom' import { activeThreadAtom } from '@/helpers/atoms/Thread.atom' const ChatBody: React.FC = () => { const messages = useAtomValue(getCurrentChatMessagesAtom) const { downloadedModels } = useGetDownloadedModels() const { setMainViewState } = useMainViewState() const thread = useAtomValue(activeThreadAtom) const deleteMessage = useSetAtom(deleteMessageAtom) const { resendChatMessage } = useSendChatMessage() const regenerateMessage = async () => { const lastMessageIndex = messages.length - 1 const message = messages[lastMessageIndex] if (message.role !== ChatCompletionRole.User) { // Delete last response before regenerating deleteMessage(message.id ?? '') if (thread) { await extensionManager .get(ExtensionType.Conversational) ?.writeMessages( thread.id, messages.filter((msg) => msg.id !== message.id) ) } const targetMessage = messages[lastMessageIndex - 1] if (targetMessage) resendChatMessage(targetMessage) } else { resendChatMessage(message) } } if (downloadedModels.length === 0) return (

Welcome!

You need to download your first model

) const showOnboardingStep = downloadedModels.filter((e) => e.engine === InferenceEngine.nitro) .length === 0 return ( {messages.length === 0 ? (
{showOnboardingStep ? ( <>

{`You don't have a local model yet.`}

) : (

How can I help you?

)}
) : ( {messages.map((message, index) => (
{message.status === MessageStatus.Error && index === messages.length - 1 && (
Oops! The generation was interrupted. Let's give it another go!
)}
))}
)}
) } export default ChatBody