mirror of https://github.com/langgenius/dify.git
fix: memory variable item
This commit is contained in:
parent
2944f831e2
commit
9d310fed92
|
|
@ -85,9 +85,11 @@ export const useNodesSyncDraft = () => {
|
|||
},
|
||||
environment_variables: environmentVariables,
|
||||
conversation_variables: conversationVariables,
|
||||
memory_blocks: memoryVariables.map(({ value_type, more, model, ...rest }) => {
|
||||
memory_blocks: memoryVariables.map(({ value_type, scope, more, node_id, model, ...rest }) => {
|
||||
return {
|
||||
...rest,
|
||||
node_id: scope === 'node' ? node_id : undefined,
|
||||
scope,
|
||||
model: model ? {
|
||||
completion_params: model.completion_params,
|
||||
mode: model.mode,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { useCallback } from 'react'
|
||||
import {
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import {
|
||||
useStore,
|
||||
useWorkflowStore,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { useMemoryVariables } from './hooks/use-memory-variables'
|
|||
import Confirm from '@/app/components/base/confirm'
|
||||
import { Memory as MemoryIcon } from '@/app/components/base/icons/src/vender/line/others'
|
||||
import VariableModal from '@/app/components/workflow/panel/chat-variable-panel/components/variable-modal'
|
||||
import cn from '@/utils/classnames'
|
||||
|
||||
type BlockMemoryProps = {
|
||||
id: string
|
||||
|
|
@ -21,6 +22,7 @@ type BlockMemoryProps = {
|
|||
}
|
||||
const BlockMemory = ({ id }: BlockMemoryProps) => {
|
||||
const { t } = useTranslation()
|
||||
const [destructiveItemId, setDestructiveItemId] = useState<string | undefined>(undefined)
|
||||
const {
|
||||
memoryVariablesInUsed,
|
||||
editMemoryVariable,
|
||||
|
|
@ -55,7 +57,10 @@ const BlockMemory = ({ id }: BlockMemoryProps) => {
|
|||
memoryVariablesInUsed.map(memoryVariable => (
|
||||
<div
|
||||
key={memoryVariable.id}
|
||||
className='group flex h-8 items-center space-x-1 rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2 pr-1 shadow-xs hover:border hover:border-state-destructive-solid hover:bg-state-destructive-hover'>
|
||||
className={cn(
|
||||
'group flex h-8 items-center space-x-1 rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg pl-2 pr-1 shadow-xs',
|
||||
destructiveItemId === memoryVariable.id && 'border border-state-destructive-solid bg-state-destructive-hover',
|
||||
)}>
|
||||
<MemoryIcon className='h-4 w-4 text-util-colors-teal-teal-700' />
|
||||
<div
|
||||
title={memoryVariable.name}
|
||||
|
|
@ -63,22 +68,30 @@ const BlockMemory = ({ id }: BlockMemoryProps) => {
|
|||
>
|
||||
{memoryVariable.name}
|
||||
</div>
|
||||
<Badge className='shrink-0'>
|
||||
<Badge className={cn('shrink-0 group-hover:hidden', editMemoryVariable?.id === memoryVariable.id && 'hidden')}>
|
||||
{memoryVariable.term}
|
||||
</Badge>
|
||||
<ActionButton
|
||||
className='hidden shrink-0 group-hover:block'
|
||||
className={cn(
|
||||
'hidden shrink-0 group-hover:inline-flex',
|
||||
editMemoryVariable?.id === memoryVariable.id && 'inline-flex bg-state-base-hover text-text-secondary',
|
||||
)}
|
||||
size='m'
|
||||
onClick={() => handleSetEditMemoryVariable(memoryVariable.id)}
|
||||
>
|
||||
<RiEditLine className='h-4 w-4 text-text-tertiary' />
|
||||
</ActionButton>
|
||||
<ActionButton
|
||||
className='hidden shrink-0 group-hover:block'
|
||||
className={cn(
|
||||
'hidden shrink-0 bg-transparent hover:bg-transparent hover:text-text-destructive group-hover:inline-flex',
|
||||
editMemoryVariable?.id === memoryVariable.id && 'inline-flex',
|
||||
)}
|
||||
size='m'
|
||||
onClick={() => handleDelete(memoryVariable.id)}
|
||||
onMouseOver={() => setDestructiveItemId(memoryVariable.id)}
|
||||
onMouseOut={() => setDestructiveItemId(undefined)}
|
||||
>
|
||||
<RiDeleteBinLine className='h-4 w-4 text-text-destructive' />
|
||||
<RiDeleteBinLine className={cn('h-4 w-4', destructiveItemId === memoryVariable.id && 'text-text-destructive')} />
|
||||
</ActionButton>
|
||||
</div>
|
||||
))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
import { memo } from 'react'
|
||||
import { useStore } from 'reactflow'
|
||||
import VariableItem from './variable-item'
|
||||
import BlockIcon from '@/app/components/workflow/block-icon'
|
||||
import { BlockEnum } from '@/app/components/workflow/types'
|
||||
import type { MemoryVariable } from '@/app/components/workflow/types'
|
||||
|
||||
type VariableItemWithNodeProps = {
|
||||
nodeId: string
|
||||
memoryVariables: MemoryVariable[]
|
||||
onEdit: (memoryVariable: MemoryVariable) => void
|
||||
onDelete: (memoryVariable: MemoryVariable) => void
|
||||
currentVarId?: string
|
||||
}
|
||||
const VariableItemWithNode = ({
|
||||
nodeId,
|
||||
memoryVariables,
|
||||
onEdit,
|
||||
onDelete,
|
||||
currentVarId,
|
||||
}: VariableItemWithNodeProps) => {
|
||||
const currentNode = useStore(s => s.nodeInternals.get(nodeId))
|
||||
|
||||
if (!currentNode) return null
|
||||
|
||||
return (
|
||||
<div className='space-y-1 py-1'>
|
||||
<div className='mb-1 flex items-center'>
|
||||
<BlockIcon className='mr-1.5 shrink-0' type={BlockEnum.LLM} />
|
||||
<div
|
||||
className='system-sm-medium grow truncate text-text-secondary'
|
||||
title={currentNode?.data.title}
|
||||
>
|
||||
{currentNode?.data.title}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
memoryVariables.map(memoryVariable => (
|
||||
<VariableItem
|
||||
key={memoryVariable.id}
|
||||
item={memoryVariable}
|
||||
onEdit={onEdit}
|
||||
onDelete={onDelete}
|
||||
scope='node'
|
||||
term={memoryVariable.term}
|
||||
currentVarId={currentVarId}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(VariableItemWithNode)
|
||||
|
|
@ -8,17 +8,24 @@ import {
|
|||
import type { ConversationVariable, MemoryVariable } from '@/app/components/workflow/types'
|
||||
import cn from '@/utils/classnames'
|
||||
import { ChatVarType } from '../type'
|
||||
import Badge from '@/app/components/base/badge'
|
||||
|
||||
type VariableItemProps = {
|
||||
item: ConversationVariable | MemoryVariable
|
||||
onEdit: (item: ConversationVariable | MemoryVariable) => void
|
||||
onDelete: (item: ConversationVariable | MemoryVariable) => void
|
||||
scope?: string
|
||||
term?: string
|
||||
currentVarId?: string
|
||||
}
|
||||
|
||||
const VariableItem = ({
|
||||
item,
|
||||
onEdit,
|
||||
onDelete,
|
||||
scope,
|
||||
term,
|
||||
currentVarId,
|
||||
}: VariableItemProps) => {
|
||||
const [destructive, setDestructive] = useState(false)
|
||||
return (
|
||||
|
|
@ -26,7 +33,7 @@ const VariableItem = ({
|
|||
'radius-md mb-1 border border-components-panel-border-subtle bg-components-panel-on-panel-item-bg px-2.5 py-2 shadow-xs hover:bg-components-panel-on-panel-item-bg-hover',
|
||||
destructive && 'border-state-destructive-border hover:bg-state-destructive-hover',
|
||||
)}>
|
||||
<div className='flex items-center justify-between'>
|
||||
<div className='group flex items-center justify-between'>
|
||||
<div className='flex grow items-center gap-1'>
|
||||
{
|
||||
item.value_type === ChatVarType.Memory && (
|
||||
|
|
@ -42,16 +49,20 @@ const VariableItem = ({
|
|||
<div className='system-xs-medium text-text-tertiary'>{capitalize(item.value_type)}</div>
|
||||
</div>
|
||||
<div className='flex shrink-0 items-center gap-1 text-text-tertiary'>
|
||||
<div className='radius-md cursor-pointer p-1 hover:bg-state-base-hover hover:text-text-secondary'>
|
||||
<div className={cn('radius-md hidden cursor-pointer p-1 hover:bg-state-base-hover hover:text-text-secondary group-hover:block', currentVarId === item.id && 'block bg-state-base-hover text-text-secondary')}>
|
||||
<RiEditLine className='h-4 w-4' onClick={() => onEdit(item)}/>
|
||||
</div>
|
||||
<div
|
||||
className='radius-md cursor-pointer p-1 hover:bg-state-destructive-hover hover:text-text-destructive'
|
||||
className={cn('radius-md hidden cursor-pointer p-1 hover:bg-state-destructive-hover hover:text-text-destructive group-hover:block', currentVarId === item.id && 'block')}
|
||||
onMouseOver={() => setDestructive(true)}
|
||||
onMouseOut={() => setDestructive(false)}
|
||||
>
|
||||
<RiDeleteBinLine className='h-4 w-4' onClick={() => onDelete(item)}/>
|
||||
</div>
|
||||
<div className={cn('flex h-6 items-center gap-0.5 group-hover:hidden', currentVarId === item.id && 'hidden')}>
|
||||
{scope && <Badge text={scope} />}
|
||||
{term && <Badge text={term} />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import {
|
|||
useCallback,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { groupBy } from 'lodash-es'
|
||||
import {
|
||||
useStoreApi,
|
||||
} from 'reactflow'
|
||||
|
|
@ -30,16 +31,24 @@ import cn from '@/utils/classnames'
|
|||
import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud'
|
||||
import { ChatVarType } from './type'
|
||||
import { useMemoryVariable } from '@/app/components/workflow/hooks'
|
||||
import VariableItemWithNode from './components/variable-item-with-node'
|
||||
|
||||
const ChatVariablePanel = () => {
|
||||
const { t } = useTranslation()
|
||||
const docLink = useDocLink()
|
||||
const store = useStoreApi()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { handleAddMemoryVariable, handleUpdateMemoryVariable, handleDeleteMemoryVariable } = useMemoryVariable()
|
||||
const appScopeMemoryVariables = useStore(s => s.memoryVariables.filter(v => v.scope === 'app'))
|
||||
const nodeScopeMemoryVariables = useStore((s) => {
|
||||
return groupBy(s.memoryVariables.filter(v => v.scope === 'node'), 'node_id')
|
||||
})
|
||||
const {
|
||||
handleAddMemoryVariable,
|
||||
handleUpdateMemoryVariable,
|
||||
handleDeleteMemoryVariable,
|
||||
} = useMemoryVariable()
|
||||
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()
|
||||
|
|
@ -220,12 +229,15 @@ const ChatVariablePanel = () => {
|
|||
</div>
|
||||
<div className='grow overflow-y-auto rounded-b-2xl px-4'>
|
||||
{
|
||||
memoryVariables.map(memoryVariable => (
|
||||
appScopeMemoryVariables.map(memoryVariable => (
|
||||
<VariableItem
|
||||
key={memoryVariable.id}
|
||||
item={memoryVariable}
|
||||
onEdit={handleEdit}
|
||||
onDelete={deleteCheck}
|
||||
term={memoryVariable.term}
|
||||
scope='conv'
|
||||
currentVarId={currentVar?.id}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
|
@ -235,8 +247,31 @@ const ChatVariablePanel = () => {
|
|||
item={chatVar}
|
||||
onEdit={handleEdit}
|
||||
onDelete={deleteCheck}
|
||||
currentVarId={currentVar?.id}
|
||||
/>
|
||||
))}
|
||||
{
|
||||
!!Object.keys(nodeScopeMemoryVariables).length && (
|
||||
<div className='pb-1 pt-4'>
|
||||
<div className='system-xs-medium-uppercase mb-1 flex items-center space-x-2 text-text-tertiary'>
|
||||
{t('workflow.chatVariable.nodeScopeMemory')}
|
||||
<div className='ml-2 h-px grow bg-gradient-to-r from-divider-regular to-background-gradient-mask-transparent'></div>
|
||||
</div>
|
||||
{
|
||||
Object.keys(nodeScopeMemoryVariables).map(nodeId => (
|
||||
<VariableItemWithNode
|
||||
key={nodeId}
|
||||
nodeId={nodeId}
|
||||
memoryVariables={nodeScopeMemoryVariables[nodeId]}
|
||||
onEdit={handleEdit}
|
||||
onDelete={deleteCheck}
|
||||
currentVarId={currentVar?.id}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<RemoveEffectVarConfirm
|
||||
isShow={showRemoveVarConfirm}
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ const translation = {
|
|||
panelDescription: 'Conversation Variables are used to store interactive information that LLM needs to remember, including conversation history, uploaded files, user preferences. They are read-write. ',
|
||||
docLink: 'Visit our docs to learn more.',
|
||||
button: 'Add Variable',
|
||||
nodeScopeMemory: 'Node Scope Memory',
|
||||
modal: {
|
||||
title: 'Add Conversation Variable',
|
||||
editTitle: 'Edit Conversation Variable',
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ const translation = {
|
|||
panelDescription: '会话变量用于存储 LLM 需要的上下文信息,如用户偏好、对话历史等。它是可读写的。',
|
||||
docLink: '查看文档了解更多。',
|
||||
button: '添加变量',
|
||||
nodeScopeMemory: '节点范围记忆',
|
||||
modal: {
|
||||
title: '添加会话变量',
|
||||
editTitle: '编辑会话变量',
|
||||
|
|
|
|||
Loading…
Reference in New Issue