From dae2e3b6fb8668b2f8c88395fd6f8d3272a32594 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 6 Feb 2026 17:51:58 +0800 Subject: [PATCH 1/3] feat: support choose var in tool config in sandbox prompt editor --- .../components/base/prompt-editor/index.tsx | 30 ++++++++++++++++--- .../nodes/_base/components/prompt/editor.tsx | 1 + .../nodes/llm/components/config-prompt.tsx | 1 + .../plugins/tool-block/component.tsx | 5 +++- .../plugins/tool-block/tool-block-context.tsx | 4 +++ .../tool-block/tool-group-block-component.tsx | 5 +++- .../tool-setting/tool-settings-section.tsx | 22 ++++++++++---- web/eslint-suppressions.json | 2 +- 8 files changed, 57 insertions(+), 13 deletions(-) diff --git a/web/app/components/base/prompt-editor/index.tsx b/web/app/components/base/prompt-editor/index.tsx index 3169b7098f..80e83ec048 100644 --- a/web/app/components/base/prompt-editor/index.tsx +++ b/web/app/components/base/prompt-editor/index.tsx @@ -16,6 +16,8 @@ import type { VariableBlockType, WorkflowVariableBlockType, } from './types' +import type { Node } from '@/app/components/workflow/types' +import type { EventPayload } from '@/context/event-emitter' import { CodeNode } from '@lexical/code' import { LexicalComposer } from '@lexical/react/LexicalComposer' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' @@ -52,12 +54,12 @@ import { UPDATE_HISTORY_EVENT_EMITTER, } from './constants' import ComponentPickerBlock from './plugins/component-picker-block' + import { ContextBlock, ContextBlockNode, ContextBlockReplacementBlock, } from './plugins/context-block' - import { CurrentBlock, CurrentBlockNode, @@ -153,6 +155,7 @@ const EnterCommandPlugin: FC<{ onEnter?: (event: KeyboardEvent) => void }> = ({ export type PromptEditorProps = { instanceId?: string + nodeId?: string compact?: boolean wrapperClassName?: string className?: string @@ -184,6 +187,7 @@ export type PromptEditorProps = { const PromptEditor: FC = ({ instanceId, + nodeId, compact, wrapperClassName, className, @@ -251,15 +255,30 @@ const PromptEditor: FC = ({ eventEmitter?.emit({ type: UPDATE_DATASETS_EVENT_EMITTER, payload: contextBlock?.datasets, - } as any) + } as EventPayload) }, [eventEmitter, contextBlock?.datasets]) useEffect(() => { eventEmitter?.emit({ type: UPDATE_HISTORY_EVENT_EMITTER, payload: historyBlock?.history, - } as any) + } as EventPayload) }, [eventEmitter, historyBlock?.history]) + const availableNodes = React.useMemo(() => { + if (!workflowVariableBlock?.workflowNodesMap) + return undefined + return Object.entries(workflowVariableBlock.workflowNodesMap).map(([id, data]) => ({ + id, + data: { + title: data.title, + type: data.type, + } as any, + position: data.position ?? { x: 0, y: 0 }, + width: data.width, + height: data.height, + })) as Node[] + }, [workflowVariableBlock?.workflowNodesMap]) + const toolBlockContextValue = React.useMemo(() => { if (!onToolMetadataChange) return null @@ -267,8 +286,11 @@ const PromptEditor: FC = ({ metadata: toolMetadata, onMetadataChange: onToolMetadataChange, useModal: true, + nodeId, + nodesOutputVars: workflowVariableBlock?.variables, + availableNodes, } - }, [onToolMetadataChange, toolMetadata]) + }, [availableNodes, nodeId, onToolMetadataChange, toolMetadata, workflowVariableBlock?.variables]) const sandboxPlaceHolder = React.useMemo(() => { if (!isSupportSandbox) diff --git a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx index fa2cfb9ca9..1887e2394e 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx @@ -267,6 +267,7 @@ const Editor: FC = ({ placeholder={placeholder} placeholderClassName={placeholderClassName} instanceId={instanceId} + nodeId={nodeId} compact className={cn('min-h-[56px]', inputClassName)} style={isExpand ? { height: editorExpandHeight - 5 } : {}} diff --git a/web/app/components/workflow/nodes/llm/components/config-prompt.tsx b/web/app/components/workflow/nodes/llm/components/config-prompt.tsx index 523dd779e1..aebe8734dd 100644 --- a/web/app/components/workflow/nodes/llm/components/config-prompt.tsx +++ b/web/app/components/workflow/nodes/llm/components/config-prompt.tsx @@ -419,6 +419,7 @@ const ConfigPrompt: FC = ({
{t(`${i18nPrefix}.prompt`, { ns: 'workflow' })}} value={((payload as PromptItem).edition_type === EditionType.basic || !(payload as PromptItem).edition_type) ? (payload as PromptItem).text : ((payload as PromptItem).jinja2_text || '')} onChange={handleCompletionPromptChange} diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx index 475c8727ff..3c30291ced 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx @@ -535,7 +535,10 @@ const ToolBlockComponent = ({ currentTool={currentTool} value={toolValue} onChange={handleToolValueChange} - nodeId={undefined} + nodeId={toolBlockContext?.nodeId} + nodesOutputVars={toolBlockContext?.nodesOutputVars} + availableNodes={toolBlockContext?.availableNodes} + enableVariableReference={useModal} /> {readmeEntrance}
diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-block-context.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-block-context.tsx index 487eab7f19..c0f3d23b65 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-block-context.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-block-context.tsx @@ -1,9 +1,13 @@ +import type { Node, NodeOutPutVar } from '@/app/components/workflow/types' import { createContext, useContext } from 'react' type ToolBlockContextValue = { metadata?: Record onMetadataChange?: (metadata: Record) => void useModal?: boolean + nodeId?: string + nodesOutputVars?: NodeOutPutVar[] + availableNodes?: Node[] } const ToolBlockContext = createContext(null) diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-group-block-component.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-group-block-component.tsx index fa646b2573..4836b5fa99 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-group-block-component.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-group-block-component.tsx @@ -611,7 +611,10 @@ const ToolGroupBlockComponent = ({ currentTool={currentTool} value={toolValue} onChange={handleToolValueChange} - nodeId={undefined} + nodeId={toolBlockContext?.nodeId} + nodesOutputVars={toolBlockContext?.nodesOutputVars} + availableNodes={toolBlockContext?.availableNodes} + enableVariableReference={useModal} /> ) diff --git a/web/app/components/workflow/skill/editor/skill-editor/tool-setting/tool-settings-section.tsx b/web/app/components/workflow/skill/editor/skill-editor/tool-setting/tool-settings-section.tsx index c18db03580..e9d1571788 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/tool-setting/tool-settings-section.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/tool-setting/tool-settings-section.tsx @@ -2,7 +2,7 @@ import type { Tool } from '@/app/components/tools/types' import type { ToolValue } from '@/app/components/workflow/block-selector/types' -import type { ToolWithProvider } from '@/app/components/workflow/types' +import type { Node, NodeOutPutVar, ToolWithProvider } from '@/app/components/workflow/types' import * as React from 'react' import { useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -34,6 +34,9 @@ type ToolSettingsSectionProps = { currentTool?: Tool value?: ToolValue nodeId?: string + nodesOutputVars?: NodeOutPutVar[] + availableNodes?: Node[] + enableVariableReference?: boolean onChange?: (value: ToolValue) => void } @@ -42,10 +45,13 @@ const ToolSettingsSection = ({ currentTool, value, nodeId, + nodesOutputVars, + availableNodes, + enableVariableReference = false, onChange, }: ToolSettingsSectionProps) => { const { t } = useTranslation() - const safeNodeId = nodeId ?? '' + const resolvedNodeId = enableVariableReference ? (nodeId || 'workflow') : undefined const currentToolSettings = useMemo(() => { if (!currentTool) @@ -144,8 +150,10 @@ const ToolSettingsSection = ({ value={getSafeConfigValue(value?.settings as ToolConfigValueMap, settingsFormSchemas)} onChange={handleSettingsFormChange} schemas={settingsFormSchemas} - nodeId={safeNodeId} - disableVariableReference + nodeId={resolvedNodeId} + nodeOutputVars={nodesOutputVars} + availableNodes={availableNodes} + disableVariableReference={!enableVariableReference} /> )} {showParamsSection && ( @@ -153,8 +161,10 @@ const ToolSettingsSection = ({ value={getSafeConfigValue(value?.parameters as ToolConfigValueMap, paramsFormSchemas)} onChange={handleParamsFormChange} schemas={paramsFormSchemas} - nodeId={safeNodeId} - disableVariableReference + nodeId={resolvedNodeId} + nodeOutputVars={nodesOutputVars} + availableNodes={availableNodes} + disableVariableReference={!enableVariableReference} /> )} diff --git a/web/eslint-suppressions.json b/web/eslint-suppressions.json index 7afb782443..d2332d54a4 100644 --- a/web/eslint-suppressions.json +++ b/web/eslint-suppressions.json @@ -1429,7 +1429,7 @@ }, "app/components/base/prompt-editor/index.tsx": { "ts/no-explicit-any": { - "count": 2 + "count": 1 } }, "app/components/base/prompt-editor/plugins/component-picker-block/index.tsx": { From 776fb04bf0b098db6664327f341697aa2d186133 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 6 Feb 2026 18:10:32 +0800 Subject: [PATCH 2/3] chore: use more good availableNodes --- .../components/base/prompt-editor/index.tsx | 23 ++++++------------- web/eslint-suppressions.json | 5 ---- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/web/app/components/base/prompt-editor/index.tsx b/web/app/components/base/prompt-editor/index.tsx index 80e83ec048..e4a97c163f 100644 --- a/web/app/components/base/prompt-editor/index.tsx +++ b/web/app/components/base/prompt-editor/index.tsx @@ -16,7 +16,6 @@ import type { VariableBlockType, WorkflowVariableBlockType, } from './types' -import type { Node } from '@/app/components/workflow/types' import type { EventPayload } from '@/context/event-emitter' import { CodeNode } from '@lexical/code' import { LexicalComposer } from '@lexical/react/LexicalComposer' @@ -49,12 +48,13 @@ import { ToolBlockContextProvider } from '@/app/components/workflow/skill/editor import ToolPickerBlock from '@/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/tool-picker-block' import { useEventEmitterContextContext } from '@/context/event-emitter' import { cn } from '@/utils/classnames' +import { useWorkflow } from '../../workflow/hooks' import { UPDATE_DATASETS_EVENT_EMITTER, UPDATE_HISTORY_EVENT_EMITTER, } from './constants' -import ComponentPickerBlock from './plugins/component-picker-block' +import ComponentPickerBlock from './plugins/component-picker-block' import { ContextBlock, ContextBlockNode, @@ -264,20 +264,11 @@ const PromptEditor: FC = ({ } as EventPayload) }, [eventEmitter, historyBlock?.history]) - const availableNodes = React.useMemo(() => { - if (!workflowVariableBlock?.workflowNodesMap) - return undefined - return Object.entries(workflowVariableBlock.workflowNodesMap).map(([id, data]) => ({ - id, - data: { - title: data.title, - type: data.type, - } as any, - position: data.position ?? { x: 0, y: 0 }, - width: data.width, - height: data.height, - })) as Node[] - }, [workflowVariableBlock?.workflowNodesMap]) + const { getBeforeNodesInSameBranch } = useWorkflow() + const availableNodes = React.useMemo( + () => nodeId && isSupportSandbox ? getBeforeNodesInSameBranch(nodeId || '') : [], + [getBeforeNodesInSameBranch, isSupportSandbox, nodeId], + ) const toolBlockContextValue = React.useMemo(() => { if (!onToolMetadataChange) diff --git a/web/eslint-suppressions.json b/web/eslint-suppressions.json index d2332d54a4..e5056a9205 100644 --- a/web/eslint-suppressions.json +++ b/web/eslint-suppressions.json @@ -1427,11 +1427,6 @@ "count": 2 } }, - "app/components/base/prompt-editor/index.tsx": { - "ts/no-explicit-any": { - "count": 1 - } - }, "app/components/base/prompt-editor/plugins/component-picker-block/index.tsx": { "ts/no-explicit-any": { "count": 1 From c5439a37398a554654235be85ba8b83d96cd86a8 Mon Sep 17 00:00:00 2001 From: Joel Date: Fri, 6 Feb 2026 18:35:01 +0800 Subject: [PATCH 3/3] fix: tool icon hover --- .../editor/skill-editor/plugins/tool-block/component.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx index 3c30291ced..bcb33fe74c 100644 --- a/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx +++ b/web/app/components/workflow/skill/editor/skill-editor/plugins/tool-block/component.tsx @@ -368,12 +368,12 @@ const ToolBlockComponent = ({ className={cn( 'hidden size-[14px]', needAuthorization ? 'text-text-warning' : 'text-text-accent', - isInteractive && 'group-hover:block', + isInteractive && 'group-hover/tool:block', )} /> ) const normalIcon = ( - + {iconNode} ) @@ -549,7 +549,7 @@ const ToolBlockComponent = ({