|
import { LlmModelType, ModelVariableType } from '@/constants/knowledge'; |
|
import { useTranslate } from '@/hooks/common-hooks'; |
|
import { useComposeLlmOptionsByModelTypes } from '@/hooks/llm-hooks'; |
|
import { camelCase } from 'lodash'; |
|
import { useCallback } from 'react'; |
|
import { useFormContext } from 'react-hook-form'; |
|
import { |
|
FormControl, |
|
FormField, |
|
FormItem, |
|
FormLabel, |
|
FormMessage, |
|
} from '../ui/form'; |
|
import { Input } from '../ui/input'; |
|
import { |
|
Select, |
|
SelectContent, |
|
SelectGroup, |
|
SelectItem, |
|
SelectLabel, |
|
SelectTrigger, |
|
SelectValue, |
|
} from '../ui/select'; |
|
import { FormSlider } from '../ui/slider'; |
|
import { Switch } from '../ui/switch'; |
|
|
|
interface SliderWithInputNumberFormFieldProps { |
|
name: string; |
|
label: string; |
|
checkName: string; |
|
max: number; |
|
min?: number; |
|
step?: number; |
|
} |
|
|
|
function SliderWithInputNumberFormField({ |
|
name, |
|
label, |
|
checkName, |
|
max, |
|
min = 0, |
|
step = 1, |
|
}: SliderWithInputNumberFormFieldProps) { |
|
const { control, watch } = useFormContext(); |
|
const { t } = useTranslate('chat'); |
|
const disabled = !watch(checkName); |
|
|
|
return ( |
|
<FormField |
|
control={control} |
|
name={name} |
|
render={({ field }) => ( |
|
<FormItem> |
|
<div className="flex items-center justify-between"> |
|
<FormLabel>{t(label)}</FormLabel> |
|
<FormField |
|
control={control} |
|
name={checkName} |
|
render={({ field }) => ( |
|
<FormItem> |
|
<FormControl> |
|
<Switch |
|
{...field} |
|
checked={field.value} |
|
onCheckedChange={field.onChange} |
|
></Switch> |
|
</FormControl> |
|
<FormMessage /> |
|
</FormItem> |
|
)} |
|
/> |
|
</div> |
|
<FormControl> |
|
<div className="flex w-full items-center space-x-2"> |
|
<FormSlider |
|
{...field} |
|
disabled={disabled} |
|
max={max} |
|
min={min} |
|
step={step} |
|
></FormSlider> |
|
<Input |
|
type={'number'} |
|
className="w-2/5" |
|
{...field} |
|
disabled={disabled} |
|
max={max} |
|
min={min} |
|
step={step} |
|
/> |
|
</div> |
|
</FormControl> |
|
<FormMessage /> |
|
</FormItem> |
|
)} |
|
/> |
|
); |
|
} |
|
|
|
interface LlmSettingFieldItemsProps { |
|
prefix?: string; |
|
} |
|
|
|
export function LlmSettingFieldItems({ prefix }: LlmSettingFieldItemsProps) { |
|
const form = useFormContext(); |
|
const { t } = useTranslate('chat'); |
|
const modelOptions = useComposeLlmOptionsByModelTypes([ |
|
LlmModelType.Chat, |
|
LlmModelType.Image2text, |
|
]); |
|
|
|
const parameterOptions = Object.values(ModelVariableType).map((x) => ({ |
|
label: t(camelCase(x)), |
|
value: x, |
|
})); |
|
|
|
const getFieldWithPrefix = useCallback( |
|
(name: string) => { |
|
return `${prefix}.${name}`; |
|
}, |
|
[prefix], |
|
); |
|
|
|
return ( |
|
<div className="space-y-8"> |
|
<FormField |
|
control={form.control} |
|
name={'llm_id'} |
|
render={({ field }) => ( |
|
<FormItem> |
|
<FormLabel>{t('model')}</FormLabel> |
|
<FormControl> |
|
<Select onValueChange={field.onChange} {...field}> |
|
<SelectTrigger value={field.value}> |
|
<SelectValue /> |
|
</SelectTrigger> |
|
<SelectContent> |
|
{modelOptions.map((x) => ( |
|
<SelectGroup key={x.value}> |
|
<SelectLabel>{x.label}</SelectLabel> |
|
{x.options.map((y) => ( |
|
<SelectItem |
|
value={y.value} |
|
key={y.value} |
|
disabled={y.disabled} |
|
> |
|
{y.label} |
|
</SelectItem> |
|
))} |
|
</SelectGroup> |
|
))} |
|
</SelectContent> |
|
</Select> |
|
</FormControl> |
|
<FormMessage /> |
|
</FormItem> |
|
)} |
|
/> |
|
<FormField |
|
control={form.control} |
|
name={'parameter'} |
|
render={({ field }) => ( |
|
<FormItem> |
|
<FormLabel>{t('freedom')}</FormLabel> |
|
<FormControl> |
|
<Select {...field} onValueChange={field.onChange}> |
|
<SelectTrigger> |
|
<SelectValue /> |
|
</SelectTrigger> |
|
<SelectContent> |
|
{parameterOptions.map((x) => ( |
|
<SelectItem value={x.value} key={x.value}> |
|
{x.label} |
|
</SelectItem> |
|
))} |
|
</SelectContent> |
|
</Select> |
|
</FormControl> |
|
<FormMessage /> |
|
</FormItem> |
|
)} |
|
/> |
|
<SliderWithInputNumberFormField |
|
name={getFieldWithPrefix('temperature')} |
|
checkName="temperatureEnabled" |
|
label="temperature" |
|
max={1} |
|
step={0.01} |
|
></SliderWithInputNumberFormField> |
|
<SliderWithInputNumberFormField |
|
name={getFieldWithPrefix('top_p')} |
|
checkName="topPEnabled" |
|
label="topP" |
|
max={1} |
|
step={0.01} |
|
></SliderWithInputNumberFormField> |
|
<SliderWithInputNumberFormField |
|
name={getFieldWithPrefix('presence_penalty')} |
|
checkName="presencePenaltyEnabled" |
|
label="presencePenalty" |
|
max={1} |
|
step={0.01} |
|
></SliderWithInputNumberFormField> |
|
<SliderWithInputNumberFormField |
|
name={getFieldWithPrefix('frequency_penalty')} |
|
checkName="frequencyPenaltyEnabled" |
|
label="frequencyPenalty" |
|
max={1} |
|
step={0.01} |
|
></SliderWithInputNumberFormField> |
|
<SliderWithInputNumberFormField |
|
name={getFieldWithPrefix('max_tokens')} |
|
checkName="maxTokensEnabled" |
|
label="maxTokens" |
|
max={128000} |
|
></SliderWithInputNumberFormField> |
|
</div> |
|
); |
|
} |
|
|