mirror of
https://github.com/langgenius/dify.git
synced 2026-07-20 00:53:34 -04:00
feat(web): add first-token timeout to the workflow model parameter panel
Append a synthetic FIRST_TOKEN_TIMEOUT_PARAMETER_RULE (int, seconds, opt-in) to the model parameter panel, mirroring how the stop rule is injected. The rule renders only in workflow advanced mode (isInWorkflow), covering the LLM, question classifier and parameter extractor panels; easy-UI app orchestration pages never show it. The value is stored in completion_params and consumed by the Dify backend before the request reaches the provider.
This commit is contained in:
+17
@@ -388,6 +388,23 @@ describe('ModelParameterModal', () => {
|
||||
expect(screen.getByText(/debugAsSingleModel/i)).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should append the first token timeout parameter only in workflow advanced mode', () => {
|
||||
render(<ModelParameterModal {...defaultProps} isAdvancedMode isInWorkflow />)
|
||||
|
||||
openSettings()
|
||||
|
||||
expect(screen.getByTestId('param-first_token_timeout')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should not append the first token timeout parameter outside workflow', () => {
|
||||
render(<ModelParameterModal {...defaultProps} isAdvancedMode />)
|
||||
|
||||
openSettings()
|
||||
|
||||
expect(screen.getByTestId('param-stop')).toBeInTheDocument()
|
||||
expect(screen.queryByTestId('param-first_token_timeout')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should render the empty loading fallback when rules resolve to an empty list', () => {
|
||||
parameterRules = []
|
||||
isRulesLoading = true
|
||||
|
||||
+23
-17
@@ -9,7 +9,11 @@ import { useMemo, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ArrowNarrowLeft } from '@/app/components/base/icons/src/vender/line/arrows'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import { PROVIDER_WITH_PRESET_TONE, STOP_PARAMETER_RULE } from '@/config'
|
||||
import {
|
||||
FIRST_TOKEN_TIMEOUT_PARAMETER_RULE,
|
||||
PROVIDER_WITH_PRESET_TONE,
|
||||
STOP_PARAMETER_RULE,
|
||||
} from '@/config'
|
||||
import { useModelParameterRules } from '@/service/use-common'
|
||||
import { useTextGenerationCurrentProviderAndModelAndModelList } from '../hooks'
|
||||
import ModelSelector from '../model-selector'
|
||||
@@ -216,22 +220,24 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
<Loading />
|
||||
</div>
|
||||
) : (
|
||||
[...parameterRules, ...(isAdvancedMode ? [STOP_PARAMETER_RULE] : [])].map(
|
||||
(parameter) => (
|
||||
<ParameterItem
|
||||
key={`${modelId}-${parameter.name}`}
|
||||
parameterRule={parameter}
|
||||
value={completionParams?.[parameter.name]}
|
||||
onChange={(v) => handleParamChange(parameter.name, v)}
|
||||
onSwitch={(checked, assignValue) =>
|
||||
handleSwitch(parameter.name, checked, assignValue)
|
||||
}
|
||||
isInWorkflow={isInWorkflow}
|
||||
nodesOutputVars={nodesOutputVars}
|
||||
availableNodes={availableNodes}
|
||||
/>
|
||||
),
|
||||
)
|
||||
[
|
||||
...parameterRules,
|
||||
...(isAdvancedMode ? [STOP_PARAMETER_RULE] : []),
|
||||
...(isAdvancedMode && isInWorkflow ? [FIRST_TOKEN_TIMEOUT_PARAMETER_RULE] : []),
|
||||
].map((parameter) => (
|
||||
<ParameterItem
|
||||
key={`${modelId}-${parameter.name}`}
|
||||
parameterRule={parameter}
|
||||
value={completionParams?.[parameter.name]}
|
||||
onChange={(v) => handleParamChange(parameter.name, v)}
|
||||
onSwitch={(checked, assignValue) =>
|
||||
handleSwitch(parameter.name, checked, assignValue)
|
||||
}
|
||||
isInWorkflow={isInWorkflow}
|
||||
nodesOutputVars={nodesOutputVars}
|
||||
availableNodes={availableNodes}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -328,6 +328,27 @@ export const STOP_PARAMETER_RULE: ModelParameterRule = {
|
||||
},
|
||||
}
|
||||
|
||||
// Synthetic rule consumed by the Dify backend before the request reaches the
|
||||
// model provider; only enforced for workflow LLM-compatible nodes.
|
||||
export const FIRST_TOKEN_TIMEOUT_PARAMETER_RULE: ModelParameterRule = {
|
||||
default: 60,
|
||||
min: 1,
|
||||
max: 1800,
|
||||
precision: 0,
|
||||
help: {
|
||||
en_US:
|
||||
'Max seconds to wait for the first streamed token. On timeout the node fails; combine with node retry to re-run it automatically.',
|
||||
zh_Hans: '等待首个流式 Token 的最长秒数。超时后节点失败,可配合节点重试自动重跑。',
|
||||
},
|
||||
label: {
|
||||
en_US: 'First token timeout',
|
||||
zh_Hans: '首个 Token 超时',
|
||||
},
|
||||
name: 'first_token_timeout',
|
||||
required: false,
|
||||
type: 'int',
|
||||
}
|
||||
|
||||
export const PARTNER_STACK_CONFIG = {
|
||||
cookieName: 'partner_stack_info',
|
||||
saveCookieDays: 90,
|
||||
|
||||
Reference in New Issue
Block a user