| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  | import { memo, useCallback, useEffect, useImperativeHandle, useMemo } from 'react' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import { useNodes } from 'reactflow' | 
					
						
							|  |  |  | import { BlockEnum } from '../../types' | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   useStore, | 
					
						
							|  |  |  |   useWorkflowStore, | 
					
						
							|  |  |  | } from '../../store' | 
					
						
							|  |  |  | import type { StartNodeType } from '../../nodes/start/types' | 
					
						
							|  |  |  | import Empty from './empty' | 
					
						
							|  |  |  | import UserInput from './user-input' | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  | import ConversationVariableModal from './conversation-variable-modal' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import { useChat } from './hooks' | 
					
						
							|  |  |  | import type { ChatWrapperRefType } from './index' | 
					
						
							|  |  |  | import Chat from '@/app/components/base/chat/chat' | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  | import type { ChatItem, ChatItemInTree, OnSend } from '@/app/components/base/chat/types' | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  | import { useFeatures } from '@/app/components/base/features/hooks' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | import { | 
					
						
							|  |  |  |   fetchSuggestedQuestions, | 
					
						
							|  |  |  |   stopChatMessageResponding, | 
					
						
							|  |  |  | } from '@/service/debug' | 
					
						
							|  |  |  | import { useStore as useAppStore } from '@/app/components/app/store' | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  | import { getLastAnswer, isValidGeneratedAnswer } from '@/app/components/base/chat/utils' | 
					
						
							| 
									
										
										
										
											2025-04-15 15:37:08 +08:00
										 |  |  | import type { FileEntity } from '@/app/components/base/file-uploader/types' | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  | type ChatWrapperProps = { | 
					
						
							|  |  |  |   showConversationVariableModal: boolean | 
					
						
							|  |  |  |   onConversationModalHide: () => void | 
					
						
							|  |  |  |   showInputsFieldsPanel: boolean | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |   onHide: () => void | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  | const ChatWrapper = ( | 
					
						
							|  |  |  |   { | 
					
						
							|  |  |  |     ref, | 
					
						
							|  |  |  |     showConversationVariableModal, | 
					
						
							|  |  |  |     onConversationModalHide, | 
					
						
							|  |  |  |     showInputsFieldsPanel, | 
					
						
							|  |  |  |     onHide, | 
					
						
							|  |  |  |   }: ChatWrapperProps & { | 
					
						
							|  |  |  |     ref: React.RefObject<ChatWrapperRefType>; | 
					
						
							|  |  |  |   }, | 
					
						
							|  |  |  | ) => { | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   const nodes = useNodes<StartNodeType>() | 
					
						
							|  |  |  |   const startNode = nodes.find(node => node.data.type === BlockEnum.Start) | 
					
						
							|  |  |  |   const startVariables = startNode?.data.variables | 
					
						
							|  |  |  |   const appDetail = useAppStore(s => s.appDetail) | 
					
						
							|  |  |  |   const workflowStore = useWorkflowStore() | 
					
						
							|  |  |  |   const inputs = useStore(s => s.inputs) | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |   const features = useFeatures(s => s.features) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   const config = useMemo(() => { | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |       opening_statement: features.opening?.enabled ? (features.opening?.opening_statement || '') : '', | 
					
						
							|  |  |  |       suggested_questions: features.opening?.enabled ? (features.opening?.suggested_questions || []) : [], | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |       suggested_questions_after_answer: features.suggested, | 
					
						
							|  |  |  |       text_to_speech: features.text2speech, | 
					
						
							|  |  |  |       speech_to_text: features.speech2text, | 
					
						
							|  |  |  |       retriever_resource: features.citation, | 
					
						
							|  |  |  |       sensitive_word_avoidance: features.moderation, | 
					
						
							|  |  |  |       file_upload: features.file, | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |   }, [features.opening, features.suggested, features.text2speech, features.speech2text, features.citation, features.moderation, features.file]) | 
					
						
							|  |  |  |   const setShowFeaturesPanel = useStore(s => s.setShowFeaturesPanel) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   const { | 
					
						
							|  |  |  |     conversationId, | 
					
						
							|  |  |  |     chatList, | 
					
						
							|  |  |  |     handleStop, | 
					
						
							|  |  |  |     isResponding, | 
					
						
							|  |  |  |     suggestedQuestions, | 
					
						
							|  |  |  |     handleSend, | 
					
						
							|  |  |  |     handleRestart, | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |     setTargetMessageId, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   } = useChat( | 
					
						
							|  |  |  |     config, | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       inputs, | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |       inputsForm: (startVariables || []) as any, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     }, | 
					
						
							|  |  |  |     [], | 
					
						
							|  |  |  |     taskId => stopChatMessageResponding(appDetail!.id, taskId), | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |   const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => { | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |     handleSend( | 
					
						
							|  |  |  |       { | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |         query: message, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |         files, | 
					
						
							|  |  |  |         inputs: workflowStore.getState().inputs, | 
					
						
							|  |  |  |         conversation_id: conversationId, | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |         parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || undefined, | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |       }, | 
					
						
							|  |  |  |       { | 
					
						
							|  |  |  |         onGetSuggestedQuestions: (messageId, getAbortController) => fetchSuggestedQuestions(appDetail!.id, messageId, getAbortController), | 
					
						
							|  |  |  |       }, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |   }, [handleSend, workflowStore, conversationId, chatList, appDetail]) | 
					
						
							| 
									
										
										
										
											2024-09-22 03:15:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-15 15:37:08 +08:00
										 |  |  |   const doRegenerate = useCallback((chatItem: ChatItemInTree, editedQuestion?: { message: string, files?: FileEntity[] }) => { | 
					
						
							|  |  |  |     const question = editedQuestion ? chatItem : chatList.find(item => item.id === chatItem.parentMessageId)! | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |     const parentAnswer = chatList.find(item => item.id === question.parentMessageId) | 
					
						
							| 
									
										
										
										
											2025-04-15 15:37:08 +08:00
										 |  |  |     doSend(editedQuestion ? editedQuestion.message : question.content, | 
					
						
							|  |  |  |       editedQuestion ? editedQuestion.files : question.message_files, | 
					
						
							|  |  |  |       true, | 
					
						
							|  |  |  |       isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |   }, [chatList, doSend]) | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   useImperativeHandle(ref, () => { | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       handleRestart, | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }, [handleRestart]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |   useEffect(() => { | 
					
						
							|  |  |  |     if (isResponding) | 
					
						
							|  |  |  |       onHide() | 
					
						
							|  |  |  |   }, [isResponding, onHide]) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |     <> | 
					
						
							|  |  |  |       <Chat | 
					
						
							|  |  |  |         config={{ | 
					
						
							|  |  |  |           ...config, | 
					
						
							|  |  |  |           supportCitationHitInfo: true, | 
					
						
							|  |  |  |         } as any} | 
					
						
							|  |  |  |         chatList={chatList} | 
					
						
							|  |  |  |         isResponding={isResponding} | 
					
						
							|  |  |  |         chatContainerClassName='px-3' | 
					
						
							| 
									
										
										
										
											2024-09-06 19:20:18 +08:00
										 |  |  |         chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto' | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |         chatFooterClassName='px-4 rounded-bl-2xl' | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |         chatFooterInnerClassName='pb-0' | 
					
						
							|  |  |  |         showFileUpload | 
					
						
							|  |  |  |         showFeatureBar | 
					
						
							|  |  |  |         onFeatureBarClick={setShowFeaturesPanel} | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |         onSend={doSend} | 
					
						
							| 
									
										
										
										
											2024-10-21 10:32:37 +08:00
										 |  |  |         inputs={inputs} | 
					
						
							|  |  |  |         inputsForm={(startVariables || []) as any} | 
					
						
							| 
									
										
										
										
											2024-09-22 03:15:11 +08:00
										 |  |  |         onRegenerate={doRegenerate} | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |         onStopResponding={handleStop} | 
					
						
							|  |  |  |         chatNode={( | 
					
						
							|  |  |  |           <> | 
					
						
							|  |  |  |             {showInputsFieldsPanel && <UserInput />} | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               !chatList.length && ( | 
					
						
							|  |  |  |                 <Empty /> | 
					
						
							|  |  |  |               ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           </> | 
					
						
							|  |  |  |         )} | 
					
						
							| 
									
										
										
										
											2024-09-10 17:01:32 +08:00
										 |  |  |         noSpacing | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |         suggestedQuestions={suggestedQuestions} | 
					
						
							|  |  |  |         showPromptLog | 
					
						
							|  |  |  |         chatAnswerContainerInner='!pr-2' | 
					
						
							| 
									
										
										
										
											2025-01-31 13:05:10 +08:00
										 |  |  |         switchSibling={setTargetMessageId} | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |       /> | 
					
						
							|  |  |  |       {showConversationVariableModal && ( | 
					
						
							|  |  |  |         <ConversationVariableModal | 
					
						
							|  |  |  |           conversationID={conversationId} | 
					
						
							|  |  |  |           onHide={onConversationModalHide} | 
					
						
							|  |  |  |         /> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |       )} | 
					
						
							| 
									
										
										
										
											2024-08-13 14:44:10 +08:00
										 |  |  |     </> | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  |   ) | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2024-04-08 18:51:46 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | ChatWrapper.displayName = 'ChatWrapper' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default memo(ChatWrapper) |