feat: Human Input Node (#32060)

The frontend and backend implementation for the human input node.

Co-authored-by: twwu <twwu@dify.ai>
Co-authored-by: JzoNg <jzongcode@gmail.com>
Co-authored-by: yyh <92089059+lyzno1@users.noreply.github.com>
Co-authored-by: zhsama <torvalds@linux.do>
This commit is contained in:
QuantumGhost
2026-02-09 14:57:23 +08:00
committed by GitHub
parent 56e3a55023
commit a1fc280102
474 changed files with 32667 additions and 2050 deletions

View File

@ -6,10 +6,12 @@ import type {
HistoryBlockType,
LastRunBlockType,
QueryBlockType,
RequestURLBlockType,
VariableBlockType,
WorkflowVariableBlockType,
} from '../../types'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { RiGlobalLine } from '@remixicon/react'
import { $insertNodes } from 'lexical'
import { useMemo } from 'react'
import { useTranslation } from 'react-i18next'
@ -27,6 +29,7 @@ import { INSERT_CONTEXT_BLOCK_COMMAND } from '../context-block'
import { $createCustomTextNode } from '../custom-text/node'
import { INSERT_HISTORY_BLOCK_COMMAND } from '../history-block'
import { INSERT_QUERY_BLOCK_COMMAND } from '../query-block'
import { INSERT_REQUEST_URL_BLOCK_COMMAND } from '../request-url-block'
import { INSERT_VARIABLE_VALUE_BLOCK_COMMAND } from '../variable-block'
import { PickerBlockMenuOption } from './menu'
import { PromptMenuItem } from './prompt-option'
@ -36,6 +39,7 @@ export const usePromptOptions = (
contextBlock?: ContextBlockType,
queryBlock?: QueryBlockType,
historyBlock?: HistoryBlockType,
requestURLBlock?: RequestURLBlockType,
) => {
const { t } = useTranslation()
const [editor] = useLexicalComposerContext()
@ -91,6 +95,30 @@ export const usePromptOptions = (
)
}
if (requestURLBlock?.show) {
promptOptions.push(new PickerBlockMenuOption({
key: t('promptEditor.requestURL.item.title', { ns: 'common' }),
group: 'request URL',
render: ({ isSelected, onSelect, onSetHighlight }) => {
return (
<PromptMenuItem
title={t('promptEditor.requestURL.item.title', { ns: 'common' })}
icon={<RiGlobalLine className="h-4 w-4 text-util-colors-violet-violet-600" />}
disabled={!requestURLBlock.selectable}
isSelected={isSelected}
onClick={onSelect}
onMouseEnter={onSetHighlight}
/>
)
},
onSelect: () => {
if (!requestURLBlock?.selectable)
return
editor.dispatchCommand(INSERT_REQUEST_URL_BLOCK_COMMAND, undefined)
},
}))
}
if (historyBlock?.show) {
promptOptions.push(
new PickerBlockMenuOption({
@ -272,12 +300,13 @@ export const useOptions = (
variableBlock?: VariableBlockType,
externalToolBlockType?: ExternalToolBlockType,
workflowVariableBlockType?: WorkflowVariableBlockType,
requestURLBlock?: RequestURLBlockType,
currentBlockType?: CurrentBlockType,
errorMessageBlockType?: ErrorMessageBlockType,
lastRunBlockType?: LastRunBlockType,
queryString?: string,
) => {
const promptOptions = usePromptOptions(contextBlock, queryBlock, historyBlock)
const promptOptions = usePromptOptions(contextBlock, queryBlock, historyBlock, requestURLBlock)
const variableOptions = useVariableOptions(variableBlock, queryString)
const externalToolOptions = useExternalToolOptions(externalToolBlockType, queryString)

View File

@ -8,6 +8,7 @@ import type {
HistoryBlockType,
LastRunBlockType,
QueryBlockType,
RequestURLBlockType,
VariableBlockType,
WorkflowVariableBlockType,
} from '../../types'
@ -44,6 +45,7 @@ type ComponentPickerProps = {
triggerString: string
contextBlock?: ContextBlockType
queryBlock?: QueryBlockType
requestURLBlock?: RequestURLBlockType
historyBlock?: HistoryBlockType
variableBlock?: VariableBlockType
externalToolBlock?: ExternalToolBlockType
@ -57,6 +59,7 @@ const ComponentPicker = ({
triggerString,
contextBlock,
queryBlock,
requestURLBlock,
historyBlock,
variableBlock,
externalToolBlock,
@ -100,6 +103,7 @@ const ComponentPicker = ({
variableBlock,
externalToolBlock,
workflowVariableBlock,
requestURLBlock,
currentBlock,
errorMessageBlock,
lastRunBlock,