chat-wrapper.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import {
  2. forwardRef,
  3. memo,
  4. useCallback,
  5. useImperativeHandle,
  6. useMemo,
  7. } from 'react'
  8. import { useNodes } from 'reactflow'
  9. import { BlockEnum } from '../../types'
  10. import {
  11. useStore,
  12. useWorkflowStore,
  13. } from '../../store'
  14. import type { StartNodeType } from '../../nodes/start/types'
  15. import Empty from './empty'
  16. import UserInput from './user-input'
  17. import ConversationVariableModal from './conversation-variable-modal'
  18. import { useChat } from './hooks'
  19. import type { ChatWrapperRefType } from './index'
  20. import Chat from '@/app/components/base/chat/chat'
  21. import type { OnSend } from '@/app/components/base/chat/types'
  22. import { useFeaturesStore } from '@/app/components/base/features/hooks'
  23. import {
  24. fetchSuggestedQuestions,
  25. stopChatMessageResponding,
  26. } from '@/service/debug'
  27. import { useStore as useAppStore } from '@/app/components/app/store'
  28. type ChatWrapperProps = {
  29. showConversationVariableModal: boolean
  30. onConversationModalHide: () => void
  31. showInputsFieldsPanel: boolean
  32. }
  33. const ChatWrapper = forwardRef<ChatWrapperRefType, ChatWrapperProps>(({ showConversationVariableModal, onConversationModalHide, showInputsFieldsPanel }, ref) => {
  34. const nodes = useNodes<StartNodeType>()
  35. const startNode = nodes.find(node => node.data.type === BlockEnum.Start)
  36. const startVariables = startNode?.data.variables
  37. const appDetail = useAppStore(s => s.appDetail)
  38. const workflowStore = useWorkflowStore()
  39. const featuresStore = useFeaturesStore()
  40. const inputs = useStore(s => s.inputs)
  41. const features = featuresStore!.getState().features
  42. const config = useMemo(() => {
  43. return {
  44. opening_statement: features.opening?.opening_statement || '',
  45. suggested_questions: features.opening?.suggested_questions || [],
  46. suggested_questions_after_answer: features.suggested,
  47. text_to_speech: features.text2speech,
  48. speech_to_text: features.speech2text,
  49. retriever_resource: features.citation,
  50. sensitive_word_avoidance: features.moderation,
  51. file_upload: features.file,
  52. }
  53. }, [features])
  54. const {
  55. conversationId,
  56. chatList,
  57. handleStop,
  58. isResponding,
  59. suggestedQuestions,
  60. handleSend,
  61. handleRestart,
  62. } = useChat(
  63. config,
  64. {
  65. inputs,
  66. promptVariables: (startVariables as any) || [],
  67. },
  68. [],
  69. taskId => stopChatMessageResponding(appDetail!.id, taskId),
  70. )
  71. const doSend = useCallback<OnSend>((query, files) => {
  72. handleSend(
  73. {
  74. query,
  75. files,
  76. inputs: workflowStore.getState().inputs,
  77. conversation_id: conversationId,
  78. },
  79. {
  80. onGetSuggestedQuestions: (messageId, getAbortController) => fetchSuggestedQuestions(appDetail!.id, messageId, getAbortController),
  81. },
  82. )
  83. }, [conversationId, handleSend, workflowStore, appDetail])
  84. useImperativeHandle(ref, () => {
  85. return {
  86. handleRestart,
  87. }
  88. }, [handleRestart])
  89. return (
  90. <>
  91. <Chat
  92. config={{
  93. ...config,
  94. supportCitationHitInfo: true,
  95. } as any}
  96. chatList={chatList}
  97. isResponding={isResponding}
  98. chatContainerClassName='px-3'
  99. chatContainerInnerClassName='pt-6'
  100. chatFooterClassName='px-4 rounded-bl-2xl'
  101. chatFooterInnerClassName='pb-4'
  102. onSend={doSend}
  103. onStopResponding={handleStop}
  104. chatNode={(
  105. <>
  106. {showInputsFieldsPanel && <UserInput />}
  107. {
  108. !chatList.length && (
  109. <Empty />
  110. )
  111. }
  112. </>
  113. )}
  114. suggestedQuestions={suggestedQuestions}
  115. showPromptLog
  116. chatAnswerContainerInner='!pr-2'
  117. />
  118. {showConversationVariableModal && (
  119. <ConversationVariableModal
  120. conversationID={conversationId}
  121. onHide={onConversationModalHide}
  122. />
  123. )}
  124. </>
  125. )
  126. })
  127. ChatWrapper.displayName = 'ChatWrapper'
  128. export default memo(ChatWrapper)