### 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
| 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> | |||||
| )} | |||||
| /> | |||||
| ); | |||||
| }; |
| 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> | |||||
| ); | |||||
| }; |
| stringTransform: 'String transform', | stringTransform: 'String transform', | ||||
| userFillUp: 'Input', | userFillUp: 'Input', | ||||
| codeExec: 'Code', | codeExec: 'Code', | ||||
| tavilySearch: 'Tavily Search', | |||||
| tavilySearchDescription: 'Search results via Tavily service.', | |||||
| tavilyExtract: 'Tavily Extract', | |||||
| tavilyExtractDescription: 'Tavily Extract', | |||||
| }, | }, | ||||
| llmTools: { | llmTools: { | ||||
| bad_calculator: { | bad_calculator: { |
| stringTransform: '文本处理', | stringTransform: '文本处理', | ||||
| userFillUp: '等待输入', | userFillUp: '等待输入', | ||||
| codeExec: '代码', | codeExec: '代码', | ||||
| tavilySearch: 'Tavily Search', | |||||
| tavilySearchDescription: '通过 Tavily 服务搜索结果', | |||||
| tavilyExtract: 'Tavily Extract', | |||||
| tavilyExtractDescription: 'Tavily Extract', | |||||
| }, | }, | ||||
| footer: { | footer: { | ||||
| profile: 'All rights reserved @ React', | profile: 'All rights reserved @ React', |
| empty_response: '', | empty_response: '', | ||||
| ...initialSimilarityThresholdValue, | ...initialSimilarityThresholdValue, | ||||
| ...initialKeywordsSimilarityWeightValue, | ...initialKeywordsSimilarityWeightValue, | ||||
| use_kg: false, | |||||
| cross_languages: [], | |||||
| outputs: { | outputs: { | ||||
| formalized_content: { | formalized_content: { | ||||
| type: 'string', | type: 'string', |
| import { CrossLanguageFormField } from '@/components/cross-language-form-field'; | |||||
| import { FormContainer } from '@/components/form-container'; | import { FormContainer } from '@/components/form-container'; | ||||
| import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | ||||
| import { RerankFormFields } from '@/components/rerank'; | import { RerankFormFields } from '@/components/rerank'; | ||||
| FormMessage, | FormMessage, | ||||
| } from '@/components/ui/form'; | } from '@/components/ui/form'; | ||||
| import { Textarea } from '@/components/ui/textarea'; | import { Textarea } from '@/components/ui/textarea'; | ||||
| import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item'; | |||||
| import { zodResolver } from '@hookform/resolvers/zod'; | import { zodResolver } from '@hookform/resolvers/zod'; | ||||
| import { memo, useMemo } from 'react'; | import { memo, useMemo } from 'react'; | ||||
| import { useForm, useFormContext } from 'react-hook-form'; | import { useForm, useFormContext } from 'react-hook-form'; | ||||
| kb_ids: z.array(z.string()), | kb_ids: z.array(z.string()), | ||||
| rerank_id: z.string(), | rerank_id: z.string(), | ||||
| empty_response: z.string(), | empty_response: z.string(), | ||||
| cross_languages: z.array(z.string()), | |||||
| use_kg: z.boolean(), | |||||
| }; | }; | ||||
| export const FormSchema = z.object({ | export const FormSchema = z.object({ | ||||
| <TopNFormField></TopNFormField> | <TopNFormField></TopNFormField> | ||||
| <RerankFormFields></RerankFormFields> | <RerankFormFields></RerankFormFields> | ||||
| <EmptyResponseField></EmptyResponseField> | <EmptyResponseField></EmptyResponseField> | ||||
| <CrossLanguageFormField name="cross_languages"></CrossLanguageFormField> | |||||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||||
| </FormContainer> | </FormContainer> | ||||
| <Output list={outputList}></Output> | <Output list={outputList}></Output> | ||||
| </form> | </form> |
| import { CrossLanguageFormField } from '@/components/cross-language-form-field'; | |||||
| import { FormContainer } from '@/components/form-container'; | import { FormContainer } from '@/components/form-container'; | ||||
| import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | import { KnowledgeBaseFormField } from '@/components/knowledge-base-item'; | ||||
| import { RerankFormFields } from '@/components/rerank'; | import { RerankFormFields } from '@/components/rerank'; | ||||
| import { SimilaritySliderFormField } from '@/components/similarity-slider'; | import { SimilaritySliderFormField } from '@/components/similarity-slider'; | ||||
| import { TopNFormField } from '@/components/top-n-item'; | import { TopNFormField } from '@/components/top-n-item'; | ||||
| import { Form } from '@/components/ui/form'; | import { Form } from '@/components/ui/form'; | ||||
| import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item'; | |||||
| import { zodResolver } from '@hookform/resolvers/zod'; | import { zodResolver } from '@hookform/resolvers/zod'; | ||||
| import { useForm } from 'react-hook-form'; | import { useForm } from 'react-hook-form'; | ||||
| import { z } from 'zod'; | import { z } from 'zod'; | ||||
| <TopNFormField></TopNFormField> | <TopNFormField></TopNFormField> | ||||
| <RerankFormFields></RerankFormFields> | <RerankFormFields></RerankFormFields> | ||||
| <EmptyResponseField></EmptyResponseField> | <EmptyResponseField></EmptyResponseField> | ||||
| <CrossLanguageFormField name="cross_languages"></CrossLanguageFormField> | |||||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | |||||
| </FormContainer> | </FormContainer> | ||||
| </form> | </form> | ||||
| </Form> | </Form> |
| import { useForm, useWatch } from 'react-hook-form'; | import { useForm, useWatch } from 'react-hook-form'; | ||||
| import { z } from 'zod'; | 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 { FormContainer } from '@/components/form-container'; | ||||
| import { | import { | ||||
| initialTopKValue, | initialTopKValue, | ||||
| import { useTestRetrieval } from '@/hooks/use-knowledge-request'; | import { useTestRetrieval } from '@/hooks/use-knowledge-request'; | ||||
| import { trim } from 'lodash'; | import { trim } from 'lodash'; | ||||
| import { CirclePlay } from 'lucide-react'; | import { CirclePlay } from 'lucide-react'; | ||||
| import { useEffect, useState } from 'react'; | |||||
| import { useEffect } from 'react'; | |||||
| import { useTranslation } from 'react-i18next'; | import { useTranslation } from 'react-i18next'; | ||||
| type TestingFormProps = Pick< | type TestingFormProps = Pick< | ||||
| setValues, | setValues, | ||||
| }: TestingFormProps) { | }: TestingFormProps) { | ||||
| const { t } = useTranslation(); | const { t } = useTranslation(); | ||||
| const [cross_languages, setCrossLangArr] = useState<string[]>([]); | |||||
| const formSchema = z.object({ | const formSchema = z.object({ | ||||
| question: z.string().min(1, { | question: z.string().min(1, { | ||||
| const values = useWatch({ control: form.control }); | const values = useWatch({ control: form.control }); | ||||
| useEffect(() => { | 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() { | function onSubmit() { | ||||
| refetch(); | refetch(); | ||||
| ></SimilaritySliderFormField> | ></SimilaritySliderFormField> | ||||
| <RerankFormFields></RerankFormFields> | <RerankFormFields></RerankFormFields> | ||||
| <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | <UseKnowledgeGraphFormField name="use_kg"></UseKnowledgeGraphFormField> | ||||
| <CrossLanguageItem | |||||
| <CrossLanguageFormField | |||||
| name={'cross_languages'} | name={'cross_languages'} | ||||
| onChange={(valArr) => { | |||||
| setCrossLangArr(valArr); | |||||
| }} | |||||
| ></CrossLanguageItem> | |||||
| ></CrossLanguageFormField> | |||||
| </FormContainer> | </FormContainer> | ||||
| <FormField | <FormField | ||||
| control={form.control} | control={form.control} |