mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 15:31:05 +08:00
Feat: Add a prefix to the name of the FormField associated with the chat. (#16178)
Fix: Add a prefix to the `name` of the `FormField` associated with the chat.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { ModelTreeSelect } from '@/components/model-tree-select';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { prefixName } from '@/utils/form';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import { SliderInputFormField } from './slider-input-form-field';
|
||||
@@ -19,16 +20,21 @@ export const initialTopKValue = {
|
||||
top_k: 1024,
|
||||
};
|
||||
|
||||
const RerankId = 'rerank_id';
|
||||
const DefaultRerankId = 'rerank_id';
|
||||
const DefaultTopK = 'top_k';
|
||||
|
||||
function RerankFormField() {
|
||||
interface RerankFormFieldProps {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
function RerankFormField({ name = DefaultRerankId }: RerankFormFieldProps) {
|
||||
const form = useFormContext();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
|
||||
return (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={RerankId}
|
||||
name={name}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('rerankTip')}>{t('rerankModel')}</FormLabel>
|
||||
@@ -48,21 +54,28 @@ function RerankFormField() {
|
||||
}
|
||||
|
||||
export const rerankFormSchema = {
|
||||
[RerankId]: z.string().optional(),
|
||||
[DefaultRerankId]: z.string().optional(),
|
||||
top_k: z.coerce.number().optional(),
|
||||
};
|
||||
|
||||
export function RerankFormFields() {
|
||||
interface RerankFormFieldsProps {
|
||||
prefix?: string;
|
||||
}
|
||||
|
||||
export function RerankFormFields({ prefix = '' }: RerankFormFieldsProps) {
|
||||
const { watch } = useFormContext();
|
||||
const { t } = useTranslate('knowledgeDetails');
|
||||
const rerankId = watch(RerankId);
|
||||
const rerankIdName = prefixName(prefix, DefaultRerankId);
|
||||
const topKName = prefixName(prefix, DefaultTopK);
|
||||
|
||||
const rerankId = watch(rerankIdName);
|
||||
|
||||
return (
|
||||
<>
|
||||
<RerankFormField></RerankFormField>
|
||||
<RerankFormField name={rerankIdName}></RerankFormField>
|
||||
{rerankId && (
|
||||
<SliderInputFormField
|
||||
name={'top_k'}
|
||||
name={topKName}
|
||||
label={t('topK')}
|
||||
max={2048}
|
||||
min={1}
|
||||
|
||||
@@ -5,18 +5,22 @@ import { SliderInputFormField } from './slider-input-form-field';
|
||||
|
||||
interface SimilaritySliderFormFieldProps {
|
||||
max?: number;
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export const topnSchema = {
|
||||
top_n: z.number().optional(),
|
||||
};
|
||||
|
||||
export function TopNFormField({ max = 30 }: SimilaritySliderFormFieldProps) {
|
||||
export function TopNFormField({
|
||||
max = 30,
|
||||
name = 'top_n',
|
||||
}: SimilaritySliderFormFieldProps) {
|
||||
const { t } = useTranslate('chat');
|
||||
|
||||
return (
|
||||
<SliderInputFormField
|
||||
name={'top_n'}
|
||||
name={name}
|
||||
label={t('topN')}
|
||||
max={max}
|
||||
tooltip={t('topNTip')}
|
||||
|
||||
@@ -12,21 +12,33 @@ import {
|
||||
} from '@/components/ui/form';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { useTranslate } from '@/hooks/common-hooks';
|
||||
import { prefixName } from '@/utils/form';
|
||||
import { getDirAttribute } from '@/utils/text-direction';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
|
||||
export default function ChatBasicSetting() {
|
||||
interface ChatBasicSettingProps {
|
||||
prefix?: string;
|
||||
option?: Record<string, any>;
|
||||
}
|
||||
|
||||
export default function ChatBasicSetting({
|
||||
prefix = '',
|
||||
}: ChatBasicSettingProps) {
|
||||
const { t } = useTranslate('chat');
|
||||
const form = useFormContext();
|
||||
|
||||
const prologueValue = useWatch({
|
||||
control: form.control,
|
||||
name: 'prompt_config.prologue',
|
||||
name: prefixName(prefix, 'prompt_config.prologue'),
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<AvatarNameDescription />
|
||||
<AvatarNameDescription
|
||||
avatarField={prefixName(prefix, 'icon')}
|
||||
nameField={prefixName(prefix, 'name')}
|
||||
descriptionField={prefixName(prefix, 'description')}
|
||||
/>
|
||||
<LlmSettingFieldItems
|
||||
prefix="llm_setting"
|
||||
llmId="llm_id"
|
||||
@@ -35,7 +47,7 @@ export default function ChatBasicSetting() {
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'prompt_config.prologue'}
|
||||
name={prefixName(prefix, 'prompt_config.prologue')}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('setAnOpenerTip')}>
|
||||
@@ -51,8 +63,9 @@ export default function ChatBasicSetting() {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<KnowledgeBaseFormField></KnowledgeBaseFormField>
|
||||
<KnowledgeBaseFormField
|
||||
name={prefixName(prefix, 'dataset_ids')}
|
||||
></KnowledgeBaseFormField>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,21 +21,30 @@ import { Switch } from '@/components/ui/switch';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { UseKnowledgeGraphFormField } from '@/components/use-knowledge-graph-item';
|
||||
import { useFetchKnowledgeMetadataKeys } from '@/hooks/use-knowledge-request';
|
||||
import { prefixName } from '@/utils/form';
|
||||
import { getDirAttribute } from '@/utils/text-direction';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useFormContext, useWatch } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DynamicVariableForm } from './dynamic-variable';
|
||||
|
||||
export function ChatPromptEngine() {
|
||||
interface ChatPromptEngineProps {
|
||||
prefix?: string;
|
||||
}
|
||||
|
||||
export function ChatPromptEngine({ prefix = '' }: ChatPromptEngineProps) {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
const systemPromptValue = form.watch('prompt_config.system');
|
||||
const systemPromptValue = form.watch(
|
||||
prefixName(prefix, 'prompt_config.system'),
|
||||
);
|
||||
|
||||
const emptyResponseValue = form.watch('prompt_config.empty_response');
|
||||
const emptyResponseValue = form.watch(
|
||||
prefixName(prefix, 'prompt_config.empty_response'),
|
||||
);
|
||||
const rawDatasetIds = useWatch({
|
||||
control: form.control,
|
||||
name: 'dataset_ids',
|
||||
name: prefixName(prefix, 'dataset_ids'),
|
||||
});
|
||||
const kbIds = useMemo(
|
||||
() => (rawDatasetIds || []) as string[],
|
||||
@@ -43,7 +52,7 @@ export function ChatPromptEngine() {
|
||||
);
|
||||
const metadataInclude = useWatch({
|
||||
control: form.control,
|
||||
name: 'prompt_config.reference_metadata.include',
|
||||
name: prefixName(prefix, 'prompt_config.reference_metadata.include'),
|
||||
});
|
||||
const { data: metadataKeys, loading: metadataKeysLoading } =
|
||||
useFetchKnowledgeMetadataKeys(kbIds);
|
||||
@@ -56,7 +65,7 @@ export function ChatPromptEngine() {
|
||||
|
||||
useEffect(() => {
|
||||
const currentFields = form.getValues(
|
||||
'prompt_config.reference_metadata.fields',
|
||||
prefixName(prefix, 'prompt_config.reference_metadata.fields'),
|
||||
);
|
||||
if (
|
||||
metadataInclude &&
|
||||
@@ -68,19 +77,25 @@ export function ChatPromptEngine() {
|
||||
metadataKeys.includes(field),
|
||||
);
|
||||
if (validFields.length !== currentFields.length) {
|
||||
form.setValue('prompt_config.reference_metadata.fields', validFields);
|
||||
form.setValue(
|
||||
prefixName(prefix, 'prompt_config.reference_metadata.fields'),
|
||||
validFields,
|
||||
);
|
||||
}
|
||||
} else if (!metadataInclude) {
|
||||
form.setValue('prompt_config.reference_metadata.fields', undefined);
|
||||
form.setValue(
|
||||
prefixName(prefix, 'prompt_config.reference_metadata.fields'),
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
}, [kbIds, metadataKeys, metadataKeysLoading, metadataInclude, form]);
|
||||
}, [kbIds, metadataKeys, metadataKeysLoading, metadataInclude, form, prefix]);
|
||||
|
||||
return (
|
||||
<Collapse title={t('flow.advancedSettings')}>
|
||||
<div className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'prompt_config.empty_response'}
|
||||
name={prefixName(prefix, 'prompt_config.empty_response')}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip={t('chat.emptyResponseTip')}>
|
||||
@@ -98,26 +113,28 @@ export function ChatPromptEngine() {
|
||||
)}
|
||||
/>
|
||||
<SwitchFormField
|
||||
name={'prompt_config.quote'}
|
||||
name={prefixName(prefix, 'prompt_config.quote')}
|
||||
label={t('chat.quote')}
|
||||
tooltip={t('chat.quoteTip')}
|
||||
></SwitchFormField>
|
||||
<SwitchFormField
|
||||
name={'prompt_config.keyword'}
|
||||
name={prefixName(prefix, 'prompt_config.keyword')}
|
||||
label={t('chat.keyword')}
|
||||
tooltip={t('chat.keywordTip')}
|
||||
></SwitchFormField>
|
||||
<SwitchFormField
|
||||
name={'prompt_config.tts'}
|
||||
name={prefixName(prefix, 'prompt_config.tts')}
|
||||
label={t('chat.tts')}
|
||||
tooltip={t('chat.ttsTip')}
|
||||
></SwitchFormField>
|
||||
<TOCEnhanceFormField name="prompt_config.toc_enhance"></TOCEnhanceFormField>
|
||||
<TOCEnhanceFormField
|
||||
name={prefixName(prefix, 'prompt_config.toc_enhance')}
|
||||
></TOCEnhanceFormField>
|
||||
<TavilyFormField></TavilyFormField>
|
||||
<MetadataFilter></MetadataFilter>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'prompt_config.reference_metadata.include'}
|
||||
name={prefixName(prefix, 'prompt_config.reference_metadata.include')}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-start space-x-3 space-y-0">
|
||||
<FormControl>
|
||||
@@ -127,7 +144,10 @@ export function ChatPromptEngine() {
|
||||
field.onChange(value);
|
||||
if (!value) {
|
||||
form.setValue(
|
||||
'prompt_config.reference_metadata.fields',
|
||||
prefixName(
|
||||
prefix,
|
||||
'prompt_config.reference_metadata.fields',
|
||||
),
|
||||
undefined,
|
||||
);
|
||||
}
|
||||
@@ -143,7 +163,7 @@ export function ChatPromptEngine() {
|
||||
{metadataInclude && (
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'prompt_config.reference_metadata.fields'}
|
||||
name={prefixName(prefix, 'prompt_config.reference_metadata.fields')}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel tooltip="Select which metadata fields to display with each chunk">
|
||||
@@ -170,7 +190,7 @@ export function ChatPromptEngine() {
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="prompt_config.system"
|
||||
name={prefixName(prefix, 'prompt_config.system')}
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('chat.system')}</FormLabel>
|
||||
@@ -187,17 +207,28 @@ export function ChatPromptEngine() {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<SimilaritySliderFormField isTooltipShown></SimilaritySliderFormField>
|
||||
<TopNFormField></TopNFormField>
|
||||
<SimilaritySliderFormField
|
||||
isTooltipShown
|
||||
similarityName={prefixName(prefix, 'similarity_threshold')}
|
||||
similarityWeightName={prefixName(prefix, 'vector_similarity_weight')}
|
||||
></SimilaritySliderFormField>
|
||||
<TopNFormField name={prefixName(prefix, 'top_n')}></TopNFormField>
|
||||
|
||||
<SwitchFormField
|
||||
name={'prompt_config.refine_multiturn'}
|
||||
name={prefixName(prefix, 'prompt_config.refine_multiturn')}
|
||||
label={t('chat.multiTurn')}
|
||||
tooltip={t('chat.multiTurnTip')}
|
||||
></SwitchFormField>
|
||||
<UseKnowledgeGraphFormField name="prompt_config.use_kg"></UseKnowledgeGraphFormField>
|
||||
<RerankFormFields></RerankFormFields>
|
||||
<CrossLanguageFormField></CrossLanguageFormField>
|
||||
<DynamicVariableForm></DynamicVariableForm>
|
||||
<UseKnowledgeGraphFormField
|
||||
name={prefixName(prefix, 'prompt_config.use_kg')}
|
||||
></UseKnowledgeGraphFormField>
|
||||
<RerankFormFields prefix={prefix}></RerankFormFields>
|
||||
<CrossLanguageFormField
|
||||
name={prefixName(prefix, 'prompt_config.cross_languages')}
|
||||
></CrossLanguageFormField>
|
||||
<DynamicVariableForm
|
||||
name={prefixName(prefix, 'prompt_config.parameters')}
|
||||
></DynamicVariableForm>
|
||||
</div>
|
||||
</Collapse>
|
||||
);
|
||||
|
||||
@@ -15,10 +15,15 @@ import { useCallback } from 'react';
|
||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function DynamicVariableForm() {
|
||||
interface DynamicVariableFormProps {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export function DynamicVariableForm({
|
||||
name = 'prompt_config.parameters',
|
||||
}: DynamicVariableFormProps) {
|
||||
const { t } = useTranslation();
|
||||
const form = useFormContext();
|
||||
const name = 'prompt_config.parameters';
|
||||
|
||||
const { fields, remove, append } = useFieldArray({
|
||||
name,
|
||||
|
||||
@@ -64,3 +64,16 @@ export function setLLMSettingEnabledValues(
|
||||
}, {});
|
||||
return values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add prefix to form field name
|
||||
* @param prefix - The prefix to add (e.g., 'chat.', 'settings.')
|
||||
* @param name - The field name
|
||||
* @returns The prefixed field name
|
||||
* @example
|
||||
* prefixName('chat.', 'icon') // returns 'chat.icon'
|
||||
* prefixName('', 'name') // returns 'name'
|
||||
*/
|
||||
export function prefixName(prefix: string, name: string): string {
|
||||
return `${prefix}${name}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user