diff --git a/web/app/components/base/chat/chat/answer/human-input-content/__tests__/utils.spec.ts b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/utils.spec.ts index e63bfc123f..96ecda2430 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/__tests__/utils.spec.ts +++ b/web/app/components/base/chat/chat/answer/human-input-content/__tests__/utils.spec.ts @@ -15,7 +15,7 @@ const createInput = (overrides: Partial): FormInputItem => ({ variable: 'field', required: false, max_length: 128, - type: InputVarType.textInput, + type: InputVarType.paragraph, default: { type: 'constant' as const, value: '', @@ -57,7 +57,7 @@ describe('human-input utils', () => { it('should initialize text fields with constants and variable defaults', () => { const formInputs = [ createInput({ - type: InputVarType.textInput, + type: InputVarType.paragraph, output_variable_name: 'name', default: { type: 'constant', value: 'John', selector: [] }, }), @@ -90,7 +90,7 @@ describe('human-input utils', () => { it('should fallback to empty string when variable default is missing', () => { const formInputs = [ createInput({ - type: InputVarType.textInput, + type: InputVarType.paragraph, output_variable_name: 'summary', default: { type: 'variable', value: '', selector: [] }, }), diff --git a/web/app/components/base/chat/chat/answer/human-input-content/utils.ts b/web/app/components/base/chat/chat/answer/human-input-content/utils.ts index da81f9f1b9..bf36c34f46 100644 --- a/web/app/components/base/chat/chat/answer/human-input-content/utils.ts +++ b/web/app/components/base/chat/chat/answer/human-input-content/utils.ts @@ -4,7 +4,10 @@ import dayjs from 'dayjs' import isSameOrAfter from 'dayjs/plugin/isSameOrAfter' import relativeTime from 'dayjs/plugin/relativeTime' import utc from 'dayjs/plugin/utc' -import { UserActionButtonType } from '@/app/components/workflow/nodes/human-input/types' +import { + isParagraphFormInput, + UserActionButtonType, +} from '@/app/components/workflow/nodes/human-input/types' import 'dayjs/locale/en' import 'dayjs/locale/zh-cn' import 'dayjs/locale/ja' @@ -32,9 +35,9 @@ export const splitByOutputVar = (content: string): string[] => { } export const initializeInputs = (formInputs: FormInputItem[], defaultValues: Record = {}) => { - const initialInputs: Record = {} + const initialInputs: Record = {} formInputs.forEach((item) => { - if (item.type === 'text-input' || item.type === 'paragraph') + if (isParagraphFormInput(item)) initialInputs[item.output_variable_name] = item.default.type === 'variable' ? defaultValues[item.output_variable_name] || '' : item.default.value else initialInputs[item.output_variable_name] = undefined diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx index 9a752062ea..f144edd766 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/component-ui.tsx @@ -8,7 +8,10 @@ import { useBoolean } from 'ahooks' import * as React from 'react' import { useCallback, useEffect, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' -import { InputVarType } from '@/app/components/workflow/types' +import { + createDefaultParagraphFormInput, + isParagraphFormInput, +} from '@/app/components/workflow/nodes/human-input/types' import ActionButton from '../../../action-button' import { VariableX } from '../../../icons/src/vender/workflow' import Modal from '../../../modal' @@ -36,15 +39,7 @@ type HITLInputComponentUIProps = { const HITLInputComponentUI: FC = ({ nodeId, varName, - formInput = { - type: InputVarType.paragraph, - output_variable_name: varName, - default: { - type: 'constant', - selector: [], - value: '', - }, - }, + formInput, onChange, onRename, onRemove, @@ -56,6 +51,10 @@ const HITLInputComponentUI: FC = ({ readonly, }) => { const { t } = useTranslation() + const resolvedFormInput = formInput || createDefaultParagraphFormInput(varName) + const paragraphDefault = isParagraphFormInput(resolvedFormInput) + ? resolvedFormInput.default + : null const [isShowEditModal, { setTrue: showEditModal, setFalse: hideEditModal, @@ -72,8 +71,7 @@ const HITLInputComponentUI: FC = ({ if (editBtn) editBtn.removeEventListener('click', showEditModal) } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []) + }, [showEditModal]) const removeBtnRef = useRef(null) useEffect(() => { @@ -97,8 +95,8 @@ const HITLInputComponentUI: FC = ({ }, [hideEditModal, onChange, onRename, varName]) const isDefaultValueVariable = useMemo(() => { - return formInput.default?.type === 'variable' - }, [formInput.default?.type]) + return paragraphDefault?.type === 'variable' + }, [paragraphDefault]) return (
= ({ {/* Default Value Info */} {isDefaultValueVariable && ( = ({ /> )} {!isDefaultValueVariable && ( -
{formInput.default?.value}
+
+ {paragraphDefault?.value ?? resolvedFormInput.type} +
)}
@@ -166,7 +166,7 @@ const HITLInputComponentUI: FC = ({ diff --git a/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.tsx b/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.tsx index 7511406718..9480c25b98 100644 --- a/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.tsx +++ b/web/app/components/base/prompt-editor/plugins/hitl-input-block/input-field.tsx @@ -1,4 +1,4 @@ -import type { FormInputItem, FormInputItemDefault } from '@/app/components/workflow/nodes/human-input/types' +import type { FormInputItem, FormInputItemDefault, ParagraphFormInput } from '@/app/components/workflow/nodes/human-input/types' import type { ValueSelector } from '@/app/components/workflow/types' import { Button } from '@langgenius/dify-ui/button' import { produce } from 'immer' @@ -6,7 +6,10 @@ import * as React from 'react' import { useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Input from '@/app/components/base/input' -import { InputVarType } from '@/app/components/workflow/types' +import { + createDefaultParagraphFormInput, + isParagraphFormInput, +} from '@/app/components/workflow/nodes/human-input/types' import { getKeyboardKeyNameBySystem } from '@/app/components/workflow/utils' import PrePopulate from './pre-populate' @@ -19,11 +22,6 @@ type InputFieldProps = { onChange: (newPayload: FormInputItem) => void onCancel: () => void } -const defaultPayload: FormInputItem = { - type: InputVarType.paragraph, - output_variable_name: '', - default: { type: 'constant', selector: [], value: '' }, -} const InputField: React.FC = ({ nodeId, isEdit, @@ -32,7 +30,13 @@ const InputField: React.FC = ({ onCancel, }) => { const { t } = useTranslation() - const [tempPayload, setTempPayload] = useState(payload || defaultPayload) + const [tempPayload, setTempPayload] = useState(() => payload || createDefaultParagraphFormInput()) + const paragraphPayload = useMemo(() => { + if (isParagraphFormInput(tempPayload)) + return tempPayload + + return createDefaultParagraphFormInput(tempPayload.output_variable_name) + }, [tempPayload]) const nameValid = useMemo(() => { const name = tempPayload.output_variable_name.trim() if (!name) @@ -46,12 +50,9 @@ const InputField: React.FC = ({ return onChange(tempPayload) }, [nameValid, onChange, tempPayload]) - const defaultValueConfig = tempPayload.default const handleDefaultValueChange = useCallback((key: keyof FormInputItemDefault) => { return (value: ValueSelector | string) => { - const nextValue = produce(tempPayload, (draft) => { - if (!draft.default) - draft.default = { type: 'constant', selector: [], value: '' } + const nextValue = produce(paragraphPayload, (draft) => { if (key === 'selector') { draft.default.type = 'variable' draft.default.selector = value as ValueSelector @@ -66,7 +67,7 @@ const InputField: React.FC = ({ }) setTempPayload(nextValue) } - }, [tempPayload]) + }, [paragraphPayload]) useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { @@ -109,14 +110,14 @@ const InputField: React.FC = ({ {t(`${i18nPrefix}.prePopulateField`, { ns: 'workflow' })} { handleDefaultValueChange('type')(isVariable ? 'variable' : 'constant') }} nodeId={nodeId} - valueSelector={defaultValueConfig?.selector} + valueSelector={paragraphPayload.default.selector} onValueSelectorChange={handleDefaultValueChange('selector')} - value={defaultValueConfig?.value} + value={paragraphPayload.default.value} onValueChange={handleDefaultValueChange('value')} /> diff --git a/web/app/components/workflow/nodes/human-input/__tests__/node.spec.tsx b/web/app/components/workflow/nodes/human-input/__tests__/node.spec.tsx index 915f9136be..fcffb286e5 100644 --- a/web/app/components/workflow/nodes/human-input/__tests__/node.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/__tests__/node.spec.tsx @@ -23,7 +23,7 @@ const createData = (overrides: Partial = {}): HumanInputNode }], form_content: 'Please review this request', inputs: [{ - type: InputVarType.textInput, + type: InputVarType.paragraph, output_variable_name: 'review_result', default: { selector: [], diff --git a/web/app/components/workflow/nodes/human-input/__tests__/panel.spec.tsx b/web/app/components/workflow/nodes/human-input/__tests__/panel.spec.tsx index 143b05afae..53664bee74 100644 --- a/web/app/components/workflow/nodes/human-input/__tests__/panel.spec.tsx +++ b/web/app/components/workflow/nodes/human-input/__tests__/panel.spec.tsx @@ -103,7 +103,7 @@ vi.mock('../components/form-content', () => ({