diff --git a/projects/app/src/components/core/chat/components/AIResponseBox.tsx b/projects/app/src/components/core/chat/components/AIResponseBox.tsx index 81248a6d6..0f3b51a7e 100644 --- a/projects/app/src/components/core/chat/components/AIResponseBox.tsx +++ b/projects/app/src/components/core/chat/components/AIResponseBox.tsx @@ -8,8 +8,7 @@ import { Box, Button, Flex, - HStack, - Textarea + HStack } from '@chakra-ui/react'; import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants'; import { @@ -17,7 +16,7 @@ import { ToolModuleResponseItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type'; -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import MyIcon from '@fastgpt/web/components/common/Icon'; import Avatar from '@fastgpt/web/components/common/Avatar'; import { @@ -26,16 +25,14 @@ import { UserSelectInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type'; import { isEqual } from 'lodash'; -import FormLabel from '@fastgpt/web/components/common/MyBox/FormLabel'; -import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; -import { FlowNodeInputTypeEnum } from '@fastgpt/global/core/workflow/node/constant'; import { useTranslation } from 'next-i18next'; -import { Controller, useForm } from 'react-hook-form'; -import MySelect from '@fastgpt/web/components/common/MySelect'; -import MyTextarea from '@/components/common/Textarea/MyTextarea'; -import MyNumberInput from '@fastgpt/web/components/common/Input/NumberInput'; -import { SendPromptFnType } from '../ChatContainer/ChatBox/type'; import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus'; +import { + SelectOptionsComponent, + SelectOption, + FormInputComponent, + FormItem +} from './Form/FormComponents'; type props = { value: UserChatItemValueItemType | AIChatItemValueItemType; @@ -43,7 +40,12 @@ type props = { isChatting: boolean; }; -const onSendPrompt: SendPromptFnType = (e) => eventBus.emit(EventNameEnum.sendQuestion, e); +interface SendPromptParams { + text: string; + isInteractivePrompt: boolean; +} + +const onSendPrompt = (e: SendPromptParams) => eventBus.emit(EventNameEnum.sendQuestion, e); const RenderText = React.memo(function RenderText({ showAnimation, @@ -53,11 +55,9 @@ const RenderText = React.memo(function RenderText({ text?: string; }) { let source = text || ''; - // First empty line - // if (!source && !isLastChild) return null; - return ; }); + const RenderTool = React.memo( function RenderTool({ showAnimation, @@ -140,6 +140,7 @@ ${toolResponse}`} }, (prevProps, nextProps) => isEqual(prevProps, nextProps) ); + const RenderResoningContent = React.memo(function RenderResoningContent({ content, isChatting, @@ -192,149 +193,66 @@ const RenderResoningContent = React.memo(function RenderResoningContent({ ); }); + const RenderUserSelectInteractive = React.memo(function RenderInteractive({ interactive }: { interactive: InteractiveBasicType & UserSelectInteractive; }) { return ( - <> - {interactive?.params?.description && } - - {interactive.params.userSelectOptions?.map((option) => { - const selected = option.value === interactive?.params?.userSelectedVal; - - return ( - - ); - })} - - + { + onSendPrompt({ + text: value, + isInteractivePrompt: true + }); + }} + isDisabled={interactive.params.userSelectedVal !== undefined} + variant="whitePrimary" + /> ); }); + const RenderUserFormInteractive = React.memo(function RenderFormInput({ interactive }: { interactive: InteractiveBasicType & UserInputInteractive; }) { const { t } = useTranslation(); - const { register, setValue, handleSubmit: handleSubmitChat, control, reset } = useForm(); - const onSubmit = useCallback((data: any) => { + // 处理默认值 + const defaultValues = useMemo(() => { + if (interactive.type === 'userInput') { + return interactive.params.inputForm?.reduce((acc: Record, item) => { + acc[item.label] = !!item.value ? item.value : item.defaultValue; + return acc; + }, {}); + } + return {}; + }, [interactive]); + + // 提交表单时的处理 + const handleFormSubmit = useCallback((data: Record) => { onSendPrompt({ text: JSON.stringify(data), isInteractivePrompt: true }); }, []); - useEffect(() => { - if (interactive.type === 'userInput') { - const defaultValues = interactive.params.inputForm?.reduce( - (acc: Record, item) => { - acc[item.label] = !!item.value ? item.value : item.defaultValue; - return acc; - }, - {} - ); - reset(defaultValues); - } - }, []); - return ( - {interactive.params.description && } - {interactive.params.inputForm?.map((input) => ( - - - {input.label} - {input.description && } - - {input.type === FlowNodeInputTypeEnum.input && ( - - )} - {input.type === FlowNodeInputTypeEnum.textarea && ( -