mirror of
https://github.com/langgenius/dify.git
synced 2026-05-13 08:57:28 +08:00
refactor: optimize workflow variable handling and enhance node state management for resumption scenarios
This commit is contained in:
parent
f0f1ae0b49
commit
52ce46c364
@ -2,7 +2,7 @@ import type { Node, ToolWithProvider } from '@/app/components/workflow/types'
|
|||||||
import type { SchemaTypeDefinition } from '@/service/use-common'
|
import type { SchemaTypeDefinition } from '@/service/use-common'
|
||||||
import type { FlowType } from '@/types/common'
|
import type { FlowType } from '@/types/common'
|
||||||
import type { NodeWithVar, VarInInspect } from '@/types/workflow'
|
import type { NodeWithVar, VarInInspect } from '@/types/workflow'
|
||||||
import { useCallback } from 'react'
|
import { useCallback, useMemo } from 'react'
|
||||||
import { useStoreApi } from 'reactflow'
|
import { useStoreApi } from 'reactflow'
|
||||||
import { useNodesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-nodes-interactions-without-sync'
|
import { useNodesInteractionsWithoutSync } from '@/app/components/workflow/hooks/use-nodes-interactions-without-sync'
|
||||||
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
import { useStore, useWorkflowStore } from '@/app/components/workflow/store'
|
||||||
@ -14,7 +14,7 @@ import {
|
|||||||
} from '@/service/use-tools'
|
} from '@/service/use-tools'
|
||||||
import { useInvalidateConversationVarValues, useInvalidateSysVarValues } from '@/service/use-workflow'
|
import { useInvalidateConversationVarValues, useInvalidateSysVarValues } from '@/service/use-workflow'
|
||||||
import { fetchAllInspectVars } from '@/service/workflow'
|
import { fetchAllInspectVars } from '@/service/workflow'
|
||||||
import useMatchSchemaType, { getMatchedSchemaType } from '../nodes/_base/components/variable/use-match-schema-type'
|
import useMatchSchemaType from '../nodes/_base/components/variable/use-match-schema-type'
|
||||||
import { toNodeOutputVars } from '../nodes/_base/components/variable/utils'
|
import { toNodeOutputVars } from '../nodes/_base/components/variable/utils'
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
@ -37,15 +37,18 @@ export const useSetWorkflowVarsWithValue = ({
|
|||||||
const { data: workflowTools } = useAllWorkflowTools()
|
const { data: workflowTools } = useAllWorkflowTools()
|
||||||
const { data: mcpTools } = useAllMCPTools()
|
const { data: mcpTools } = useAllMCPTools()
|
||||||
const dataSourceList = useStore(s => s.dataSourceList)
|
const dataSourceList = useStore(s => s.dataSourceList)
|
||||||
const allPluginInfoList = {
|
|
||||||
buildInTools: buildInTools || [],
|
|
||||||
customTools: customTools || [],
|
|
||||||
workflowTools: workflowTools || [],
|
|
||||||
mcpTools: mcpTools || [],
|
|
||||||
dataSourceList: dataSourceList || [],
|
|
||||||
}
|
|
||||||
|
|
||||||
const setInspectVarsToStore = (inspectVars: VarInInspect[], passedInAllPluginInfoList?: Record<string, ToolWithProvider[]>, passedInSchemaTypeDefinitions?: SchemaTypeDefinition[]) => {
|
const allPluginInfoList = useMemo(() => {
|
||||||
|
return {
|
||||||
|
buildInTools: buildInTools || [],
|
||||||
|
customTools: customTools || [],
|
||||||
|
workflowTools: workflowTools || [],
|
||||||
|
mcpTools: mcpTools || [],
|
||||||
|
dataSourceList: dataSourceList || [],
|
||||||
|
}
|
||||||
|
}, [buildInTools, customTools, workflowTools, mcpTools, dataSourceList])
|
||||||
|
|
||||||
|
const setInspectVarsToStore = useCallback((inspectVars: VarInInspect[], passedInAllPluginInfoList?: Record<string, ToolWithProvider[]>, passedInSchemaTypeDefinitions?: SchemaTypeDefinition[]) => {
|
||||||
const { setNodesWithInspectVars } = workflowStore.getState()
|
const { setNodesWithInspectVars } = workflowStore.getState()
|
||||||
const { getNodes } = store.getState()
|
const { getNodes } = store.getState()
|
||||||
|
|
||||||
@ -95,7 +98,7 @@ export const useSetWorkflowVarsWithValue = ({
|
|||||||
return nodeWithVar
|
return nodeWithVar
|
||||||
})
|
})
|
||||||
setNodesWithInspectVars(res)
|
setNodesWithInspectVars(res)
|
||||||
}
|
}, [workflowStore, store, allPluginInfoList, schemaTypeDefinitions])
|
||||||
|
|
||||||
const fetchInspectVars = useCallback(async (params: {
|
const fetchInspectVars = useCallback(async (params: {
|
||||||
passInVars?: boolean
|
passInVars?: boolean
|
||||||
@ -109,7 +112,8 @@ export const useSetWorkflowVarsWithValue = ({
|
|||||||
const data = passInVars ? vars! : await fetchAllInspectVars(flowType, flowId)
|
const data = passInVars ? vars! : await fetchAllInspectVars(flowType, flowId)
|
||||||
setInspectVarsToStore(data, passedInAllPluginInfoList, passedInSchemaTypeDefinitions)
|
setInspectVarsToStore(data, passedInAllPluginInfoList, passedInSchemaTypeDefinitions)
|
||||||
handleCancelAllNodeSuccessStatus() // to make sure clear node output show the unset status
|
handleCancelAllNodeSuccessStatus() // to make sure clear node output show the unset status
|
||||||
}, [invalidateConversationVarValues, invalidateSysVarValues, flowType, flowId, setInspectVarsToStore, handleCancelAllNodeSuccessStatus, schemaTypeDefinitions, getMatchedSchemaType])
|
}, [invalidateConversationVarValues, invalidateSysVarValues, flowType, flowId, setInspectVarsToStore, handleCancelAllNodeSuccessStatus])
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fetchInspectVars,
|
fetchInspectVars,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ export const useWorkflowNodeStarted = () => {
|
|||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
const { data } = params
|
const { data } = params
|
||||||
|
const { is_resumption } = data
|
||||||
const {
|
const {
|
||||||
workflowRunningData,
|
workflowRunningData,
|
||||||
setWorkflowRunningData,
|
setWorkflowRunningData,
|
||||||
@ -33,12 +34,25 @@ export const useWorkflowNodeStarted = () => {
|
|||||||
transform,
|
transform,
|
||||||
} = store.getState()
|
} = store.getState()
|
||||||
const nodes = getNodes()
|
const nodes = getNodes()
|
||||||
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
|
if (is_resumption) {
|
||||||
draft.tracing!.push({
|
const currentIndex = workflowRunningData?.tracing?.findIndex(item => item.node_id === data.node_id)
|
||||||
...data,
|
if (currentIndex && currentIndex > -1) {
|
||||||
status: NodeRunningStatus.Running,
|
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
|
||||||
})
|
draft.tracing![currentIndex] = {
|
||||||
}))
|
...data,
|
||||||
|
status: NodeRunningStatus.Running,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setWorkflowRunningData(produce(workflowRunningData!, (draft) => {
|
||||||
|
draft.tracing!.push({
|
||||||
|
...data,
|
||||||
|
status: NodeRunningStatus.Running,
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setViewport,
|
setViewport,
|
||||||
|
|||||||
@ -301,35 +301,38 @@ export const useChat = (
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
async onCompleted(hasError?: boolean, errorMessage?: string) {
|
async onCompleted(hasError?: boolean, errorMessage?: string) {
|
||||||
|
const { workflowRunningData } = workflowStore.getState()
|
||||||
handleResponding(false)
|
handleResponding(false)
|
||||||
fetchInspectVars({})
|
if (workflowRunningData?.result.status !== WorkflowRunningStatus.Paused) {
|
||||||
invalidAllLastRun()
|
fetchInspectVars({})
|
||||||
|
invalidAllLastRun()
|
||||||
|
|
||||||
if (hasError) {
|
if (hasError) {
|
||||||
if (errorMessage) {
|
if (errorMessage) {
|
||||||
responseItem.content = errorMessage
|
responseItem.content = errorMessage
|
||||||
responseItem.isError = true
|
responseItem.isError = true
|
||||||
updateCurrentQAOnTree({
|
updateCurrentQAOnTree({
|
||||||
placeholderQuestionId,
|
placeholderQuestionId,
|
||||||
questionItem,
|
questionItem,
|
||||||
responseItem,
|
responseItem,
|
||||||
parentId: params.parent_message_id,
|
parentId: params.parent_message_id,
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config?.suggested_questions_after_answer?.enabled && !hasStopResponded.current && onGetSuggestedQuestions) {
|
if (config?.suggested_questions_after_answer?.enabled && !hasStopResponded.current && onGetSuggestedQuestions) {
|
||||||
try {
|
try {
|
||||||
const { data }: any = await onGetSuggestedQuestions(
|
const { data }: any = await onGetSuggestedQuestions(
|
||||||
responseItem.id,
|
responseItem.id,
|
||||||
newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController,
|
newAbortController => suggestedQuestionsAbortControllerRef.current = newAbortController,
|
||||||
)
|
)
|
||||||
setSuggestQuestions(data)
|
setSuggestQuestions(data)
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line unused-imports/no-unused-vars
|
// eslint-disable-next-line unused-imports/no-unused-vars
|
||||||
catch (error) {
|
catch (error) {
|
||||||
setSuggestQuestions([])
|
setSuggestQuestions([])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -353,6 +356,7 @@ export const useChat = (
|
|||||||
},
|
},
|
||||||
onWorkflowStarted: ({ workflow_run_id, task_id, data: { is_resumption } }) => {
|
onWorkflowStarted: ({ workflow_run_id, task_id, data: { is_resumption } }) => {
|
||||||
if (is_resumption) {
|
if (is_resumption) {
|
||||||
|
handleResponding(true)
|
||||||
responseItem.workflowProcess!.status = WorkflowRunningStatus.Running
|
responseItem.workflowProcess!.status = WorkflowRunningStatus.Running
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -434,10 +438,22 @@ export const useChat = (
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onNodeStarted: ({ data }) => {
|
onNodeStarted: ({ data }) => {
|
||||||
responseItem.workflowProcess!.tracing!.push({
|
const { is_resumption } = data
|
||||||
...data,
|
if (is_resumption) {
|
||||||
status: NodeRunningStatus.Running,
|
const currentIndex = responseItem.workflowProcess!.tracing!.findIndex(item => item.node_id === data.node_id)
|
||||||
} as any)
|
if (currentIndex > -1) {
|
||||||
|
responseItem.workflowProcess!.tracing![currentIndex] = {
|
||||||
|
...data,
|
||||||
|
status: NodeRunningStatus.Running,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
responseItem.workflowProcess!.tracing!.push({
|
||||||
|
...data,
|
||||||
|
status: NodeRunningStatus.Running,
|
||||||
|
})
|
||||||
|
}
|
||||||
updateCurrentQAOnTree({
|
updateCurrentQAOnTree({
|
||||||
placeholderQuestionId,
|
placeholderQuestionId,
|
||||||
questionItem,
|
questionItem,
|
||||||
@ -538,7 +554,6 @@ export const useChat = (
|
|||||||
|
|
||||||
const handleSubmitHumanInputForm = async (formID: string, formData: any) => {
|
const handleSubmitHumanInputForm = async (formID: string, formData: any) => {
|
||||||
await submitHumanInputForm(formID, formData)
|
await submitHumanInputForm(formID, formData)
|
||||||
// TODO deal with success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const getHumanInputNodeData = (nodeID: string) => {
|
const getHumanInputNodeData = (nodeID: string) => {
|
||||||
|
|||||||
@ -105,6 +105,7 @@ export type NodeTracing = {
|
|||||||
parent_parallel_id?: string
|
parent_parallel_id?: string
|
||||||
parent_parallel_start_node_id?: string
|
parent_parallel_start_node_id?: string
|
||||||
agentLog?: AgentLogItemWithChildren[] // agent log
|
agentLog?: AgentLogItemWithChildren[] // agent log
|
||||||
|
is_resumption?: boolean // for human input node
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FetchWorkflowDraftResponse = {
|
export type FetchWorkflowDraftResponse = {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user