index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useRef } from 'react'
  4. import { useContext } from 'use-context-selector'
  5. import produce from 'immer'
  6. import { useBoolean, useScroll } from 'ahooks'
  7. import { useFormattingChangedDispatcher } from '../debug/hooks'
  8. import DatasetConfig from '../dataset-config'
  9. import ChatGroup from '../features/chat-group'
  10. import ExperienceEnchanceGroup from '../features/experience-enchance-group'
  11. import Toolbox from '../toolbox'
  12. import HistoryPanel from '../config-prompt/conversation-histroy/history-panel'
  13. import ConfigVision from '../config-vision'
  14. import useAnnotationConfig from '../toolbox/annotation/use-annotation-config'
  15. import AddFeatureBtn from './feature/add-feature-btn'
  16. import ChooseFeature from './feature/choose-feature'
  17. import useFeature from './feature/use-feature'
  18. import AgentTools from './agent/agent-tools'
  19. import ConfigContext from '@/context/debug-configuration'
  20. import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
  21. import ConfigVar from '@/app/components/app/configuration/config-var'
  22. import { type CitationConfig, type ModelConfig, type ModerationConfig, type MoreLikeThisConfig, type PromptVariable, type SpeechToTextConfig, type SuggestedQuestionsAfterAnswerConfig, type TextToSpeechConfig } from '@/models/debug'
  23. import type { AppType } from '@/types/app'
  24. import { ModelModeType } from '@/types/app'
  25. import { useModalContext } from '@/context/modal-context'
  26. import ConfigParamModal from '@/app/components/app/configuration/toolbox/annotation/config-param-modal'
  27. import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
  28. import { useDefaultModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
  29. import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
  30. const Config: FC = () => {
  31. const {
  32. appId,
  33. mode,
  34. isAdvancedMode,
  35. modelModeType,
  36. isAgent,
  37. // canReturnToSimpleMode,
  38. // setPromptMode,
  39. hasSetBlockStatus,
  40. showHistoryModal,
  41. introduction,
  42. setIntroduction,
  43. suggestedQuestions,
  44. setSuggestedQuestions,
  45. modelConfig,
  46. setModelConfig,
  47. setPrevPromptConfig,
  48. moreLikeThisConfig,
  49. setMoreLikeThisConfig,
  50. suggestedQuestionsAfterAnswerConfig,
  51. setSuggestedQuestionsAfterAnswerConfig,
  52. speechToTextConfig,
  53. setSpeechToTextConfig,
  54. textToSpeechConfig,
  55. setTextToSpeechConfig,
  56. citationConfig,
  57. setCitationConfig,
  58. annotationConfig,
  59. setAnnotationConfig,
  60. moderationConfig,
  61. setModerationConfig,
  62. } = useContext(ConfigContext)
  63. const isChatApp = ['advanced-chat', 'agent-chat', 'chat'].includes(mode)
  64. const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text)
  65. const { data: text2speechDefaultModel } = useDefaultModel(ModelTypeEnum.tts)
  66. const { setShowModerationSettingModal } = useModalContext()
  67. const formattingChangedDispatcher = useFormattingChangedDispatcher()
  68. const promptTemplate = modelConfig.configs.prompt_template
  69. const promptVariables = modelConfig.configs.prompt_variables
  70. // simple mode
  71. const handlePromptChange = (newTemplate: string, newVariables: PromptVariable[]) => {
  72. const newModelConfig = produce(modelConfig, (draft: ModelConfig) => {
  73. draft.configs.prompt_template = newTemplate
  74. draft.configs.prompt_variables = [...draft.configs.prompt_variables, ...newVariables]
  75. })
  76. if (modelConfig.configs.prompt_template !== newTemplate)
  77. formattingChangedDispatcher()
  78. setPrevPromptConfig(modelConfig.configs)
  79. setModelConfig(newModelConfig)
  80. }
  81. const handlePromptVariablesNameChange = (newVariables: PromptVariable[]) => {
  82. setPrevPromptConfig(modelConfig.configs)
  83. const newModelConfig = produce(modelConfig, (draft: ModelConfig) => {
  84. draft.configs.prompt_variables = newVariables
  85. })
  86. setModelConfig(newModelConfig)
  87. }
  88. const [showChooseFeature, {
  89. setTrue: showChooseFeatureTrue,
  90. setFalse: showChooseFeatureFalse,
  91. }] = useBoolean(false)
  92. const { featureConfig, handleFeatureChange } = useFeature({
  93. introduction,
  94. setIntroduction,
  95. moreLikeThis: moreLikeThisConfig.enabled,
  96. setMoreLikeThis: (value) => {
  97. setMoreLikeThisConfig(produce(moreLikeThisConfig, (draft: MoreLikeThisConfig) => {
  98. draft.enabled = value
  99. }))
  100. },
  101. suggestedQuestionsAfterAnswer: suggestedQuestionsAfterAnswerConfig.enabled,
  102. setSuggestedQuestionsAfterAnswer: (value) => {
  103. setSuggestedQuestionsAfterAnswerConfig(produce(suggestedQuestionsAfterAnswerConfig, (draft: SuggestedQuestionsAfterAnswerConfig) => {
  104. draft.enabled = value
  105. }))
  106. formattingChangedDispatcher()
  107. },
  108. speechToText: speechToTextConfig.enabled,
  109. setSpeechToText: (value) => {
  110. setSpeechToTextConfig(produce(speechToTextConfig, (draft: SpeechToTextConfig) => {
  111. draft.enabled = value
  112. }))
  113. },
  114. textToSpeech: textToSpeechConfig.enabled,
  115. setTextToSpeech: (value) => {
  116. setTextToSpeechConfig(produce(textToSpeechConfig, (draft: TextToSpeechConfig) => {
  117. draft.enabled = value
  118. draft.voice = textToSpeechConfig?.voice
  119. draft.language = textToSpeechConfig?.language
  120. }))
  121. },
  122. citation: citationConfig.enabled,
  123. setCitation: (value) => {
  124. setCitationConfig(produce(citationConfig, (draft: CitationConfig) => {
  125. draft.enabled = value
  126. }))
  127. formattingChangedDispatcher()
  128. },
  129. annotation: annotationConfig.enabled,
  130. setAnnotation: async (value) => {
  131. if (value) {
  132. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  133. setIsShowAnnotationConfigInit(true)
  134. }
  135. else {
  136. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  137. await handleDisableAnnotation(annotationConfig.embedding_model)
  138. }
  139. },
  140. moderation: moderationConfig.enabled,
  141. setModeration: (value) => {
  142. setModerationConfig(produce(moderationConfig, (draft: ModerationConfig) => {
  143. draft.enabled = value
  144. }))
  145. if (value && !moderationConfig.type) {
  146. setShowModerationSettingModal({
  147. payload: {
  148. enabled: true,
  149. type: 'keywords',
  150. config: {
  151. keywords: '',
  152. inputs_config: {
  153. enabled: true,
  154. preset_response: '',
  155. },
  156. },
  157. },
  158. onSaveCallback: setModerationConfig,
  159. onCancelCallback: () => {
  160. setModerationConfig(produce(moderationConfig, (draft: ModerationConfig) => {
  161. draft.enabled = false
  162. showChooseFeatureTrue()
  163. }))
  164. },
  165. })
  166. showChooseFeatureFalse()
  167. }
  168. },
  169. })
  170. const {
  171. handleEnableAnnotation,
  172. setScore,
  173. handleDisableAnnotation,
  174. isShowAnnotationConfigInit,
  175. setIsShowAnnotationConfigInit,
  176. isShowAnnotationFullModal,
  177. setIsShowAnnotationFullModal,
  178. } = useAnnotationConfig({
  179. appId,
  180. annotationConfig,
  181. setAnnotationConfig,
  182. })
  183. const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && !!speech2textDefaultModel) || (featureConfig.textToSpeech && !!text2speechDefaultModel) || featureConfig.citation)
  184. const hasCompletionConfig = !isChatApp && (moreLikeThisConfig.enabled || (featureConfig.textToSpeech && !!text2speechDefaultModel))
  185. const hasToolbox = moderationConfig.enabled || featureConfig.annotation
  186. const wrapRef = useRef<HTMLDivElement>(null)
  187. const wrapScroll = useScroll(wrapRef)
  188. const toBottomHeight = (() => {
  189. if (!wrapRef.current)
  190. return 999
  191. const elem = wrapRef.current
  192. const { clientHeight } = elem
  193. const value = (wrapScroll?.top || 0) + clientHeight
  194. return value
  195. })()
  196. return (
  197. <>
  198. <div
  199. ref={wrapRef}
  200. className="grow h-0 relative px-6 pb-[50px] overflow-y-auto"
  201. >
  202. <AddFeatureBtn toBottomHeight={toBottomHeight} onClick={showChooseFeatureTrue} />
  203. {showChooseFeature && (
  204. <ChooseFeature
  205. isShow={showChooseFeature}
  206. onClose={showChooseFeatureFalse}
  207. isChatApp={isChatApp}
  208. config={featureConfig}
  209. onChange={handleFeatureChange}
  210. showSpeechToTextItem={!!speech2textDefaultModel}
  211. showTextToSpeechItem={!!text2speechDefaultModel}
  212. />
  213. )}
  214. {/* Template */}
  215. <ConfigPrompt
  216. mode={mode as AppType}
  217. promptTemplate={promptTemplate}
  218. promptVariables={promptVariables}
  219. onChange={handlePromptChange}
  220. />
  221. {/* Variables */}
  222. <ConfigVar
  223. promptVariables={promptVariables}
  224. onPromptVariablesChange={handlePromptVariablesNameChange}
  225. />
  226. {/* Dataset */}
  227. <DatasetConfig />
  228. {/* Tools */}
  229. {isAgent && (
  230. <AgentTools />
  231. )}
  232. <ConfigVision />
  233. {/* Chat History */}
  234. {isAdvancedMode && isChatApp && modelModeType === ModelModeType.completion && (
  235. <HistoryPanel
  236. showWarning={!hasSetBlockStatus.history}
  237. onShowEditModal={showHistoryModal}
  238. />
  239. )}
  240. {/* ChatConifig */}
  241. {
  242. hasChatConfig && (
  243. <ChatGroup
  244. isShowOpeningStatement={featureConfig.openingStatement}
  245. openingStatementConfig={
  246. {
  247. value: introduction,
  248. onChange: setIntroduction,
  249. suggestedQuestions,
  250. onSuggestedQuestionsChange: setSuggestedQuestions,
  251. }
  252. }
  253. isShowSuggestedQuestionsAfterAnswer={featureConfig.suggestedQuestionsAfterAnswer}
  254. isShowTextToSpeech={featureConfig.textToSpeech && !!text2speechDefaultModel}
  255. isShowSpeechText={featureConfig.speechToText && !!speech2textDefaultModel}
  256. isShowCitation={featureConfig.citation}
  257. />
  258. )
  259. }
  260. {/* Text Generation config */}{
  261. hasCompletionConfig && (
  262. <ExperienceEnchanceGroup
  263. isShowMoreLike={moreLikeThisConfig.enabled}
  264. isShowTextToSpeech={featureConfig.textToSpeech && !!text2speechDefaultModel}
  265. />
  266. )
  267. }
  268. {/* Toolbox */}
  269. {
  270. hasToolbox && (
  271. <Toolbox
  272. showModerationSettings={moderationConfig.enabled}
  273. showAnnotation={isChatApp && featureConfig.annotation}
  274. onEmbeddingChange={handleEnableAnnotation}
  275. onScoreChange={setScore}
  276. />
  277. )
  278. }
  279. <ConfigParamModal
  280. appId={appId}
  281. isInit
  282. isShow={isShowAnnotationConfigInit}
  283. onHide={() => {
  284. setIsShowAnnotationConfigInit(false)
  285. showChooseFeatureTrue()
  286. }}
  287. onSave={async (embeddingModel, score) => {
  288. await handleEnableAnnotation(embeddingModel, score)
  289. setIsShowAnnotationConfigInit(false)
  290. }}
  291. annotationConfig={annotationConfig}
  292. />
  293. {isShowAnnotationFullModal && (
  294. <AnnotationFullModal
  295. show={isShowAnnotationFullModal}
  296. onHide={() => setIsShowAnnotationFullModal(false)}
  297. />
  298. )}
  299. </div>
  300. </>
  301. )
  302. }
  303. export default React.memo(Config)