Merge branch 'feat/parent-child-retrieval' of https://github.com/langgenius/dify into feat/parent-child-retrieval

pull/12097/head
twwu 1 year ago
commit 0c4e06e1c1

@ -1,4 +1,3 @@
import { useState } from 'react'
import type { FC, SetStateAction } from 'react' import type { FC, SetStateAction } from 'react'
import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react' import { RiArrowDownSLine, RiArrowUpSLine } from '@remixicon/react'
import Input, { type InputProps } from '../input' import Input, { type InputProps } from '../input'
@ -6,35 +5,34 @@ import classNames from '@/utils/classnames'
export type InputNumberProps = { export type InputNumberProps = {
unit?: string unit?: string
value: number
onChange: (value: number) => void onChange: (value: number) => void
amount?: number amount?: number
size?: 'sm' | 'md' size?: 'sm' | 'md'
} & Omit<InputProps, 'value' | 'onChange' | 'size'> } & Omit<InputProps, 'value' | 'onChange' | 'size'>
export const InputNumber: FC<InputNumberProps> = (props) => { export const InputNumber: FC<InputNumberProps> = (props) => {
const { unit, className, onChange, defaultValue = 0, amount = 1, size = 'sm', max, min, ...rest } = props const { unit, className, onChange, amount = 1, value, size = 'sm', max, min, ...rest } = props
const [val, setVal] = useState<number>(defaultValue as number) const update = (input: SetStateAction<number>) => {
const update = (value: SetStateAction<number>) => { const current = typeof input === 'function' ? input(value) : input as number
const current = typeof value === 'function' ? value(val) : value as number
if (max && current >= (max as number)) if (max && current >= (max as number))
return return
if (min && current <= (min as number)) if (min && current <= (min as number))
return return
setVal(value) onChange(current)
} }
const inc = () => update(val => val + amount) const inc = () => update(val => val + amount)
const dec = () => update(val => val - amount) const dec = () => update(val => val - amount)
return <div className='flex'> return <div className='flex'>
<Input {...rest} <Input {...rest}
className={classNames('rounded-r-none', className)} className={classNames('rounded-r-none', className)}
value={val} value={value}
max={max} max={max}
min={min} min={min}
onChange={(e) => { onChange={(e) => {
const parsed = Number(e.target.value) const parsed = Number(e.target.value)
if (Number.isNaN(parsed)) if (Number.isNaN(parsed))
return return
setVal(parsed)
onChange(parsed) onChange(parsed)
}} }}
/> />

@ -55,10 +55,8 @@ const ParamItem: FC<Props> = ({ className, id, name, noTooltip, tip, step = 0.1,
max={max} max={max}
step={step} step={step}
size='sm' size='sm'
value={value}
onChange={(value) => { onChange={(value) => {
if (value < min || value > max)
return
onChange(id, value) onChange(id, value)
}} }}
/> />

@ -119,6 +119,19 @@ type ParentChildConfig = {
rules: PreProcessingRule[] rules: PreProcessingRule[]
} }
const defaultParentChildConfig: ParentChildConfig = {
chunkForContext: 'paragraph',
parent: {
delimiter: '\\n\\n',
maxLength: 4000,
},
child: {
delimiter: '\\n\\n',
maxLength: 4000,
},
rules: [],
}
const StepTwo = ({ const StepTwo = ({
isSetting, isSetting,
documentDetail, documentDetail,
@ -186,18 +199,7 @@ const StepTwo = ({
})() })()
const [isCreating, setIsCreating] = useState(false) const [isCreating, setIsCreating] = useState(false)
const [parentChildConfig, setParentChildConfig] = useState<ParentChildConfig>({ const [parentChildConfig, setParentChildConfig] = useState<ParentChildConfig>(defaultParentChildConfig)
chunkForContext: 'paragraph',
parent: {
delimiter: '\\n\\n',
maxLength: 4000,
},
child: {
delimiter: '\\n\\n',
maxLength: 4000,
},
rules: [],
})
const scrollHandle = (e: Event) => { const scrollHandle = (e: Event) => {
if ((e.target as HTMLDivElement).scrollTop > 0) if ((e.target as HTMLDivElement).scrollTop > 0)
@ -248,6 +250,7 @@ const StepTwo = ({
setOverlap(defaultConfig.segmentation.chunk_overlap) setOverlap(defaultConfig.segmentation.chunk_overlap)
setRules(defaultConfig.pre_processing_rules) setRules(defaultConfig.pre_processing_rules)
} }
setParentChildConfig(defaultParentChildConfig)
} }
const fetchFileIndexingEstimate = async (docForm = DocForm.TEXT, language?: string) => { const fetchFileIndexingEstimate = async (docForm = DocForm.TEXT, language?: string) => {
@ -659,24 +662,24 @@ const StepTwo = ({
<RiSearchEyeLine className='h-4 w-4 mr-1.5' /> <RiSearchEyeLine className='h-4 w-4 mr-1.5' />
{t('datasetCreation.stepTwo.previewChunk')} {t('datasetCreation.stepTwo.previewChunk')}
</Button> </Button>
<Button variant={'ghost'} disabled> <Button variant={'ghost'} onClick={resetRules}>
{t('datasetCreation.stepTwo.reset')} {t('datasetCreation.stepTwo.reset')}
</Button> </Button>
</> </>
} }
> >
<div className='space-y-4'> <div className='space-y-4'>
<div className='flex gap-2'> <div className='flex gap-3'>
<DelimiterInput <DelimiterInput
value={segmentIdentifier} value={segmentIdentifier}
onChange={e => setSegmentIdentifier(e.target.value)} onChange={e => setSegmentIdentifier(e.target.value)}
/> />
<MaxLengthInput <MaxLengthInput
defaultValue={max} value={max}
onChange={setMax} onChange={setMax}
/> />
<OverlapInput <OverlapInput
defaultValue={overlap} value={overlap}
min={1} min={1}
onChange={setOverlap} onChange={setOverlap}
/> />
@ -749,7 +752,7 @@ const StepTwo = ({
})} })}
/> />
<MaxLengthInput <MaxLengthInput
defaultValue={parentChildConfig.parent.maxLength} value={parentChildConfig.parent.maxLength}
onChange={value => setParentChildConfig({ onChange={value => setParentChildConfig({
...parentChildConfig, ...parentChildConfig,
parent: { parent: {
@ -775,11 +778,11 @@ const StepTwo = ({
/> />
</div> </div>
<div className='space-y-2'> <div className='space-y-4'>
<TextLabel> <TextLabel>
{t('datasetCreation.stepTwo.childChunkForRetrieval')} {t('datasetCreation.stepTwo.childChunkForRetrieval')}
</TextLabel> </TextLabel>
<div className='flex gap-2 mt-2'> <div className='flex gap-3 mt-2'>
<DelimiterInput <DelimiterInput
value={parentChildConfig.child.delimiter} value={parentChildConfig.child.delimiter}
onChange={e => setParentChildConfig({ onChange={e => setParentChildConfig({
@ -791,8 +794,7 @@ const StepTwo = ({
})} })}
/> />
<MaxLengthInput <MaxLengthInput
defaultValue={parentChildConfig.child.maxLength} value={parentChildConfig.child.maxLength}
onChange={value => setParentChildConfig({ onChange={value => setParentChildConfig({
...parentChildConfig, ...parentChildConfig,
child: { child: {
@ -803,20 +805,22 @@ const StepTwo = ({
/> />
</div> </div>
<TextLabel>
{t('datasetCreation.stepTwo.rules')}
</TextLabel>
<div className='space-y-2'> <div className='space-y-2'>
{rules.map(rule => ( <TextLabel>
<div key={rule.id} className={s.ruleItem} onClick={() => { {t('datasetCreation.stepTwo.rules')}
ruleChangeHandle(rule.id) </TextLabel>
}}> <div className='space-y-2 mt-2'>
<Checkbox {rules.map(rule => (
checked={rule.enabled} <div key={rule.id} className={s.ruleItem} onClick={() => {
/> ruleChangeHandle(rule.id)
<label className="ml-2 text-sm font-normal cursor-pointer text-gray-800">{getRuleName(rule.id)}</label> }}>
</div> <Checkbox
))} checked={rule.enabled}
/>
<label className="ml-2 text-sm font-normal cursor-pointer text-gray-800">{getRuleName(rule.id)}</label>
</div>
))}
</div>
</div> </div>
</div> </div>
</div> </div>

@ -75,7 +75,7 @@ export const OptionCard: FC<OptionCardProps> = (props) => {
/> />
{/** Body */} {/** Body */}
{isActive && <div className='p-3'>{children} {isActive && <div className='p-3'>{children}
{actions && <div className='flex gap-2 mt-3'> {actions && <div className='flex gap-2 mt-4'>
{actions} {actions}
</div>} </div>}
</div>} </div>}

@ -27,7 +27,7 @@ export const StepperStep: FC<StepperStepProps> = (props) => {
<div className={classNames( <div className={classNames(
'text-center text-[10px] font-semibold uppercase leading-3', 'text-center text-[10px] font-semibold uppercase leading-3',
isActive isActive
? 'text-white' ? 'text-text-primary-on-surface'
: !isDisabled : !isDisabled
? 'text-text-tertiary' ? 'text-text-tertiary'
: 'text-text-tertiary opacity-30', : 'text-text-tertiary opacity-30',

@ -122,6 +122,7 @@ const translation = {
removeUrlEmails: 'Delete all URLs and email addresses', removeUrlEmails: 'Delete all URLs and email addresses',
removeStopwords: 'Remove stopwords such as "a", "an", "the"', removeStopwords: 'Remove stopwords such as "a", "an", "the"',
preview: 'Confirm & Preview', preview: 'Confirm & Preview',
previewChunk: 'Preview Chunk',
reset: 'Reset', reset: 'Reset',
indexMode: 'Index mode', indexMode: 'Index mode',
qualified: 'High Quality', qualified: 'High Quality',

Loading…
Cancel
Save