mirror of
https://github.com/langgenius/dify.git
synced 2026-07-31 01:09:32 +08:00
refactor(web): localize retrieval method query (#39795)
This commit is contained in:
parent
0bb1b4d6d2
commit
e4947811a5
@ -10,7 +10,6 @@ export const baseProviderContextValue: ProviderContextState = {
|
||||
refreshModelProviders: noop,
|
||||
isLoadingModelProviders: false,
|
||||
textGenerationModelList: [],
|
||||
supportRetrievalMethods: [],
|
||||
isAPIKeySet: true,
|
||||
plan: defaultPlan,
|
||||
isFetchedPlan: false,
|
||||
|
||||
@ -13,6 +13,7 @@ import {
|
||||
DataSourceType,
|
||||
RerankingModeEnum,
|
||||
} from '@/models/datasets'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { updateDatasetSetting } from '@/service/datasets'
|
||||
import { useMembers } from '@/service/use-common'
|
||||
import { renderWithConsoleQuery as render } from '@/test/console/query-data'
|
||||
@ -93,12 +94,6 @@ vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: () => ({
|
||||
modelProviders: [],
|
||||
textGenerationModelList: [],
|
||||
supportRetrievalMethods: [
|
||||
RETRIEVE_METHOD.semantic,
|
||||
RETRIEVE_METHOD.fullText,
|
||||
RETRIEVE_METHOD.hybrid,
|
||||
RETRIEVE_METHOD.keywordSearch,
|
||||
],
|
||||
}),
|
||||
}))
|
||||
|
||||
@ -206,9 +201,12 @@ const createDataset = (
|
||||
|
||||
const renderWithProviders = (dataset: DataSet) => {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: { queries: { retry: false } },
|
||||
defaultOptions: { queries: { retry: false, staleTime: Number.POSITIVE_INFINITY } },
|
||||
})
|
||||
queryClient.setQueryData(systemFeaturesQueryOptions().queryKey, createSystemFeaturesFixture())
|
||||
queryClient.setQueryData(consoleQuery.datasets.retrievalSetting.get.queryOptions().queryKey, {
|
||||
retrieval_method: [RETRIEVE_METHOD.semantic, RETRIEVE_METHOD.fullText, RETRIEVE_METHOD.hybrid],
|
||||
})
|
||||
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import type { ReactElement } from 'react'
|
||||
import type { DataSet } from '@/models/datasets'
|
||||
import type { RetrievalConfig } from '@/types/app'
|
||||
import type { DocPathWithoutLang } from '@/types/doc-paths'
|
||||
import { render, screen } from '@testing-library/react'
|
||||
import { screen } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { IndexingType } from '@/app/components/datasets/create/step-two'
|
||||
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
@ -11,6 +12,8 @@ import {
|
||||
DataSourceType,
|
||||
RerankingModeEnum,
|
||||
} from '@/models/datasets'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { createConsoleQueryClient, renderWithConsoleQuery } from '@/test/console/query-data'
|
||||
import { withSelectorKey } from '@/test/i18n-mock'
|
||||
import { RETRIEVE_METHOD } from '@/types/app'
|
||||
import { RetrievalChangeTip, RetrievalSection } from '../retrieval-section'
|
||||
@ -31,12 +34,6 @@ vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: () => ({
|
||||
modelProviders: [],
|
||||
textGenerationModelList: [],
|
||||
supportRetrievalMethods: [
|
||||
RETRIEVE_METHOD.semantic,
|
||||
RETRIEVE_METHOD.fullText,
|
||||
RETRIEVE_METHOD.hybrid,
|
||||
RETRIEVE_METHOD.keywordSearch,
|
||||
],
|
||||
}),
|
||||
}))
|
||||
|
||||
@ -63,6 +60,14 @@ vi.mock('@/app/components/datasets/create/step-two', () => ({
|
||||
},
|
||||
}))
|
||||
|
||||
const render = (ui: ReactElement) => {
|
||||
const queryClient = createConsoleQueryClient()
|
||||
queryClient.setQueryData(consoleQuery.datasets.retrievalSetting.get.queryOptions().queryKey, {
|
||||
retrieval_method: [RETRIEVE_METHOD.semantic, RETRIEVE_METHOD.fullText, RETRIEVE_METHOD.hybrid],
|
||||
})
|
||||
return renderWithConsoleQuery(ui, { queryClient })
|
||||
}
|
||||
|
||||
const createRetrievalConfig = (overrides: Partial<RetrievalConfig> = {}): RetrievalConfig => ({
|
||||
search_method: RETRIEVE_METHOD.semantic,
|
||||
reranking_enable: false,
|
||||
|
||||
@ -42,7 +42,6 @@ const defaultProviderContext = {
|
||||
refreshModelProviders: noop,
|
||||
isLoadingModelProviders: false,
|
||||
textGenerationModelList: [],
|
||||
supportRetrievalMethods: [],
|
||||
isAPIKeySet: false,
|
||||
plan: defaultPlan,
|
||||
isFetchedPlan: false,
|
||||
|
||||
@ -1,23 +1,18 @@
|
||||
import type { RetrievalConfig } from '@/types/app'
|
||||
import { fireEvent, render, screen } from '@testing-library/react'
|
||||
import { fireEvent, screen } from '@testing-library/react'
|
||||
import * as React from 'react'
|
||||
import { DEFAULT_WEIGHTED_SCORE, RerankingModeEnum, WeightedScoreEnum } from '@/models/datasets'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { createConsoleQueryClient, renderWithConsoleQuery } from '@/test/console/query-data'
|
||||
import { RETRIEVE_METHOD } from '@/types/app'
|
||||
import RetrievalMethodConfig from '../index'
|
||||
|
||||
// Mock provider context with controllable supportRetrievalMethods
|
||||
let mockSupportRetrievalMethods: RETRIEVE_METHOD[] = [
|
||||
let mockRetrievalMethods: string[] = [
|
||||
RETRIEVE_METHOD.semantic,
|
||||
RETRIEVE_METHOD.fullText,
|
||||
RETRIEVE_METHOD.hybrid,
|
||||
]
|
||||
|
||||
vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: () => ({
|
||||
supportRetrievalMethods: mockSupportRetrievalMethods,
|
||||
}),
|
||||
}))
|
||||
|
||||
// Mock model hooks with controllable return values
|
||||
let mockRerankDefaultModel: { provider: { provider: string }; model: string } | undefined = {
|
||||
provider: { provider: 'test-provider' },
|
||||
@ -72,6 +67,14 @@ const createMockRetrievalConfig = (overrides: Partial<RetrievalConfig> = {}): Re
|
||||
...overrides,
|
||||
})
|
||||
|
||||
const render = (ui: React.ReactElement) => {
|
||||
const queryClient = createConsoleQueryClient()
|
||||
queryClient.setQueryData(consoleQuery.datasets.retrievalSetting.get.queryOptions().queryKey, {
|
||||
retrieval_method: mockRetrievalMethods,
|
||||
})
|
||||
return renderWithConsoleQuery(ui, { queryClient })
|
||||
}
|
||||
|
||||
// Helper to render component with default props
|
||||
const renderComponent = (
|
||||
props: Partial<React.ComponentProps<typeof RetrievalMethodConfig>> = {},
|
||||
@ -87,7 +90,7 @@ describe('RetrievalMethodConfig', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
// Reset mock values to defaults
|
||||
mockSupportRetrievalMethods = [
|
||||
mockRetrievalMethods = [
|
||||
RETRIEVE_METHOD.semantic,
|
||||
RETRIEVE_METHOD.fullText,
|
||||
RETRIEVE_METHOD.hybrid,
|
||||
@ -118,7 +121,7 @@ describe('RetrievalMethodConfig', () => {
|
||||
})
|
||||
|
||||
it('should only render semantic search when only semantic is supported', () => {
|
||||
mockSupportRetrievalMethods = [RETRIEVE_METHOD.semantic]
|
||||
mockRetrievalMethods = [RETRIEVE_METHOD.semantic]
|
||||
renderComponent()
|
||||
|
||||
expect(screen.getByText('dataset.retrieval.semantic_search.title')).toBeInTheDocument()
|
||||
@ -127,7 +130,7 @@ describe('RetrievalMethodConfig', () => {
|
||||
})
|
||||
|
||||
it('should only render fullText search when only fullText is supported', () => {
|
||||
mockSupportRetrievalMethods = [RETRIEVE_METHOD.fullText]
|
||||
mockRetrievalMethods = [RETRIEVE_METHOD.fullText]
|
||||
renderComponent()
|
||||
|
||||
expect(screen.queryByText('dataset.retrieval.semantic_search.title')).not.toBeInTheDocument()
|
||||
@ -136,7 +139,7 @@ describe('RetrievalMethodConfig', () => {
|
||||
})
|
||||
|
||||
it('should only render hybrid search when only hybrid is supported', () => {
|
||||
mockSupportRetrievalMethods = [RETRIEVE_METHOD.hybrid]
|
||||
mockRetrievalMethods = [RETRIEVE_METHOD.hybrid]
|
||||
renderComponent()
|
||||
|
||||
expect(screen.queryByText('dataset.retrieval.semantic_search.title')).not.toBeInTheDocument()
|
||||
@ -145,7 +148,7 @@ describe('RetrievalMethodConfig', () => {
|
||||
})
|
||||
|
||||
it('should render nothing when no retrieval methods are supported', () => {
|
||||
mockSupportRetrievalMethods = []
|
||||
mockRetrievalMethods = []
|
||||
const { container } = renderComponent()
|
||||
|
||||
// Only the wrapper div should exist
|
||||
@ -763,15 +766,15 @@ describe('RetrievalMethodConfig', () => {
|
||||
expect(onChange).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('should handle empty supportRetrievalMethods array', () => {
|
||||
mockSupportRetrievalMethods = []
|
||||
it('should ignore unknown retrieval methods from the API', () => {
|
||||
mockRetrievalMethods = ['unknown_search']
|
||||
const { container } = renderComponent()
|
||||
|
||||
expect(container.querySelector('[class*="flex-col"]')?.childNodes.length).toBe(0)
|
||||
})
|
||||
|
||||
it('should handle partial supportRetrievalMethods', () => {
|
||||
mockSupportRetrievalMethods = [RETRIEVE_METHOD.semantic, RETRIEVE_METHOD.hybrid]
|
||||
it('should handle partial retrieval methods', () => {
|
||||
mockRetrievalMethods = [RETRIEVE_METHOD.semantic, RETRIEVE_METHOD.hybrid]
|
||||
renderComponent()
|
||||
|
||||
expect(screen.getByText('dataset.retrieval.semantic_search.title')).toBeInTheDocument()
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
'use client'
|
||||
import type { FC } from 'react'
|
||||
import type { RetrievalConfig } from '@/types/app'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import * as React from 'react'
|
||||
import { useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@ -11,8 +12,8 @@ import {
|
||||
} from '@/app/components/base/icons/src/vender/knowledge'
|
||||
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 { useProviderContext } from '@/context/provider-context'
|
||||
import { DEFAULT_WEIGHTED_SCORE, RerankingModeEnum, WeightedScoreEnum } from '@/models/datasets'
|
||||
import { consoleQuery } from '@/service/client'
|
||||
import { RETRIEVE_METHOD } from '@/types/app'
|
||||
import { EffectColor } from '../../settings/chunk-structure/types'
|
||||
import OptionCard from '../../settings/option-card'
|
||||
@ -32,7 +33,10 @@ const RetrievalMethodConfig: FC<Props> = ({
|
||||
onChange,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { supportRetrievalMethods } = useProviderContext()
|
||||
const { data: retrievalSetting } = useQuery(
|
||||
consoleQuery.datasets.retrievalSetting.get.queryOptions(),
|
||||
)
|
||||
const supportedRetrievalMethods = new Set(retrievalSetting?.retrieval_method ?? [])
|
||||
const { defaultModel: rerankDefaultModel, currentModel: isRerankDefaultModelValid } =
|
||||
useModelListAndDefaultModelAndCurrentProviderAndModel(ModelTypeEnum.rerank)
|
||||
|
||||
@ -107,7 +111,7 @@ const RetrievalMethodConfig: FC<Props> = ({
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-y-2">
|
||||
{supportRetrievalMethods.includes(RETRIEVE_METHOD.semantic) && (
|
||||
{supportedRetrievalMethods.has(RETRIEVE_METHOD.semantic) && (
|
||||
<OptionCard
|
||||
id={RETRIEVE_METHOD.semantic}
|
||||
disabled={disabled}
|
||||
@ -131,7 +135,7 @@ const RetrievalMethodConfig: FC<Props> = ({
|
||||
/>
|
||||
</OptionCard>
|
||||
)}
|
||||
{supportRetrievalMethods.includes(RETRIEVE_METHOD.fullText) && (
|
||||
{supportedRetrievalMethods.has(RETRIEVE_METHOD.fullText) && (
|
||||
<OptionCard
|
||||
id={RETRIEVE_METHOD.fullText}
|
||||
disabled={disabled}
|
||||
@ -155,7 +159,7 @@ const RetrievalMethodConfig: FC<Props> = ({
|
||||
/>
|
||||
</OptionCard>
|
||||
)}
|
||||
{supportRetrievalMethods.includes(RETRIEVE_METHOD.hybrid) && (
|
||||
{supportedRetrievalMethods.has(RETRIEVE_METHOD.hybrid) && (
|
||||
<OptionCard
|
||||
id={RETRIEVE_METHOD.hybrid}
|
||||
disabled={disabled}
|
||||
|
||||
@ -288,13 +288,6 @@ vi.mock('@/context/i18n', () => ({
|
||||
useDocLink: vi.fn(() => () => 'https://docs.example.com'),
|
||||
}))
|
||||
|
||||
// Mock provider context for retrieval method config
|
||||
vi.mock('@/context/provider-context', () => ({
|
||||
useProviderContext: vi.fn(() => ({
|
||||
supportRetrievalMethods: ['semantic_search', 'full_text_search', 'hybrid_search'],
|
||||
})),
|
||||
}))
|
||||
|
||||
// Mock model list hook - include all exports used by child components
|
||||
vi.mock('@/app/components/header/account-setting/model-provider-page/hooks', () => ({
|
||||
useModelList: vi.fn(() => ({
|
||||
|
||||
@ -227,7 +227,6 @@ vi.mock('@/context/provider-context', () => ({
|
||||
plan: { type: 'free' },
|
||||
enableBilling: false,
|
||||
onPlanInfoChanged: vi.fn(),
|
||||
supportRetrievalMethods: ['semantic_search', 'full_text_search', 'hybrid_search'],
|
||||
}),
|
||||
}))
|
||||
|
||||
|
||||
@ -19,11 +19,7 @@ import {
|
||||
import { ZENDESK_FIELD_IDS } from '@/config'
|
||||
import { deploymentEditionAtom } from '@/context/system-features-state'
|
||||
import { fetchCurrentPlanInfo } from '@/service/billing'
|
||||
import {
|
||||
useModelListByType,
|
||||
useModelProviders,
|
||||
useSupportRetrievalMethods,
|
||||
} from '@/service/use-common'
|
||||
import { useModelListByType, useModelProviders } from '@/service/use-common'
|
||||
import { useEducationStatus } from '@/service/use-education'
|
||||
import { ProviderContext } from './provider-context'
|
||||
import { useAnthropicQuotaNotice } from './provider-storage'
|
||||
@ -69,7 +65,6 @@ export const ProviderContextProvider = ({ children }: ProviderContextProviderPro
|
||||
const queryClient = useQueryClient()
|
||||
const { data: providersData, isLoading: isLoadingModelProviders } = useModelProviders()
|
||||
const { data: textGenerationModelList } = useModelListByType(ModelTypeEnum.textGeneration)
|
||||
const { data: supportRetrievalMethods } = useSupportRetrievalMethods()
|
||||
|
||||
const [plan, setPlan] = useState<ProviderContextState['plan']>(defaultPlan)
|
||||
const [isFetchedPlan, setIsFetchedPlan] = useState(false)
|
||||
@ -205,7 +200,6 @@ export const ProviderContextProvider = ({ children }: ProviderContextProviderPro
|
||||
isAPIKeySet: !!textGenerationModelList?.data?.some(
|
||||
(model) => model.status === ModelStatusEnum.active,
|
||||
),
|
||||
supportRetrievalMethods: supportRetrievalMethods?.retrieval_method || [],
|
||||
plan,
|
||||
isFetchedPlan,
|
||||
isFetchedPlanInfo,
|
||||
|
||||
@ -5,7 +5,6 @@ import type {
|
||||
Model,
|
||||
ModelProvider,
|
||||
} from '@/app/components/header/account-setting/model-provider-page/declarations'
|
||||
import type { RETRIEVE_METHOD } from '@/types/app'
|
||||
import { noop } from 'es-toolkit/function'
|
||||
import { createContext, useContext, useContextSelector } from 'use-context-selector'
|
||||
import { defaultPlan } from '@/app/components/billing/config'
|
||||
@ -15,7 +14,6 @@ export type ProviderContextState = {
|
||||
isLoadingModelProviders: boolean
|
||||
refreshModelProviders: () => void
|
||||
textGenerationModelList: Model[]
|
||||
supportRetrievalMethods: RETRIEVE_METHOD[]
|
||||
isAPIKeySet: boolean
|
||||
plan: {
|
||||
type: Plan
|
||||
@ -55,7 +53,6 @@ export const baseProviderContextValue: ProviderContextState = {
|
||||
isLoadingModelProviders: false,
|
||||
refreshModelProviders: noop,
|
||||
textGenerationModelList: [],
|
||||
supportRetrievalMethods: [],
|
||||
isAPIKeySet: true,
|
||||
plan: defaultPlan,
|
||||
isFetchedPlan: false,
|
||||
|
||||
@ -14,7 +14,6 @@ import type {
|
||||
StructuredOutputRulesRequestBody,
|
||||
StructuredOutputRulesResponse,
|
||||
} from '@/models/common'
|
||||
import type { RETRIEVE_METHOD } from '@/types/app'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { get, post } from './base'
|
||||
@ -29,7 +28,6 @@ export const commonQueryKeys = {
|
||||
modelProviders: [NAME_SPACE, 'model-providers'] as const,
|
||||
modelList: (type: ModelTypeEnum) => [NAME_SPACE, 'model-list', type] as const,
|
||||
defaultModel: (type: ModelTypeEnum) => [NAME_SPACE, 'default-model', type] as const,
|
||||
retrievalMethods: [NAME_SPACE, 'support-retrieval-methods'] as const,
|
||||
accountIntegrates: [NAME_SPACE, 'account-integrates'] as const,
|
||||
notionConnection: [NAME_SPACE, 'notion-connection'] as const,
|
||||
codeBasedExtensions: (module?: string) => [NAME_SPACE, 'code-based-extensions', module] as const,
|
||||
@ -211,13 +209,6 @@ export const useModelListByType = (type: ModelTypeEnum, enabled = true) => {
|
||||
})
|
||||
}
|
||||
|
||||
export const useSupportRetrievalMethods = () => {
|
||||
return useQuery<{ retrieval_method: RETRIEVE_METHOD[] }>({
|
||||
queryKey: commonQueryKeys.retrievalMethods,
|
||||
queryFn: () => get<{ retrieval_method: RETRIEVE_METHOD[] }>('/datasets/retrieval-setting'),
|
||||
})
|
||||
}
|
||||
|
||||
export const useCodeBasedExtensions = (module: string) => {
|
||||
return useQuery<CodeBasedExtension>({
|
||||
queryKey: commonQueryKeys.codeBasedExtensions(module),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user