diff --git a/web/app/components/base/prompt-editor/plugins/memory-popup-plugin/index.tsx b/web/app/components/base/prompt-editor/plugins/memory-popup-plugin/index.tsx index 7d48fd6e43..f825349434 100644 --- a/web/app/components/base/prompt-editor/plugins/memory-popup-plugin/index.tsx +++ b/web/app/components/base/prompt-editor/plugins/memory-popup-plugin/index.tsx @@ -25,7 +25,7 @@ import { } from 'lexical' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import { useEventEmitterContextContext } from '@/context/event-emitter' -import { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER } from '@/app/components/workflow/nodes/_base/components/prompt/add-memory-button' +import { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER, MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER, MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER } from '@/app/components/workflow/nodes/_base/components/prompt/type' import Divider from '@/app/components/base/divider' import VariableIcon from '@/app/components/workflow/nodes/_base/components/variable/variable-label/base/variable-icon' import type { @@ -135,15 +135,25 @@ export default function MemoryPopupPlugin({ setOpen(false) }, [setOpen]) + const handleSelectVariable = useCallback((variable: string[]) => { + editor.dispatchCommand(INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND, variable) + closePortal() + }, [editor, closePortal]) + + const handleCreate = useCallback(() => { + eventEmitter?.emit({ type: MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER, instanceId } as any) + closePortal() + }, [eventEmitter, instanceId, closePortal]) + eventEmitter?.useSubscription((v: any) => { if (v.type === MEMORY_POPUP_SHOW_BY_EVENT_EMITTER && v.instanceId === instanceId) openPortal() }) - const handleSelectVariable = useCallback((variable: string[]) => { - editor.dispatchCommand(INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND, variable) - closePortal() - }, [editor, closePortal]) + eventEmitter?.useSubscription((v: any) => { + if (v.type === MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER && v.instanceId === instanceId) + handleSelectVariable(v.variable) + }) useEffect(() => { return editor.registerUpdateListener(({ editorState }) => { @@ -245,7 +255,7 @@ export default function MemoryPopupPlugin({ )} -
+
{t('workflow.nodes.llm.memory.createButton')}
diff --git a/web/app/components/workflow/nodes/_base/components/prompt/add-memory-button.tsx b/web/app/components/workflow/nodes/_base/components/prompt/add-memory-button.tsx index fa0594fd82..c1427eebb2 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/add-memory-button.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/add-memory-button.tsx @@ -2,9 +2,6 @@ import { useTranslation } from 'react-i18next' import Button from '@/app/components/base/button' import { Memory } from '@/app/components/base/icons/src/vender/line/others' -export const MEMORY_POPUP_SHOW_BY_EVENT_EMITTER = 'MEMORY_POPUP_SHOW_BY_EVENT_EMITTER' -export const PROMPT_EDITOR_INSERT_QUICKLY = 'PROMPT_EDITOR_INSERT_QUICKLY' - type Props = { onAddMemory: () => void } 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 252d0e1060..3bee8c7b5f 100644 --- a/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx +++ b/web/app/components/workflow/nodes/_base/components/prompt/editor.tsx @@ -36,10 +36,12 @@ import Switch from '@/app/components/base/switch' import { Jinja } from '@/app/components/base/icons/src/vender/workflow' import { useStore } from '@/app/components/workflow/store' import { useWorkflowVariableType } from '@/app/components/workflow/hooks' -import AddMemoryButton, { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER } from './add-memory-button' +import AddMemoryButton from './add-memory-button' +import { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER } from './type' import type { ConversationVariable, } from '@/app/components/workflow/types' +import MemoryCreateButton from '@/app/components/workflow/nodes/llm/components/memory-system/memory-create-button' type Props = { className?: string @@ -169,175 +171,178 @@ const Editor: FC = ({ } return ( - -
-
-
-
-
{title} {required && *}
- {titleTooltip && } -
-
-
{value?.length || 0}
- {isSupportPromptGenerator && ( - - )} - -
- {/* Operations */} -
- {isSupportJinja && ( - -
{t('workflow.common.enableJinja')}
- {t('workflow.common.learnMore')} -
- } - > -
- - { - onEditionTypeChange?.(checked ? EditionType.jinja2 : EditionType.basic) - }} - /> -
- - - )} - {!readOnly && ( - - - - - - )} - {showRemove && ( - - - - )} - {!isCopied - ? ( - - - - ) - : ( - - - - ) - } - + <> + +
+
+
+
+
{title} {required && *}
+ {titleTooltip && }
- -
-
- - {/* Min: 80 Max: 560. Header: 24 */} -
- {!(isSupportJinja && editionType === EditionType.jinja2) - ? ( - <> -
- { - acc[node.id] = { - title: node.data.title, - type: node.data.type, - width: node.width, - height: node.height, - position: node.position, - } - if (node.data.type === BlockEnum.Start) { - acc.sys = { - title: t('workflow.blocks.start'), - type: BlockEnum.Start, - } - } - return acc - }, {} as any), - showManageInputField: !!pipelineId, - onManageInputField: () => setShowInputFieldPanel?.(true), - }} - onChange={onChange} - onBlur={setBlur} - onFocus={setFocus} - editable={!readOnly} - isSupportFileVar={isSupportFileVar} - isMemorySupported - memoryVarInNode={memoryVarInNode} - memoryVarInApp={memoryVarInApp} - /> - {/* to patch Editor not support dynamic change editable status */} - {readOnly &&
} -
- {isMemorySupported && } - - ) - : ( -
- +
{value?.length || 0}
+ {isSupportPromptGenerator && ( + + )} + +
+ {/* Operations */} +
+ {isSupportJinja && ( + +
{t('workflow.common.enableJinja')}
+ {t('workflow.common.learnMore')} +
+ } + > +
+ + { + onEditionTypeChange?.(checked ? EditionType.jinja2 : EditionType.basic) + }} + /> +
+ + + )} + {!readOnly && ( + + + + + + )} + {showRemove && ( + + + + )} + {!isCopied + ? ( + + + + ) + : ( + + + + ) + } +
- )} + +
+
+ + {/* Min: 80 Max: 560. Header: 24 */} +
+ {!(isSupportJinja && editionType === EditionType.jinja2) + ? ( + <> +
+ { + acc[node.id] = { + title: node.data.title, + type: node.data.type, + width: node.width, + height: node.height, + position: node.position, + } + if (node.data.type === BlockEnum.Start) { + acc.sys = { + title: t('workflow.blocks.start'), + type: BlockEnum.Start, + } + } + return acc + }, {} as any), + showManageInputField: !!pipelineId, + onManageInputField: () => setShowInputFieldPanel?.(true), + }} + onChange={onChange} + onBlur={setBlur} + onFocus={setFocus} + editable={!readOnly} + isSupportFileVar={isSupportFileVar} + isMemorySupported + memoryVarInNode={memoryVarInNode} + memoryVarInApp={memoryVarInApp} + /> + {/* to patch Editor not support dynamic change editable status */} + {readOnly &&
} +
+ {isMemorySupported && } + + ) + : ( +
+ +
+ )} +
-
- + + {isMemorySupported && } + ) } diff --git a/web/app/components/workflow/nodes/_base/components/prompt/type.ts b/web/app/components/workflow/nodes/_base/components/prompt/type.ts new file mode 100644 index 0000000000..a10c405b32 --- /dev/null +++ b/web/app/components/workflow/nodes/_base/components/prompt/type.ts @@ -0,0 +1,3 @@ +export const MEMORY_POPUP_SHOW_BY_EVENT_EMITTER = 'MEMORY_POPUP_SHOW_BY_EVENT_EMITTER' +export const MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER = 'MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER' +export const MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER = 'MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER' diff --git a/web/app/components/workflow/nodes/llm/components/memory-system/memory-create-button.tsx b/web/app/components/workflow/nodes/llm/components/memory-system/memory-create-button.tsx index b55fae28ea..1a6125f7cc 100644 --- a/web/app/components/workflow/nodes/llm/components/memory-system/memory-create-button.tsx +++ b/web/app/components/workflow/nodes/llm/components/memory-system/memory-create-button.tsx @@ -1,6 +1,7 @@ import { useCallback, useState } from 'react' import { RiAddLine } from '@remixicon/react' import VariableModal from '@/app/components/workflow/panel/chat-variable-panel/components/variable-modal' +import type { OffsetOptions, Placement } from '@floating-ui/react' import { PortalToFollowElem, PortalToFollowElemContent, @@ -11,8 +12,23 @@ import type { ConversationVariable } from '@/app/components/workflow/types' import { useStore } from '@/app/components/workflow/store' import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft' import useInspectVarsCrud from '@/app/components/workflow/hooks/use-inspect-vars-crud' +import { useEventEmitterContextContext } from '@/context/event-emitter' +import { MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER, MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER } from '@/app/components/workflow/nodes/_base/components/prompt/type' -const MemoryCreateButton = () => { +type Props = { + placement?: Placement + offset?: number | OffsetOptions + hideTrigger?: boolean + instanceId?: string +} + +const MemoryCreateButton = ({ + placement, + offset, + hideTrigger, + instanceId, +}: Props) => { + const { eventEmitter } = useEventEmitterContextContext() const [open, setOpen] = useState(false) const varList = useStore(s => s.conversationVariables) as ConversationVariable[] const updateChatVarList = useStore(s => s.setConversationVariables) @@ -34,19 +50,30 @@ const MemoryCreateButton = () => { updateChatVarList(newList) handleVarChanged() setOpen(false) - }, [varList, updateChatVarList, handleVarChanged, setOpen]) + if (instanceId) + eventEmitter?.emit({ type: MEMORY_VAR_CREATED_BY_MODAL_BY_EVENT_EMITTER, instanceId, variable: ['conversation', newChatVar.name] } as any) + }, [varList, updateChatVarList, handleVarChanged, setOpen, eventEmitter, instanceId]) + + eventEmitter?.useSubscription((v: any) => { + if (v.type === MEMORY_VAR_MODAL_SHOW_BY_EVENT_EMITTER && v.instanceId === instanceId) + setOpen(true) + }) return ( <> setOpen(v => !v)}> - - - + {hideTrigger &&
} + {!hideTrigger && ( + + + + )}