import { ChatContext } from '@/app/chat-context'; import { apiInterceptors, getChatFeedBackSelect } from '@/client/api'; import useSummary from '@/hooks/use-summary'; import { FeedBack, IChatDialogueMessageSchema } from '@/types/chat'; import { STORAGE_INIT_MESSAGE_KET, getInitMessage } from '@/utils'; import { CopyOutlined, RedoOutlined } from '@ant-design/icons'; import { Button, IconButton } from '@mui/joy'; import { useAsyncEffect } from 'ahooks'; import { Modal, Tooltip, message } from 'antd'; import classNames from 'classnames'; import copy from 'copy-to-clipboard'; import { cloneDeep } from 'lodash'; import { useSearchParams } from 'next/navigation'; import { useContext, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import MyEmpty from '../common/MyEmpty'; import CompletionInput from '../common/completion-input'; import AgentContent from './agent-content'; import ChatContent from './chat-content'; import ChatFeedback from './chat-feedback'; import { renderModelIcon } from './header/model-selector'; import MonacoEditor from './monaco-editor'; type Props = { messages: IChatDialogueMessageSchema[]; onSubmit: (message: string, otherQueryBody?: Record) => Promise; }; const Completion = ({ messages, onSubmit }: Props) => { const { dbParam, currentDialogue, scene, model, refreshDialogList, chatId, agent, docId } = useContext(ChatContext); const { t } = useTranslation(); const searchParams = useSearchParams(); const flowSelectParam = (searchParams && searchParams.get('select_param')) ?? ''; const spaceNameOriginal = (searchParams && searchParams.get('spaceNameOriginal')) ?? ''; const [isLoading, setIsLoading] = useState(false); const [jsonModalOpen, setJsonModalOpen] = useState(false); const [showMessages, setShowMessages] = useState(messages); const [jsonValue, setJsonValue] = useState(''); const [select_param, setSelectParam] = useState(); const scrollableRef = useRef(null); // const incremental = useMemo(() => scene === 'chat_flow', [scene]); const isChartChat = useMemo(() => scene === 'chat_dashboard', [scene]); const summary = useSummary(); const selectParam = useMemo(() => { switch (scene) { case 'chat_agent': return agent; case 'chat_excel': return currentDialogue?.select_param; case 'chat_flow': return flowSelectParam; default: return spaceNameOriginal || dbParam; } }, [scene, agent, currentDialogue, dbParam, spaceNameOriginal, flowSelectParam]); const handleChat = async (content: string) => { if (isLoading || !content.trim()) return; if (scene === 'chat_agent' && !agent) { message.warning(t('choice_agent_tip')); return; } try { setIsLoading(true); await onSubmit(content, { select_param: selectParam ?? '', // incremental, }); } finally { setIsLoading(false); } }; const handleJson2Obj = (jsonStr: string) => { try { return JSON.parse(jsonStr); } catch { return jsonStr; } }; const [messageApi, contextHolder] = message.useMessage(); const onCopyContext = async (context: any) => { const pureStr = context?.replace(/\trelations:.*/g, ''); const result = copy(pureStr); if (result) { if (pureStr) { messageApi.open({ type: 'success', content: t('copy_success') }); } else { messageApi.open({ type: 'warning', content: t('copy_nothing') }); } } else { messageApi.open({ type: 'error', content: t('copy_failed') }); } }; const handleRetry = async () => { if (isLoading || !docId) { return; } setIsLoading(true); await summary(docId); setIsLoading(false); }; useAsyncEffect(async () => { const initMessage = getInitMessage(); if (initMessage && initMessage.id === chatId) { await handleChat(initMessage.message); refreshDialogList(); localStorage.removeItem(STORAGE_INIT_MESSAGE_KET); } }, [chatId]); useEffect(() => { let tempMessage: IChatDialogueMessageSchema[] = messages; if (isChartChat) { tempMessage = cloneDeep(messages).map(item => { if (item?.role === 'view' && typeof item?.context === 'string') { item.context = handleJson2Obj(item?.context); } return item; }); } setShowMessages(tempMessage.filter(item => ['view', 'human'].includes(item.role))); }, [isChartChat, messages]); useEffect(() => { apiInterceptors(getChatFeedBackSelect()) .then(res => { setSelectParam(res[1] ?? {}); }) .catch(err => { console.log(err); }); }, []); useEffect(() => { setTimeout(() => { scrollableRef.current?.scrollTo(0, scrollableRef.current.scrollHeight); }, 50); }, [messages]); return ( <> {contextHolder}
{showMessages.length ? ( showMessages.map((content, index) => { if (scene === 'chat_agent') { return ; } return ( { setJsonModalOpen(true); setJsonValue(JSON.stringify(content?.context, null, 2)); }} > {content.role === 'view' && (
{scene === 'chat_knowledge' && content.retry ? ( ) : null}
e?.role === 'human' && e?.order === content.order)[0]?.context } knowledge_space={spaceNameOriginal || dbParam || ''} />
)}
); }) ) : ( )}
{model &&
{renderModelIcon(model)}
}
{ setJsonModalOpen(false); }} onCancel={() => { setJsonModalOpen(false); }} > ); }; export default Completion;