mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 08:48:10 +08:00
fix(workflow): allow KnowledgeFS top n up to 100
This commit is contained in:
parent
66a93d5dfb
commit
73e449c3ef
@ -109,15 +109,17 @@ describe('ParamItem', () => {
|
||||
expect(defaultProps.onChange).toHaveBeenLastCalledWith('test_param', 0.8)
|
||||
})
|
||||
|
||||
it('should reset the textbox and slider when users clear the input', async () => {
|
||||
it('should allow users to replace the minimum value with a multi-digit value', async () => {
|
||||
const user = userEvent.setup()
|
||||
const StatefulParamItem = () => {
|
||||
const [value, setValue] = useState(defaultProps.value)
|
||||
const [value, setValue] = useState(1)
|
||||
|
||||
return (
|
||||
<ParamItem
|
||||
{...defaultProps}
|
||||
value={value}
|
||||
min={1}
|
||||
max={100}
|
||||
onChange={(key: string, nextValue: number) => {
|
||||
defaultProps.onChange(key, nextValue)
|
||||
setValue(nextValue)
|
||||
@ -131,12 +133,14 @@ describe('ParamItem', () => {
|
||||
const input = screen.getByRole('textbox')
|
||||
await user.clear(input)
|
||||
|
||||
expect(defaultProps.onChange).toHaveBeenLastCalledWith('test_param', 0)
|
||||
expect(getSlider()).toHaveAttribute('aria-valuenow', '0')
|
||||
expect(input).toHaveValue('')
|
||||
expect(defaultProps.onChange).not.toHaveBeenCalled()
|
||||
|
||||
await user.tab()
|
||||
await user.type(input, '20')
|
||||
|
||||
expect(input).toHaveValue('0')
|
||||
expect(input).toHaveValue('20')
|
||||
expect(defaultProps.onChange).toHaveBeenLastCalledWith('test_param', 20)
|
||||
expect(getSlider()).toHaveAttribute('aria-valuenow', '20')
|
||||
})
|
||||
|
||||
it('should clamp out-of-range text edits before updating state', async () => {
|
||||
|
||||
@ -75,6 +75,12 @@ describe('TopKItem', () => {
|
||||
expect(input).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should allow a feature-specific maximum', () => {
|
||||
render(<TopKItem {...defaultProps} max={100} />)
|
||||
|
||||
expect(getSlider()).toHaveAttribute('max', '100')
|
||||
})
|
||||
|
||||
it('should render slider with max >= 5 so no scaling is applied', () => {
|
||||
render(<TopKItem {...defaultProps} />)
|
||||
const slider = getSlider()
|
||||
|
||||
@ -85,7 +85,9 @@ const ParamItem: FC<Props> = ({
|
||||
max={max}
|
||||
step={step}
|
||||
value={value}
|
||||
onValueChange={(nextValue) => onChange(id, nextValue ?? min)}
|
||||
onValueChange={(nextValue) => {
|
||||
if (nextValue !== null) onChange(id, nextValue)
|
||||
}}
|
||||
>
|
||||
<NumberFieldGroup>
|
||||
<NumberFieldInput aria-label={name} className="w-18" />
|
||||
|
||||
@ -11,22 +11,28 @@ type Props = Readonly<{
|
||||
onChange: (key: string, value: number) => void
|
||||
enable: boolean
|
||||
disabled?: boolean
|
||||
max?: number
|
||||
}>
|
||||
|
||||
const maxTopK = env.NEXT_PUBLIC_TOP_K_MAX_VALUE
|
||||
const VALUE_LIMIT = {
|
||||
default: 2,
|
||||
step: 1,
|
||||
min: 1,
|
||||
max: maxTopK,
|
||||
}
|
||||
|
||||
const TopKItem: FC<Props> = ({ className, value, enable, onChange, disabled = false }) => {
|
||||
const TopKItem: FC<Props> = ({
|
||||
className,
|
||||
value,
|
||||
enable,
|
||||
onChange,
|
||||
disabled = false,
|
||||
max = env.NEXT_PUBLIC_TOP_K_MAX_VALUE,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const handleParamChange = (key: string, value: number) => {
|
||||
let notOutRangeValue = Number.parseInt(value.toFixed(0))
|
||||
notOutRangeValue = Math.max(VALUE_LIMIT.min, notOutRangeValue)
|
||||
notOutRangeValue = Math.min(VALUE_LIMIT.max, notOutRangeValue)
|
||||
notOutRangeValue = Math.min(max, notOutRangeValue)
|
||||
onChange(key, notOutRangeValue)
|
||||
}
|
||||
return (
|
||||
@ -36,6 +42,7 @@ const TopKItem: FC<Props> = ({ className, value, enable, onChange, disabled = fa
|
||||
name={t(($) => $['datasetConfig.top_k'], { ns: 'appDebug' })}
|
||||
tip={t(($) => $['datasetConfig.top_kTip'], { ns: 'appDebug' }) as string}
|
||||
{...VALUE_LIMIT}
|
||||
max={max}
|
||||
value={value}
|
||||
enable={enable}
|
||||
disabled={disabled}
|
||||
|
||||
@ -3,6 +3,7 @@ import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import RecallSettings from '../recall-settings'
|
||||
|
||||
const mockModelSelector = vi.hoisted(() => vi.fn())
|
||||
const mockTopKItem = vi.hoisted(() => vi.fn())
|
||||
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
||||
useModelListAndDefaultModelAndCurrentProviderAndModel: () => ({
|
||||
@ -45,11 +46,18 @@ vi.mock('@langgenius/dify-ui/select', () => ({
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/param-item/top-k-item', () => ({
|
||||
default: (props: { onChange: (key: string, value: number) => void; value: number }) => (
|
||||
<button type="button" onClick={() => props.onChange('top_k', 20)}>
|
||||
top-{props.value}
|
||||
</button>
|
||||
),
|
||||
default: (props: {
|
||||
max?: number
|
||||
onChange: (key: string, value: number) => void
|
||||
value: number
|
||||
}) => {
|
||||
mockTopKItem(props)
|
||||
return (
|
||||
<button type="button" onClick={() => props.onChange('top_k', 20)}>
|
||||
top-{props.value}
|
||||
</button>
|
||||
)
|
||||
},
|
||||
}))
|
||||
|
||||
vi.mock('@/app/components/base/param-item/score-threshold-item', () => ({
|
||||
@ -86,6 +94,7 @@ describe('RecallSettings', () => {
|
||||
)
|
||||
|
||||
expect(screen.getByText('common.modelProvider.defaultConfig')).toBeInTheDocument()
|
||||
expect(mockTopKItem).toHaveBeenLastCalledWith(expect.objectContaining({ max: 100 }))
|
||||
expect(mockModelSelector).toHaveBeenLastCalledWith(
|
||||
expect.objectContaining({
|
||||
value: { provider: 'system/provider', model: 'system-rerank' },
|
||||
|
||||
@ -20,6 +20,7 @@ import TopKItem from '@/app/components/base/param-item/top-k-item'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/components/header/account-setting/model-provider-page/hooks'
|
||||
import { ModelSelector } from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||
import { KNOWLEDGE_RETRIEVAL_V2_TOP_N_MAX } from '../constants'
|
||||
|
||||
const i18nPrefix = 'nodes.knowledgeRetrievalV2'
|
||||
const DEFAULT_SCORE_THRESHOLD = 0.5
|
||||
@ -186,6 +187,7 @@ const RecallSettings: FC<Props> = ({
|
||||
value={topK}
|
||||
enable
|
||||
disabled={readonly}
|
||||
max={KNOWLEDGE_RETRIEVAL_V2_TOP_N_MAX}
|
||||
onChange={(_, value) => onTopKChange(value)}
|
||||
/>
|
||||
<ScoreThresholdItem
|
||||
|
||||
@ -52,3 +52,5 @@ export const KNOWLEDGE_RETRIEVAL_V2_NODE_KINDS = [
|
||||
'image',
|
||||
'summary',
|
||||
] as const
|
||||
|
||||
export const KNOWLEDGE_RETRIEVAL_V2_TOP_N_MAX = 100
|
||||
|
||||
@ -27,6 +27,7 @@ import {
|
||||
import { useNodesReadOnly } from '../../hooks/use-workflow'
|
||||
import { VarType } from '../../types'
|
||||
import { toggleControlSpaceId } from './config-helpers'
|
||||
import { KNOWLEDGE_RETRIEVAL_V2_TOP_N_MAX } from './constants'
|
||||
|
||||
const useConfig = (id: string, payload: KnowledgeRetrievalV2NodeType) => {
|
||||
const { nodesReadOnly: readOnly } = useNodesReadOnly()
|
||||
@ -91,7 +92,7 @@ const useConfig = (id: string, payload: KnowledgeRetrievalV2NodeType) => {
|
||||
|
||||
const handleTopNChange = useCallback(
|
||||
(topN: number) => {
|
||||
if (!Number.isInteger(topN) || topN < 1 || topN > 100) return
|
||||
if (!Number.isInteger(topN) || topN < 1 || topN > KNOWLEDGE_RETRIEVAL_V2_TOP_N_MAX) return
|
||||
setInputs(
|
||||
produce(inputs, (draft) => {
|
||||
draft.top_n = topN
|
||||
|
||||
Loading…
Reference in New Issue
Block a user