| 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 |
|
|