revert: revert human input relevant code (#31766)

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
QuantumGhost
2026-01-30 19:18:49 +08:00
committed by GitHub
parent ba568a634d
commit 90fe9abab7
470 changed files with 2082 additions and 32508 deletions

View File

@ -1,85 +0,0 @@
import type { DeliveryMethod, HumanInputNodeType, UserAction } from '../types'
import { produce } from 'immer'
import { useState } from 'react'
import { useUpdateNodeInternals } from 'reactflow'
import {
useNodesReadOnly,
} from '@/app/components/workflow/hooks'
import { useEdgesInteractions } from '@/app/components/workflow/hooks/use-edges-interactions'
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import useFormContent from './use-form-content'
const useConfig = (id: string, payload: HumanInputNodeType) => {
const updateNodeInternals = useUpdateNodeInternals()
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const { inputs, setInputs } = useNodeCrud<HumanInputNodeType>(id, payload)
const formContentHook = useFormContent(id, payload)
const { handleEdgeDeleteByDeleteBranch, handleEdgeSourceHandleChange } = useEdgesInteractions()
const [structuredOutputCollapsed, setStructuredOutputCollapsed] = useState(true)
const handleDeliveryMethodChange = (methods: DeliveryMethod[]) => {
setInputs({
...inputs,
delivery_methods: methods,
})
}
const handleUserActionAdd = (newAction: UserAction) => {
setInputs({
...inputs,
user_actions: [...inputs.user_actions, newAction],
})
}
const handleUserActionChange = (index: number, updatedAction: UserAction) => {
const newActions = produce(inputs.user_actions, (draft) => {
if (draft[index])
draft[index] = updatedAction
})
setInputs({
...inputs,
user_actions: newActions,
})
// Update edges to use the new handle
const oldAction = inputs.user_actions[index]
if (oldAction && oldAction.id !== updatedAction.id) {
handleEdgeSourceHandleChange(id, oldAction.id, updatedAction.id)
updateNodeInternals(id) // Update handles
}
}
const handleUserActionDelete = (actionId: string) => {
const newActions = inputs.user_actions.filter(action => action.id !== actionId)
setInputs({
...inputs,
user_actions: newActions,
})
// Delete edges connected to this action
handleEdgeDeleteByDeleteBranch(id, actionId)
}
const handleTimeoutChange = ({ timeout, unit }: { timeout: number, unit: 'hour' | 'day' }) => {
setInputs({
...inputs,
timeout,
timeout_unit: unit,
})
}
return {
readOnly,
inputs,
handleDeliveryMethodChange,
handleUserActionAdd,
handleUserActionChange,
handleUserActionDelete,
handleTimeoutChange,
structuredOutputCollapsed,
setStructuredOutputCollapsed,
...formContentHook,
}
}
export default useConfig

View File

@ -1,65 +0,0 @@
import type { FormInputItem, HumanInputNodeType } from '../types'
import { produce } from 'immer'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useWorkflow } from '@/app/components/workflow/hooks'
import useNodeCrud from '../../_base/hooks/use-node-crud'
const useFormContent = (id: string, payload: HumanInputNodeType) => {
const [editorKey, setEditorKey] = useState(0)
const { inputs, setInputs } = useNodeCrud<HumanInputNodeType>(id, payload)
const { handleOutVarRenameChange } = useWorkflow()
const inputsRef = useRef(inputs)
useEffect(() => {
inputsRef.current = inputs
}, [inputs])
const handleFormContentChange = useCallback((value: string) => {
setInputs({
...inputs,
form_content: value,
})
}, [inputs, setInputs])
const handleFormInputsChange = useCallback((formInputs: FormInputItem[]) => {
setInputs({
...inputs,
inputs: formInputs,
})
setEditorKey(editorKey => editorKey + 1)
}, [inputs, setInputs])
const handleFormInputItemRename = useCallback((payload: FormInputItem, oldName: string) => {
const inputs = inputsRef.current
const newInputs = produce(inputs, (draft) => {
draft.form_content = draft.form_content.replaceAll(`{{#$output.${oldName}#}}`, `{{#$output.${payload.output_variable_name}#}}`)
draft.inputs = draft.inputs.map(item => item.output_variable_name === oldName ? payload : item)
if (!draft.inputs.find(item => item.output_variable_name === payload.output_variable_name))
draft.inputs = [...draft.inputs, payload]
})
setInputs(newInputs)
setEditorKey(editorKey => editorKey + 1)
// Update downstream nodes that reference this variable
if (oldName !== payload.output_variable_name)
handleOutVarRenameChange(id, [id, oldName], [id, payload.output_variable_name])
}, [setInputs, handleOutVarRenameChange, id])
const handleFormInputItemRemove = useCallback((varName: string) => {
const inputs = inputsRef.current
const newInputs = produce(inputs, (draft) => {
draft.form_content = draft.form_content.replaceAll(`{{#$output.${varName}#}}`, '')
draft.inputs = draft.inputs.filter(item => item.output_variable_name !== varName)
})
setInputs(newInputs)
setEditorKey(editorKey => editorKey + 1)
}, [setInputs])
return {
editorKey,
handleFormContentChange,
handleFormInputsChange,
handleFormInputItemRename,
handleFormInputItemRemove,
}
}
export default useFormContent

