This commit is contained in:
zxhlyh 2025-08-28 10:53:29 +08:00
parent 01f0ee339e
commit a7156244f7
7 changed files with 103 additions and 32 deletions

View File

@ -29,7 +29,7 @@ export const useNodeUpdate = (id: string) => {
return nodes.find(node => node.id === id)
}, [store, id])
const handleNodeDataUpdate = useCallback((data: Partial<CommonNodeType>) => {
const handleNodeDataUpdate = useCallback((data: any) => {
handleNodeDataUpdateWithSyncDraft({
id,
data,

View File

@ -5,6 +5,10 @@ import {
} from 'react'
import type { LLMNodeType } from '../../types'
import { useNodeUpdate } from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import {
MEMORY_DEFAULT,
} from './linear-memory'
import type { Memory } from '@/app/components/workflow/types'
export const useMemory = (
id: string,
@ -18,23 +22,77 @@ export const useMemory = (
return false
}, [memory])
const [collapsed, setCollapsed] = useState(initCollapsed)
const { getNodeData } = useNodeUpdate(id)
const {
getNodeData,
handleNodeDataUpdate,
} = useNodeUpdate(id)
const handleMemoryTypeChange = useCallback((value: string) => {
const nodeData = getNodeData()
console.log('nodeData', nodeData)
const { memory: memoryData = {} } = nodeData as any
if (value === 'disabled')
console.log('disabled')
if (value === 'linear')
if (value === 'disabled') {
setCollapsed(true)
if (value === 'block')
setCollapsed(true)
}, [getNodeData])
handleNodeDataUpdate({
memory: {
...memoryData,
enabled: false,
mode: '',
},
})
}
if (value === 'linear') {
setCollapsed(false)
handleNodeDataUpdate({
memory: {
...memoryData,
enabled: true,
mode: 'linear',
window: memoryData?.window || MEMORY_DEFAULT.window,
query_prompt_template: memoryData?.query_prompt_template || MEMORY_DEFAULT.query_prompt_template,
},
})
}
if (value === 'block') {
setCollapsed(false)
handleNodeDataUpdate({
memory: {
...memoryData,
enabled: true,
mode: 'block',
block_id: memoryData?.block_id || [],
query_prompt_template: memoryData?.query_prompt_template || MEMORY_DEFAULT.query_prompt_template,
},
})
}
}, [getNodeData, handleNodeDataUpdate])
const handleUpdateMemory = useCallback((memory: Memory) => {
handleNodeDataUpdate({
memory,
})
}, [handleNodeDataUpdate])
const memoryType = useMemo(() => {
if (memory?.enabled) {
if (memory.mode === 'linear')
return 'linear'
if (memory.mode === 'block')
return 'block'
}
else {
if (memory?.window.enabled)
return 'linear'
return 'disabled'
}
}, [memory])
return {
collapsed,
setCollapsed,
handleMemoryTypeChange,
memoryType,
handleUpdateMemory,
}
}

View File

@ -13,10 +13,15 @@ import type { Memory } from '@/app/components/workflow/types'
import type { LLMNodeType } from '../../types'
import { useMemory } from './hooks'
type MemoryProps = Pick<Node, 'id' | 'data'>
type MemoryProps = Pick<Node, 'id' | 'data'> & {
readonly?: boolean
canSetRoleName?: boolean
}
const MemorySystem = ({
id,
data,
readonly,
canSetRoleName,
}: MemoryProps) => {
const { t } = useTranslation()
const { memory } = data as LLMNodeType
@ -24,6 +29,8 @@ const MemorySystem = ({
collapsed,
setCollapsed,
handleMemoryTypeChange,
memoryType,
handleUpdateMemory,
} = useMemory(id, data as LLMNodeType)
return (
@ -40,29 +47,31 @@ const MemorySystem = ({
<div className='flex grow items-center justify-between'>
<div className='flex items-center'>
<div className='system-sm-semibold-uppercase mr-0.5 text-text-secondary'>
{t('workflow.nodes.common.errorHandle.title')}
{t('workflow.nodes.common.memory.memory')}
</div>
<Tooltip
popupContent={t('workflow.nodes.common.errorHandle.tip')}
popupContent={t('workflow.nodes.common.memory.memoryTip')}
triggerClassName='w-4 h-4'
/>
{collapseIcon}
</div>
<MemorySelector
value='linear'
value={memoryType}
onSelected={handleMemoryTypeChange}
readonly={readonly}
/>
</div>
)}
>
<>
{
(memory?.mode === 'linear' || !memory?.mode) && !collapsed && (
memoryType === 'linear' && !collapsed && (
<LinearMemory
className='mt-2'
payload={memory as Memory}
onChange={() => {
console.log('onChange')
}}
onChange={handleUpdateMemory}
readonly={readonly}
canSetRoleName={canSetRoleName}
/>
)
}

View File

@ -9,16 +9,17 @@ import Slider from '@/app/components/base/slider'
import Input from '@/app/components/base/input'
import type { Memory } from '@/app/components/workflow/types'
import { MemoryRole } from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
const WINDOW_SIZE_MIN = 1
const WINDOW_SIZE_MAX = 100
const WINDOW_SIZE_DEFAULT = 50
const MEMORY_DEFAULT: Memory = {
export const WINDOW_SIZE_DEFAULT = 50
export const MEMORY_DEFAULT: Memory = {
window: { enabled: false, size: WINDOW_SIZE_DEFAULT },
query_prompt_template: '{{#sys.query#}}\n\n{{#sys.files#}}',
}
type RoleItemProps = {
readonly: boolean
readonly?: boolean
title: string
value: string
onChange: (value: string) => void
@ -50,12 +51,14 @@ type LinearMemoryProps = {
readonly?: boolean
onChange: (payload: Memory) => void
canSetRoleName?: boolean
className?: string
}
const LinearMemory = ({
payload,
readonly,
onChange,
canSetRoleName,
className,
}: LinearMemoryProps) => {
const i18nPrefix = 'workflow.nodes.common.memory'
const { t } = useTranslation()
@ -119,7 +122,7 @@ const LinearMemory = ({
return (
<>
<div className='flex justify-between'>
<div className={cn('flex justify-between', className)}>
<div className='flex h-8 items-center space-x-2'>
<Switch
defaultValue={payload?.window?.enabled}

View File

@ -15,12 +15,14 @@ import {
import Button from '@/app/components/base/button'
type MemorySelectorProps = {
value: string
value?: string
onSelected: (value: string) => void
readonly?: boolean
}
const MemorySelector = ({
value,
onSelected,
readonly,
}: MemorySelectorProps) => {
const { t } = useTranslation()
const [open, setOpen] = useState(false)
@ -51,14 +53,17 @@ const MemorySelector = ({
offset={4}
>
<PortalToFollowElemTrigger onClick={(e) => {
if (readonly)
return
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
setOpen(v => !v)
}}>
<Button
size='small'
disabled={readonly}
>
{selectedOption?.label}
{selectedOption?.label || t('workflow.nodes.common.memory.disabled.title')}
<RiArrowDownSLine className='h-3.5 w-3.5' />
</Button>
</PortalToFollowElemTrigger>
@ -70,6 +75,8 @@ const MemorySelector = ({
key={option.value}
className='flex cursor-pointer rounded-lg p-2 pr-3 hover:bg-state-base-hover'
onClick={(e) => {
if (readonly)
return
e.stopPropagation()
e.nativeEvent.stopImmediatePropagation()
onSelected(option.value)

View File

@ -1,7 +1,6 @@
import type { FC } from 'react'
import React, { useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import MemoryConfig from '../_base/components/memory-config'
import VarReferencePicker from '../_base/components/variable/var-reference-picker'
import ConfigVision from '../_base/components/config-vision'
import useConfig from './use-config'
@ -53,7 +52,6 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
handleVarListChange,
handleVarNameChange,
handleSyeQueryChange,
handleMemoryChange,
handleVisionResolutionEnabledChange,
handleVisionResolutionChange,
isModelSupportStructuredOutput,
@ -221,15 +219,11 @@ const Panel: FC<NodePanelProps<LLMNodeType>> = ({
{isChatMode && (
<>
<Split />
<MemoryConfig
readonly={readOnly}
config={{ data: inputs.memory }}
onChange={handleMemoryChange}
canSetRoleName={!isCompletionModel}
/>
<MemorySystem
id={id}
data={data}
readonly={readOnly}
canSetRoleName={isCompletionModel}
/>
</>
)}

View File

@ -266,7 +266,7 @@ export type Memory = {
size: number | string | null
}
query_prompt_template: string
block_id?: string
block_id?: string[]
mode?: 'linear' | 'block'
}