From 450d76ada52ab321dddec96b1fa53e40f3294d15 Mon Sep 17 00:00:00 2001 From: L1nSn0w Date: Tue, 14 Jul 2026 18:28:52 +0800 Subject: [PATCH] fix(web): render first-token timeout only for panels that consume it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit isInWorkflow was a proxy for 'this panel's model config reaches fetch_model_config', which is false for the knowledge-retrieval metadata filter and single-retrieval model, and for tool/trigger model-selector params rendered through form-input-item — the field showed up there but the backend never consumed it. Gate the rule on an explicit supportFirstTokenTimeout prop passed only by the LLM, question classifier and parameter extractor panels, and extend the help text with the inter-token semantics of the read window. --- .../__tests__/index.spec.tsx | 18 ++++++++++++++---- .../model-parameter-modal/index.tsx | 9 ++++++++- .../components/workflow/nodes/llm/panel.tsx | 1 + .../nodes/parameter-extractor/panel.tsx | 1 + .../nodes/question-classifier/panel.tsx | 1 + web/config/index.ts | 5 +++-- 6 files changed, 28 insertions(+), 7 deletions(-) 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)',