diff --git a/web/app/components/workflow/nodes/code/use-config.ts b/web/app/components/workflow/nodes/code/use-config.ts index fdb1c8ce51..2655dd1d43 100644 --- a/web/app/components/workflow/nodes/code/use-config.ts +++ b/web/app/components/workflow/nodes/code/use-config.ts @@ -56,17 +56,21 @@ const useConfig = (id: string, payload: CodeNodeType) => { setInputs, }) - const [outputKeyOrders, setOutputKeyOrders] = useState([]) + const [outputKeyOrders, setOutputKeyOrders] = useState(() => Object.keys(payload.outputs || {})) const syncOutputKeyOrders = useCallback((outputs: OutputVar) => { setOutputKeyOrders(Object.keys(outputs)) }, []) useEffect(() => { - if (inputs.code) { - if (inputs.outputs && Object.keys(inputs.outputs).length > 0) - syncOutputKeyOrders(inputs.outputs) + const outputKeys = inputs.outputs ? Object.keys(inputs.outputs) : [] + if (outputKeys.length > 0 && outputKeyOrders.length === 0) + syncOutputKeyOrders(inputs.outputs) + const hasExistingConfig = Boolean(inputs.code) + || (inputs.variables?.length ?? 0) > 0 + || outputKeys.length > 0 + + if (hasExistingConfig) return - } const isReady = defaultConfig && Object.keys(defaultConfig).length > 0 if (isReady) { @@ -76,7 +80,7 @@ const useConfig = (id: string, payload: CodeNodeType) => { }) syncOutputKeyOrders(defaultConfig.outputs) } - }, [defaultConfig]) + }, [defaultConfig, inputs.code, inputs.outputs, inputs.variables, outputKeyOrders.length, setInputs, syncOutputKeyOrders]) const handleCodeChange = useCallback((code: string) => { const newInputs = produce(inputs, (draft) => { diff --git a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx index 1527a27178..703559a2ee 100644 --- a/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx +++ b/web/app/components/workflow/nodes/tool/components/mixed-variable-text-input/index.tsx @@ -334,6 +334,14 @@ const MixedVariableTextInput = ({ return detectAgentFromText(value) }, [detectAgentFromText, value]) + // Check if value only contains agent context variable without other user input + const isOnlyAgentContext = useMemo(() => { + if (!detectedAgentFromValue || !value) + return false + const valueWithoutAgentContext = value.replace(AGENT_CONTEXT_VAR_PATTERN, '').trim() + return valueWithoutAgentContext === '' + }, [detectedAgentFromValue, value]) + const agentNodes = useMemo(() => { if (!contextNodeIds.size) return [] @@ -574,39 +582,48 @@ const MixedVariableTextInput = ({ /> )} {!isAssembleValue && ( - 0 && !detectedAgentFromValue, - agentNodes, - onSelect: handleAgentSelect, - }} - placeholder={} - onChange={(text) => { - const hasPlaceholder = new RegExp(AGENT_CONTEXT_VAR_PATTERN.source).test(text) - if (hasPlaceholder) - syncExtractorPromptFromText(text) - if (detectedAgentFromValue && !hasPlaceholder) { - removeExtractorNode() - onChange?.(text, VarKindTypeEnum.mixed, null) - return - } - onChange?.(text) - }} - /> +
+ 0 && !detectedAgentFromValue, + agentNodes, + onSelect: handleAgentSelect, + }} + placeholder={} + onChange={(text) => { + const hasPlaceholder = new RegExp(AGENT_CONTEXT_VAR_PATTERN.source).test(text) + if (hasPlaceholder) + syncExtractorPromptFromText(text) + if (detectedAgentFromValue && !hasPlaceholder) { + removeExtractorNode() + onChange?.(text, VarKindTypeEnum.mixed, null) + return + } + onChange?.(text) + }} + /> + {isOnlyAgentContext && paramKey && ( +
+ + {t('nodes.tool.agentPlaceholder', { ns: 'workflow', paramKey })} + +
+ )} +
)} {toolNodeId && paramKey && isAssembleValue && (