diff --git a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx index 4714139541..40614dec31 100644 --- a/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx +++ b/web/app/components/workflow/nodes/_base/components/editor/code-editor/index.tsx @@ -26,6 +26,8 @@ export type Props = { value?: string | object placeholder?: React.JSX.Element | string onChange?: (value: string) => void + onBlur?: () => void + onFocus?: () => void title?: string | React.JSX.Element language: CodeLanguage headerRight?: React.JSX.Element @@ -55,6 +57,8 @@ const CodeEditor: FC = ({ value = '', placeholder = '', onChange = noop, + onBlur, + onFocus, title = '', headerRight, language, @@ -109,9 +113,11 @@ const CodeEditor: FC = ({ editor.onDidFocusEditorText(() => { setIsFocus(true) + onFocus?.() }) editor.onDidBlurEditorText(() => { setIsFocus(false) + onBlur?.() }) monaco.editor.setTheme(appTheme === Theme.light ? 'light' : 'vs-dark') // Fix: sometimes not load the default theme 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 33d78032bd..37451149c5 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx @@ -83,6 +83,8 @@ type Props = { placeholderClassName?: string titleClassName?: string required?: boolean + onBlur?: () => void + onFocus?: () => void } const Editor: FC = ({ @@ -125,6 +127,8 @@ const Editor: FC = ({ titleClassName, editorContainerClassName, required, + onBlur, + onFocus, }) => { const { t } = useTranslation() const { eventEmitter } = useEventEmitterContextContext() @@ -297,8 +301,14 @@ const Editor: FC = ({ onManageInputField: () => setShowInputFieldPanel?.(true), }} onChange={onChange} - onBlur={setBlur} - onFocus={setFocus} + onBlur={() => { + setBlur() + onBlur?.() + }} + onFocus={() => { + setFocus() + onFocus?.() + }} editable={!readOnly} isSupportFileVar={isSupportFileVar} isSupportSandbox={isSupportSandbox} @@ -323,6 +333,8 @@ const Editor: FC = ({ noWrapper isExpand={isExpand} className={inputClassName} + onBlur={onBlur} + onFocus={onFocus} /> )} diff --git a/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx b/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx index 28a07fb09e..f27cb2731c 100644 --- a/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/computer-use-config.tsx @@ -17,6 +17,7 @@ type Props = { onChange: (enabled: boolean) => void nodeId: string toolSettings?: ToolSetting[] + promptTemplateKey: string } const ComputerUseConfig: FC = ({ @@ -25,6 +26,7 @@ const ComputerUseConfig: FC = ({ onChange, nodeId, toolSettings, + promptTemplateKey, }) => { const { t } = useTranslation() @@ -64,6 +66,7 @@ const ComputerUseConfig: FC = ({ enabled={enabled} nodeId={nodeId} toolSettings={toolSettings} + promptTemplateKey={promptTemplateKey} /> diff --git a/web/app/components/workflow/nodes/llm/components/config-prompt-item.tsx b/web/app/components/workflow/nodes/llm/components/config-prompt-item.tsx index 7b843ec816..69b30f94e8 100644 --- a/web/app/components/workflow/nodes/llm/components/config-prompt-item.tsx +++ b/web/app/components/workflow/nodes/llm/components/config-prompt-item.tsx @@ -42,6 +42,7 @@ type Props = { handleAddVariable: (payload: any) => void modelConfig?: ModelConfig isSupportSandbox?: boolean + onPromptEditorBlur?: () => void } const roleOptions = [ @@ -86,6 +87,7 @@ const ConfigPromptItem: FC = ({ handleAddVariable, modelConfig, isSupportSandbox, + onPromptEditorBlur, }) => { const { t } = useTranslation() const workflowStore = useWorkflowStore() @@ -156,6 +158,7 @@ const ConfigPromptItem: FC = ({ handleAddVariable={handleAddVariable} isSupportFileVar isSupportSandbox={isSupportSandbox} + onBlur={onPromptEditorBlur} /> ) } 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 f6306bddce..36c6b763c1 100644 --- a/web/app/components/workflow/nodes/llm/components/config-prompt.tsx +++ b/web/app/components/workflow/nodes/llm/components/config-prompt.tsx @@ -65,6 +65,7 @@ type Props = { varList?: Variable[] handleAddVariable: (payload: any) => void modelConfig: ModelConfig + onPromptEditorBlur?: () => void } const ConfigPrompt: FC = ({ @@ -80,6 +81,7 @@ const ConfigPrompt: FC = ({ varList = [], handleAddVariable, modelConfig, + onPromptEditorBlur, }) => { const { t } = useTranslation() const workflowStore = useWorkflowStore() @@ -358,6 +360,7 @@ const ConfigPrompt: FC = ({ handleAddVariable={handleAddVariable} modelConfig={modelConfig} isSupportSandbox={isSupportSandbox} + onPromptEditorBlur={onPromptEditorBlur} /> ) @@ -434,6 +437,7 @@ const ConfigPrompt: FC = ({ onGenerated={handleGenerated} modelConfig={modelConfig} isSupportSandbox={isSupportSandbox} + onBlur={onPromptEditorBlur} /> )} diff --git a/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx b/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx index f12f5fb3c2..306a118709 100644 --- a/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx +++ b/web/app/components/workflow/nodes/llm/components/reference-tool-config.tsx @@ -17,6 +17,7 @@ type ReferenceToolConfigProps = { enabled: boolean nodeId: string toolSettings?: ToolSetting[] + promptTemplateKey: string } type ToolDependency = { @@ -35,20 +36,28 @@ const ReferenceToolConfig: FC = ({ enabled, nodeId, toolSettings, + promptTemplateKey, }) => { const isDisabled = readonly || !enabled const appId = useAppStore(s => s.appDetail?.id) const { handleNodeDataUpdate } = useNodeCurdKit(nodeId) - const { data } = useQuery({ - queryKey: consoleQuery.workflowDraft.nodeSkills.queryKey({ - input: { - params: { - appId: appId ?? '', - nodeId, + const queryKey = useMemo(() => { + return [ + ...consoleQuery.workflowDraft.nodeSkills.queryKey({ + input: { + params: { + appId: appId ?? '', + nodeId, + }, }, - }, - }), + }), + promptTemplateKey, + ] + }, [appId, nodeId, promptTemplateKey]) + + const { data } = useQuery({ + queryKey, queryFn: () => consoleClient.workflowDraft.nodeSkills({ params: { appId: appId ?? '', diff --git a/web/app/components/workflow/nodes/llm/panel.tsx b/web/app/components/workflow/nodes/llm/panel.tsx index 621c891089..9ccb02088f 100644 --- a/web/app/components/workflow/nodes/llm/panel.tsx +++ b/web/app/components/workflow/nodes/llm/panel.tsx @@ -2,6 +2,7 @@ import type { FC } from 'react' import type { LLMNodeType } from './types' import type { NodePanelProps } from '@/app/components/workflow/types' import { RiAlertFill, RiInformationLine, RiQuestionLine } from '@remixicon/react' +import { useDebounceFn } from 'ahooks' import * as React from 'react' import { useCallback } from 'react' import { useTranslation } from 'react-i18next' @@ -74,6 +75,22 @@ const Panel: FC> = ({ handleComputerUseChange, } = useConfig(id, data) + const promptTemplateKey = React.useMemo(() => { + try { + return JSON.stringify(inputs.prompt_template ?? null) + } + catch { + return '' + } + }, [inputs.prompt_template]) + const [skillsRefreshKey, setSkillsRefreshKey] = React.useState(promptTemplateKey) + const { run: scheduleSkillsRefresh } = useDebounceFn((nextKey: string) => { + setSkillsRefreshKey(nextKey) + }, { wait: 3000 }) + const handlePromptEditorBlur = useCallback(() => { + scheduleSkillsRefresh(promptTemplateKey) + }, [promptTemplateKey, scheduleSkillsRefresh]) + const { handleMaxIterationsChange, } = useNodeTools(id) @@ -144,6 +161,7 @@ const Panel: FC> = ({ varList={inputs.prompt_config?.jinja2_variables || []} handleAddVariable={handleAddVariable} modelConfig={model} + onPromptEditorBlur={handlePromptEditorBlur} /> )} @@ -234,6 +252,7 @@ const Panel: FC> = ({ onChange={handleComputerUseChange} nodeId={id} toolSettings={inputs.tool_settings} + promptTemplateKey={skillsRefreshKey} /> )}