mirror of
https://github.com/langgenius/dify.git
synced 2026-07-19 16:44:00 -04:00
fix(web): render first-token timeout only for panels that consume it
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.
This commit is contained in:
+14
-4
@@ -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(<ModelParameterModal {...defaultProps} isAdvancedMode isInWorkflow />)
|
||||
it('should append the first token timeout parameter when the panel supports it', () => {
|
||||
render(
|
||||
<ModelParameterModal
|
||||
{...defaultProps}
|
||||
isAdvancedMode
|
||||
isInWorkflow
|
||||
supportFirstTokenTimeout
|
||||
/>,
|
||||
)
|
||||
|
||||
openSettings()
|
||||
|
||||
expect(screen.getByTestId('param-first_token_timeout_ms')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should not append the first token timeout parameter outside workflow', () => {
|
||||
render(<ModelParameterModal {...defaultProps} isAdvancedMode />)
|
||||
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(<ModelParameterModal {...defaultProps} isAdvancedMode isInWorkflow />)
|
||||
|
||||
openSettings()
|
||||
|
||||
|
||||
+8
-1
@@ -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<ModelParameterModalProps> = ({
|
||||
renderTrigger,
|
||||
readonly,
|
||||
isInWorkflow,
|
||||
supportFirstTokenTimeout,
|
||||
nodesOutputVars,
|
||||
availableNodes,
|
||||
}) => {
|
||||
@@ -223,7 +228,9 @@ const ModelParameterModal: FC<ModelParameterModalProps> = ({
|
||||
[
|
||||
...parameterRules,
|
||||
...(isAdvancedMode ? [STOP_PARAMETER_RULE] : []),
|
||||
...(isAdvancedMode && isInWorkflow ? [FIRST_TOKEN_TIMEOUT_PARAMETER_RULE] : []),
|
||||
...(isAdvancedMode && supportFirstTokenTimeout
|
||||
? [FIRST_TOKEN_TIMEOUT_PARAMETER_RULE]
|
||||
: []),
|
||||
].map((parameter) => (
|
||||
<ParameterItem
|
||||
key={`${modelId}-${parameter.name}`}
|
||||
|
||||
@@ -117,6 +117,7 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({ id, data }) => {
|
||||
popupClassName="w-[387px]!"
|
||||
isInWorkflow
|
||||
isAdvancedMode={true}
|
||||
supportFirstTokenTimeout
|
||||
provider={model?.provider}
|
||||
completionParams={model?.completion_params}
|
||||
modelId={model?.name}
|
||||
|
||||
@@ -61,6 +61,7 @@ const Panel: FC<NodePanelProps<ParameterExtractorNodeType>> = ({ id, data }) =>
|
||||
popupClassName="w-[387px]!"
|
||||
isInWorkflow
|
||||
isAdvancedMode={true}
|
||||
supportFirstTokenTimeout
|
||||
provider={model?.provider}
|
||||
completionParams={model?.completion_params}
|
||||
modelId={model?.name}
|
||||
|
||||
@@ -50,6 +50,7 @@ const Panel: FC<NodePanelProps<QuestionClassifierNodeType>> = ({ id, data }) =>
|
||||
popupClassName="w-[387px]!"
|
||||
isInWorkflow
|
||||
isAdvancedMode={true}
|
||||
supportFirstTokenTimeout
|
||||
provider={model?.provider}
|
||||
completionParams={model.completion_params}
|
||||
modelId={model.name}
|
||||
|
||||
+3
-2
@@ -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)',
|
||||
|
||||
Reference in New Issue
Block a user