feat: workflow knowledge retrieval metadata

This commit is contained in:
zxhlyh
2025-03-05 16:28:47 +08:00
parent 591063a755
commit c47c77f556
17 changed files with 289 additions and 125 deletions

View File

@@ -4,6 +4,7 @@ const useNodeCrud = <T>(id: string, data: CommonNodeType<T>) => {
const { handleNodeDataUpdateWithSyncDraft } = useNodeDataUpdate()
const setInputs = (newInputs: CommonNodeType<T>) => {
console.log(newInputs, 'xx')
handleNodeDataUpdateWithSyncDraft({
id,
data: newInputs,

View File

@@ -1,10 +1,12 @@
import {
useCallback,
useMemo,
useState,
} from 'react'
import {
RiAddLine,
} from '@remixicon/react'
import MetadataIcon from './metadata-icon'
import {
PortalToFollowElem,
PortalToFollowElemContent,
@@ -13,6 +15,7 @@ import {
import Button from '@/app/components/base/button'
import Input from '@/app/components/base/input'
import type { MetadataShape } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import type { MetadataInDoc } from '@/models/datasets'
const AddCondition = ({
metadataList,
@@ -25,6 +28,11 @@ const AddCondition = ({
return metadataList?.filter(metadata => metadata.name.includes(searchText))
}, [metadataList, searchText])
const handleAddConditionWrapped = useCallback((item: MetadataInDoc) => {
handleAddCondition?.(item)
setOpen(false)
}, [handleAddCondition])
return (
<PortalToFollowElem
open={open}
@@ -61,10 +69,13 @@ const AddCondition = ({
key={metadata.id}
className='flex items-center px-3 h-6 rounded-md system-sm-medium text-text-secondary cursor-pointer hover:bg-state-base-hover'
>
<div className='mr-1 p-[1px]'>
<MetadataIcon type={metadata.type} />
</div>
<div
className='grow truncate'
title={metadata.name}
onClick={() => handleAddCondition?.(metadata.name)}
onClick={() => handleAddConditionWrapped(metadata)}
>
{metadata.name}
</div>

View File

@@ -3,7 +3,10 @@ import {
useMemo,
useState,
} from 'react'
import { RiDeleteBinLine } from '@remixicon/react'
import {
RiDeleteBinLine,
} from '@remixicon/react'
import MetadataIcon from '../metadata-icon'
import {
VARIABLE_REGEX,
comparisonOperatorNotRequireValue,
@@ -12,7 +15,6 @@ import ConditionOperator from './condition-operator'
import ConditionString from './condition-string'
import ConditionNumber from './condition-number'
import ConditionDate from './condition-date'
import { useCondition } from './hooks'
import type {
ComparisonOperator,
HandleRemoveCondition,
@@ -21,11 +23,6 @@ import type {
MetadataShape,
} from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import { MetadataFilteringVariableType } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import type {
Node,
NodeOutPutVar,
} from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
type ConditionItemProps = {
@@ -34,9 +31,7 @@ type ConditionItemProps = {
condition: MetadataFilteringCondition // condition may the condition of case or condition of sub variable
onRemoveCondition?: HandleRemoveCondition
onUpdateCondition?: HandleUpdateCondition
nodesOutputVars: NodeOutPutVar[]
availableNodes: Node[]
} & Pick<MetadataShape, 'metadataList'>
} & Pick<MetadataShape, 'metadataList' | 'availableStringVars' | 'availableStringNodesWithParent' | 'availableNumberVars' | 'availableNumberNodesWithParent'>
const ConditionItem = ({
className,
disabled,
@@ -44,11 +39,12 @@ const ConditionItem = ({
onRemoveCondition,
onUpdateCondition,
metadataList = [],
nodesOutputVars,
availableNodes,
availableStringVars = [],
availableStringNodesWithParent = [],
availableNumberVars = [],
availableNumberNodesWithParent = [],
}: ConditionItemProps) => {
const [isHovered, setIsHovered] = useState(false)
const { getConditionVariableType } = useCondition()
const canChooseOperator = useMemo(() => {
if (disabled)
@@ -66,7 +62,13 @@ const ConditionItem = ({
}, [metadataList, condition.name])
const handleConditionOperatorChange = useCallback((operator: ComparisonOperator) => {
onUpdateCondition?.(condition.name, { ...condition, comparison_operator: operator })
onUpdateCondition?.(
condition.name,
{
...condition,
value: comparisonOperatorNotRequireValue(condition.comparison_operator) ? undefined : condition.value,
comparison_operator: operator,
})
}, [onUpdateCondition, condition])
const valueAndValueMethod = useMemo(() => {
@@ -95,7 +97,7 @@ const ConditionItem = ({
valueMethod: 'constant',
}
}, [currentMetadata, condition.value])
const [localValueMethod, setLocalValueMethod] = useState(valueAndValueMethod.value)
const [localValueMethod, setLocalValueMethod] = useState(valueAndValueMethod.valueMethod)
const handleValueMethodChange = useCallback((v: string) => {
setLocalValueMethod(v)
@@ -114,9 +116,12 @@ const ConditionItem = ({
)}>
<div className='flex items-center p-1'>
<div className='grow w-0'>
<div className='inline-flex items-center h-6 border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark rounded-md shadow-xs'>
<div className='mr-0.5 system-xs-medium text-text-secondary'>Language</div>
<div className='system-xs-regular text-text-tertiary'>string</div>
<div className='inline-flex items-center pl-1 pr-1.5 h-6 border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark rounded-md shadow-xs'>
<div className='mr-0.5 p-[1px]'>
<MetadataIcon type={currentMetadata?.type} className='w-3 h-3' />
</div>
<div className='mr-0.5 system-xs-medium text-text-secondary'>{currentMetadata?.name}</div>
<div className='system-xs-regular text-text-tertiary'>{currentMetadata?.type}</div>
</div>
</div>
<div className='mx-1 w-[1px] h-3 bg-divider-regular'></div>
@@ -127,38 +132,40 @@ const ConditionItem = ({
onSelect={handleConditionOperatorChange}
/>
</div>
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && getConditionVariableType(condition.name) === MetadataFilteringVariableType.string && (
<ConditionString
valueMethod={localValueMethod}
onValueMethodChange={handleValueMethodChange}
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
value={valueAndValueMethod.value}
onChange={handleValueChange}
/>
)
}
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && getConditionVariableType(condition.name) === MetadataFilteringVariableType.number && (
<ConditionNumber
valueMethod={localValueMethod}
onValueMethodChange={handleValueMethodChange}
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
value={valueAndValueMethod.value}
onChange={handleValueChange}
/>
)
}
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && getConditionVariableType(condition.name) === MetadataFilteringVariableType.date && (
<ConditionDate
value={condition.value}
onChange={handleValueChange}
/>
)
}
<div className='border-t border-t-divider-subtle'>
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && currentMetadata?.type === MetadataFilteringVariableType.string && (
<ConditionString
valueMethod={localValueMethod}
onValueMethodChange={handleValueMethodChange}
nodesOutputVars={availableStringVars}
availableNodes={availableStringNodesWithParent}
value={valueAndValueMethod.value}
onChange={handleValueChange}
/>
)
}
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && currentMetadata?.type === MetadataFilteringVariableType.number && (
<ConditionNumber
valueMethod={localValueMethod}
onValueMethodChange={handleValueMethodChange}
nodesOutputVars={availableNumberVars}
availableNodes={availableNumberNodesWithParent}
value={valueAndValueMethod.value}
onChange={handleValueChange}
/>
)
}
{
!comparisonOperatorNotRequireValue(condition.comparison_operator) && currentMetadata?.type === MetadataFilteringVariableType.time && (
<ConditionDate
value={condition.value}
onChange={handleValueChange}
/>
)
}
</div>
</div>
<div
className='shrink-0 flex items-center justify-center ml-1 mt-1 w-6 h-6 rounded-lg cursor-pointer hover:bg-state-destructive-hover text-text-tertiary hover:text-text-destructive'

View File

@@ -7,6 +7,7 @@ import type {
NodeOutPutVar,
ValueSelector,
} from '@/app/components/workflow/types'
import Input from '@/app/components/base/input'
type ConditionNumberProps = {
value?: string | number
@@ -36,7 +37,7 @@ const ConditionNumber = ({
{
valueMethod === 'variable' && (
<ConditionVariableSelector
valueSelector={(value as string).split('.')}
valueSelector={value ? (value as string).split('.') : []}
onChange={handleVariableValueChange}
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
@@ -45,10 +46,12 @@ const ConditionNumber = ({
}
{
valueMethod === 'constant' && (
<input
<Input
className='bg-transparent hover:bg-transparent outline-none border-none focus:shadow-none focus:bg-transparent'
value={value}
type='number'
onChange={e => onChange(e.target.value)}
placeholder='Enter value'
type='number'
/>
)
}

View File

@@ -7,6 +7,7 @@ import type {
NodeOutPutVar,
ValueSelector,
} from '@/app/components/workflow/types'
import Input from '@/app/components/base/input'
type ConditionStringProps = {
value?: string
@@ -17,7 +18,7 @@ type ConditionStringProps = {
const ConditionString = ({
value,
onChange,
valueMethod,
valueMethod = 'constant',
onValueMethodChange,
nodesOutputVars,
availableNodes,
@@ -36,7 +37,7 @@ const ConditionString = ({
{
valueMethod === 'variable' && (
<ConditionVariableSelector
valueSelector={value!.split('.')}
valueSelector={value ? value!.split('.') : []}
onChange={handleVariableValueChange}
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
@@ -45,9 +46,11 @@ const ConditionString = ({
}
{
valueMethod === 'constant' && (
<input
<Input
className='bg-transparent hover:bg-transparent outline-none border-none focus:shadow-none focus:bg-transparent'
value={value}
onChange={e => onChange(e.target.value)}
placeholder='Enter value'
/>
)
}

View File

@@ -30,7 +30,7 @@ const ConditionValueMethod = ({
placement='bottom-start'
offset={{ mainAxis: 4, crossAxis: 0 }}
>
<PortalToFollowElemTrigger onClick={() => setOpen(v => !v)}>
<PortalToFollowElemTrigger asChild onClick={() => setOpen(v => !v)}>
<Button
className='shrink-0'
variant='ghost'

View File

@@ -1,4 +1,4 @@
import { useState } from 'react'
import { useCallback, useState } from 'react'
import {
PortalToFollowElem,
PortalToFollowElemContent,
@@ -13,6 +13,7 @@ import type {
Var,
} from '@/app/components/workflow/types'
import { VarType } from '@/app/components/workflow/types'
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
type ConditionVariableSelectorProps = {
valueSelector?: ValueSelector
@@ -31,6 +32,11 @@ const ConditionVariableSelector = ({
}: ConditionVariableSelectorProps) => {
const [open, setOpen] = useState(false)
const handleChange = useCallback((valueSelector: ValueSelector, varItem: Var) => {
onChange(valueSelector, varItem)
setOpen(false)
}, [onChange])
return (
<PortalToFollowElem
open={open}
@@ -41,14 +47,31 @@ const ConditionVariableSelector = ({
crossAxis: 0,
}}
>
<PortalToFollowElemTrigger onClick={() => setOpen(!open)}>
<div className="cursor-pointer">
<VariableTag
valueSelector={valueSelector}
varType={varType}
availableNodes={availableNodes}
isShort
/>
<PortalToFollowElemTrigger asChild onClick={() => setOpen(!open)}>
<div className="grow flex items-center cursor-pointer h-6">
{
!!valueSelector.length && (
<VariableTag
valueSelector={valueSelector}
varType={varType}
availableNodes={availableNodes}
isShort
/>
)
}
{
!valueSelector.length && (
<>
<div className='grow flex items-center text-components-input-text-placeholder system-sm-regular'>
<Variable02 className='mr-1 w-4 h-4' />
Select variable...
</div>
<div className='shrink-0 flex items-center px-[5px] h-5 border border-divider-deep rounded-[5px] system-2xs-medium text-text-tertiary'>
string
</div>
</>
)
}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'>
@@ -56,7 +79,7 @@ const ConditionVariableSelector = ({
<VarReferenceVars
vars={nodesOutputVars}
isSupportFileVar
onChange={onChange}
onChange={handleChange}
/>
</div>
</PortalToFollowElemContent>

View File

@@ -1,19 +1,13 @@
import { RiLoopLeftLine } from '@remixicon/react'
import { useMemo } from 'react'
import ConditionItem from './condition-item'
import type {
Node,
NodeOutPutVar,
} from '@/app/components/workflow/types'
import cn from '@/utils/classnames'
import type { MetadataShape } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import { LogicalOperator } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
type ConditionListProps = {
disabled?: boolean
nodesOutputVars?: NodeOutPutVar[]
availableNodes?: Node[]
} & Omit<MetadataShape, 'handleAddCondition'>
const ConditionList = ({
disabled,
metadataList = [],
@@ -24,25 +18,21 @@ const ConditionList = ({
handleRemoveCondition,
handleToggleConditionLogicalOperator,
handleUpdateCondition,
nodesOutputVars = [],
availableNodes = [],
availableStringVars,
availableStringNodesWithParent,
availableNumberVars,
availableNumberNodesWithParent,
}: ConditionListProps) => {
const { conditions, logical_operator } = metadataFilteringConditions
const conditionItemClassName = useMemo(() => {
if (conditions.length < 2)
return ''
return logical_operator === LogicalOperator.and ? 'pl-[51px]' : 'pl-[42px]'
}, [conditions.length, logical_operator])
return (
<div className={cn('relative')}>
{
conditions.length > 1 && (
<div className={cn(
'absolute top-0 bottom-0 left-0 w-[60px]',
'absolute top-0 bottom-0 left-0 w-[44px]',
)}>
<div className='absolute top-4 bottom-4 left-[46px] w-2.5 border border-divider-deep rounded-l-[8px] border-r-0'></div>
<div className='absolute top-4 bottom-4 right-1 w-2.5 border border-divider-deep rounded-l-[8px] border-r-0'></div>
<div className='absolute top-1/2 -translate-y-1/2 right-0 w-4 h-[29px] bg-components-panel-bg'></div>
<div
className='absolute top-1/2 right-1 -translate-y-1/2 flex items-center px-1 h-[21px] rounded-md border-[0.5px] border-components-button-secondary-border shadow-xs bg-components-button-secondary-bg text-text-accent-secondary text-[10px] font-semibold cursor-pointer select-none'
@@ -54,21 +44,24 @@ const ConditionList = ({
</div>
)
}
{
conditions.map(condition => (
<ConditionItem
key={condition.name}
className={conditionItemClassName}
disabled={disabled}
condition={condition}
onUpdateCondition={handleUpdateCondition}
onRemoveCondition={handleRemoveCondition}
nodesOutputVars={nodesOutputVars}
availableNodes={availableNodes}
metadataList={metadataList}
/>
))
}
<div className={cn(conditions.length > 1 && 'pl-[44px]')}>
{
conditions.map(condition => (
<ConditionItem
key={condition.name}
disabled={disabled}
condition={condition}
onUpdateCondition={handleUpdateCondition}
onRemoveCondition={handleRemoveCondition}
metadataList={metadataList}
availableStringVars={availableStringVars}
availableStringNodesWithParent={availableStringNodesWithParent}
availableNumberVars={availableNumberVars}
availableNumberNodesWithParent={availableNumberNodesWithParent}
/>
))
}
</div>
</div>
)
}

View File

@@ -23,12 +23,12 @@ export const getOperators = (type?: MetadataFilteringVariableType) => {
switch (type) {
case MetadataFilteringVariableType.string:
return [
ComparisonOperator.is,
ComparisonOperator.isNot,
ComparisonOperator.contains,
ComparisonOperator.notContains,
ComparisonOperator.startWith,
ComparisonOperator.endWith,
ComparisonOperator.is,
ComparisonOperator.isNot,
ComparisonOperator.empty,
ComparisonOperator.notEmpty,
]
@@ -46,7 +46,8 @@ export const getOperators = (type?: MetadataFilteringVariableType) => {
default:
return [
ComparisonOperator.is,
ComparisonOperator.isNot,
ComparisonOperator.before,
ComparisonOperator.after,
ComparisonOperator.empty,
ComparisonOperator.notEmpty,
]

View File

@@ -1,4 +1,7 @@
import { useState } from 'react'
import {
useCallback,
useState,
} from 'react'
import MetadataTrigger from '../metadata-trigger'
import MetadataFilterSelector from './metadata-filter-selector'
import Collapse from '@/app/components/workflow/nodes/_base/components/collapse'
@@ -12,7 +15,7 @@ type MetadataFilterProps = {
handleMetadataFilterModeChange: (mode: MetadataFilteringModeEnum) => void
} & MetadataShape
const MetadataFilter = ({
metadataFilterMode,
metadataFilterMode = MetadataFilteringModeEnum.disabled,
handleMetadataFilterModeChange,
metadataModelConfig,
handleMetadataModelChange,
@@ -21,6 +24,13 @@ const MetadataFilter = ({
}: MetadataFilterProps) => {
const [collapsed, setCollapsed] = useState(true)
const handleMetadataFilterModeChangeWrapped = useCallback((mode: MetadataFilteringModeEnum) => {
if (mode === MetadataFilteringModeEnum.automatic)
setCollapsed(false)
handleMetadataFilterModeChange(mode)
}, [handleMetadataFilterModeChange])
return (
<Collapse
disabled={metadataFilterMode === MetadataFilteringModeEnum.disabled || metadataFilterMode === MetadataFilteringModeEnum.manual}
@@ -43,7 +53,7 @@ const MetadataFilter = ({
<div className='flex items-center'>
<MetadataFilterSelector
value={metadataFilterMode}
onSelect={handleMetadataFilterModeChange}
onSelect={handleMetadataFilterModeChangeWrapped}
/>
{
metadataFilterMode === MetadataFilteringModeEnum.manual && (

View File

@@ -55,6 +55,7 @@ const MetadataFilterSelector = ({
e.stopPropagation()
setOpen(!open)
}}
asChild
>
<Button
variant='secondary'

View File

@@ -0,0 +1,39 @@
import { memo } from 'react'
import {
RiHashtag,
RiTextSnippet,
RiTimeLine,
} from '@remixicon/react'
import { MetadataFilteringVariableType } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import cn from '@/utils/classnames'
type MetadataIconProps = {
type?: MetadataFilteringVariableType
className?: string
}
const MetadataIcon = ({
type,
className,
}: MetadataIconProps) => {
return (
<>
{
type === MetadataFilteringVariableType.string && (
<RiTextSnippet className={cn('w-3.5 h-3.5', className)} />
)
}
{
type === MetadataFilteringVariableType.number && (
<RiHashtag className={cn('w-3.5 h-3.5', className)} />
)
}
{
type === MetadataFilteringVariableType.time && (
<RiTimeLine className={cn('w-3.5 h-3.5', className)} />
)
}
</>
)
}
export default memo(MetadataIcon)

View File

@@ -28,11 +28,13 @@ const MetadataPanel = ({
</div>
<div className='px-1 py-2'>
<div className='px-3 py-1'>
<ConditionList
metadataList={metadataList}
metadataFilteringConditions={metadataFilteringConditions}
{...restProps}
/>
<div className='pb-2'>
<ConditionList
metadataList={metadataList}
metadataFilteringConditions={metadataFilteringConditions}
{...restProps}
/>
</div>
<AddCondition
metadataList={metadataList}
handleAddCondition={handleAddCondition}

View File

@@ -30,7 +30,7 @@ const MetadataTrigger = ({
<RiFilter3Line className='mr-1 w-3.5 h-3.5' />
Conditions
<div className='flex items-center ml-1 px-1 rounded-[5px] border border-divider-deep system-2xs-medium-uppercase text-text-tertiary'>
{metadataFilteringConditions?.conditions.length}
{metadataFilteringConditions?.conditions.length || 0}
</div>
</Button>
</PortalToFollowElemTrigger>

View File

@@ -55,6 +55,10 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
handleUpdateCondition,
handleMetadataModelChange,
handleMetadataCompletionParamsChange,
availableStringVars,
availableStringNodesWithParent,
availableNumberVars,
availableNumberNodesWithParent,
} = useConfig(id, data)
const handleOpenFromPropsChange = useCallback((openFromProps: boolean) => {
@@ -71,7 +75,7 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
return (
<div className='pt-2'>
<div className='px-4 pb-4 space-y-4'>
<div className='px-4 pb-2 space-y-4'>
{/* {JSON.stringify(inputs, null, 2)} */}
<Field
title={t(`${i18nPrefix}.queryVariable`)}
@@ -123,7 +127,7 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
/>
</Field>
</div>
<div className='py-2'>
<div className='mb-2 py-2'>
<MetadataFilter
metadataList={metadataList}
metadataFilterMode={inputs.metadata_filtering_mode}
@@ -136,6 +140,10 @@ const Panel: FC<NodePanelProps<KnowledgeRetrievalNodeType>> = ({
metadataModelConfig={inputs.metadata_model_config}
handleMetadataModelChange={handleMetadataModelChange}
handleMetadataCompletionParamsChange={handleMetadataCompletionParamsChange}
availableStringVars={availableStringVars}
availableStringNodesWithParent={availableStringNodesWithParent}
availableNumberVars={availableNumberVars}
availableNumberNodesWithParent={availableNumberNodesWithParent}
/>
</div>
<Split />

View File

@@ -1,4 +1,10 @@
import type { CommonNodeType, ModelConfig, ValueSelector } from '@/app/components/workflow/types'
import type {
CommonNodeType,
ModelConfig,
Node,
NodeOutPutVar,
ValueSelector,
} from '@/app/components/workflow/types'
import type { RETRIEVE_TYPE } from '@/types/app'
import type {
DataSet,
@@ -58,6 +64,8 @@ export enum ComparisonOperator {
allOf = 'all of',
exists = 'exists',
notExists = 'not exists',
before = 'before',
after = 'after',
}
export enum MetadataFilteringModeEnum {
@@ -69,7 +77,7 @@ export enum MetadataFilteringModeEnum {
export enum MetadataFilteringVariableType {
string = 'string',
number = 'number',
date = 'date',
time = 'time',
}
export type MetadataFilteringCondition = {
@@ -95,7 +103,7 @@ export type KnowledgeRetrievalNodeType = CommonNodeType & {
metadata_model_config?: ModelConfig
}
export type HandleAddCondition = (name: string) => void
export type HandleAddCondition = (metadataItem: MetadataInDoc) => void
export type HandleRemoveCondition = (name: string) => void
export type HandleUpdateCondition = (name: string, newCondition: MetadataFilteringCondition) => void
export type HandleToggleConditionLogicalOperator = () => void
@@ -110,4 +118,8 @@ export type MetadataShape = {
metadataModelConfig?: ModelConfig
handleMetadataModelChange?: (model: { modelId: string; provider: string; mode?: string; features?: string[] }) => void
handleMetadataCompletionParamsChange?: (params: Record<string, any>) => void
availableStringVars?: NodeOutPutVar[]
availableStringNodesWithParent?: Node[]
availableNumberVars?: NodeOutPutVar[]
availableNumberNodesWithParent?: Node[]
}

View File

@@ -22,7 +22,11 @@ import type {
MetadataFilteringModeEnum,
MultipleRetrievalConfig,
} from './types'
import { ComparisonOperator, LogicalOperator } from './types'
import {
ComparisonOperator,
LogicalOperator,
MetadataFilteringVariableType,
} from './types'
import {
getMultipleRetrievalConfig,
getSelectedDatasetsMode,
@@ -35,6 +39,7 @@ import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-cr
import useOneStepRun from '@/app/components/workflow/nodes/_base/hooks/use-one-step-run'
import { useCurrentProviderAndModel, useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
@@ -303,18 +308,34 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
}))
}, [setInputs])
const handleAddCondition = useCallback<HandleAddCondition>((name) => {
const handleAddCondition = useCallback<HandleAddCondition>(({ name, type }) => {
let operator: ComparisonOperator = ComparisonOperator.is
if (type === MetadataFilteringVariableType.number)
operator = ComparisonOperator.equal
const newCondition = {
name,
comparison_operator: operator,
}
const newInputs = produce(inputRef.current, (draft) => {
draft.metadata_filtering_conditions?.conditions.push({
name,
comparison_operator: ComparisonOperator.is,
})
if (draft.metadata_filtering_conditions) {
draft.metadata_filtering_conditions.conditions.push(newCondition)
}
else {
draft.metadata_filtering_conditions = {
logical_operator: LogicalOperator.and,
conditions: [newCondition],
}
}
})
setInputs(newInputs)
}, [setInputs])
const handleRemoveCondition = useCallback<HandleRemoveCondition>((name) => {
const index = inputRef.current.metadata_filtering_conditions?.conditions.findIndex(c => c.name === name) || -1
const conditions = inputRef.current.metadata_filtering_conditions?.conditions || []
const index = conditions.findIndex(c => c.name === name)
const newInputs = produce(inputRef.current, (draft) => {
if (index > -1)
draft.metadata_filtering_conditions?.conditions.splice(index, 1)
@@ -323,7 +344,8 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
}, [setInputs])
const handleUpdateCondition = useCallback<HandleUpdateCondition>((name, newCondition) => {
const index = inputRef.current.metadata_filtering_conditions?.conditions.findIndex(c => c.name === name) || -1
const conditions = inputRef.current.metadata_filtering_conditions?.conditions || []
const index = conditions.findIndex(c => c.name === name)
const newInputs = produce(inputRef.current, (draft) => {
if (index > -1)
draft.metadata_filtering_conditions!.conditions[index] = newCondition
@@ -362,6 +384,30 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
setInputs(newInputs)
}, [setInputs])
const filterStringVar = useCallback((varPayload: Var) => {
return [VarType.string].includes(varPayload.type)
}, [])
const {
availableVars: availableStringVars,
availableNodesWithParent: availableStringNodesWithParent,
} = useAvailableVarList(id, {
onlyLeafNodeVar: false,
filterVar: filterStringVar,
})
const filterNumberVar = useCallback((varPayload: Var) => {
return [VarType.number].includes(varPayload.type)
}, [])
const {
availableVars: availableNumberVars,
availableNodesWithParent: availableNumberNodesWithParent,
} = useAvailableVarList(id, {
onlyLeafNodeVar: false,
filterVar: filterNumberVar,
})
return {
readOnly,
inputs,
@@ -390,6 +436,10 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
handleToggleConditionLogicalOperator,
handleMetadataModelChange,
handleMetadataCompletionParamsChange,
availableStringVars,
availableStringNodesWithParent,
availableNumberVars,
availableNumberNodesWithParent,
}
}