|
import { useCallback } from 'react' |
|
import produce from 'immer' |
|
import { useBoolean } from 'ahooks' |
|
import { |
|
useIsChatMode, |
|
useIsNodeInIteration, |
|
useNodesReadOnly, |
|
useWorkflow, |
|
} from '../../hooks' |
|
import { VarType } from '../../types' |
|
import type { ErrorHandleMode, ValueSelector, Var } from '../../types' |
|
import useNodeCrud from '../_base/hooks/use-node-crud' |
|
import { getNodeInfoById, getNodeUsedVarPassToServerKey, getNodeUsedVars, isSystemVar, toNodeOutputVars } from '../_base/components/variable/utils' |
|
import useOneStepRun from '../_base/hooks/use-one-step-run' |
|
import type { IterationNodeType } from './types' |
|
import type { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' |
|
import type { Item } from '@/app/components/base/select' |
|
|
|
const DELIMITER = '@@@@@' |
|
const useConfig = (id: string, payload: IterationNodeType) => { |
|
const { nodesReadOnly: readOnly } = useNodesReadOnly() |
|
const { isNodeInIteration } = useIsNodeInIteration(id) |
|
const isChatMode = useIsChatMode() |
|
|
|
const { inputs, setInputs } = useNodeCrud<IterationNodeType>(id, payload) |
|
|
|
const filterInputVar = useCallback((varPayload: Var) => { |
|
return [VarType.array, VarType.arrayString, VarType.arrayNumber, VarType.arrayObject, VarType.arrayFile].includes(varPayload.type) |
|
}, []) |
|
|
|
const handleInputChange = useCallback((input: ValueSelector | string) => { |
|
const newInputs = produce(inputs, (draft) => { |
|
draft.iterator_selector = input as ValueSelector || [] |
|
}) |
|
setInputs(newInputs) |
|
}, [inputs, setInputs]) |
|
|
|
|
|
const { getIterationNodeChildren, getBeforeNodesInSameBranch } = useWorkflow() |
|
const beforeNodes = getBeforeNodesInSameBranch(id) |
|
const iterationChildrenNodes = getIterationNodeChildren(id) |
|
const canChooseVarNodes = [...beforeNodes, ...iterationChildrenNodes] |
|
const childrenNodeVars = toNodeOutputVars(iterationChildrenNodes, isChatMode) |
|
|
|
const handleOutputVarChange = useCallback((output: ValueSelector | string, _varKindType: VarKindType, varInfo?: Var) => { |
|
const newInputs = produce(inputs, (draft) => { |
|
draft.output_selector = output as ValueSelector || [] |
|
const outputItemType = varInfo?.type || VarType.string |
|
|
|
draft.output_type = ({ |
|
[VarType.string]: VarType.arrayString, |
|
[VarType.number]: VarType.arrayNumber, |
|
[VarType.object]: VarType.arrayObject, |
|
[VarType.file]: VarType.arrayFile, |
|
} as Record<VarType, VarType>)[outputItemType] || VarType.arrayString |
|
}) |
|
setInputs(newInputs) |
|
}, [inputs, setInputs]) |
|
|
|
|
|
const iteratorInputKey = `${id}.input_selector` |
|
const { |
|
isShowSingleRun, |
|
showSingleRun, |
|
hideSingleRun, |
|
toVarInputs, |
|
runningStatus, |
|
handleRun: doHandleRun, |
|
handleStop, |
|
runInputData, |
|
setRunInputData, |
|
runResult, |
|
iterationRunResult, |
|
} = useOneStepRun<IterationNodeType>({ |
|
id, |
|
data: inputs, |
|
iteratorInputKey, |
|
defaultRunInputData: { |
|
[iteratorInputKey]: [''], |
|
}, |
|
}) |
|
|
|
const [isShowIterationDetail, { |
|
setTrue: doShowIterationDetail, |
|
setFalse: doHideIterationDetail, |
|
}] = useBoolean(false) |
|
|
|
const hideIterationDetail = useCallback(() => { |
|
hideSingleRun() |
|
doHideIterationDetail() |
|
}, [doHideIterationDetail, hideSingleRun]) |
|
|
|
const showIterationDetail = useCallback(() => { |
|
doShowIterationDetail() |
|
}, [doShowIterationDetail]) |
|
|
|
const backToSingleRun = useCallback(() => { |
|
hideIterationDetail() |
|
showSingleRun() |
|
}, [hideIterationDetail, showSingleRun]) |
|
|
|
const { usedOutVars, allVarObject } = (() => { |
|
const vars: ValueSelector[] = [] |
|
const varObjs: Record<string, boolean> = {} |
|
const allVarObject: Record<string, { |
|
inSingleRunPassedKey: string |
|
}> = {} |
|
iterationChildrenNodes.forEach((node) => { |
|
const nodeVars = getNodeUsedVars(node).filter(item => item && item.length > 0) |
|
nodeVars.forEach((varSelector) => { |
|
if (varSelector[0] === id) { |
|
return |
|
} |
|
const isInIteration = isNodeInIteration(varSelector[0]) |
|
if (isInIteration) |
|
return |
|
|
|
const varSectorStr = varSelector.join('.') |
|
if (!varObjs[varSectorStr]) { |
|
varObjs[varSectorStr] = true |
|
vars.push(varSelector) |
|
} |
|
let passToServerKeys = getNodeUsedVarPassToServerKey(node, varSelector) |
|
if (typeof passToServerKeys === 'string') |
|
passToServerKeys = [passToServerKeys] |
|
|
|
passToServerKeys.forEach((key: string, index: number) => { |
|
allVarObject[[varSectorStr, node.id, index].join(DELIMITER)] = { |
|
inSingleRunPassedKey: key, |
|
} |
|
}) |
|
}) |
|
}) |
|
const res = toVarInputs(vars.map((item) => { |
|
const varInfo = getNodeInfoById(canChooseVarNodes, item[0]) |
|
return { |
|
label: { |
|
nodeType: varInfo?.data.type, |
|
nodeName: varInfo?.data.title || canChooseVarNodes[0]?.data.title, |
|
variable: isSystemVar(item) ? item.join('.') : item[item.length - 1], |
|
}, |
|
variable: `${item.join('.')}`, |
|
value_selector: item, |
|
} |
|
})) |
|
return { |
|
usedOutVars: res, |
|
allVarObject, |
|
} |
|
})() |
|
|
|
const handleRun = useCallback((data: Record<string, any>) => { |
|
const formattedData: Record<string, any> = {} |
|
Object.keys(allVarObject).forEach((key) => { |
|
const [varSectorStr, nodeId] = key.split(DELIMITER) |
|
formattedData[`${nodeId}.${allVarObject[key].inSingleRunPassedKey}`] = data[varSectorStr] |
|
}) |
|
formattedData[iteratorInputKey] = data[iteratorInputKey] |
|
doHandleRun(formattedData) |
|
}, [allVarObject, doHandleRun, iteratorInputKey]) |
|
|
|
const inputVarValues = (() => { |
|
const vars: Record<string, any> = {} |
|
Object.keys(runInputData) |
|
.filter(key => ![iteratorInputKey].includes(key)) |
|
.forEach((key) => { |
|
vars[key] = runInputData[key] |
|
}) |
|
return vars |
|
})() |
|
|
|
const setInputVarValues = useCallback((newPayload: Record<string, any>) => { |
|
const newVars = { |
|
...newPayload, |
|
[iteratorInputKey]: runInputData[iteratorInputKey], |
|
} |
|
setRunInputData(newVars) |
|
}, [iteratorInputKey, runInputData, setRunInputData]) |
|
|
|
const iterator = runInputData[iteratorInputKey] |
|
const setIterator = useCallback((newIterator: string[]) => { |
|
setRunInputData({ |
|
...runInputData, |
|
[iteratorInputKey]: newIterator, |
|
}) |
|
}, [iteratorInputKey, runInputData, setRunInputData]) |
|
|
|
const changeParallel = useCallback((value: boolean) => { |
|
const newInputs = produce(inputs, (draft) => { |
|
draft.is_parallel = value |
|
}) |
|
setInputs(newInputs) |
|
}, [inputs, setInputs]) |
|
|
|
const changeErrorResponseMode = useCallback((item: Item) => { |
|
const newInputs = produce(inputs, (draft) => { |
|
draft.error_handle_mode = item.value as ErrorHandleMode |
|
}) |
|
setInputs(newInputs) |
|
}, [inputs, setInputs]) |
|
const changeParallelNums = useCallback((num: number) => { |
|
const newInputs = produce(inputs, (draft) => { |
|
draft.parallel_nums = num |
|
}) |
|
setInputs(newInputs) |
|
}, [inputs, setInputs]) |
|
return { |
|
readOnly, |
|
inputs, |
|
filterInputVar, |
|
handleInputChange, |
|
childrenNodeVars, |
|
iterationChildrenNodes, |
|
handleOutputVarChange, |
|
isShowSingleRun, |
|
showSingleRun, |
|
hideSingleRun, |
|
isShowIterationDetail, |
|
showIterationDetail, |
|
hideIterationDetail, |
|
backToSingleRun, |
|
runningStatus, |
|
handleRun, |
|
handleStop, |
|
runResult, |
|
inputVarValues, |
|
setInputVarValues, |
|
usedOutVars, |
|
iterator, |
|
setIterator, |
|
iteratorInputKey, |
|
iterationRunResult, |
|
changeParallel, |
|
changeErrorResponseMode, |
|
changeParallelNums, |
|
} |
|
} |
|
|
|
export default useConfig |
|
|