diff --git a/web/app/components/workflow-app/components/workflow-main.tsx b/web/app/components/workflow-app/components/workflow-main.tsx index f979a12f26..fd7f3d17af 100644 --- a/web/app/components/workflow-app/components/workflow-main.tsx +++ b/web/app/components/workflow-app/components/workflow-main.tsx @@ -34,6 +34,7 @@ const WorkflowMain = ({ features, conversation_variables, environment_variables, + memory_blocks, } = payload if (features && featuresStore) { const { setFeatures } = featuresStore.getState() @@ -48,6 +49,10 @@ const WorkflowMain = ({ const { setEnvironmentVariables } = workflowStore.getState() setEnvironmentVariables(environment_variables) } + if (memory_blocks) { + const { setMemoryVariables } = workflowStore.getState() + setMemoryVariables(memory_blocks) + } }, [featuresStore, workflowStore]) const { diff --git a/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts b/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts index 5705deb0c0..1f8bff8cd5 100644 --- a/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts +++ b/web/app/components/workflow-app/hooks/use-nodes-sync-draft.ts @@ -33,6 +33,7 @@ export const useNodesSyncDraft = () => { const { appId, conversationVariables, + memoryVariables, environmentVariables, syncWorkflowDraftHash, } = workflowStore.getState() @@ -84,6 +85,7 @@ export const useNodesSyncDraft = () => { }, environment_variables: environmentVariables, conversation_variables: conversationVariables, + memory_blocks: memoryVariables, hash: syncWorkflowDraftHash, }, } diff --git a/web/app/components/workflow-app/hooks/use-workflow-init.ts b/web/app/components/workflow-app/hooks/use-workflow-init.ts index fadd2007bc..bb0d5b54ff 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-init.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-init.ts @@ -53,6 +53,7 @@ export const useWorkflowInit = () => { }, {} as Record), environmentVariables: res.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || [], conversationVariables: res.conversation_variables || [], + memoryVariables: res.memory_blocks || [], }) setSyncWorkflowDraftHash(res.hash) setIsLoading(false) diff --git a/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts b/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts index c944e10c4c..3a2fa18b19 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-refresh-draft.ts @@ -16,6 +16,7 @@ export const useWorkflowRefreshDraft = () => { setEnvironmentVariables, setEnvSecrets, setConversationVariables, + setMemoryVariables, } = workflowStore.getState() setIsSyncingWorkflowDraft(true) fetchWorkflowDraft(`/apps/${appId}/workflows/draft`).then((response) => { @@ -27,6 +28,7 @@ export const useWorkflowRefreshDraft = () => { }, {} as Record)) setEnvironmentVariables(response.environment_variables?.map(env => env.value_type === 'secret' ? { ...env, value: '[__HIDDEN__]' } : env) || []) setConversationVariables(response.conversation_variables || []) + setMemoryVariables(response.memory_blocks || []) }).finally(() => setIsSyncingWorkflowDraft(false)) }, [handleUpdateWorkflowCanvas, workflowStore]) diff --git a/web/app/components/workflow/nodes/llm/components/memory-system/block-memory.tsx b/web/app/components/workflow/nodes/llm/components/memory-system/block-memory.tsx new file mode 100644 index 0000000000..c6f01521e8 --- /dev/null +++ b/web/app/components/workflow/nodes/llm/components/memory-system/block-memory.tsx @@ -0,0 +1,99 @@ +import { + memo, + useState, +} from 'react' +import { useTranslation } from 'react-i18next' +import { + RiDeleteBinLine, + RiEditLine, +} from '@remixicon/react' +import type { Memory } from '@/app/components/workflow/types' +import Badge from '@/app/components/base/badge' +import ActionButton from '@/app/components/base/action-button' +import { useMemoryVariables } from './hooks/use-memory-variables' +import Confirm from '@/app/components/base/confirm' + +type BlockMemoryProps = { + payload: Memory +} +const BlockMemory = ({ payload }: BlockMemoryProps) => { + const { t } = useTranslation() + const { block_id } = payload + const { memoryVariablesInUsed } = useMemoryVariables(block_id || []) + const [showConfirm, setShowConfirm] = useState<{ + title: string + desc: string + onConfirm: () => void + } | undefined>(undefined) + + const handleEdit = (blockId: string) => { + console.log('edit', blockId) + } + + const handleDelete = (blockId: string) => { + setShowConfirm({ + title: t('workflow.nodes.common.memory.block.deleteConfirmTitle'), + desc: t('workflow.nodes.common.memory.block.deleteConfirmDesc'), + onConfirm: () => handleDelete(blockId), + }) + } + + if (!block_id?.length) { + return ( +
+ {t('workflow.nodes.common.memory.block.empty')} +
+ ) + } + return ( + <> +
+ { + memoryVariablesInUsed.map(memoryVariable => ( +
+
+
+ {memoryVariable.name} +
+ + {memoryVariable.term} + + handleEdit(memoryVariable.id)} + > + + + handleDelete(memoryVariable.id)} + > + + +
+ )) + } +
+ { + !!showConfirm && ( + setShowConfirm(undefined)} + onConfirm={showConfirm.onConfirm} + title={showConfirm.title} + content={showConfirm.desc} + /> + ) + } + + ) +} + +export default memo(BlockMemory) diff --git a/web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory-variables.ts b/web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory-variables.ts new file mode 100644 index 0000000000..df416ae640 --- /dev/null +++ b/web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory-variables.ts @@ -0,0 +1,18 @@ +import { useMemo } from 'react' +import { useStore } from '@/app/components/workflow/store' + +export const useMemoryVariables = (blockIds: string[]) => { + const memoryVariables = useStore(s => s.memoryVariables) + + const memoryVariablesInUsed = useMemo(() => { + return memoryVariables.filter(variable => blockIds.includes(variable.id)) + }, [memoryVariables, blockIds]) + + const handleDelete = (blockId: string) => { + console.log('delete', blockId) + } + return { + memoryVariablesInUsed, + handleDelete, + } +} diff --git a/web/app/components/workflow/nodes/llm/components/memory-system/hooks.ts b/web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory.ts similarity index 97% rename from web/app/components/workflow/nodes/llm/components/memory-system/hooks.ts rename to web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory.ts index 000749cfa0..a98a908bbd 100644 --- a/web/app/components/workflow/nodes/llm/components/memory-system/hooks.ts +++ b/web/app/components/workflow/nodes/llm/components/memory-system/hooks/use-memory.ts @@ -3,11 +3,11 @@ import { useMemo, useState, } from 'react' -import type { LLMNodeType } from '../../types' +import type { LLMNodeType } from '../../../types' import { useNodeUpdate } from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' import { MEMORY_DEFAULT, -} from './linear-memory' +} from '../linear-memory' import type { Memory } from '@/app/components/workflow/types' import { MemoryMode } from '@/app/components/workflow/types' diff --git a/web/app/components/workflow/nodes/llm/components/memory-system/index.tsx b/web/app/components/workflow/nodes/llm/components/memory-system/index.tsx index 180a491f75..4eb11e3785 100644 --- a/web/app/components/workflow/nodes/llm/components/memory-system/index.tsx +++ b/web/app/components/workflow/nodes/llm/components/memory-system/index.tsx @@ -13,9 +13,10 @@ import MemorySelector from './memory-selector' import LinearMemory from './linear-memory' import type { Memory } from '@/app/components/workflow/types' import type { LLMNodeType } from '../../types' -import { useMemory } from './hooks' +import { useMemory } from './hooks/use-memory' import Split from '@/app/components/workflow/nodes/_base/components/split' import { MemoryMode } from '@/app/components/workflow/types' +import BlockMemory from './block-memory' type MemoryProps = Pick & { readonly?: boolean @@ -89,6 +90,11 @@ const MemorySystem = ({ /> ) } + { + memoryType === MemoryMode.block && !collapsed && ( + + ) + } diff --git a/web/app/components/workflow/nodes/llm/panel.tsx b/web/app/components/workflow/nodes/llm/panel.tsx index 21ea5c6f2a..647201346e 100644 --- a/web/app/components/workflow/nodes/llm/panel.tsx +++ b/web/app/components/workflow/nodes/llm/panel.tsx @@ -22,7 +22,7 @@ import { RiAlertFill, RiQuestionLine } from '@remixicon/react' import { fetchAndMergeValidCompletionParams } from '@/utils/completion-params' import Toast from '@/app/components/base/toast' import MemorySystem from './components/memory-system' -import { useMemory } from './components/memory-system/hooks' +import { useMemory } from './components/memory-system/hooks/use-memory' import { MemoryMode } from '@/app/components/workflow/types' const i18nPrefix = 'workflow.nodes.llm' diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx index 3e46b7afcb..0186b137cd 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-item.tsx @@ -1,14 +1,18 @@ import { memo, useState } from 'react' import { capitalize } from 'lodash-es' import { RiDeleteBinLine, RiEditLine } from '@remixicon/react' -import { BubbleX } from '@/app/components/base/icons/src/vender/line/others' -import type { ConversationVariable } from '@/app/components/workflow/types' +import { + BubbleX, + Memory, +} from '@/app/components/base/icons/src/vender/line/others' +import type { ConversationVariable, MemoryVariable } from '@/app/components/workflow/types' import cn from '@/utils/classnames' +import { ChatVarType } from '../type' type VariableItemProps = { - item: ConversationVariable - onEdit: (item: ConversationVariable) => void - onDelete: (item: ConversationVariable) => void + item: ConversationVariable | MemoryVariable + onEdit: (item: ConversationVariable | MemoryVariable) => void + onDelete: (item: ConversationVariable | MemoryVariable) => void } const VariableItem = ({ @@ -24,7 +28,16 @@ const VariableItem = ({ )}>
- + { + item.value_type === ChatVarType.Memory && ( + + ) + } + { + item.value_type !== ChatVarType.Memory && ( + + ) + }
{item.name}
{capitalize(item.value_type)}
@@ -41,7 +54,11 @@ const VariableItem = ({
-
{item.description}
+ { + 'description' in item && item.description && ( +
{item.description}
+ ) + } ) } diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx index 9d19b61093..3bc94d39a8 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal-trigger.tsx @@ -9,15 +9,15 @@ import { PortalToFollowElemContent, PortalToFollowElemTrigger, } from '@/app/components/base/portal-to-follow-elem' -import type { ConversationVariable } from '@/app/components/workflow/types' +import type { ConversationVariable, MemoryVariable } from '@/app/components/workflow/types' type Props = { open: boolean setOpen: (value: React.SetStateAction) => void showTip: boolean - chatVar?: ConversationVariable + chatVar?: ConversationVariable | MemoryVariable onClose: () => void - onSave: (env: ConversationVariable) => void + onSave: (env: ConversationVariable | MemoryVariable) => void } const VariableModalTrigger = ({ diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx index 41f7f4c3d2..c8a14aad71 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx @@ -10,7 +10,7 @@ import { RiCloseLine } from '@remixicon/react' import Button from '@/app/components/base/button' import { ToastContext } from '@/app/components/base/toast' import { useStore } from '@/app/components/workflow/store' -import type { ConversationVariable } from '@/app/components/workflow/types' +import type { ConversationVariable, MemoryVariable } from '@/app/components/workflow/types' import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type' import cn from '@/utils/classnames' import { checkKeys } from '@/utils/var' @@ -19,9 +19,9 @@ import VariableForm from '@/app/components/base/form/form-scenarios/variable' import { useForm } from '../hooks' export type ModalPropsType = { - chatVar?: ConversationVariable + chatVar?: ConversationVariable | MemoryVariable onClose: () => void - onSave: (chatVar: ConversationVariable) => void + onSave: (chatVar: ConversationVariable | MemoryVariable) => void } const ChatVariableModal = ({ diff --git a/web/app/components/workflow/panel/chat-variable-panel/hooks/use-form/index.ts b/web/app/components/workflow/panel/chat-variable-panel/hooks/use-form/index.ts index caaebb6112..4091857d55 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/hooks/use-form/index.ts +++ b/web/app/components/workflow/panel/chat-variable-panel/hooks/use-form/index.ts @@ -8,9 +8,9 @@ import { useMemoryDefaultValues, useMemorySchema, } from './use-memory-schema' -import type { ConversationVariable } from '@/app/components/workflow/types' +import type { ConversationVariable, MemoryVariable } from '@/app/components/workflow/types' -export const useForm = (chatVar?: ConversationVariable) => { +export const useForm = (chatVar?: ConversationVariable | MemoryVariable) => { const { t } = useTranslation() const typeSchema = useTypeSchema() diff --git a/web/app/components/workflow/panel/chat-variable-panel/index.tsx b/web/app/components/workflow/panel/chat-variable-panel/index.tsx index 7006c18cc5..093a799d8c 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/index.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/index.tsx @@ -8,7 +8,10 @@ import { } from 'reactflow' import { RiBookOpenLine, RiCloseLine } from '@remixicon/react' import { useTranslation } from 'react-i18next' -import { useStore } from '@/app/components/workflow/store' +import { + useStore, + useWorkflowStore, +} from '@/app/components/workflow/store' import ActionButton, { ActionButtonState } from '@/app/components/base/action-button' import { BubbleX, LongArrowLeft, LongArrowRight } from '@/app/components/base/icons/src/vender/line/others' import BlockIcon from '@/app/components/workflow/block-icon' @@ -17,6 +20,7 @@ import VariableItem from '@/app/components/workflow/panel/chat-variable-panel/co import RemoveEffectVarConfirm from '@/app/components/workflow/nodes/_base/components/remove-effect-var-confirm' import type { ConversationVariable, + MemoryVariable, } from '@/app/components/workflow/types' import { findUsedVarNodes, updateNodeVars } from '@/app/components/workflow/nodes/_base/components/variable/utils' import { useNodesSyncDraft } from '@/app/components/workflow/hooks/use-nodes-sync-draft' @@ -24,34 +28,39 @@ import { BlockEnum } from '@/app/components/workflow/types' import { useDocLink } from '@/context/i18n' import cn from '@/utils/classnames' import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud' +import { ChatVarType } from './type' const ChatVariablePanel = () => { const { t } = useTranslation() const docLink = useDocLink() const store = useStoreApi() + const workflowStore = useWorkflowStore() const setShowChatVariablePanel = useStore(s => s.setShowChatVariablePanel) const varList = useStore(s => s.conversationVariables) as ConversationVariable[] + const memoryVariables = useStore(s => s.memoryVariables) as MemoryVariable[] const updateChatVarList = useStore(s => s.setConversationVariables) + const setMemoryVariables = useStore(s => s.setMemoryVariables) const { doSyncWorkflowDraft } = useNodesSyncDraft() const { invalidateConversationVarValues, } = useInspectVarsCrud() - const handleVarChanged = useCallback(() => { + const handleVarChanged = useCallback((updateMemoryVariables?: boolean) => { doSyncWorkflowDraft(false, { onSuccess() { - invalidateConversationVarValues() + if (!updateMemoryVariables) + invalidateConversationVarValues() }, }) }, [doSyncWorkflowDraft, invalidateConversationVarValues]) const [showTip, setShowTip] = useState(true) const [showVariableModal, setShowVariableModal] = useState(false) - const [currentVar, setCurrentVar] = useState() + const [currentVar, setCurrentVar] = useState() const [showRemoveVarConfirm, setShowRemoveConfirm] = useState(false) - const [cacheForDelete, setCacheForDelete] = useState() + const [cacheForDelete, setCacheForDelete] = useState() - const getEffectedNodes = useCallback((chatVar: ConversationVariable) => { + const getEffectedNodes = useCallback((chatVar: ConversationVariable | MemoryVariable) => { const { getNodes } = store.getState() const allNodes = getNodes() return findUsedVarNodes( @@ -60,7 +69,7 @@ const ChatVariablePanel = () => { ) }, [store]) - const removeUsedVarInNodes = useCallback((chatVar: ConversationVariable) => { + const removeUsedVarInNodes = useCallback((chatVar: ConversationVariable | MemoryVariable) => { const { getNodes, setNodes } = store.getState() const effectedNodes = getEffectedNodes(chatVar) const newNodes = getNodes().map((node) => { @@ -72,20 +81,21 @@ const ChatVariablePanel = () => { setNodes(newNodes) }, [getEffectedNodes, store]) - const handleEdit = (chatVar: ConversationVariable) => { + const handleEdit = (chatVar: ConversationVariable | MemoryVariable) => { setCurrentVar(chatVar) setShowVariableModal(true) } - const handleDelete = useCallback((chatVar: ConversationVariable) => { + const handleDelete = useCallback((chatVar: ConversationVariable | MemoryVariable) => { removeUsedVarInNodes(chatVar) + const varList = workflowStore.getState().conversationVariables updateChatVarList(varList.filter(v => v.id !== chatVar.id)) setCacheForDelete(undefined) setShowRemoveConfirm(false) - handleVarChanged() - }, [handleVarChanged, removeUsedVarInNodes, updateChatVarList, varList]) + handleVarChanged(chatVar.value_type === ChatVarType.Memory) + }, [handleVarChanged, removeUsedVarInNodes, updateChatVarList]) - const deleteCheck = useCallback((chatVar: ConversationVariable) => { + const deleteCheck = useCallback((chatVar: ConversationVariable | MemoryVariable) => { const effectedNodes = getEffectedNodes(chatVar) if (effectedNodes.length > 0) { setCacheForDelete(chatVar) @@ -96,17 +106,24 @@ const ChatVariablePanel = () => { } }, [getEffectedNodes, handleDelete]) - const handleSave = useCallback(async (chatVar: ConversationVariable) => { + const handleSave = useCallback(async (chatVar: ConversationVariable | MemoryVariable) => { + if (chatVar.value_type === ChatVarType.Memory) { + const memoryVarList = workflowStore.getState().memoryVariables + setMemoryVariables([chatVar, ...memoryVarList]) + handleVarChanged(true) + return + } + const varList = workflowStore.getState().conversationVariables // add chatVar if (!currentVar) { - const newList = [chatVar, ...varList] + const newList = [chatVar, ...varList] as ConversationVariable[] updateChatVarList(newList) handleVarChanged() return } // edit chatVar const newList = varList.map(v => v.id === currentVar.id ? chatVar : v) - updateChatVarList(newList) + updateChatVarList(newList as ConversationVariable[]) // side effects of rename env if (currentVar.name !== chatVar.name) { const { getNodes, setNodes } = store.getState() @@ -120,7 +137,7 @@ const ChatVariablePanel = () => { setNodes(newNodes) } handleVarChanged() - }, [currentVar, getEffectedNodes, handleVarChanged, store, updateChatVarList, varList]) + }, [currentVar, getEffectedNodes, handleVarChanged, store, updateChatVarList]) return (
{ />
+ { + memoryVariables.map(memoryVariable => ( + + )) + } {varList.map(chatVar => ( { return createStore((...args) => ({ ...createChatVariableSlice(...args), + ...createMemoryVariableSlice(...args), ...createEnvVariableSlice(...args), ...createFormSlice(...args), ...createHelpLineSlice(...args), diff --git a/web/app/components/workflow/store/workflow/memory-variable-slice.ts b/web/app/components/workflow/store/workflow/memory-variable-slice.ts new file mode 100644 index 0000000000..1de044e8ce --- /dev/null +++ b/web/app/components/workflow/store/workflow/memory-variable-slice.ts @@ -0,0 +1,14 @@ +import type { StateCreator } from 'zustand' +import type { MemoryVariable } from '@/app/components/workflow/types' + +export type MemoryVariableSliceShape = { + memoryVariables: MemoryVariable[] + setMemoryVariables: (memoryVariables: MemoryVariable[]) => void +} + +export const createMemoryVariableSlice: StateCreator = (set) => { + return ({ + memoryVariables: [], + setMemoryVariables: memoryVariables => set(() => ({ memoryVariables })), + }) +} diff --git a/web/app/components/workflow/types.ts b/web/app/components/workflow/types.ts index 555731a9c1..6e719ab847 100644 --- a/web/app/components/workflow/types.ts +++ b/web/app/components/workflow/types.ts @@ -167,6 +167,8 @@ export type EnvironmentVariable = { } export type MemoryVariable = { + id: string + name: string template?: string instruction?: string schedule_mode?: string @@ -176,6 +178,7 @@ export type MemoryVariable = { scope?: string term?: string end_user_editable?: boolean + value_type: ChatVarType } export type ConversationVariable = { @@ -184,7 +187,7 @@ export type ConversationVariable = { value_type: ChatVarType value: any description?: string -} & MemoryVariable +} export type GlobalVariable = { name: string diff --git a/web/app/components/workflow/update-dsl-modal.tsx b/web/app/components/workflow/update-dsl-modal.tsx index 00c36cce90..795a2756c0 100644 --- a/web/app/components/workflow/update-dsl-modal.tsx +++ b/web/app/components/workflow/update-dsl-modal.tsx @@ -88,6 +88,7 @@ const UpdateDSLModal = ({ hash, conversation_variables, environment_variables, + memory_blocks, } = await fetchWorkflowDraft(`/apps/${app_id}/workflows/draft`) const { nodes, edges, viewport } = graph @@ -126,6 +127,7 @@ const UpdateDSLModal = ({ hash, conversation_variables: conversation_variables || [], environment_variables: environment_variables || [], + memory_blocks: memory_blocks || [], }, } as any) }, [eventEmitter]) diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index 736c7b19a1..0df20fd37e 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -377,6 +377,7 @@ const translation = { block: { title: 'Memory Block', desc: 'AI remembers specific information you define using custom templates', + empty: 'Please add a memory variable in the Prompt', }, }, memories: { diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index f5d75fe806..8099594af4 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -377,6 +377,7 @@ const translation = { block: { title: '记忆块', desc: 'AI 会记住你定义的特定信息', + empty: '请在提示词中添加记忆变量以启用记忆块', }, }, memories: { diff --git a/web/types/workflow.ts b/web/types/workflow.ts index 26d6731a09..a32b6015bb 100644 --- a/web/types/workflow.ts +++ b/web/types/workflow.ts @@ -1,5 +1,5 @@ import type { Viewport } from 'reactflow' -import type { BlockEnum, CommonNodeType, ConversationVariable, Edge, EnvironmentVariable, InputVar, Node, ValueSelector, VarType, Variable } from '@/app/components/workflow/types' +import type { BlockEnum, CommonNodeType, ConversationVariable, Edge, EnvironmentVariable, InputVar, MemoryVariable, Node, ValueSelector, VarType, Variable } from '@/app/components/workflow/types' import type { TransferMethod } from '@/types/app' import type { ErrorHandleTypeEnum } from '@/app/components/workflow/nodes/_base/components/error-handle/types' import type { RAGPipelineVariables } from '@/models/pipeline' @@ -130,6 +130,7 @@ export type FetchWorkflowDraftResponse = { tool_published: boolean environment_variables?: EnvironmentVariable[] conversation_variables?: ConversationVariable[] + memory_blocks?: MemoryVariable[] rag_pipeline_variables?: RAGPipelineVariables version: string marked_name: string