### What problem does this PR solve? Feat: Add the option to use the knowledge graph to the retrieval form #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)tags/v0.20.0
| @@ -0,0 +1,67 @@ | |||
| import { | |||
| FormControl, | |||
| FormField, | |||
| FormItem, | |||
| FormLabel, | |||
| } from '@/components/ui/form'; | |||
| import { MultiSelect } from '@/components/ui/multi-select'; | |||
| import { cn } from '@/lib/utils'; | |||
| import { useFormContext } from 'react-hook-form'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| const Languages = [ | |||
| 'English', | |||
| 'Chinese', | |||
| 'Spanish', | |||
| 'French', | |||
| 'German', | |||
| 'Japanese', | |||
| 'Korean', | |||
| 'Vietnamese', | |||
| ]; | |||
| const options = Languages.map((x) => ({ label: x, value: x })); | |||
| type CrossLanguageItemProps = { | |||
| name?: string; | |||
| vertical?: boolean; | |||
| }; | |||
| export const CrossLanguageFormField = ({ | |||
| name = 'prompt_config.cross_languages', | |||
| vertical = true, | |||
| }: CrossLanguageItemProps) => { | |||
| const { t } = useTranslation(); | |||
| const form = useFormContext(); | |||
| return ( | |||
| <FormField | |||
| control={form.control} | |||
| name={name} | |||
| render={({ field }) => ( | |||
| <FormItem | |||
| className={cn('flex', { | |||
| 'gap-2': vertical, | |||
| 'flex-col': vertical, | |||
| 'justify-between': !vertical, | |||
| 'items-center': !vertical, | |||
| })} | |||
| > | |||
| <FormLabel tooltip={t('chat.crossLanguageTip')}> | |||
| {t('chat.crossLanguage')} | |||
| </FormLabel> | |||
| <FormControl> | |||
| <MultiSelect | |||
| options={options} | |||
| placeholder={t('fileManager.pleaseSelect')} | |||
| maxCount={100} | |||
| {...field} | |||
| onValueChange={field.onChange} | |||
| modalPopover | |||
| /> | |||
| </FormControl> | |||
| </FormItem> | |||
| )} | |||
| /> | |||
| ); | |||
| }; | |||
| @@ -1,49 +0,0 @@ | |||
| import { FormLabel } from '@/components/ui/form'; | |||
| import { MultiSelect } from '@/components/ui/multi-select'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| const Languages = [ | |||
| 'English', | |||
| 'Chinese', | |||
| 'Spanish', | |||
| 'French', | |||
| 'German', | |||
| 'Japanese', | |||
| 'Korean', | |||
| 'Vietnamese', | |||
| ]; | |||
| const options = Languages.map((x) => ({ label: x, value: x })); | |||
| type CrossLanguageItemProps = { | |||
| name?: string | Array<string>; | |||
| onChange: (arg: string[]) => void; | |||
| }; | |||
| export const CrossLanguageItem = ({ | |||
| name = ['prompt_config', 'cross_languages'], | |||
| onChange = () => {}, | |||
| }: CrossLanguageItemProps) => { | |||
| const { t } = useTranslation(); | |||
| return ( | |||
| <div> | |||
| <div className="pb-2"> | |||
| <FormLabel tooltip={t('chat.crossLanguageTip')}> | |||
| {t('chat.crossLanguage')} | |||
| </FormLabel> | |||
| </div> | |||
| <MultiSelect | |||
| options={options} | |||
| onValueChange={(val) => { | |||
| onChange(val); | |||
| }} | |||
| // defaultValue={field.value} | |||
| placeholder={t('fileManager.pleaseSelect')} | |||
| maxCount={100} | |||
| // {...field} | |||
| modalPopover | |||
| /> | |||
| </div> | |||
| ); | |||
| }; | |||
| @@ -1298,6 +1298,10 @@ This delimiter is used to split the input text into several text pieces echo of | |||
| stringTransform: 'String transform', | |||
| userFillUp: 'Input', | |||
| codeExec: 'Code', | |||
| tavilySearch: 'Tavily Search', | |||
| tavilySearchDescription: 'Search results via Tavily service.', | |||
| tavilyExtract: 'Tavily Extract', | |||
| tavilyExtractDescription: 'Tavily Extract', | |||
| }, | |||
| llmTools: { | |||
| bad_calculator: { | |||
| @@ -1251,6 +1251,10 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于 | |||
| stringTransform: '文本处理', | |||
| userFillUp: '等待输入', | |||
| codeExec: '代码', | |||
| tavilySearch: 'Tavily Search', | |||
| tavilySearchDescription: '通过 Tavily 服务搜索结果', | |||
| tavilyExtract: 'Tavily Extract', | |||
| tavilyExtractDescription: 'Tavily Extract', | |||
| }, | |||
| footer: { | |||
| profile: 'All rights reserved @ React', | |||
| @@ -265,6 +265,8 @@ export const initialRetrievalValues = { | |||
| empty_response: '', | |||
| ...initialSimilarityThresholdValue, | |||
| ...initialKeywordsSimilarityWeightValue, | |||
| use_kg: false, | |||
| cross_languages: [], | |||
| outputs: { | |||
| formalized_content: { | |||
| type: 'string', | |||
| @@ -1,3 +1,4 @@ | |||
| import { CrossLanguageFormField } from '@/components/cross-language-form-field'; | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | |||
| import { RerankFormFields } from '@/components/rerank'; | |||
| @@ -12,6 +13,7 @@ import { | |||
| FormMessage, | |||
| } from '@/components/ui/form'; | |||
| import { Textarea } from '@/components/ui/textarea'; | |||
| import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { memo, useMemo } from 'react'; | |||
| import { useForm, useFormContext } from 'react-hook-form'; | |||
| @@ -32,6 +34,8 @@ export const RetrievalPartialSchema = { | |||
| kb_ids: z.array(z.string()), | |||
| rerank_id: z.string(), | |||
| empty_response: z.string(), | |||
| cross_languages: z.array(z.string()), | |||
| use_kg: z.boolean(), | |||
| }; | |||
| export const FormSchema = z.object({ | |||
| @@ -106,6 +110,8 @@ function RetrievalForm({ node }: INextOperatorForm) { | |||
| <TopNFormField></TopNFormField> | |||
| <RerankFormFields></RerankFormFields> | |||
| <EmptyResponseField></EmptyResponseField> | |||
| <CrossLanguageFormField name="cross_languages"></CrossLanguageFormField> | |||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||
| </FormContainer> | |||
| <Output list={outputList}></Output> | |||
| </form> | |||
| @@ -1,9 +1,11 @@ | |||
| import { CrossLanguageFormField } from '@/components/cross-language-form-field'; | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | |||
| import { RerankFormFields } from '@/components/rerank'; | |||
| import { SimilaritySliderFormField } from '@/components/similarity-slider'; | |||
| import { TopNFormField } from '@/components/top-n-item'; | |||
| import { Form } from '@/components/ui/form'; | |||
| import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item'; | |||
| import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { useForm } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| @@ -50,6 +52,8 @@ const RetrievalForm = () => { | |||
| <TopNFormField></TopNFormField> | |||
| <RerankFormFields></RerankFormFields> | |||
| <EmptyResponseField></EmptyResponseField> | |||
| <CrossLanguageFormField name="cross_languages"></CrossLanguageFormField> | |||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||
| </FormContainer> | |||
| </form> | |||
| </Form> | |||
| @@ -4,7 +4,7 @@ import { zodResolver } from '@hookform/resolvers/zod'; | |||
| import { useForm, useWatch } from 'react-hook-form'; | |||
| import { z } from 'zod'; | |||
| import { CrossLanguageItem } from '@/components/cross-language-item-ui'; | |||
| import { CrossLanguageFormField } from '@/components/cross-language-form-field'; | |||
| import { FormContainer } from '@/components/form-container'; | |||
| import { | |||
| initialTopKValue, | |||
| @@ -32,7 +32,7 @@ import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-ite | |||
| import { useTestRetrieval } from '@/hooks/use-knowledge-request'; | |||
| import { trim } from 'lodash'; | |||
| import { CirclePlay } from 'lucide-react'; | |||
| import { useEffect, useState } from 'react'; | |||
| import { useEffect } from 'react'; | |||
| import { useTranslation } from 'react-i18next'; | |||
| type TestingFormProps = Pick< | |||
| @@ -46,7 +46,6 @@ export default function TestingForm({ | |||
| setValues, | |||
| }: TestingFormProps) { | |||
| const { t } = useTranslation(); | |||
| const [cross_languages, setCrossLangArr] = useState<string[]>([]); | |||
| const formSchema = z.object({ | |||
| question: z.string().min(1, { | |||
| @@ -71,9 +70,8 @@ export default function TestingForm({ | |||
| const values = useWatch({ control: form.control }); | |||
| useEffect(() => { | |||
| // setValues(values as Required<z.infer<typeof formSchema>>); | |||
| setValues({ ...values, cross_languages }); | |||
| }, [setValues, values, cross_languages]); | |||
| setValues(values as Required<z.infer<typeof formSchema>>); | |||
| }, [setValues, values]); | |||
| function onSubmit() { | |||
| refetch(); | |||
| @@ -89,12 +87,9 @@ export default function TestingForm({ | |||
| ></SimilaritySliderFormField> | |||
| <RerankFormFields></RerankFormFields> | |||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||
| <CrossLanguageItem | |||
| <CrossLanguageFormField | |||
| name={'cross_languages'} | |||
| onChange={(valArr) => { | |||
| setCrossLangArr(valArr); | |||
| }} | |||
| ></CrossLanguageItem> | |||
| ></CrossLanguageFormField> | |||
| </FormContainer> | |||
| <FormField | |||
| control={form.control} | |||