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)',