From 2b021e8752a9b8e18867634f04144859b2f6c8f4 Mon Sep 17 00:00:00 2001 From: lif <1835304752@qq.com> Date: Thu, 15 Jan 2026 17:43:00 +0800 Subject: [PATCH] fix: remove hardcoded 48-character limit from text inputs (#30156) Signed-off-by: majiayu000 <1835304752@qq.com> Co-authored-by: crazywoola <100913391+crazywoola@users.noreply.github.com> --- .../config-var/config-modal/index.tsx | 3 -- .../app/configuration/config-var/index.tsx | 3 -- .../configuration/debug/chat-user-input.tsx | 5 +-- .../prompt-value-panel/index.tsx | 5 +-- .../panel/input-field/editor/form/hooks.ts | 3 -- .../input-field/editor/form/index.spec.tsx | 21 ---------- .../share/text-generation/index.tsx | 9 ++-- .../text-generation/run-once/index.spec.tsx | 42 +++++++++++++++++++ .../share/text-generation/run-once/index.tsx | 3 +- web/config/index.ts | 3 -- web/utils/var.ts | 2 +- 11 files changed, 52 insertions(+), 47 deletions(-) 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 5ffa87375c..7ea784baa3 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 @@ -21,7 +21,6 @@ import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/ import FileUploadSetting from '@/app/components/workflow/nodes/_base/components/file-upload-setting' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { ChangeType, InputVarType, SupportUploadFileTypes } from '@/app/components/workflow/types' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import ConfigContext from '@/context/debug-configuration' import { AppModeEnum, TransferMethod } from '@/types/app' import { checkKeys, getNewVarInWorkflow, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var' @@ -198,8 +197,6 @@ const ConfigModal: FC = ({ if (type === InputVarType.multiFiles) draft.max_length = DEFAULT_FILE_UPLOAD_SETTING.max_length } - if (type === InputVarType.paragraph) - draft.max_length = DEFAULT_VALUE_MAX_LEN }) setTempPayload(newPayload) }, [tempPayload]) diff --git a/web/app/components/app/configuration/config-var/index.tsx b/web/app/components/app/configuration/config-var/index.tsx index 4a38fc92a6..1a8810f7cd 100644 --- a/web/app/components/app/configuration/config-var/index.tsx +++ b/web/app/components/app/configuration/config-var/index.tsx @@ -15,7 +15,6 @@ import Confirm from '@/app/components/base/confirm' import Toast from '@/app/components/base/toast' import Tooltip from '@/app/components/base/tooltip' import { InputVarType } from '@/app/components/workflow/types' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import ConfigContext from '@/context/debug-configuration' import { useEventEmitterContextContext } from '@/context/event-emitter' import { useModalContext } from '@/context/modal-context' @@ -58,8 +57,6 @@ const buildPromptVariableFromInput = (payload: InputVar): PromptVariable => { key: variable, name: label as string, } - if (payload.type === InputVarType.textInput) - nextItem.max_length = nextItem.max_length || DEFAULT_VALUE_MAX_LEN if (payload.type !== InputVarType.select) delete nextItem.options diff --git a/web/app/components/app/configuration/debug/chat-user-input.tsx b/web/app/components/app/configuration/debug/chat-user-input.tsx index 11189751e0..3f9fdc32be 100644 --- a/web/app/components/app/configuration/debug/chat-user-input.tsx +++ b/web/app/components/app/configuration/debug/chat-user-input.tsx @@ -7,7 +7,6 @@ import Input from '@/app/components/base/input' import Select from '@/app/components/base/select' import Textarea from '@/app/components/base/textarea' import BoolInput from '@/app/components/workflow/nodes/_base/components/before-run-form/bool-input' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import ConfigContext from '@/context/debug-configuration' import { cn } from '@/utils/classnames' @@ -88,7 +87,7 @@ const ChatUserInput = ({ onChange={(e) => { handleInputValueChange(key, e.target.value) }} placeholder={name} autoFocus={index === 0} - maxLength={max_length || DEFAULT_VALUE_MAX_LEN} + maxLength={max_length} /> )} {type === 'paragraph' && ( @@ -115,7 +114,7 @@ const ChatUserInput = ({ onChange={(e) => { handleInputValueChange(key, e.target.value) }} placeholder={name} autoFocus={index === 0} - maxLength={max_length || DEFAULT_VALUE_MAX_LEN} + maxLength={max_length} /> )} {type === 'checkbox' && ( diff --git a/web/app/components/app/configuration/prompt-value-panel/index.tsx b/web/app/components/app/configuration/prompt-value-panel/index.tsx index 9b61b3c7aa..613efb8710 100644 --- a/web/app/components/app/configuration/prompt-value-panel/index.tsx +++ b/web/app/components/app/configuration/prompt-value-panel/index.tsx @@ -20,7 +20,6 @@ import Select from '@/app/components/base/select' import Textarea from '@/app/components/base/textarea' import Tooltip from '@/app/components/base/tooltip' import BoolInput from '@/app/components/workflow/nodes/_base/components/before-run-form/bool-input' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import ConfigContext from '@/context/debug-configuration' import { AppModeEnum, ModelModeType } from '@/types/app' import { cn } from '@/utils/classnames' @@ -142,7 +141,7 @@ const PromptValuePanel: FC = ({ onChange={(e) => { handleInputValueChange(key, e.target.value) }} placeholder={name} autoFocus={index === 0} - maxLength={max_length || DEFAULT_VALUE_MAX_LEN} + maxLength={max_length} /> )} {type === 'paragraph' && ( @@ -170,7 +169,7 @@ const PromptValuePanel: FC = ({ onChange={(e) => { handleInputValueChange(key, e.target.value) }} placeholder={name} autoFocus={index === 0} - maxLength={max_length || DEFAULT_VALUE_MAX_LEN} + maxLength={max_length} /> )} {type === 'checkbox' && ( diff --git a/web/app/components/rag-pipeline/components/panel/input-field/editor/form/hooks.ts b/web/app/components/rag-pipeline/components/panel/input-field/editor/form/hooks.ts index 3820d5f1b8..80aa879b8f 100644 --- a/web/app/components/rag-pipeline/components/panel/input-field/editor/form/hooks.ts +++ b/web/app/components/rag-pipeline/components/panel/input-field/editor/form/hooks.ts @@ -6,7 +6,6 @@ import { useTranslation } from 'react-i18next' import { useFileSizeLimit } from '@/app/components/base/file-uploader/hooks' import { InputFieldType } from '@/app/components/base/form/form-scenarios/input-field/types' import { DEFAULT_FILE_UPLOAD_SETTING } from '@/app/components/workflow/constants' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import { PipelineInputVarType } from '@/models/pipeline' import { useFileUploadConfig } from '@/service/use-common' import { formatFileSize } from '@/utils/format' @@ -87,8 +86,6 @@ export const useConfigurations = (props: { if (type === PipelineInputVarType.multiFiles) setFieldValue('maxLength', DEFAULT_FILE_UPLOAD_SETTING.max_length) } - if (type === PipelineInputVarType.paragraph) - setFieldValue('maxLength', DEFAULT_VALUE_MAX_LEN) }, [setFieldValue]) const handleVariableNameBlur = useCallback((value: string) => { diff --git a/web/app/components/rag-pipeline/components/panel/input-field/editor/form/index.spec.tsx b/web/app/components/rag-pipeline/components/panel/input-field/editor/form/index.spec.tsx index 0470bd4c68..48df13acb2 100644 --- a/web/app/components/rag-pipeline/components/panel/input-field/editor/form/index.spec.tsx +++ b/web/app/components/rag-pipeline/components/panel/input-field/editor/form/index.spec.tsx @@ -779,27 +779,6 @@ describe('useConfigurations', () => { expect(mockSetFieldValue).toHaveBeenCalledWith('maxLength', expect.any(Number)) }) - it('should call setFieldValue when type changes to paragraph', () => { - // Arrange - const mockGetFieldValue = vi.fn() - const mockSetFieldValue = vi.fn() - - const { result } = renderHookWithProviders(() => - useConfigurations({ - getFieldValue: mockGetFieldValue, - setFieldValue: mockSetFieldValue, - supportFile: false, - }), - ) - - // Act - const typeConfig = result.current.find(config => config.variable === 'type') - typeConfig?.listeners?.onChange?.(createMockEvent(PipelineInputVarType.paragraph)) - - // Assert - expect(mockSetFieldValue).toHaveBeenCalledWith('maxLength', 48) // DEFAULT_VALUE_MAX_LEN - }) - it('should set label from variable name on blur when label is empty', () => { // Arrange const mockGetFieldValue = vi.fn().mockReturnValue('') diff --git a/web/app/components/share/text-generation/index.tsx b/web/app/components/share/text-generation/index.tsx index b793a03ce7..509687e245 100644 --- a/web/app/components/share/text-generation/index.tsx +++ b/web/app/components/share/text-generation/index.tsx @@ -26,7 +26,7 @@ import DifyLogo from '@/app/components/base/logo/dify-logo' import Toast from '@/app/components/base/toast' import Res from '@/app/components/share/text-generation/result' import RunOnce from '@/app/components/share/text-generation/run-once' -import { appDefaultIconBackground, BATCH_CONCURRENCY, DEFAULT_VALUE_MAX_LEN } from '@/config' +import { appDefaultIconBackground, BATCH_CONCURRENCY } from '@/config' import { useGlobalPublicStore } from '@/context/global-public-context' import { useWebAppStore } from '@/context/web-app-context' import { useAppFavicon } from '@/hooks/use-app-favicon' @@ -256,11 +256,10 @@ const TextGeneration: FC = ({ promptConfig?.prompt_variables.forEach((varItem, varIndex) => { if (errorRowIndex !== 0) return - if (varItem.type === 'string') { - const maxLen = varItem.max_length || DEFAULT_VALUE_MAX_LEN - if (item[varIndex].length > maxLen) { + if (varItem.type === 'string' && varItem.max_length) { + if (item[varIndex].length > varItem.max_length) { moreThanMaxLengthVarName = varItem.name - maxLength = maxLen + maxLength = varItem.max_length errorRowIndex = index + 1 return } diff --git a/web/app/components/share/text-generation/run-once/index.spec.tsx b/web/app/components/share/text-generation/run-once/index.spec.tsx index 8882253d0e..ea5ce3c902 100644 --- a/web/app/components/share/text-generation/run-once/index.spec.tsx +++ b/web/app/components/share/text-generation/run-once/index.spec.tsx @@ -236,4 +236,46 @@ describe('RunOnce', () => { const stopButton = screen.getByTestId('stop-button') expect(stopButton).toBeDisabled() }) + + describe('maxLength behavior', () => { + it('should not have maxLength attribute when max_length is not set', async () => { + const promptConfig: PromptConfig = { + prompt_template: 'template', + prompt_variables: [ + createPromptVariable({ + key: 'textInput', + name: 'Text Input', + type: 'string', + // max_length is not set + }), + ], + } + const { onInputsChange } = setup({ promptConfig, visionConfig: { ...baseVisionConfig, enabled: false } }) + await waitFor(() => { + expect(onInputsChange).toHaveBeenCalled() + }) + const input = screen.getByPlaceholderText('Text Input') + expect(input).not.toHaveAttribute('maxLength') + }) + + it('should have maxLength attribute when max_length is set', async () => { + const promptConfig: PromptConfig = { + prompt_template: 'template', + prompt_variables: [ + createPromptVariable({ + key: 'textInput', + name: 'Text Input', + type: 'string', + max_length: 100, + }), + ], + } + const { onInputsChange } = setup({ promptConfig, visionConfig: { ...baseVisionConfig, enabled: false } }) + await waitFor(() => { + expect(onInputsChange).toHaveBeenCalled() + }) + const input = screen.getByPlaceholderText('Text Input') + expect(input).toHaveAttribute('maxLength', '100') + }) + }) }) diff --git a/web/app/components/share/text-generation/run-once/index.tsx b/web/app/components/share/text-generation/run-once/index.tsx index b8193fd944..ca29ce1a98 100644 --- a/web/app/components/share/text-generation/run-once/index.tsx +++ b/web/app/components/share/text-generation/run-once/index.tsx @@ -19,7 +19,6 @@ import Textarea from '@/app/components/base/textarea' import BoolInput from '@/app/components/workflow/nodes/_base/components/before-run-form/bool-input' import CodeEditor from '@/app/components/workflow/nodes/_base/components/editor/code-editor' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' -import { DEFAULT_VALUE_MAX_LEN } from '@/config' import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints' import { cn } from '@/utils/classnames' @@ -140,7 +139,7 @@ const RunOnce: FC = ({ placeholder={item.name} value={inputs[item.key]} onChange={(e: ChangeEvent) => { handleInputsChange({ ...inputsRef.current, [item.key]: e.target.value }) }} - maxLength={item.max_length || DEFAULT_VALUE_MAX_LEN} + maxLength={item.max_length} /> )} {item.type === 'paragraph' && ( diff --git a/web/config/index.ts b/web/config/index.ts index b804629048..08ce14b264 100644 --- a/web/config/index.ts +++ b/web/config/index.ts @@ -208,7 +208,6 @@ export const VAR_ITEM_TEMPLATE = { key: '', name: '', type: 'string', - max_length: DEFAULT_VALUE_MAX_LEN, required: true, } @@ -216,7 +215,6 @@ export const VAR_ITEM_TEMPLATE_IN_WORKFLOW = { variable: '', label: '', type: InputVarType.textInput, - max_length: DEFAULT_VALUE_MAX_LEN, required: true, options: [], } @@ -225,7 +223,6 @@ export const VAR_ITEM_TEMPLATE_IN_PIPELINE = { variable: '', label: '', type: PipelineInputVarType.textInput, - max_length: DEFAULT_VALUE_MAX_LEN, required: true, options: [], } diff --git a/web/utils/var.ts b/web/utils/var.ts index 4f572d7768..1851084b2e 100644 --- a/web/utils/var.ts +++ b/web/utils/var.ts @@ -30,7 +30,7 @@ export const getNewVar = (key: string, type: string) => { } export const getNewVarInWorkflow = (key: string, type = InputVarType.textInput): InputVar => { - const { max_length: _maxLength, ...rest } = VAR_ITEM_TEMPLATE_IN_WORKFLOW + const { ...rest } = VAR_ITEM_TEMPLATE_IN_WORKFLOW if (type !== InputVarType.textInput) { return { ...rest,