mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 18:08:07 +08:00
refactor: rename mention node to nested_node for generic sub-graph support
This commit is contained in:
@ -21,8 +21,8 @@ export type ContextGenerateChatMessage = ContextGenerateMessage & {
|
||||
|
||||
const defaultCompletionParams: CompletionParams = {
|
||||
temperature: 0.7,
|
||||
max_tokens: 0,
|
||||
top_p: 0,
|
||||
max_tokens: 4096,
|
||||
top_p: 0.1,
|
||||
echo: false,
|
||||
stop: [],
|
||||
presence_penalty: 0,
|
||||
|
||||
@ -12,7 +12,7 @@ import { useCallback, useMemo } from 'react'
|
||||
import { Type } from '@/app/components/workflow/nodes/llm/types'
|
||||
import { BlockEnum, EditionType, isPromptMessageContext, PromptRole, VarType } from '@/app/components/workflow/types'
|
||||
import { generateNewNode, getNodeCustomTypeByNodeDataType, mergeNodeDefaultData } from '@/app/components/workflow/utils'
|
||||
import { fetchMentionGraph } from '@/service/workflow'
|
||||
import { fetchNestedNodeGraph } from '@/service/workflow'
|
||||
import { FlowType } from '@/types/common'
|
||||
|
||||
// Constants
|
||||
@ -160,7 +160,7 @@ export function useMixedVariableExtractor({
|
||||
return `${toolNodeId}_ext_${paramKey}`
|
||||
}, [paramKey, toolNodeId])
|
||||
|
||||
const resolveMentionParameterSchema = useCallback((key: string) => {
|
||||
const resolveNestedNodeParameterSchema = useCallback((key: string) => {
|
||||
if (!toolNodeId) {
|
||||
return {
|
||||
name: key,
|
||||
@ -337,37 +337,37 @@ export function useMixedVariableExtractor({
|
||||
handleSyncWorkflowDraft()
|
||||
}, [handleSyncWorkflowDraft, paramKey, reactFlowStore, toolNodeId])
|
||||
|
||||
const applyMentionGraphNodeData = useCallback((payload: {
|
||||
const applyNestedNodeGraphData = useCallback((payload: {
|
||||
extractorNodeId: string
|
||||
mentionNodeData: Partial<LLMNodeType>
|
||||
nestedNodeData: Partial<LLMNodeType>
|
||||
valueText: string
|
||||
detectAgentFromText: (text: string) => DetectedAgent | null
|
||||
}) => {
|
||||
const { extractorNodeId, mentionNodeData, valueText, detectAgentFromText } = payload
|
||||
const { extractorNodeId, nestedNodeData, valueText, detectAgentFromText } = payload
|
||||
if (!toolNodeId)
|
||||
return
|
||||
const hasPromptTemplate = Array.isArray(mentionNodeData.prompt_template)
|
||||
? mentionNodeData.prompt_template.length > 0
|
||||
: Boolean(mentionNodeData.prompt_template)
|
||||
const hasPromptTemplate = Array.isArray(nestedNodeData.prompt_template)
|
||||
? nestedNodeData.prompt_template.length > 0
|
||||
: Boolean(nestedNodeData.prompt_template)
|
||||
const nextData: Partial<LLMNodeType> = {}
|
||||
if (mentionNodeData.title)
|
||||
nextData.title = mentionNodeData.title
|
||||
if (mentionNodeData.desc)
|
||||
nextData.desc = mentionNodeData.desc
|
||||
if (mentionNodeData.model && (mentionNodeData.model.provider || mentionNodeData.model.name))
|
||||
nextData.model = mentionNodeData.model
|
||||
if (nestedNodeData.title)
|
||||
nextData.title = nestedNodeData.title
|
||||
if (nestedNodeData.desc)
|
||||
nextData.desc = nestedNodeData.desc
|
||||
if (nestedNodeData.model && (nestedNodeData.model.provider || nestedNodeData.model.name))
|
||||
nextData.model = nestedNodeData.model
|
||||
if (hasPromptTemplate)
|
||||
nextData.prompt_template = mentionNodeData.prompt_template
|
||||
if (typeof mentionNodeData.structured_output_enabled === 'boolean')
|
||||
nextData.structured_output_enabled = mentionNodeData.structured_output_enabled
|
||||
if (mentionNodeData.structured_output?.schema)
|
||||
nextData.structured_output = mentionNodeData.structured_output
|
||||
if (mentionNodeData.context)
|
||||
nextData.context = mentionNodeData.context
|
||||
if (mentionNodeData.vision)
|
||||
nextData.vision = mentionNodeData.vision
|
||||
if (Object.prototype.hasOwnProperty.call(mentionNodeData, 'memory'))
|
||||
nextData.memory = mentionNodeData.memory
|
||||
nextData.prompt_template = nestedNodeData.prompt_template
|
||||
if (typeof nestedNodeData.structured_output_enabled === 'boolean')
|
||||
nextData.structured_output_enabled = nestedNodeData.structured_output_enabled
|
||||
if (nestedNodeData.structured_output?.schema)
|
||||
nextData.structured_output = nestedNodeData.structured_output
|
||||
if (nestedNodeData.context)
|
||||
nextData.context = nestedNodeData.context
|
||||
if (nestedNodeData.vision)
|
||||
nextData.vision = nestedNodeData.vision
|
||||
if (Object.prototype.hasOwnProperty.call(nestedNodeData, 'memory'))
|
||||
nextData.memory = nestedNodeData.memory
|
||||
|
||||
if (Object.keys(nextData).length === 0)
|
||||
return
|
||||
@ -396,7 +396,7 @@ export function useMixedVariableExtractor({
|
||||
syncExtractorPromptFromText(valueText, detectAgentFromText)
|
||||
}, [handleSyncWorkflowDraft, reactFlowStore, syncExtractorPromptFromText, toolNodeId])
|
||||
|
||||
const requestMentionGraph = useCallback(async (payload: {
|
||||
const requestNestedNodeGraph = useCallback(async (payload: {
|
||||
agentId: string
|
||||
extractorNodeId: string
|
||||
valueText: string
|
||||
@ -406,28 +406,28 @@ export function useMixedVariableExtractor({
|
||||
return
|
||||
if (!configsMap?.flowId || configsMap.flowType !== FlowType.appFlow)
|
||||
return
|
||||
const parameterSchema = resolveMentionParameterSchema(paramKey)
|
||||
const parameterSchema = resolveNestedNodeParameterSchema(paramKey)
|
||||
try {
|
||||
const response = await fetchMentionGraph(configsMap.flowType, configsMap.flowId, {
|
||||
const response = await fetchNestedNodeGraph(configsMap.flowType, configsMap.flowId, {
|
||||
parent_node_id: toolNodeId,
|
||||
parameter_key: paramKey,
|
||||
context_source: [payload.agentId, 'context'],
|
||||
parameter_schema: parameterSchema,
|
||||
})
|
||||
const mentionNode = response?.graph?.nodes?.find(node => node.id === payload.extractorNodeId)
|
||||
const mentionNodeData = mentionNode?.data as Partial<LLMNodeType> | undefined
|
||||
if (!mentionNodeData)
|
||||
const nestedNode = response?.graph?.nodes?.find(node => node.id === payload.extractorNodeId)
|
||||
const nestedNodeData = nestedNode?.data as Partial<LLMNodeType> | undefined
|
||||
if (!nestedNodeData)
|
||||
return
|
||||
applyMentionGraphNodeData({
|
||||
applyNestedNodeGraphData({
|
||||
extractorNodeId: payload.extractorNodeId,
|
||||
mentionNodeData,
|
||||
nestedNodeData,
|
||||
valueText: payload.valueText,
|
||||
detectAgentFromText: payload.detectAgentFromText,
|
||||
})
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}, [applyMentionGraphNodeData, configsMap?.flowId, configsMap?.flowType, paramKey, resolveMentionParameterSchema, toolNodeId])
|
||||
}, [applyNestedNodeGraphData, configsMap?.flowId, configsMap?.flowType, paramKey, resolveNestedNodeParameterSchema, toolNodeId])
|
||||
|
||||
return {
|
||||
assembleExtractorNodeId,
|
||||
@ -435,6 +435,6 @@ export function useMixedVariableExtractor({
|
||||
ensureAssembleExtractorNode,
|
||||
removeExtractorNode,
|
||||
syncExtractorPromptFromText,
|
||||
requestMentionGraph,
|
||||
requestNestedNodeGraph,
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ import type { ContextGenerateModalHandle } from '../context-generate-modal'
|
||||
import type { DetectedAgent } from './hooks'
|
||||
import type { AgentNode, WorkflowVariableBlockType } from '@/app/components/base/prompt-editor/types'
|
||||
import type { StrategyDetail, StrategyPluginDetail } from '@/app/components/plugins/types'
|
||||
import type { MentionConfig, VarKindType } from '@/app/components/workflow/nodes/_base/types'
|
||||
import type { NestedNodeConfig, VarKindType } from '@/app/components/workflow/nodes/_base/types'
|
||||
import type { AgentNodeType } from '@/app/components/workflow/nodes/agent/types'
|
||||
import type {
|
||||
CommonNodeType,
|
||||
@ -41,7 +41,7 @@ import {
|
||||
|
||||
type WorkflowNodesMap = NonNullable<WorkflowVariableBlockType['workflowNodesMap']>
|
||||
|
||||
const DEFAULT_MENTION_CONFIG: MentionConfig = {
|
||||
const DEFAULT_NESTED_NODE_CONFIG: NestedNodeConfig = {
|
||||
extractor_node_id: '',
|
||||
output_selector: [],
|
||||
null_strategy: 'use_default',
|
||||
@ -60,7 +60,7 @@ type MixedVariableTextInputProps = {
|
||||
nodesOutputVars?: NodeOutPutVar[]
|
||||
availableNodes?: WorkflowNode[]
|
||||
value?: string
|
||||
onChange?: (text: string, type?: VarKindType, mentionConfig?: MentionConfig | null) => void
|
||||
onChange?: (text: string, type?: VarKindType, nestedNodeConfig?: NestedNodeConfig | null) => void
|
||||
showManageInputField?: boolean
|
||||
onManageInputField?: () => void
|
||||
disableVariableInsertion?: boolean
|
||||
@ -134,7 +134,7 @@ const MixedVariableTextInput = ({
|
||||
ensureAssembleExtractorNode,
|
||||
removeExtractorNode,
|
||||
syncExtractorPromptFromText,
|
||||
requestMentionGraph,
|
||||
requestNestedNodeGraph,
|
||||
} = useMixedVariableExtractor({
|
||||
toolNodeId,
|
||||
paramKey,
|
||||
@ -297,22 +297,22 @@ const MixedVariableTextInput = ({
|
||||
})
|
||||
}
|
||||
|
||||
const mentionConfigWithOutputSelector: MentionConfig = {
|
||||
...DEFAULT_MENTION_CONFIG,
|
||||
const nestedNodeConfigWithOutputSelector: NestedNodeConfig = {
|
||||
...DEFAULT_NESTED_NODE_CONFIG,
|
||||
extractor_node_id: extractorNodeId,
|
||||
output_selector: paramKey ? ['structured_output', paramKey] : [],
|
||||
}
|
||||
onChange(newValue, VarKindTypeEnum.mention, mentionConfigWithOutputSelector)
|
||||
onChange(newValue, VarKindTypeEnum.nested_node, nestedNodeConfigWithOutputSelector)
|
||||
syncExtractorPromptFromText(newValue, detectAgentFromText)
|
||||
if (extractorNodeId) {
|
||||
void requestMentionGraph({
|
||||
void requestNestedNodeGraph({
|
||||
agentId: agent.id,
|
||||
extractorNodeId,
|
||||
valueText: newValue,
|
||||
detectAgentFromText,
|
||||
})
|
||||
}
|
||||
}, [detectAgentFromText, ensureExtractorNode, onChange, paramKey, requestMentionGraph, syncExtractorPromptFromText, toolNodeId, value])
|
||||
}, [detectAgentFromText, ensureExtractorNode, onChange, paramKey, requestNestedNodeGraph, syncExtractorPromptFromText, toolNodeId, value])
|
||||
|
||||
const handleAssembleSelect = useCallback((): ValueSelector | null => {
|
||||
if (!toolNodeId || !paramKey || !assemblePlaceholder)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { SubGraphModalProps } from './types'
|
||||
import type { MentionConfig } from '@/app/components/workflow/nodes/_base/types'
|
||||
import type { NestedNodeConfig } from '@/app/components/workflow/nodes/_base/types'
|
||||
import type { CodeNodeType } from '@/app/components/workflow/nodes/code/types'
|
||||
import type { LLMNodeType } from '@/app/components/workflow/nodes/llm/types'
|
||||
import type { ToolNodeType } from '@/app/components/workflow/nodes/tool/types'
|
||||
@ -88,8 +88,8 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
return vars.filter(nodeVar => availableNodeIds.has(nodeVar.nodeId))
|
||||
}, [getNodeAvailableVars, isChatMode, parentAvailableNodes])
|
||||
|
||||
const mentionConfig = useMemo<MentionConfig>(() => {
|
||||
const current = toolParam?.mention_config
|
||||
const nestedNodeConfig = useMemo<NestedNodeConfig>(() => {
|
||||
const current = toolParam?.nested_node_config
|
||||
const rawSelector = Array.isArray(current?.output_selector) ? current!.output_selector : []
|
||||
const outputSelector = rawSelector[0] === extractorNodeId ? rawSelector.slice(1) : rawSelector
|
||||
const defaultOutputSelector = ['structured_output', paramKey]
|
||||
@ -100,9 +100,9 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
null_strategy: current?.null_strategy || 'use_default',
|
||||
default_value: current?.default_value ?? '',
|
||||
}
|
||||
}, [extractorNodeId, paramKey, toolParam?.mention_config])
|
||||
}, [extractorNodeId, paramKey, toolParam?.nested_node_config])
|
||||
|
||||
const handleMentionConfigChange = useCallback((config: MentionConfig) => {
|
||||
const handleNestedNodeConfigChange = useCallback((config: NestedNodeConfig) => {
|
||||
if (!isAgentVariant)
|
||||
return
|
||||
|
||||
@ -124,8 +124,8 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
...toolData.tool_parameters,
|
||||
[paramKey]: {
|
||||
...currentParam,
|
||||
type: currentParam.type || VarKindType.mention,
|
||||
mention_config: config,
|
||||
type: currentParam.type || VarKindType.nested_node,
|
||||
nested_node_config: config,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -136,18 +136,18 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
}, [handleSyncWorkflowDraft, isAgentVariant, paramKey, reactflowStore, toolNodeId])
|
||||
|
||||
useEffect(() => {
|
||||
if (!isAgentVariant || !toolParam || (toolParam.type && toolParam.type !== VarKindType.mention))
|
||||
if (!isAgentVariant || !toolParam || (toolParam.type && toolParam.type !== VarKindType.nested_node))
|
||||
return
|
||||
|
||||
const current = toolParam.mention_config
|
||||
const current = toolParam.nested_node_config
|
||||
const needsExtractor = !current?.extractor_node_id
|
||||
const needsNullStrategy = !current?.null_strategy
|
||||
const needsOutputSelector = !Array.isArray(current?.output_selector)
|
||||
const needsDefaultValue = current?.default_value === undefined
|
||||
|
||||
if (needsExtractor || needsNullStrategy || needsOutputSelector || needsDefaultValue)
|
||||
handleMentionConfigChange(mentionConfig)
|
||||
}, [handleMentionConfigChange, isAgentVariant, mentionConfig, toolParam])
|
||||
handleNestedNodeConfigChange(nestedNodeConfig)
|
||||
}, [handleNestedNodeConfigChange, isAgentVariant, nestedNodeConfig, toolParam])
|
||||
|
||||
const getUserPromptText = useCallback((promptTemplate?: PromptTemplateItem[] | PromptItem) => {
|
||||
if (!promptTemplate)
|
||||
@ -281,8 +281,8 @@ const SubGraphModal: FC<SubGraphModalProps> = (props) => {
|
||||
agentNodeId={props.agentNodeId}
|
||||
agentName={props.agentName}
|
||||
configsMap={configsMap}
|
||||
mentionConfig={mentionConfig}
|
||||
onMentionConfigChange={handleMentionConfigChange}
|
||||
nestedNodeConfig={nestedNodeConfig}
|
||||
onNestedNodeConfigChange={handleNestedNodeConfigChange}
|
||||
extractorNode={extractorNode as Node<LLMNodeType> | undefined}
|
||||
toolParamValue={toolParamValue}
|
||||
parentAvailableNodes={parentAvailableNodes}
|
||||
|
||||
@ -77,7 +77,7 @@ const Node: FC<NodeProps<ToolNodeType>> = ({
|
||||
}, {} as Record<string, WorkflowNode>)
|
||||
}, [nodes])
|
||||
|
||||
const mentionEntries = useMemo(() => {
|
||||
const nestedNodeEntries = useMemo(() => {
|
||||
const entries: Array<{ agentNodeId: string, extractorNodeId?: string, paramKey: string }> = []
|
||||
const seen = new Set<string>()
|
||||
const toolParams = data.tool_parameters || {}
|
||||
@ -97,8 +97,8 @@ const Node: FC<NodeProps<ToolNodeType>> = ({
|
||||
entries.push({
|
||||
agentNodeId,
|
||||
paramKey,
|
||||
extractorNodeId: param?.mention_config?.extractor_node_id
|
||||
|| (param?.type === VarType.mention ? `${id}_ext_${paramKey}` : undefined),
|
||||
extractorNodeId: param?.nested_node_config?.extractor_node_id
|
||||
|| (param?.type === VarType.nested_node ? `${id}_ext_${paramKey}` : undefined),
|
||||
})
|
||||
}
|
||||
})
|
||||
@ -106,7 +106,7 @@ const Node: FC<NodeProps<ToolNodeType>> = ({
|
||||
}, [data.tool_parameters, id])
|
||||
|
||||
const referenceItems = useMemo(() => {
|
||||
if (!mentionEntries.length)
|
||||
if (!nestedNodeEntries.length)
|
||||
return []
|
||||
|
||||
const getNodeWarning = (node?: WorkflowNode) => {
|
||||
@ -132,7 +132,7 @@ const Node: FC<NodeProps<ToolNodeType>> = ({
|
||||
return Boolean(errorMessage)
|
||||
}
|
||||
|
||||
return mentionEntries.map(({ agentNodeId, extractorNodeId, paramKey }) => {
|
||||
return nestedNodeEntries.map(({ agentNodeId, extractorNodeId, paramKey }) => {
|
||||
const agentNode = nodesById[agentNodeId]
|
||||
const agentLabel = `@${agentNode?.data.title || agentNodeId}`
|
||||
const agentWarning = getNodeWarning(agentNode)
|
||||
@ -148,7 +148,7 @@ const Node: FC<NodeProps<ToolNodeType>> = ({
|
||||
hasWarning,
|
||||
}
|
||||
})
|
||||
}, [mentionEntries, nodesById, nodesMetaDataMap, strategyProviders, language, t])
|
||||
}, [nestedNodeEntries, nodesById, nodesMetaDataMap, strategyProviders, language, t])
|
||||
|
||||
const hasConfigs = toolConfigs.length > 0
|
||||
const hasReferences = referenceItems.length > 0
|
||||
|
||||
@ -32,7 +32,7 @@ const useSingleRunFormParams = ({
|
||||
const { inputs } = useNodeCrud<ToolNodeType>(id, payload)
|
||||
|
||||
const hadVarParams = Object.keys(inputs.tool_parameters)
|
||||
.filter(key => ![VarType.constant, VarType.mention].includes(inputs.tool_parameters[key].type))
|
||||
.filter(key => ![VarType.constant, VarType.nested_node].includes(inputs.tool_parameters[key].type))
|
||||
.map(k => inputs.tool_parameters[k])
|
||||
|
||||
const hadVarSettings = Object.keys(inputs.tool_configurations)
|
||||
|
||||
Reference in New Issue
Block a user