mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
fix: ensure sub-graph modal syncs immediately when
applying generated code.
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
import type { Var, Variable } from '../../types'
|
||||
import type { CodeNodeType, OutputVar } from './types'
|
||||
import { produce } from 'immer'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import {
|
||||
useNodesReadOnly,
|
||||
} from '@/app/components/workflow/hooks'
|
||||
@ -56,9 +56,28 @@ const useConfig = (id: string, payload: CodeNodeType) => {
|
||||
setInputs,
|
||||
})
|
||||
|
||||
const [outputKeyOrders, setOutputKeyOrders] = useState<string[]>(() => Object.keys(payload.outputs || {}))
|
||||
const outputKeyOrdersRef = useRef<string[]>(Object.keys(payload.outputs || {}))
|
||||
const outputKeyOrders = (() => {
|
||||
const outputKeys = inputs.outputs ? Object.keys(inputs.outputs) : []
|
||||
if (outputKeys.length === 0) {
|
||||
if (outputKeyOrdersRef.current.length > 0)
|
||||
outputKeyOrdersRef.current = []
|
||||
return [] as string[]
|
||||
}
|
||||
|
||||
const nextOutputKeyOrders = outputKeyOrdersRef.current.filter(key => outputKeys.includes(key))
|
||||
outputKeys.forEach((key) => {
|
||||
if (!nextOutputKeyOrders.includes(key))
|
||||
nextOutputKeyOrders.push(key)
|
||||
})
|
||||
outputKeyOrdersRef.current = nextOutputKeyOrders
|
||||
return nextOutputKeyOrders
|
||||
})()
|
||||
const syncOutputKeyOrders = useCallback((outputs: OutputVar) => {
|
||||
setOutputKeyOrders(Object.keys(outputs))
|
||||
outputKeyOrdersRef.current = Object.keys(outputs)
|
||||
}, [])
|
||||
const handleOutputKeyOrdersChange = useCallback((newOutputKeyOrders: string[]) => {
|
||||
outputKeyOrdersRef.current = newOutputKeyOrders
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
const outputKeys = inputs.outputs ? Object.keys(inputs.outputs) : []
|
||||
@ -174,7 +193,7 @@ const useConfig = (id: string, payload: CodeNodeType) => {
|
||||
inputs,
|
||||
setInputs,
|
||||
outputKeyOrders,
|
||||
onOutputKeyOrdersChange: setOutputKeyOrders,
|
||||
onOutputKeyOrdersChange: handleOutputKeyOrdersChange,
|
||||
})
|
||||
|
||||
const filterVar = useCallback((varPayload: Var) => {
|
||||
|
||||
@ -179,7 +179,7 @@ const ContextGenerateModal = forwardRef<ContextGenerateModalHandle, Props>(({
|
||||
outputs: nextOutputs,
|
||||
variables: nextVariables,
|
||||
},
|
||||
})
|
||||
}, { sync: true })
|
||||
|
||||
if (closeOnApply)
|
||||
handleCloseModal()
|
||||
|
||||
@ -48,6 +48,7 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
const workflowNodes = useWorkflowStore(state => state.nodes)
|
||||
const workflowEdges = useReactFlowStore(state => state.edges)
|
||||
const setControlPromptEditorRerenderKey = useWorkflowStore(state => state.setControlPromptEditorRerenderKey)
|
||||
const setWorkflowNodes = useWorkflowStore(state => state.setNodes)
|
||||
const { handleSyncWorkflowDraft, doSyncWorkflowDraft } = useNodesSyncDraft()
|
||||
const configsMap = useHooksStore(state => state.configsMap)
|
||||
const { getBeforeNodesInSameBranch } = useWorkflow()
|
||||
@ -134,8 +135,9 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
}
|
||||
})
|
||||
setNodes(nextNodes)
|
||||
handleSyncWorkflowDraft()
|
||||
}, [handleSyncWorkflowDraft, paramKey, reactflowStore, toolNodeId])
|
||||
setWorkflowNodes(nextNodes)
|
||||
handleSyncWorkflowDraft(true)
|
||||
}, [handleSyncWorkflowDraft, paramKey, reactflowStore, setWorkflowNodes, toolNodeId])
|
||||
|
||||
useEffect(() => {
|
||||
if (!toolParam || (toolParam.type && toolParam.type !== VarKindType.nested_node))
|
||||
@ -179,7 +181,7 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
|
||||
const ensureAssembleOutputs = (payload: CodeNodeType) => {
|
||||
const outputs = payload.outputs || {}
|
||||
if (outputs.result)
|
||||
if (Object.keys(outputs).length > 0)
|
||||
return payload
|
||||
return {
|
||||
...payload,
|
||||
@ -193,6 +195,20 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
}
|
||||
}
|
||||
|
||||
const resolveAssembleOutputSelector = (rawSelector: unknown, outputKeys: string[]) => {
|
||||
if (outputKeys.length === 0)
|
||||
return null
|
||||
const normalizedSelector = Array.isArray(rawSelector)
|
||||
? (rawSelector[0] === extractorNodeId ? rawSelector.slice(1) : rawSelector)
|
||||
: []
|
||||
const currentKey = normalizedSelector[0]
|
||||
const fallbackKey = outputKeys.includes('result') ? 'result' : outputKeys[0]
|
||||
const nextKey = outputKeys.includes(currentKey) ? currentKey : fallbackKey
|
||||
if (!nextKey || nextKey === currentKey)
|
||||
return null
|
||||
return [nextKey, ...normalizedSelector.slice(1)]
|
||||
}
|
||||
|
||||
const userPromptText = isAgentVariant
|
||||
? getUserPromptText((extractorNodeData.data as LLMNodeType).prompt_template)
|
||||
: ''
|
||||
@ -223,6 +239,19 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
return node
|
||||
|
||||
const currentParam = toolData.tool_parameters[paramKey]
|
||||
const baseNestedConfig = currentParam.nested_node_config ?? nestedNodeConfig
|
||||
let nextNestedConfig = baseNestedConfig
|
||||
if (!isAgentVariant) {
|
||||
const outputKeys = Object.keys((extractorNodeData.data as CodeNodeType).outputs || {})
|
||||
const nextSelector = resolveAssembleOutputSelector(baseNestedConfig?.output_selector, outputKeys)
|
||||
if (nextSelector) {
|
||||
nextNestedConfig = {
|
||||
...baseNestedConfig,
|
||||
extractor_node_id: baseNestedConfig?.extractor_node_id || extractorNodeId,
|
||||
output_selector: nextSelector,
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
...node,
|
||||
data: {
|
||||
@ -233,7 +262,7 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
...currentParam,
|
||||
type: VarKindType.nested_node,
|
||||
value: nextValue,
|
||||
nested_node_config: currentParam.nested_node_config ?? nestedNodeConfig,
|
||||
nested_node_config: nextNestedConfig,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -242,8 +271,9 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
return node
|
||||
})
|
||||
setNodes(nextNodes)
|
||||
setWorkflowNodes(nextNodes)
|
||||
setControlPromptEditorRerenderKey(Date.now())
|
||||
}, [assemblePlaceholder, extractorNodeId, getUserPromptText, isAgentVariant, nestedNodeConfig, paramKey, reactflowStore, resolvedAgentNodeId, setControlPromptEditorRerenderKey, toolNodeId])
|
||||
}, [assemblePlaceholder, extractorNodeId, getUserPromptText, isAgentVariant, nestedNodeConfig, paramKey, reactflowStore, resolvedAgentNodeId, setControlPromptEditorRerenderKey, setWorkflowNodes, toolNodeId])
|
||||
|
||||
return (
|
||||
<Transition appear show={isOpen} as={Fragment}>
|
||||
|
||||
Reference in New Issue
Block a user