This commit is contained in:
zxhlyh 2025-11-05 18:28:17 +08:00
parent 9d310fed92
commit 7cef0fff89
22 changed files with 104 additions and 129 deletions

View File

@ -80,9 +80,6 @@ import {
UPDATE_HISTORY_EVENT_EMITTER,
} from './constants'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import type {
MemoryVariable,
} from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
export type PromptEditorProps = {
@ -109,8 +106,6 @@ export type PromptEditorProps = {
lastRunBlock?: LastRunBlockType
isSupportFileVar?: boolean
isMemorySupported?: boolean
memoryVarInNode?: MemoryVariable[]
memoryVarInApp?: MemoryVariable[]
}
const PromptEditor: FC<PromptEditorProps> = ({
@ -137,8 +132,6 @@ const PromptEditor: FC<PromptEditorProps> = ({
lastRunBlock,
isSupportFileVar,
isMemorySupported,
memoryVarInNode = [],
memoryVarInApp = [],
}) => {
const { eventEmitter } = useEventEmitterContextContext()
const initialConfig = {
@ -209,11 +202,10 @@ const PromptEditor: FC<PromptEditorProps> = ({
}
ErrorBoundary={LexicalErrorBoundary}
/>
{isMemorySupported && (
{isMemorySupported && workflowVariableBlock?.show && (
<MemoryPopupPlugin
instanceId={instanceId}
memoryVarInNode={memoryVarInNode}
memoryVarInApp={memoryVarInApp}
memoryVariables={workflowVariableBlock?.variables?.find(v => v.nodeId === 'memory_block')?.vars || []}
/>
)}
<ComponentPickerBlock

View File

@ -29,7 +29,7 @@ import { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER, MEMORY_VAR_CREATED_BY_MODAL_BY_EVEN
import Divider from '@/app/components/base/divider'
import VariableIcon from '@/app/components/workflow/nodes/_base/components/variable/variable-label/base/variable-icon'
import type {
MemoryVariable,
Var,
} from '@/app/components/workflow/types'
import { INSERT_WORKFLOW_VARIABLE_BLOCK_COMMAND } from '../workflow-variable-block'
@ -39,16 +39,14 @@ export type MemoryPopupProps = {
className?: string
container?: Element | null
instanceId?: string
memoryVarInNode: MemoryVariable[]
memoryVarInApp: MemoryVariable[]
memoryVariables: Var[]
}
export default function MemoryPopupPlugin({
className,
container,
instanceId,
memoryVarInNode,
memoryVarInApp,
memoryVariables,
}: MemoryPopupProps) {
const { t } = useTranslation()
const [editor] = useLexicalComposerContext()
@ -61,6 +59,8 @@ export default function MemoryPopupPlugin({
const containerEl = useMemo(() => container ?? (typeof document !== 'undefined' ? document.body : null), [container])
const useContainer = !!containerEl && containerEl !== document.body
const memoryVarInNode = memoryVariables.filter(memoryVariable => memoryVariable.memoryVariableNodeId)
const memoryVarInApp = memoryVariables.filter(memoryVariable => !memoryVariable.memoryVariableNodeId)
const { refs, floatingStyles, isPositioned } = useFloating({
placement: 'bottom-start',
@ -213,15 +213,15 @@ export default function MemoryPopupPlugin({
<div className='p-1'>
{memoryVarInNode.map(variable => (
<div
key={variable.id}
key={variable.variable}
className='flex cursor-pointer items-center gap-1 rounded-md px-3 py-1 hover:bg-state-base-hover'
onClick={() => handleSelectVariable(['memory_block', variable.id])}
onClick={() => handleSelectVariable(['memory_block', variable.variable])}
>
<VariableIcon
variables={['memory_block', variable.id]}
variables={['memory_block', '']}
className='text-util-colors-teal-teal-700'
/>
<div title={variable.name} className='system-sm-medium shrink-0 truncate text-text-secondary'>{variable.name}</div>
<div title={variable.memoryVariableName} className='system-sm-medium shrink-0 truncate text-text-secondary'>{variable.memoryVariableName}</div>
</div>
))}
</div>
@ -237,15 +237,15 @@ export default function MemoryPopupPlugin({
<div className='p-1'>
{memoryVarInApp.map(variable => (
<div
key={variable.id}
key={variable.variable}
className='flex cursor-pointer items-center gap-1 rounded-md px-3 py-1 hover:bg-state-base-hover'
onClick={() => handleSelectVariable(['memory_block', variable.id])}
onClick={() => handleSelectVariable(['memory_block', variable.variable])}
>
<VariableIcon
variables={['memory_block', variable.id]}
variables={['memory_block', '']}
className='text-util-colors-teal-teal-700'
/>
<div title={variable.name} className='system-sm-medium shrink-0 truncate text-text-secondary'>{variable.name}</div>
<div title={variable.variable} className='system-sm-medium shrink-0 truncate text-text-secondary'>{variable.memoryVariableName}</div>
</div>
))}
</div>

View File

@ -13,6 +13,7 @@ export type SerializedNode = SerializedLexicalNode & {
getVarType?: GetVarType
environmentVariables?: Var[]
conversationVariables?: Var[]
memoryVariables?: Var[]
ragVariables?: Var[]
}
@ -98,6 +99,7 @@ export class WorkflowVariableBlockNode extends DecoratorNode<React.JSX.Element>
getVarType: this.getVarType(),
environmentVariables: this.getEnvironmentVariables(),
conversationVariables: this.getConversationVariables(),
memoryVariables: this.getMemoryVariables(),
ragVariables: this.getRagVariables(),
}
}

View File

@ -28,6 +28,7 @@ const WorkflowVariableBlockReplacementBlock = ({
acc.push(...curr.vars.filter(v => v.isRagVariable))
return acc
}, [])
const memoryVariables = variables?.find(variable => variable.nodeId === 'memory_block')?.vars || []
useEffect(() => {
if (!editor.hasNodes([WorkflowVariableBlockNode]))
@ -39,7 +40,7 @@ const WorkflowVariableBlockReplacementBlock = ({
onInsert()
const nodePathString = textNode.getTextContent().slice(3, -3)
return $applyNodeReplacement($createWorkflowVariableBlockNode(nodePathString.split('.'), workflowNodesMap, getVarType, variables?.find(o => o.nodeId === 'env')?.vars || [], variables?.find(o => o.nodeId === 'conversation')?.vars || [], ragVariables))
return $applyNodeReplacement($createWorkflowVariableBlockNode(nodePathString.split('.'), workflowNodesMap, getVarType, variables?.find(o => o.nodeId === 'env')?.vars || [], variables?.find(o => o.nodeId === 'conversation')?.vars || [], memoryVariables, ragVariables))
}, [onInsert, workflowNodesMap, getVarType, variables])
const getMatch = useCallback((text: string) => {

View File

@ -51,7 +51,7 @@ export const useSetWorkflowVarsWithValue = ({
const { getNodes } = store.getState()
const nodeArr = getNodes()
const allNodesOutputVars = toNodeOutputVars(nodeArr, false, () => true, [], [], [], passedInAllPluginInfoList || allPluginInfoList, passedInSchemaTypeDefinitions || schemaTypeDefinitions)
const allNodesOutputVars = toNodeOutputVars(nodeArr, false, () => true, [], [], [], [], passedInAllPluginInfoList || allPluginInfoList, passedInSchemaTypeDefinitions || schemaTypeDefinitions)
const nodesKeyValue: Record<string, Node> = {}
nodeArr.forEach((node) => {

View File

@ -132,7 +132,7 @@ export const useInspectVarsCrudCommon = ({
mcpTools: mcpTools || [],
dataSourceList: dataSourceList || [],
}
const currentNodeOutputVars = toNodeOutputVars([currentNode], false, () => true, [], [], [], allPluginInfoList, schemaTypeDefinitions)
const currentNodeOutputVars = toNodeOutputVars([currentNode], false, () => true, [], [], [], [], allPluginInfoList, schemaTypeDefinitions)
const vars = await fetchNodeInspectVars(flowType, flowId, nodeId)
const varsWithSchemaType = vars.map((varItem) => {
const schemaType = currentNodeOutputVars[0]?.vars.find(v => v.variable === varItem.name)?.schemaType || ''

View File

@ -37,7 +37,6 @@ export const useWorkflowVariables = () => {
hideEnv,
hideChatVar,
conversationVariablesFirst,
memoryVarSortFn,
}: {
parentNode?: Node | null
beforeNodes: Node[]
@ -46,11 +45,11 @@ export const useWorkflowVariables = () => {
hideEnv?: boolean
hideChatVar?: boolean
conversationVariablesFirst?: boolean
memoryVarSortFn?: (a: string, b: string) => number
}): NodeOutPutVar[] => {
const {
conversationVariables,
environmentVariables,
memoryVariables,
ragPipelineVariables,
dataSourceList,
} = workflowStore.getState()
@ -61,6 +60,7 @@ export const useWorkflowVariables = () => {
isChatMode,
environmentVariables: hideEnv ? [] : environmentVariables,
conversationVariables: (isChatMode && !hideChatVar) ? conversationVariables : [],
memoryVariables: isChatMode ? memoryVariables : [],
ragVariables: ragPipelineVariables,
filterVar,
allPluginInfoList: {
@ -72,7 +72,6 @@ export const useWorkflowVariables = () => {
},
schemaTypeDefinitions,
conversationVariablesFirst,
memoryVarSortFn,
})
}, [t, workflowStore, schemaTypeDefinitions, buildInTools, customTools, workflowTools, mcpTools])

View File

@ -38,9 +38,6 @@ import { useStore } from '@/app/components/workflow/store'
import { useWorkflowVariableType } from '@/app/components/workflow/hooks'
import AddMemoryButton from './add-memory-button'
import { MEMORY_POPUP_SHOW_BY_EVENT_EMITTER } from './type'
import type {
MemoryVariable,
} from '@/app/components/workflow/types'
import MemoryCreateButton from '@/app/components/workflow/nodes/llm/components/memory-system/memory-create-button'
type Props = {
@ -86,8 +83,6 @@ type Props = {
titleClassName?: string
required?: boolean
isMemorySupported?: boolean
memoryVarInNode?: MemoryVariable[]
memoryVarInApp?: MemoryVariable[]
}
const Editor: FC<Props> = ({
@ -128,8 +123,6 @@ const Editor: FC<Props> = ({
editorContainerClassName,
required,
isMemorySupported,
memoryVarInNode = [],
memoryVarInApp = [],
}) => {
const { t } = useTranslation()
const { eventEmitter } = useEventEmitterContextContext()
@ -311,8 +304,6 @@ const Editor: FC<Props> = ({
editable={!readOnly}
isSupportFileVar={isSupportFileVar}
isMemorySupported
memoryVarInNode={memoryVarInNode}
memoryVarInApp={memoryVarInApp}
/>
{/* to patch Editor not support dynamic change editable status */}
{readOnly && <div className='absolute inset-0 z-10'></div>}

View File

@ -39,7 +39,7 @@ import type {
import type { VariableAssignerNodeType } from '@/app/components/workflow/nodes/variable-assigner/types'
import type { Field as StructField } from '@/app/components/workflow/nodes/llm/types'
import type { RAGPipelineVariable } from '@/models/pipeline'
import type { MemoryVariable } from '@/app/components/workflow/types'
import {
AGENT_OUTPUT_STRUCT,
FILE_STRUCT,
@ -82,7 +82,7 @@ export const isRagVariableVar = (valueSelector: ValueSelector) => {
}
export const isSpecialVar = (prefix: string): boolean => {
return ['sys', 'env', 'conversation', 'rag'].includes(prefix)
return ['sys', 'env', 'conversation', 'memory_block', 'rag'].includes(prefix)
}
export const hasValidChildren = (children: any): boolean => {
@ -313,7 +313,6 @@ const formatItem = (
allPluginInfoList: Record<string, ToolWithProvider[]>,
ragVars?: Var[],
schemaTypeDefinitions: SchemaTypeDefinition[] = [],
memoryVarSortFn?: (a: string, b: string) => number,
): NodeOutPutVar => {
const { id, data } = item
@ -629,15 +628,25 @@ const formatItem = (
}
case 'conversation': {
if (memoryVarSortFn)
data.chatVarList.sort(memoryVarSortFn)
res.vars = data.chatVarList.map((chatVar: ConversationVariable) => {
return {
variable: `conversation.${chatVar.name}`,
type: chatVar.value_type,
description: chatVar.description,
}
}) as Var[]
res.vars = [
...data.memoryVarList.map((memoryVar: MemoryVariable) => {
return {
variable: `memory_block.${memoryVar.node_id ? `${memoryVar.node_id}_` : ''}${memoryVar.id}`,
type: 'memory_block',
description: '',
isMemoryVariable: true,
memoryVariableName: memoryVar.name,
memoryVariableNodeId: memoryVar.node_id,
}
}) as Var[],
...data.chatVarList.map((chatVar: ConversationVariable) => {
return {
variable: `conversation.${chatVar.name}`,
type: chatVar.value_type,
description: chatVar.description,
}
}) as Var[],
]
break
}
@ -680,11 +689,13 @@ const formatItem = (
(() => {
const variableArr = v.variable.split('.')
const [first] = variableArr
if (isSpecialVar(first)) return variableArr
return [...selector, ...variableArr]
})(),
)
if (isCurrentMatched) return true
const isFile = v.type === VarType.file
@ -759,11 +770,11 @@ export const toNodeOutputVars = (
filterVar = (_payload: Var, _selector: ValueSelector) => true,
environmentVariables: EnvironmentVariable[] = [],
conversationVariables: ConversationVariable[] = [],
memoryVariables: MemoryVariable[] = [],
ragVariables: RAGPipelineVariable[] = [],
allPluginInfoList: Record<string, ToolWithProvider[]>,
schemaTypeDefinitions?: SchemaTypeDefinition[],
conversationVariablesFirst: boolean = false,
memoryVarSortFn?: (a: string, b: string) => number,
): NodeOutPutVar[] => {
// ENV_NODE data format
const ENV_NODE = {
@ -780,6 +791,7 @@ export const toNodeOutputVars = (
data: {
title: 'CONVERSATION',
type: 'conversation',
memoryVarList: memoryVariables,
chatVarList: conversationVariables,
},
}
@ -802,6 +814,8 @@ export const toNodeOutputVars = (
if (b.data.type === 'env') return -1
if (a.data.type === 'conversation') return 1
if (b.data.type === 'conversation') return -1
if (a.data.type === 'memory_block') return 1
if (b.data.type === 'memory_block') return -1
// sort nodes by x position
return (b.position?.x || 0) - (a.position?.x || 0)
})
@ -851,7 +865,6 @@ export const toNodeOutputVars = (
} as Var),
),
schemaTypeDefinitions,
memoryVarSortFn,
),
isStartNode: node.data.type === BlockEnum.Start,
}
@ -979,6 +992,7 @@ export const getVarType = ({
isConstant,
environmentVariables = [],
conversationVariables = [],
memoryVariables = [],
ragVariables = [],
allPluginInfoList,
schemaTypeDefinitions,
@ -993,6 +1007,7 @@ export const getVarType = ({
isConstant?: boolean;
environmentVariables?: EnvironmentVariable[];
conversationVariables?: ConversationVariable[];
memoryVariables?: MemoryVariable[];
ragVariables?: RAGPipelineVariable[];
allPluginInfoList: Record<string, ToolWithProvider[]>;
schemaTypeDefinitions?: SchemaTypeDefinition[];
@ -1006,6 +1021,7 @@ export const getVarType = ({
undefined,
environmentVariables,
conversationVariables,
memoryVariables,
ragVariables,
allPluginInfoList,
schemaTypeDefinitions,
@ -1132,12 +1148,12 @@ export const toNodeAvailableVars = ({
isChatMode,
environmentVariables,
conversationVariables,
memoryVariables,
ragVariables,
filterVar,
allPluginInfoList,
schemaTypeDefinitions,
conversationVariablesFirst,
memoryVarSortFn,
}: {
parentNode?: Node | null;
t?: any;
@ -1148,13 +1164,14 @@ export const toNodeAvailableVars = ({
environmentVariables?: EnvironmentVariable[];
// chat var
conversationVariables?: ConversationVariable[];
// memory variables
memoryVariables?: MemoryVariable[];
// rag variables
ragVariables?: RAGPipelineVariable[];
filterVar: (payload: Var, selector: ValueSelector) => boolean;
allPluginInfoList: Record<string, ToolWithProvider[]>;
schemaTypeDefinitions?: SchemaTypeDefinition[];
conversationVariablesFirst?: boolean
memoryVarSortFn?: (a: string, b: string) => number
}): NodeOutPutVar[] => {
const beforeNodesOutputVars = toNodeOutputVars(
beforeNodes,
@ -1162,11 +1179,11 @@ export const toNodeAvailableVars = ({
filterVar,
environmentVariables,
conversationVariables,
memoryVariables,
ragVariables,
allPluginInfoList,
schemaTypeDefinitions,
conversationVariablesFirst,
memoryVarSortFn,
)
const isInIteration = parentNode?.data.type === BlockEnum.Iteration
if (isInIteration) {
@ -1179,6 +1196,7 @@ export const toNodeAvailableVars = ({
isChatMode,
environmentVariables,
conversationVariables,
memoryVariables,
allPluginInfoList,
schemaTypeDefinitions,
})

View File

@ -64,6 +64,7 @@ const Item: FC<ItemProps> = ({
const isSys = itemData.variable.startsWith('sys.')
const isEnv = itemData.variable.startsWith('env.')
const isChatVar = itemData.variable.startsWith('conversation.')
const isMemoryVar = itemData.variable.startsWith('memory_block')
const isRagVariable = itemData.isRagVariable
const flatVarIcon = useMemo(() => {
if (!isFlat)
@ -147,7 +148,7 @@ const Item: FC<ItemProps> = ({
if (isFlat) {
onChange([itemData.variable], itemData)
}
else if (isSys || isEnv || isChatVar || isRagVariable) { // system variable | environment variable | conversation variable
else if (isSys || isEnv || isChatVar || isMemoryVar || isRagVariable) { // system variable | environment variable | conversation variable
onChange([...objPath, ...itemData.variable.split('.')], itemData)
}
else {
@ -157,10 +158,16 @@ const Item: FC<ItemProps> = ({
const variableCategory = useMemo(() => {
if (isEnv) return 'environment'
if (isChatVar) return 'conversation'
if (isMemoryVar) return 'memory_block'
if (isLoopVar) return 'loop'
if (isRagVariable) return 'rag'
return 'system'
}, [isEnv, isChatVar, isSys, isLoopVar, isRagVariable])
}, [isEnv, isChatVar, isMemoryVar, isSys, isLoopVar, isRagVariable])
const variableType = useMemo(() => {
if (itemData.type === 'memory_block')
return 'memory'
return itemData.type
}, [itemData.type])
return (
<PortalToFollowElem
open={open}
@ -187,7 +194,7 @@ const Item: FC<ItemProps> = ({
/>}
{isFlat && flatVarIcon}
{!isEnv && !isChatVar && !isRagVariable && (
{!isEnv && !isChatVar && !isMemoryVar && !isRagVariable && (
<div title={itemData.variable} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{varName}</div>
)}
{isEnv && (
@ -196,11 +203,15 @@ const Item: FC<ItemProps> = ({
{isChatVar && (
<div title={itemData.des} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.replace('conversation.', '')}</div>
)}
{isMemoryVar && (
<div title={itemData.memoryVariableName} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.memoryVariableName}</div>
)
}
{isRagVariable && (
<div title={itemData.des} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.split('.').slice(-1)[0]}</div>
)}
</div>
<div className='ml-1 shrink-0 text-xs font-normal capitalize text-text-tertiary'>{(preferSchemaType && itemData.schemaType) ? itemData.schemaType : itemData.type}</div>
<div className='ml-1 shrink-0 text-xs font-normal capitalize text-text-tertiary'>{(preferSchemaType && itemData.schemaType) ? itemData.schemaType : variableType}</div>
{
(isObj || isStructureOutput) && (
<ChevronRight className={cn('ml-0.5 h-3 w-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />

View File

@ -16,7 +16,6 @@ type Params = {
filterVar: (payload: Var, selector: ValueSelector) => boolean
passedInAvailableNodes?: Node[]
conversationVariablesFirst?: boolean
memoryVarSortFn?: (a: string, b: string) => number
}
// TODO: loop type?
@ -27,7 +26,6 @@ const useAvailableVarList = (nodeId: string, {
hideChatVar,
passedInAvailableNodes,
conversationVariablesFirst,
memoryVarSortFn,
}: Params = {
onlyLeafNodeVar: false,
filterVar: () => true,
@ -67,7 +65,7 @@ const useAvailableVarList = (nodeId: string, {
})
}
}
const availableVars = [...getNodeAvailableVars({
const nodeAvailableVars = getNodeAvailableVars({
parentNode: iterationNode,
beforeNodes: availableNodes,
isChatMode,
@ -75,7 +73,22 @@ const useAvailableVarList = (nodeId: string, {
hideEnv,
hideChatVar,
conversationVariablesFirst,
memoryVarSortFn,
})
const availableVars = [...nodeAvailableVars.map((availableVar) => {
if (availableVar.nodeId === 'conversation') {
return {
...availableVar,
vars: availableVar.vars.filter((v) => {
if (!v.memoryVariableNodeId)
return true
return v.memoryVariableNodeId === nodeId
}),
}
}
return availableVar
}), ...dataSourceRagVars]
return {

View File

@ -131,6 +131,7 @@ const useOneStepRun = <T>({
const { t } = useTranslation()
const { getBeforeNodesInSameBranch, getBeforeNodesInSameBranchIncludeParent } = useWorkflow() as any
const conversationVariables = useStore(s => s.conversationVariables)
const memoryVariables = useStore(s => s.memoryVariables)
const isChatMode = useIsChatMode()
const isIteration = data.type === BlockEnum.Iteration
const isLoop = data.type === BlockEnum.Loop
@ -159,7 +160,7 @@ const useOneStepRun = <T>({
dataSourceList: dataSourceList || [],
}
const allOutputVars = toNodeOutputVars(availableNodes, isChatMode, undefined, undefined, conversationVariables, [], allPluginInfoList, schemaTypeDefinitions)
const allOutputVars = toNodeOutputVars(availableNodes, isChatMode, undefined, undefined, conversationVariables, memoryVariables, [], allPluginInfoList, schemaTypeDefinitions)
const targetVar = allOutputVars.find(item => isSystem ? !!item.isStartNode : item.nodeId === valueSelector[0])
if (!targetVar)
return undefined

View File

@ -58,7 +58,7 @@ const useConfig = (id: string, payload: IterationNodeType) => {
mcpTools: mcpTools || [],
dataSourceList: dataSourceList || [],
}
const childrenNodeVars = toNodeOutputVars(iterationChildrenNodes, isChatMode, undefined, [], [], [], allPluginInfoList)
const childrenNodeVars = toNodeOutputVars(iterationChildrenNodes, isChatMode, undefined, [], [], [], [], allPluginInfoList)
const handleOutputVarChange = useCallback((output: ValueSelector | string, _varKindType: VarKindType, varInfo?: Var) => {
if (isEqual(inputs.output_selector, output as ValueSelector))

View File

@ -9,9 +9,6 @@ import Editor from '@/app/components/workflow/nodes/_base/components/prompt/edit
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
import Tooltip from '@/app/components/base/tooltip'
import { PromptRole } from '@/models/debug'
import type {
MemoryVariable,
} from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.llm'
@ -42,8 +39,6 @@ type Props = {
varList: Variable[]
handleAddVariable: (payload: any) => void
modelConfig?: ModelConfig
memoryVarInNode?: MemoryVariable[]
memoryVarInApp?: MemoryVariable[]
}
const roleOptions = [
@ -86,8 +81,6 @@ const ConfigPromptItem: FC<Props> = ({
varList,
handleAddVariable,
modelConfig,
memoryVarInNode = [],
memoryVarInApp = [],
}) => {
const { t } = useTranslation()
const workflowStore = useWorkflowStore()
@ -164,8 +157,6 @@ const ConfigPromptItem: FC<Props> = ({
</>
}
isMemorySupported
memoryVarInNode={memoryVarInNode}
memoryVarInApp={memoryVarInApp}
/>
)
}

View File

@ -14,9 +14,6 @@ import cn from '@/utils/classnames'
import Editor from '@/app/components/workflow/nodes/_base/components/prompt/editor'
import AddButton from '@/app/components/workflow/nodes/_base/components/add-button'
import { DragHandle } from '@/app/components/base/icons/src/vender/line/others'
import type {
MemoryVariable,
} from '@/app/components/workflow/types'
const i18nPrefix = 'workflow.nodes.llm'
@ -37,9 +34,6 @@ type Props = {
varList?: Variable[]
handleAddVariable: (payload: any) => void
modelConfig: ModelConfig
memoryVarSortFn?: (a: string, b: string) => number
memoryVarInNode?: MemoryVariable[]
memoryVarInApp?: MemoryVariable[]
}
const ConfigPrompt: FC<Props> = ({
@ -55,9 +49,6 @@ const ConfigPrompt: FC<Props> = ({
varList = [],
handleAddVariable,
modelConfig,
memoryVarSortFn,
memoryVarInNode,
memoryVarInApp,
}) => {
const { t } = useTranslation()
const workflowStore = useWorkflowStore()
@ -83,7 +74,6 @@ const ConfigPrompt: FC<Props> = ({
onlyLeafNodeVar: false,
filterVar,
conversationVariablesFirst: true,
memoryVarSortFn,
})
const handleChatModePromptChange = useCallback((index: number) => {
@ -215,8 +205,6 @@ const ConfigPrompt: FC<Props> = ({
varList={varList}
handleAddVariable={handleAddVariable}
modelConfig={modelConfig}
memoryVarInNode={memoryVarInNode}
memoryVarInApp={memoryVarInApp}
/>
</div>
)

View File

@ -64,9 +64,6 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
handleStructureOutputChange,
filterJinja2InputVar,
handleReasoningFormatChange,
memoryVarSortFn,
memoryVarInNode,
memoryVarInApp,
} = useConfig(id, data)
const { memoryType } = useMemory(id, data)
@ -158,9 +155,6 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
varList={inputs.prompt_config?.jinja2_variables || []}
handleAddVariable={handleAddVariable}
modelConfig={model}
memoryVarSortFn={memoryVarSortFn}
memoryVarInNode={memoryVarInNode}
memoryVarInApp={memoryVarInApp}
/>
)}

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import produce from 'immer'
import { EditionType, VarType } from '../../types'
import type { Memory, PromptItem, ValueSelector, Var, Variable } from '../../types'
@ -22,7 +22,6 @@ import useInspectVarsCrud from '@/app/components/workflow/hooks/use-inspect-vars
const useConfig = (id: string, payload: LLMNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const isChatMode = useIsChatMode()
const memoryVariables = useStore(s => s.memoryVariables)
const defaultConfig = useStore(s => s.nodesDefaultConfigs)?.[payload.type]
const [defaultRolePrefix, setDefaultRolePrefix] = useState<{ user: string; assistant: string }>({ user: '', assistant: '' })
@ -308,11 +307,11 @@ const useConfig = (id: string, payload: LLMNodeType) => {
}, [setInputs, deleteNodeInspectorVars, id])
const filterInputVar = useCallback((varPayload: Var) => {
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber, VarType.file, VarType.arrayFile].includes(varPayload.type)
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber, VarType.file, VarType.arrayFile, VarType.memory].includes(varPayload.type)
}, [])
const filterJinja2InputVar = useCallback((varPayload: Var) => {
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber, VarType.arrayBoolean, VarType.arrayObject, VarType.object, VarType.array, VarType.boolean].includes(varPayload.type)
return [VarType.number, VarType.string, VarType.secret, VarType.arrayString, VarType.arrayNumber, VarType.arrayBoolean, VarType.arrayObject, VarType.object, VarType.array, VarType.boolean, VarType.memory].includes(varPayload.type)
}, [])
const filterMemoryPromptVar = useCallback((varPayload: Var) => {
@ -335,29 +334,6 @@ const useConfig = (id: string, payload: LLMNodeType) => {
filterVar: filterMemoryPromptVar,
})
const memoryVarSortFn = useCallback((a: string, b: string) => {
const idsInNode = inputs.memory?.block_id || []
const aInNode = idsInNode.includes(a)
const bInNode = idsInNode.includes(b)
if (aInNode && !bInNode) return -1
if (!aInNode && bInNode) return 1
return a.localeCompare(b)
}, [inputs.memory?.block_id])
const memoryVarInNode = useMemo(() => {
const idsInNode = inputs.memory?.block_id || []
return memoryVariables
.filter(varItem => idsInNode.includes(varItem.id))
}, [inputs.memory?.block_id, memoryVariables])
const memoryVarInApp = useMemo(() => {
const idsInApp = inputs.memory?.block_id || []
return memoryVariables
.filter(varItem => !idsInApp.includes(varItem.id))
}, [inputs.memory?.block_id, memoryVariables])
return {
readOnly,
isChatMode,
@ -391,9 +367,6 @@ const useConfig = (id: string, payload: LLMNodeType) => {
handleStructureOutputEnableChange,
filterJinja2InputVar,
handleReasoningFormatChange,
memoryVarSortFn,
memoryVarInNode,
memoryVarInApp,
}
}

View File

@ -38,7 +38,7 @@ const useConfig = (id: string, payload: LoopNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
const isChatMode = useIsChatMode()
const conversationVariables = useStore(s => s.conversationVariables)
const memoryVariables = useStore(s => s.memoryVariables)
const { inputs, setInputs } = useNodeCrud<LoopNodeType>(id, payload)
const inputsRef = useRef(inputs)
const handleInputsChange = useCallback((newInputs: LoopNodeType) => {
@ -65,7 +65,7 @@ const useConfig = (id: string, payload: LoopNodeType) => {
mcpTools: mcpTools || [],
dataSourceList: dataSourceList || [],
}
const childrenNodeVars = toNodeOutputVars(loopChildrenNodes, isChatMode, undefined, [], conversationVariables, [], allPluginInfoList)
const childrenNodeVars = toNodeOutputVars(loopChildrenNodes, isChatMode, undefined, [], conversationVariables, memoryVariables, [], allPluginInfoList)
const {
getIsVarFileAttribute,

View File

@ -1,7 +1,6 @@
import React, { useCallback, useRef } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import { v4 as uuid4 } from 'uuid'
import {
useForm as useTanstackForm,
useStore as useTanstackStore,
@ -84,7 +83,7 @@ const ChatVariableModal = ({
return notify({ type: 'error', message: 'object key can not be empty' })
onSave({
id: chatVar ? chatVar.id : uuid4(),
id: chatVar ? chatVar.id : `${Date.now()}`,
name,
value_type,
value: editInJSON ? JSON.parse(value) : value,

View File

@ -44,7 +44,7 @@ export const useTypeSchema = () => {
label: t('workflow.chatVariable.modal.type'),
type: 'select',
options: typeList.map(type => ({
label: type,
label: type === ChatVarType.Memory ? 'memory' : type,
value: type,
})),
onChange: handleTypeChange,

View File

@ -7,7 +7,7 @@ export enum ChatVarType {
ArrayNumber = 'array[number]',
ArrayBoolean = 'array[boolean]',
ArrayObject = 'array[object]',
Memory = 'memory',
Memory = 'memory_block',
}
export type ObjectValueItem = {

View File

@ -312,7 +312,7 @@ export enum VarType {
arrayFile = 'array[file]',
any = 'any',
arrayAny = 'array[any]',
memory = 'memory',
memory = 'memory_block',
}
export enum ValueType {
@ -334,6 +334,8 @@ export type Var = {
nodeId?: string
isRagVariable?: boolean
schemaType?: string
memoryVariableName?: string
memoryVariableNodeId?: string
}
export type NodeOutPutVar = {