diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/__tests__/index.spec.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/__tests__/index.spec.tsx index 58765f81404..dbcda3cd91e 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/__tests__/index.spec.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/__tests__/index.spec.tsx @@ -388,16 +388,26 @@ describe('ModelParameterModal', () => { expect(screen.getByText(/debugAsSingleModel/i)).toBeInTheDocument() }) - it('should append the first token timeout parameter only in workflow advanced mode', () => { - render() + it('should append the first token timeout parameter when the panel supports it', () => { + render( + , + ) openSettings() expect(screen.getByTestId('param-first_token_timeout_ms')).toBeInTheDocument() }) - it('should not append the first token timeout parameter outside workflow', () => { - render() + it('should not append the first token timeout parameter for workflow panels that do not support it', () => { + // Being in a workflow is not enough: panels whose model config is not consumed + // by fetch_model_config (knowledge retrieval, tool/trigger model params) must + // not render a dead setting. + render() openSettings() diff --git a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx index 1d30756a1f9..69f583df234 100644 --- a/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx +++ b/web/app/components/header/account-setting/model-provider-page/model-parameter-modal/index.tsx @@ -40,6 +40,10 @@ export type ModelParameterModalProps = { renderTrigger?: (v: TriggerProps) => ReactNode readonly?: boolean isInWorkflow?: boolean + // Only LLM-compatible node panels (LLM / question classifier / parameter + // extractor) should pass this: the backend consumes the value solely on + // their model-config path, so rendering it elsewhere yields dead config. + supportFirstTokenTimeout?: boolean scope?: string nodesOutputVars?: NodeOutPutVar[] availableNodes?: Node[] @@ -59,6 +63,7 @@ const ModelParameterModal: FC = ({ renderTrigger, readonly, isInWorkflow, + supportFirstTokenTimeout, nodesOutputVars, availableNodes, }) => { @@ -223,7 +228,9 @@ const ModelParameterModal: FC = ({ [ ...parameterRules, ...(isAdvancedMode ? [STOP_PARAMETER_RULE] : []), - ...(isAdvancedMode && isInWorkflow ? [FIRST_TOKEN_TIMEOUT_PARAMETER_RULE] : []), + ...(isAdvancedMode && supportFirstTokenTimeout + ? [FIRST_TOKEN_TIMEOUT_PARAMETER_RULE] + : []), ].map((parameter) => ( > = ({ id, data }) => { popupClassName="w-[387px]!" isInWorkflow isAdvancedMode={true} + supportFirstTokenTimeout provider={model?.provider} completionParams={model?.completion_params} modelId={model?.name} diff --git a/web/app/components/workflow/nodes/parameter-extractor/panel.tsx b/web/app/components/workflow/nodes/parameter-extractor/panel.tsx index 8453b8b0188..11b43212775 100644 --- a/web/app/components/workflow/nodes/parameter-extractor/panel.tsx +++ b/web/app/components/workflow/nodes/parameter-extractor/panel.tsx @@ -61,6 +61,7 @@ const Panel: FC> = ({ id, data }) => popupClassName="w-[387px]!" isInWorkflow isAdvancedMode={true} + supportFirstTokenTimeout provider={model?.provider} completionParams={model?.completion_params} modelId={model?.name} diff --git a/web/app/components/workflow/nodes/question-classifier/panel.tsx b/web/app/components/workflow/nodes/question-classifier/panel.tsx index ed7d78ca69d..4c9bfc39157 100644 --- a/web/app/components/workflow/nodes/question-classifier/panel.tsx +++ b/web/app/components/workflow/nodes/question-classifier/panel.tsx @@ -50,6 +50,7 @@ const Panel: FC> = ({ id, data }) => popupClassName="w-[387px]!" isInWorkflow isAdvancedMode={true} + supportFirstTokenTimeout provider={model?.provider} completionParams={model.completion_params} modelId={model.name} diff --git a/web/config/index.ts b/web/config/index.ts index bf1a48c10e4..5c520db8b76 100644 --- a/web/config/index.ts +++ b/web/config/index.ts @@ -337,8 +337,9 @@ export const FIRST_TOKEN_TIMEOUT_PARAMETER_RULE: ModelParameterRule = { precision: 0, help: { en_US: - 'Max milliseconds to wait for the first streamed token. On timeout the node fails; combine with node retry to re-run it automatically.', - zh_Hans: '等待首个流式 Token 的最长毫秒数。超时后节点失败,可配合节点重试自动重跑。', + 'Max milliseconds to wait for the first streamed token; the same window also bounds each gap between tokens. On timeout the node fails; combine with node retry to re-run it automatically.', + zh_Hans: + '等待首个流式 Token 的最长毫秒数;同一窗口也约束后续每次 Token 间隔。超时后节点失败,可配合节点重试自动重跑。', }, label: { en_US: 'First token timeout (ms)',