diff --git a/api/core/app/app_config/entities.py b/api/core/app/app_config/entities.py index 8ae52131f2..3f31b1c3d5 100644 --- a/api/core/app/app_config/entities.py +++ b/api/core/app/app_config/entities.py @@ -109,6 +109,7 @@ class VariableEntity(BaseModel): description: str = "" type: VariableEntityType required: bool = False + hide: bool = False max_length: Optional[int] = None options: Sequence[str] = Field(default_factory=list) allowed_file_types: Sequence[FileType] = Field(default_factory=list) diff --git a/web/app/components/app/configuration/config-var/config-modal/index.tsx b/web/app/components/app/configuration/config-var/config-modal/index.tsx index 4b6bfdacd6..29cbc55b90 100644 --- a/web/app/components/app/configuration/config-var/config-modal/index.tsx +++ b/web/app/components/app/configuration/config-var/config-modal/index.tsx @@ -234,9 +234,14 @@ const ConfigModal: FC = ({ )}
- handlePayloadChange('required')(!tempPayload.required)} /> + handlePayloadChange('required')(!tempPayload.required)} /> {t('appDebug.variableConfig.required')}
+ +
+ handlePayloadChange('hide')(!tempPayload.hide)} /> + {t('appDebug.variableConfig.hide')} +
{ clearChatList, setClearChatList, setIsResponding, + allInputsHidden, } = useChatWithHistoryContext() const appConfig = useMemo(() => { const config = appParams || {} @@ -81,6 +82,9 @@ const ChatWrapper = () => { ) const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputsRef?.current const inputDisabled = useMemo(() => { + if (allInputsHidden) + return false + let hasEmptyInput = '' let fileIsUploading = false const requiredVars = inputsForms.filter(({ required }) => required) @@ -110,7 +114,7 @@ const ChatWrapper = () => { if (fileIsUploading) return true return false - }, [inputsFormValue, inputsForms]) + }, [inputsFormValue, inputsForms, allInputsHidden]) useEffect(() => { if (currentChatInstanceRef.current) @@ -161,7 +165,7 @@ const ChatWrapper = () => { const [collapsed, setCollapsed] = useState(!!currentConversationId) const chatNode = useMemo(() => { - if (!inputsForms.length) + if (allInputsHidden || !inputsForms.length) return null if (isMobile) { if (!currentConversationId) @@ -171,7 +175,7 @@ const ChatWrapper = () => { else { return } - }, [inputsForms.length, isMobile, currentConversationId, collapsed]) + }, [inputsForms.length, isMobile, currentConversationId, collapsed, allInputsHidden]) const welcome = useMemo(() => { const welcomeMessage = chatList.find(item => item.isOpeningStatement) @@ -181,7 +185,7 @@ const ChatWrapper = () => { return null if (!welcomeMessage) return null - if (!collapsed && inputsForms.length > 0) + if (!collapsed && inputsForms.length > 0 && !allInputsHidden) return null if (welcomeMessage.suggestedQuestions && welcomeMessage.suggestedQuestions?.length > 0) { return ( @@ -218,7 +222,7 @@ const ChatWrapper = () => { ) - }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState]) + }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState, allInputsHidden]) const answerIcon = (appData?.site && appData.site.use_icon_as_answer_icon) ? void, currentConversationInputs: Record | null, setCurrentConversationInputs: (v: Record) => void, + allInputsHidden: boolean, } export const ChatWithHistoryContext = createContext({ @@ -95,5 +96,6 @@ export const ChatWithHistoryContext = createContext setIsResponding: noop, currentConversationInputs: {}, setCurrentConversationInputs: noop, + allInputsHidden: false, }) export const useChatWithHistoryContext = () => useContext(ChatWithHistoryContext) diff --git a/web/app/components/base/chat/chat-with-history/hooks.tsx b/web/app/components/base/chat/chat-with-history/hooks.tsx index d03a28ae57..3694666139 100644 --- a/web/app/components/base/chat/chat-with-history/hooks.tsx +++ b/web/app/components/base/chat/chat-with-history/hooks.tsx @@ -240,6 +240,11 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { } }) }, [appParams]) + + const allInputsHidden = useMemo(() => { + return inputsForms.length > 0 && inputsForms.every(item => item.hide === true) + }, [inputsForms]) + useEffect(() => { const conversationInputs: Record = {} @@ -304,6 +309,9 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { const { notify } = useToastContext() const checkInputsRequired = useCallback((silent?: boolean) => { + if (allInputsHidden) + return true + let hasEmptyInput = '' let fileIsUploading = false const requiredVars = inputsForms.filter(({ required }) => required) @@ -339,7 +347,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { } return true - }, [inputsForms, notify, t]) + }, [inputsForms, notify, t, allInputsHidden]) const handleStartChat = useCallback((callback: any) => { if (checkInputsRequired()) { setShowNewConversationItemInList(true) @@ -507,5 +515,6 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => { setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, } } diff --git a/web/app/components/base/chat/chat-with-history/index.tsx b/web/app/components/base/chat/chat-with-history/index.tsx index 2ba50ea49b..de023e7f58 100644 --- a/web/app/components/base/chat/chat-with-history/index.tsx +++ b/web/app/components/base/chat/chat-with-history/index.tsx @@ -161,6 +161,7 @@ const ChatWithHistoryWrap: FC = ({ setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, } = useChatWithHistory(installedAppInfo) return ( @@ -206,6 +207,7 @@ const ChatWithHistoryWrap: FC = ({ setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, }}> diff --git a/web/app/components/base/chat/chat-with-history/inputs-form/content.tsx b/web/app/components/base/chat/chat-with-history/inputs-form/content.tsx index b8d18244e1..73a1f07b69 100644 --- a/web/app/components/base/chat/chat-with-history/inputs-form/content.tsx +++ b/web/app/components/base/chat/chat-with-history/inputs-form/content.tsx @@ -36,9 +36,11 @@ const InputsFormContent = ({ showTip }: Props) => { }) }, [newConversationInputsRef, handleNewConversationInputsChange, currentConversationInputs, setCurrentConversationInputs]) + const visibleInputsForms = inputsForms.filter(form => form.hide !== true) + return (
- {inputsForms.map(form => ( + {visibleInputsForms.map(form => (
{form.label}
diff --git a/web/app/components/base/chat/chat-with-history/inputs-form/index.tsx b/web/app/components/base/chat/chat-with-history/inputs-form/index.tsx index 30ec11c729..3a1b92089c 100644 --- a/web/app/components/base/chat/chat-with-history/inputs-form/index.tsx +++ b/web/app/components/base/chat/chat-with-history/inputs-form/index.tsx @@ -21,9 +21,14 @@ const InputsFormNode = ({ isMobile, currentConversationId, handleStartChat, + allInputsHidden, themeBuilder, + inputsForms, } = useChatWithHistoryContext() + if (allInputsHidden || inputsForms.length === 0) + return null + return (
{ clearChatList, setClearChatList, setIsResponding, + allInputsHidden, } = useEmbeddedChatbotContext() const appConfig = useMemo(() => { const config = appParams || {} @@ -82,6 +83,9 @@ const ChatWrapper = () => { ) const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputsRef?.current const inputDisabled = useMemo(() => { + if (allInputsHidden) + return false + let hasEmptyInput = '' let fileIsUploading = false const requiredVars = inputsForms.filter(({ required }) => required) @@ -111,7 +115,7 @@ const ChatWrapper = () => { if (fileIsUploading) return true return false - }, [inputsFormValue, inputsForms]) + }, [inputsFormValue, inputsForms, allInputsHidden]) useEffect(() => { if (currentChatInstanceRef.current) @@ -160,7 +164,7 @@ const ChatWrapper = () => { const [collapsed, setCollapsed] = useState(!!currentConversationId) const chatNode = useMemo(() => { - if (!inputsForms.length) + if (allInputsHidden || !inputsForms.length) return null if (isMobile) { if (!currentConversationId) @@ -170,7 +174,7 @@ const ChatWrapper = () => { else { return } - }, [inputsForms.length, isMobile, currentConversationId, collapsed]) + }, [inputsForms.length, isMobile, currentConversationId, collapsed, allInputsHidden]) const welcome = useMemo(() => { const welcomeMessage = chatList.find(item => item.isOpeningStatement) @@ -180,7 +184,7 @@ const ChatWrapper = () => { return null if (!welcomeMessage) return null - if (!collapsed && inputsForms.length > 0) + if (!collapsed && inputsForms.length > 0 && !allInputsHidden) return null if (welcomeMessage.suggestedQuestions && welcomeMessage.suggestedQuestions?.length > 0) { return ( @@ -215,7 +219,7 @@ const ChatWrapper = () => {
) - }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState]) + }, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, currentConversationId, inputsForms.length, respondingState, allInputsHidden]) const answerIcon = isDify() ? diff --git a/web/app/components/base/chat/embedded-chatbot/context.tsx b/web/app/components/base/chat/embedded-chatbot/context.tsx index 0dd6e7a29a..5964efd806 100644 --- a/web/app/components/base/chat/embedded-chatbot/context.tsx +++ b/web/app/components/base/chat/embedded-chatbot/context.tsx @@ -53,6 +53,7 @@ export type EmbeddedChatbotContextValue = { setIsResponding: (state: boolean) => void, currentConversationInputs: Record | null, setCurrentConversationInputs: (v: Record) => void, + allInputsHidden: boolean } export const EmbeddedChatbotContext = createContext({ @@ -82,5 +83,6 @@ export const EmbeddedChatbotContext = createContext setIsResponding: noop, currentConversationInputs: {}, setCurrentConversationInputs: noop, + allInputsHidden: false, }) export const useEmbeddedChatbotContext = () => useContext(EmbeddedChatbotContext) diff --git a/web/app/components/base/chat/embedded-chatbot/hooks.tsx b/web/app/components/base/chat/embedded-chatbot/hooks.tsx index ce42575bc9..40c56eca7b 100644 --- a/web/app/components/base/chat/embedded-chatbot/hooks.tsx +++ b/web/app/components/base/chat/embedded-chatbot/hooks.tsx @@ -235,6 +235,10 @@ export const useEmbeddedChatbot = () => { }) }, [initInputs, appParams]) + const allInputsHidden = useMemo(() => { + return inputsForms.length > 0 && inputsForms.every(item => item.hide === true) + }, [inputsForms]) + useEffect(() => { // init inputs from url params (async () => { @@ -306,6 +310,9 @@ export const useEmbeddedChatbot = () => { const { notify } = useToastContext() const checkInputsRequired = useCallback((silent?: boolean) => { + if (allInputsHidden) + return true + let hasEmptyInput = '' let fileIsUploading = false const requiredVars = inputsForms.filter(({ required }) => required) @@ -341,7 +348,7 @@ export const useEmbeddedChatbot = () => { } return true - }, [inputsForms, notify, t]) + }, [inputsForms, notify, t, allInputsHidden]) const handleStartChat = useCallback((callback?: any) => { if (checkInputsRequired()) { setShowNewConversationItemInList(true) @@ -417,5 +424,6 @@ export const useEmbeddedChatbot = () => { setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, } } diff --git a/web/app/components/base/chat/embedded-chatbot/index.tsx b/web/app/components/base/chat/embedded-chatbot/index.tsx index 49189c419e..ffcb128c8f 100644 --- a/web/app/components/base/chat/embedded-chatbot/index.tsx +++ b/web/app/components/base/chat/embedded-chatbot/index.tsx @@ -168,6 +168,7 @@ const EmbeddedChatbotWrapper = () => { setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, } = useEmbeddedChatbot() return { setIsResponding, currentConversationInputs, setCurrentConversationInputs, + allInputsHidden, }}> diff --git a/web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx b/web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx index e56520d23f..c5f39718f1 100644 --- a/web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx +++ b/web/app/components/base/chat/embedded-chatbot/inputs-form/content.tsx @@ -36,9 +36,11 @@ const InputsFormContent = ({ showTip }: Props) => { }) }, [newConversationInputsRef, handleNewConversationInputsChange, currentConversationInputs, setCurrentConversationInputs]) + const visibleInputsForms = inputsForms.filter(form => form.hide !== true) + return (
- {inputsForms.map(form => ( + {visibleInputsForms.map(form => (
{form.label}
diff --git a/web/app/components/base/chat/embedded-chatbot/inputs-form/index.tsx b/web/app/components/base/chat/embedded-chatbot/inputs-form/index.tsx index 4ac4aaa16b..88472b5d8f 100644 --- a/web/app/components/base/chat/embedded-chatbot/inputs-form/index.tsx +++ b/web/app/components/base/chat/embedded-chatbot/inputs-form/index.tsx @@ -22,8 +22,13 @@ const InputsFormNode = ({ currentConversationId, themeBuilder, handleStartChat, + allInputsHidden, + inputsForms, } = useEmbeddedChatbotContext() + if (allInputsHidden || inputsForms.length === 0) + return null + return (
{ const nodes = useNodes() const startNode = nodes.find(node => node.data.type === BlockEnum.Start) const variables = startNode?.data.variables || [] + const visibleVariables = variables.filter(v => v.hide !== true) const [showConversationVariableModal, setShowConversationVariableModal] = useState(false) @@ -107,7 +108,7 @@ const DebugAndPreview = () => { )} - {variables.length > 0 && ( + {visibleVariables.length > 0 && (
{ const nodes = useNodes() const startNode = nodes.find(node => node.data.type === BlockEnum.Start) const variables = startNode?.data.variables || [] + const visibleVariables = variables.filter(v => v.hide !== true) const handleValueChange = (variable: string, v: string) => { const { @@ -29,13 +30,13 @@ const UserInput = () => { }) } - if (!variables.length) + if (!visibleVariables.length) return null return (
- {variables.map((variable, index) => ( + {visibleVariables.map((variable, index) => (
export type ModelConfig = { diff --git a/web/i18n/en-US/app-debug.ts b/web/i18n/en-US/app-debug.ts index 3ee5fd3e1d..349ff37118 100644 --- a/web/i18n/en-US/app-debug.ts +++ b/web/i18n/en-US/app-debug.ts @@ -368,6 +368,7 @@ const translation = { 'inputPlaceholder': 'Please input', 'content': 'Content', 'required': 'Required', + 'hide': 'Hide', 'file': { supportFileTypes: 'Support File Types', image: {