View File

@ -1,128 +0,0 @@
import type { HumanInputNodeType } from '../types'
import type { Props as FormProps } from '@/app/components/workflow/nodes/_base/components/before-run-form/form'
import type { InputVar } from '@/app/components/workflow/types'
import type { HumanInputFormData } from '@/types/workflow'
import { useCallback, useMemo, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useStore as useAppStore } from '@/app/components/app/store'
import { fetchHumanInputNodeStepRunForm, submitHumanInputNodeStepRunForm } from '@/service/workflow'
import { AppModeEnum } from '@/types/app'
import useNodeCrud from '../../_base/hooks/use-node-crud'
import { isOutput } from '../utils'
const i18nPrefix = 'nodes.humanInput'
type Params = {
id: string
payload: HumanInputNodeType
runInputData: Record<string, string>
getInputVars: (textList: string[]) => InputVar[]
setRunInputData: (data: Record<string, string>) => void
}
const useSingleRunFormParams = ({
id,
payload,
runInputData,
getInputVars,
setRunInputData,
}: Params) => {
const { t } = useTranslation()
const { inputs } = useNodeCrud<HumanInputNodeType>(id, payload)
const [showGeneratedForm, setShowGeneratedForm] = useState(false)
const [formData, setFormData] = useState<HumanInputFormData | null>(null)
const [requiredInputs, setRequiredInputs] = useState<Record<string, string>>({})
const generatedInputs = useMemo(() => {
const defaultInputs = inputs.inputs.reduce((acc, input) => {
if (input.default.type === 'variable') {
acc.push(`{{#${input.default.selector.join('.')}#}}`)
}
return acc
}, [] as string[])
const allInputs = getInputVars([...defaultInputs, inputs.form_content || '']).filter(item => !isOutput(item.value_selector || []))
return allInputs
}, [getInputVars, inputs.form_content, inputs.inputs])
const forms = useMemo(() => {
const forms: FormProps[] = [{
label: t(`${i18nPrefix}.singleRun.label`, { ns: 'workflow' })!,
inputs: generatedInputs,
values: runInputData,
onChange: setRunInputData,
}]
return forms
}, [t, generatedInputs, runInputData, setRunInputData])
const getDependentVars = () => {
return generatedInputs.map((item) => {
// Guard against null/undefined variable to prevent app crash
if (!item.variable || typeof item.variable !== 'string')
return []
return item.variable.slice(1, -1).split('.')
}).filter(arr => arr.length > 0)
}
const appDetail = useAppStore(s => s.appDetail)
const appId = appDetail?.id
const isWorkflowMode = appDetail?.mode === AppModeEnum.WORKFLOW
const fetchURL = useMemo(() => {
if (!appId)
return ''
if (!isWorkflowMode) {
return `/apps/${appId}/advanced-chat/workflows/draft/human-input/nodes/${id}/form`
}
else {
return `/apps/${appId}/workflows/draft/human-input/nodes/${id}/form`
}
}, [appId, id, isWorkflowMode])
const handleFetchFormContent = useCallback(async (inputs: Record<string, string>) => {
if (!fetchURL)
return null
let requestParamsObj: Record<string, string> = {}
Object.keys(inputs).forEach((key) => {
if (inputs[key] === undefined) {
delete inputs[key]
}
})
requestParamsObj = { ...inputs }
const data = await fetchHumanInputNodeStepRunForm(fetchURL, { inputs: requestParamsObj! })
setFormData(data)
setRequiredInputs(requestParamsObj)
return data
}, [fetchURL])
const handleSubmitHumanInputForm = useCallback(async (formData: {
inputs: Record<string, string> | undefined
form_inputs: Record<string, string> | undefined
action: string
}) => {
await submitHumanInputNodeStepRunForm(fetchURL, {
inputs: requiredInputs,
form_inputs: formData.inputs,
action: formData.action,
})
}, [fetchURL, requiredInputs])
const handleShowGeneratedForm = async (formValue: Record<string, string>) => {
setShowGeneratedForm(true)
await handleFetchFormContent(formValue)
}
const handleHideGeneratedForm = () => {
setShowGeneratedForm(false)
}
return {
forms,
getDependentVars,
showGeneratedForm,
handleShowGeneratedForm,
handleHideGeneratedForm,
formData,
handleFetchFormContent,
handleSubmitHumanInputForm,
}
}
export default useSingleRunFormParams