mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 00:40:14 +01:00
🔧 fix: Preset Dialog Styling and Values (#2657)
* style: preset dialog styling * refactor: coerce number input for convo schema * refactor: replace dynamic input number with static component
This commit is contained in:
parent
98c96cd020
commit
2b37a44b8d
9 changed files with 258 additions and 133 deletions
|
|
@ -1,4 +1,5 @@
|
||||||
import { FileSources } from 'librechat-data-provider';
|
import { FileSources } from 'librechat-data-provider';
|
||||||
|
import type * as InputNumberPrimitive from 'rc-input-number';
|
||||||
import type { ColumnDef } from '@tanstack/react-table';
|
import type { ColumnDef } from '@tanstack/react-table';
|
||||||
import type { SetterOrUpdater } from 'recoil';
|
import type { SetterOrUpdater } from 'recoil';
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -115,6 +116,8 @@ export type TSetExample = (
|
||||||
newValue: number | string | boolean | null,
|
newValue: number | string | boolean | null,
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
|
export type OnInputNumberChange = InputNumberPrimitive.InputNumberProps['onChange'];
|
||||||
|
|
||||||
export const defaultDebouncedDelay = 450;
|
export const defaultDebouncedDelay = 450;
|
||||||
|
|
||||||
export enum ESide {
|
export enum ESide {
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,9 @@ const EditPresetDialog = ({
|
||||||
title={`${localize('com_ui_edit') + ' ' + localize('com_endpoint_preset')} - ${
|
title={`${localize('com_ui_edit') + ' ' + localize('com_endpoint_preset')} - ${
|
||||||
preset?.title
|
preset?.title
|
||||||
}`}
|
}`}
|
||||||
className="h-full max-w-full overflow-y-auto pb-4 sm:w-[680px] sm:pb-0 md:h-[720px] md:w-[750px] md:overflow-y-hidden lg:w-[950px] xl:h-[720px]"
|
className="h-full max-w-full overflow-y-auto pb-4 sm:w-[680px] sm:pb-0 md:h-[720px] md:w-[750px] md:overflow-y-hidden md:overflow-y-hidden lg:w-[950px] xl:h-[720px]"
|
||||||
main={
|
main={
|
||||||
<div className="flex w-full flex-col items-center gap-2 md:h-[530px]">
|
<div className="flex w-full flex-col items-center gap-2 md:h-[550px] md:overflow-y-auto">
|
||||||
<div className="grid w-full">
|
<div className="grid w-full">
|
||||||
<div className="col-span-4 flex flex-col items-start justify-start gap-6 pb-4 md:flex-row">
|
<div className="col-span-4 flex flex-col items-start justify-start gap-6 pb-4 md:flex-row">
|
||||||
<div className="flex w-full flex-col">
|
<div className="flex w-full flex-col">
|
||||||
|
|
@ -126,6 +126,7 @@ const EditPresetDialog = ({
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
footerClassName="bg-white dark:bg-gray-700"
|
||||||
/>
|
/>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import type { TModelSelectProps } from '~/common';
|
import type { TModelSelectProps, OnInputNumberChange } from '~/common';
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
Label,
|
Label,
|
||||||
|
|
@ -12,18 +12,34 @@ import {
|
||||||
HoverCardTrigger,
|
HoverCardTrigger,
|
||||||
} from '~/components/ui';
|
} from '~/components/ui';
|
||||||
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
||||||
import { DynamicInputNumber } from '~/components/SidePanel/Parameters';
|
import OptionHoverAlt from '~/components/SidePanel/Parameters/OptionHover';
|
||||||
|
import { useLocalize, useDebouncedInput } from '~/hooks';
|
||||||
import OptionHover from './OptionHover';
|
import OptionHover from './OptionHover';
|
||||||
import { useLocalize } from '~/hooks';
|
|
||||||
import { ESide } from '~/common';
|
import { ESide } from '~/common';
|
||||||
|
|
||||||
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
|
const {
|
||||||
|
model,
|
||||||
|
modelLabel,
|
||||||
|
promptPrefix,
|
||||||
|
temperature,
|
||||||
|
topP,
|
||||||
|
topK,
|
||||||
|
maxOutputTokens,
|
||||||
|
maxContextTokens,
|
||||||
|
resendFiles,
|
||||||
|
} = conversation ?? {};
|
||||||
|
const [setMaxContextTokens, maxContextTokensValue] = useDebouncedInput<number | null | undefined>(
|
||||||
|
{
|
||||||
|
setOption,
|
||||||
|
optionKey: 'maxContextTokens',
|
||||||
|
initialValue: maxContextTokens,
|
||||||
|
},
|
||||||
|
);
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const { model, modelLabel, promptPrefix, temperature, topP, topK, maxOutputTokens, resendFiles } =
|
|
||||||
conversation;
|
|
||||||
|
|
||||||
const setModel = setOption('model');
|
const setModel = setOption('model');
|
||||||
const setModelLabel = setOption('modelLabel');
|
const setModelLabel = setOption('modelLabel');
|
||||||
|
|
@ -84,28 +100,40 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
||||||
<DynamicInputNumber
|
<HoverCard openDelay={300}>
|
||||||
columnSpan={2}
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
settingKey="maxContextTokens"
|
<div className="mt-1 flex w-full justify-between">
|
||||||
setOption={setOption}
|
<Label htmlFor="max-context-tokens" className="text-left text-sm font-medium">
|
||||||
label="com_endpoint_context_tokens"
|
{localize('com_endpoint_context_tokens')}{' '}
|
||||||
labelCode={true}
|
</Label>
|
||||||
description="com_endpoint_context_info"
|
<InputNumber
|
||||||
descriptionCode={true}
|
id="max-context-tokens"
|
||||||
placeholder="com_nav_theme_system"
|
stringMode={false}
|
||||||
placeholderCode={true}
|
disabled={readonly}
|
||||||
descriptionSide="right"
|
value={maxContextTokensValue as number}
|
||||||
conversation={conversation}
|
onChange={setMaxContextTokens as OnInputNumberChange}
|
||||||
readonly={readonly}
|
placeholder={localize('com_nav_theme_system')}
|
||||||
range={{
|
min={10}
|
||||||
min: 10,
|
max={2000000}
|
||||||
max: 2000000,
|
step={1000}
|
||||||
step: 1000,
|
controls={false}
|
||||||
}}
|
className={cn(
|
||||||
className="mt-1 w-full justify-between"
|
defaultTextProps,
|
||||||
inputClassName="w-1/3"
|
cn(
|
||||||
showDefault={false}
|
optionText,
|
||||||
/>
|
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
|
||||||
|
'w-1/3',
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<OptionHoverAlt
|
||||||
|
description="com_endpoint_context_info"
|
||||||
|
langCode={true}
|
||||||
|
side={ESide.Left}
|
||||||
|
/>
|
||||||
|
</HoverCard>
|
||||||
<HoverCard openDelay={300}>
|
<HoverCard openDelay={300}>
|
||||||
<HoverCardTrigger className="grid w-full items-center gap-2">
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import { EModelEndpoint, endpointSettings } from 'librechat-data-provider';
|
import { EModelEndpoint, endpointSettings } from 'librechat-data-provider';
|
||||||
import type { TModelSelectProps } from '~/common';
|
import type { TModelSelectProps, OnInputNumberChange } from '~/common';
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
Label,
|
Label,
|
||||||
|
|
@ -12,16 +12,24 @@ import {
|
||||||
HoverCardTrigger,
|
HoverCardTrigger,
|
||||||
} from '~/components/ui';
|
} from '~/components/ui';
|
||||||
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
||||||
import { DynamicInputNumber } from '~/components/SidePanel/Parameters';
|
import OptionHoverAlt from '~/components/SidePanel/Parameters/OptionHover';
|
||||||
|
import { useLocalize, useDebouncedInput } from '~/hooks';
|
||||||
import OptionHover from './OptionHover';
|
import OptionHover from './OptionHover';
|
||||||
import { useLocalize } from '~/hooks';
|
|
||||||
import { ESide } from '~/common';
|
import { ESide } from '~/common';
|
||||||
|
|
||||||
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
const google = endpointSettings[EModelEndpoint.google];
|
const google = endpointSettings[EModelEndpoint.google];
|
||||||
const { model, modelLabel, promptPrefix, temperature, topP, topK, maxOutputTokens } =
|
const {
|
||||||
conversation ?? {};
|
model,
|
||||||
|
modelLabel,
|
||||||
|
promptPrefix,
|
||||||
|
temperature,
|
||||||
|
topP,
|
||||||
|
topK,
|
||||||
|
maxContextTokens,
|
||||||
|
maxOutputTokens,
|
||||||
|
} = conversation ?? {};
|
||||||
|
|
||||||
const isGemini = model?.toLowerCase()?.includes('gemini');
|
const isGemini = model?.toLowerCase()?.includes('gemini');
|
||||||
|
|
||||||
|
|
@ -42,6 +50,14 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
[model],
|
[model],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [setMaxContextTokens, maxContextTokensValue] = useDebouncedInput<number | null | undefined>(
|
||||||
|
{
|
||||||
|
setOption,
|
||||||
|
optionKey: 'maxContextTokens',
|
||||||
|
initialValue: maxContextTokens,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
if (!conversation) {
|
if (!conversation) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -104,28 +120,40 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
||||||
<DynamicInputNumber
|
<HoverCard openDelay={300}>
|
||||||
columnSpan={2}
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
settingKey="maxContextTokens"
|
<div className="mt-1 flex w-full justify-between">
|
||||||
setOption={setOption}
|
<Label htmlFor="max-context-tokens" className="text-left text-sm font-medium">
|
||||||
label="com_endpoint_context_tokens"
|
{localize('com_endpoint_context_tokens')}{' '}
|
||||||
labelCode={true}
|
</Label>
|
||||||
description="com_endpoint_context_info"
|
<InputNumber
|
||||||
descriptionCode={true}
|
id="max-context-tokens"
|
||||||
placeholder="com_nav_theme_system"
|
stringMode={false}
|
||||||
placeholderCode={true}
|
disabled={readonly}
|
||||||
descriptionSide="right"
|
value={maxContextTokensValue as number}
|
||||||
conversation={conversation}
|
onChange={setMaxContextTokens as OnInputNumberChange}
|
||||||
readonly={readonly}
|
placeholder={localize('com_nav_theme_system')}
|
||||||
range={{
|
min={10}
|
||||||
min: 10,
|
max={2000000}
|
||||||
max: 2000000,
|
step={1000}
|
||||||
step: 1000,
|
controls={false}
|
||||||
}}
|
className={cn(
|
||||||
className="mt-1 w-full justify-between"
|
defaultTextProps,
|
||||||
inputClassName="w-1/3"
|
cn(
|
||||||
showDefault={false}
|
optionText,
|
||||||
/>
|
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
|
||||||
|
'w-1/3',
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<OptionHoverAlt
|
||||||
|
description="com_endpoint_context_info"
|
||||||
|
langCode={true}
|
||||||
|
side={ESide.Left}
|
||||||
|
/>
|
||||||
|
</HoverCard>
|
||||||
<HoverCard openDelay={300}>
|
<HoverCard openDelay={300}>
|
||||||
<HoverCardTrigger className="grid w-full items-center gap-2">
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import * as InputNumberPrimitive from 'rc-input-number';
|
|
||||||
import {
|
import {
|
||||||
EModelEndpoint,
|
EModelEndpoint,
|
||||||
ImageDetail,
|
ImageDetail,
|
||||||
imageDetailNumeric,
|
imageDetailNumeric,
|
||||||
imageDetailValue,
|
imageDetailValue,
|
||||||
} from 'librechat-data-provider';
|
} from 'librechat-data-provider';
|
||||||
|
import type { TModelSelectProps, OnInputNumberChange } from '~/common';
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
Label,
|
Label,
|
||||||
|
|
@ -18,14 +18,12 @@ import {
|
||||||
HoverCardTrigger,
|
HoverCardTrigger,
|
||||||
} from '~/components/ui';
|
} from '~/components/ui';
|
||||||
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
import { cn, defaultTextProps, optionText, removeFocusOutlines } from '~/utils';
|
||||||
import { DynamicTags, DynamicInputNumber } from '~/components/SidePanel/Parameters';
|
import OptionHoverAlt from '~/components/SidePanel/Parameters/OptionHover';
|
||||||
|
import { DynamicTags } from '~/components/SidePanel/Parameters';
|
||||||
import { useLocalize, useDebouncedInput } from '~/hooks';
|
import { useLocalize, useDebouncedInput } from '~/hooks';
|
||||||
import type { TModelSelectProps } from '~/common';
|
|
||||||
import OptionHover from './OptionHover';
|
import OptionHover from './OptionHover';
|
||||||
import { ESide } from '~/common';
|
import { ESide } from '~/common';
|
||||||
|
|
||||||
type OnInputNumberChange = InputNumberPrimitive.InputNumberProps['onChange'];
|
|
||||||
|
|
||||||
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
export default function Settings({ conversation, setOption, models, readonly }: TModelSelectProps) {
|
||||||
const localize = useLocalize();
|
const localize = useLocalize();
|
||||||
const {
|
const {
|
||||||
|
|
@ -41,6 +39,8 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
presence_penalty: presP,
|
presence_penalty: presP,
|
||||||
resendFiles,
|
resendFiles,
|
||||||
imageDetail,
|
imageDetail,
|
||||||
|
maxContextTokens,
|
||||||
|
max_tokens,
|
||||||
} = conversation ?? {};
|
} = conversation ?? {};
|
||||||
|
|
||||||
const [setChatGptLabel, chatGptLabelValue] = useDebouncedInput<string | null | undefined>({
|
const [setChatGptLabel, chatGptLabelValue] = useDebouncedInput<string | null | undefined>({
|
||||||
|
|
@ -73,6 +73,18 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
optionKey: 'presence_penalty',
|
optionKey: 'presence_penalty',
|
||||||
initialValue: presP,
|
initialValue: presP,
|
||||||
});
|
});
|
||||||
|
const [setMaxContextTokens, maxContextTokensValue] = useDebouncedInput<number | null | undefined>(
|
||||||
|
{
|
||||||
|
setOption,
|
||||||
|
optionKey: 'maxContextTokens',
|
||||||
|
initialValue: maxContextTokens,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const [setMaxOutputTokens, maxOutputTokensValue] = useDebouncedInput<number | null | undefined>({
|
||||||
|
setOption,
|
||||||
|
optionKey: 'max_tokens',
|
||||||
|
initialValue: max_tokens,
|
||||||
|
});
|
||||||
|
|
||||||
const optionEndpoint = useMemo(() => endpointType ?? endpoint, [endpoint, endpointType]);
|
const optionEndpoint = useMemo(() => endpointType ?? endpoint, [endpoint, endpointType]);
|
||||||
const isOpenAI = useMemo(
|
const isOpenAI = useMemo(
|
||||||
|
|
@ -154,50 +166,74 @@ export default function Settings({ conversation, setOption, models, readonly }:
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
<div className="col-span-5 flex flex-col items-center justify-start gap-6 px-3 sm:col-span-2">
|
||||||
<DynamicInputNumber
|
<HoverCard openDelay={300}>
|
||||||
columnSpan={2}
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
settingKey="maxContextTokens"
|
<div className="mt-1 flex w-full justify-between">
|
||||||
setOption={setOption}
|
<Label htmlFor="max-context-tokens" className="text-left text-sm font-medium">
|
||||||
label="com_endpoint_context_tokens"
|
{localize('com_endpoint_context_tokens')}{' '}
|
||||||
labelCode={true}
|
</Label>
|
||||||
description="com_endpoint_context_info"
|
<InputNumber
|
||||||
descriptionCode={true}
|
id="max-context-tokens"
|
||||||
placeholder="com_nav_theme_system"
|
stringMode={false}
|
||||||
placeholderCode={true}
|
disabled={readonly}
|
||||||
descriptionSide="right"
|
value={maxContextTokensValue as number}
|
||||||
conversation={conversation}
|
onChange={setMaxContextTokens as OnInputNumberChange}
|
||||||
readonly={readonly}
|
placeholder={localize('com_nav_theme_system')}
|
||||||
range={{
|
min={10}
|
||||||
min: 10,
|
max={2000000}
|
||||||
max: 2000000,
|
step={1000}
|
||||||
step: 1000,
|
controls={false}
|
||||||
}}
|
className={cn(
|
||||||
className="mt-1 w-full justify-between"
|
defaultTextProps,
|
||||||
inputClassName="w-1/3"
|
cn(
|
||||||
showDefault={false}
|
optionText,
|
||||||
/>
|
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
|
||||||
<DynamicInputNumber
|
'w-1/3',
|
||||||
columnSpan={2}
|
),
|
||||||
settingKey="max_tokens"
|
)}
|
||||||
setOption={setOption}
|
/>
|
||||||
label="com_endpoint_max_output_tokens"
|
</div>
|
||||||
labelCode={true}
|
</HoverCardTrigger>
|
||||||
description="com_endpoint_openai_max_tokens"
|
<OptionHoverAlt
|
||||||
descriptionCode={true}
|
description="com_endpoint_context_info"
|
||||||
placeholder="com_nav_theme_system"
|
langCode={true}
|
||||||
placeholderCode={true}
|
side={ESide.Left}
|
||||||
descriptionSide="top"
|
/>
|
||||||
conversation={conversation}
|
</HoverCard>
|
||||||
readonly={readonly}
|
<HoverCard openDelay={300}>
|
||||||
range={{
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
min: 10,
|
<div className="mt-1 flex w-full justify-between">
|
||||||
max: 2000000,
|
<Label htmlFor="max-output-tokens" className="text-left text-sm font-medium">
|
||||||
step: 1000,
|
{localize('com_endpoint_max_output_tokens')}{' '}
|
||||||
}}
|
</Label>
|
||||||
className="mt-1 w-full justify-between"
|
<InputNumber
|
||||||
inputClassName="w-1/3"
|
id="max-output-tokens"
|
||||||
showDefault={false}
|
stringMode={false}
|
||||||
/>
|
disabled={readonly}
|
||||||
|
value={maxOutputTokensValue as number}
|
||||||
|
onChange={setMaxOutputTokens as OnInputNumberChange}
|
||||||
|
placeholder={localize('com_nav_theme_system')}
|
||||||
|
min={10}
|
||||||
|
max={2000000}
|
||||||
|
step={1000}
|
||||||
|
controls={false}
|
||||||
|
className={cn(
|
||||||
|
defaultTextProps,
|
||||||
|
cn(
|
||||||
|
optionText,
|
||||||
|
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
|
||||||
|
'w-1/3',
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<OptionHoverAlt
|
||||||
|
description="com_endpoint_openai_max_tokens"
|
||||||
|
langCode={true}
|
||||||
|
side={ESide.Left}
|
||||||
|
/>
|
||||||
|
</HoverCard>
|
||||||
<HoverCard openDelay={300}>
|
<HoverCard openDelay={300}>
|
||||||
<HoverCardTrigger className="grid w-full items-center gap-2">
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { useRecoilValue } from 'recoil';
|
||||||
import TextareaAutosize from 'react-textarea-autosize';
|
import TextareaAutosize from 'react-textarea-autosize';
|
||||||
import { useAvailablePluginsQuery } from 'librechat-data-provider/react-query';
|
import { useAvailablePluginsQuery } from 'librechat-data-provider/react-query';
|
||||||
import type { TPlugin } from 'librechat-data-provider';
|
import type { TPlugin } from 'librechat-data-provider';
|
||||||
import type { TModelSelectProps } from '~/common';
|
import type { TModelSelectProps, OnInputNumberChange } from '~/common';
|
||||||
import {
|
import {
|
||||||
Input,
|
Input,
|
||||||
Label,
|
Label,
|
||||||
|
|
@ -22,7 +22,7 @@ import {
|
||||||
processPlugins,
|
processPlugins,
|
||||||
selectPlugins,
|
selectPlugins,
|
||||||
} from '~/utils';
|
} from '~/utils';
|
||||||
import { DynamicInputNumber } from '~/components/SidePanel/Parameters';
|
import OptionHoverAlt from '~/components/SidePanel/Parameters/OptionHover';
|
||||||
import { useLocalize, useDebouncedInput } from '~/hooks';
|
import { useLocalize, useDebouncedInput } from '~/hooks';
|
||||||
import OptionHover from './OptionHover';
|
import OptionHover from './OptionHover';
|
||||||
import { ESide } from '~/common';
|
import { ESide } from '~/common';
|
||||||
|
|
@ -69,6 +69,7 @@ export default function Settings({
|
||||||
top_p: topP,
|
top_p: topP,
|
||||||
frequency_penalty: freqP,
|
frequency_penalty: freqP,
|
||||||
presence_penalty: presP,
|
presence_penalty: presP,
|
||||||
|
maxContextTokens,
|
||||||
} = conversation ?? {};
|
} = conversation ?? {};
|
||||||
|
|
||||||
const [setChatGptLabel, chatGptLabelValue] = useDebouncedInput<string | null | undefined>({
|
const [setChatGptLabel, chatGptLabelValue] = useDebouncedInput<string | null | undefined>({
|
||||||
|
|
@ -101,6 +102,13 @@ export default function Settings({
|
||||||
optionKey: 'presence_penalty',
|
optionKey: 'presence_penalty',
|
||||||
initialValue: presP,
|
initialValue: presP,
|
||||||
});
|
});
|
||||||
|
const [setMaxContextTokens, maxContextTokensValue] = useDebouncedInput<number | null | undefined>(
|
||||||
|
{
|
||||||
|
setOption,
|
||||||
|
optionKey: 'maxContextTokens',
|
||||||
|
initialValue: maxContextTokens,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const setModel = setOption('model');
|
const setModel = setOption('model');
|
||||||
|
|
||||||
|
|
@ -177,28 +185,40 @@ export default function Settings({
|
||||||
containerClassName="flex w-full resize-none border border-transparent"
|
containerClassName="flex w-full resize-none border border-transparent"
|
||||||
labelClassName="dark:text-white"
|
labelClassName="dark:text-white"
|
||||||
/>
|
/>
|
||||||
<DynamicInputNumber
|
<HoverCard openDelay={300}>
|
||||||
columnSpan={2}
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
settingKey="maxContextTokens"
|
<div className="mt-1 flex w-full justify-between">
|
||||||
setOption={setOption}
|
<Label htmlFor="max-context-tokens" className="text-left text-sm font-medium">
|
||||||
label="com_endpoint_context_tokens"
|
{localize('com_endpoint_context_tokens')}{' '}
|
||||||
labelCode={true}
|
</Label>
|
||||||
description="com_endpoint_context_info"
|
<InputNumber
|
||||||
descriptionCode={true}
|
id="max-context-tokens"
|
||||||
placeholder="com_nav_theme_system"
|
stringMode={false}
|
||||||
placeholderCode={true}
|
disabled={readonly}
|
||||||
descriptionSide="right"
|
value={maxContextTokensValue as number}
|
||||||
conversation={conversation}
|
onChange={setMaxContextTokens as OnInputNumberChange}
|
||||||
readonly={readonly}
|
placeholder={localize('com_nav_theme_system')}
|
||||||
range={{
|
min={10}
|
||||||
min: 10,
|
max={2000000}
|
||||||
max: 2000000,
|
step={1000}
|
||||||
step: 1000,
|
controls={false}
|
||||||
}}
|
className={cn(
|
||||||
className="mt-1 w-full justify-between"
|
defaultTextProps,
|
||||||
inputClassName="w-1/3"
|
cn(
|
||||||
showDefault={false}
|
optionText,
|
||||||
/>
|
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200',
|
||||||
|
'w-1/3',
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<OptionHoverAlt
|
||||||
|
description="com_endpoint_context_info"
|
||||||
|
langCode={true}
|
||||||
|
side={ESide.Left}
|
||||||
|
/>
|
||||||
|
</HoverCard>
|
||||||
<HoverCard openDelay={300}>
|
<HoverCard openDelay={300}>
|
||||||
<HoverCardTrigger className="grid w-full items-center gap-2">
|
<HoverCardTrigger className="grid w-full items-center gap-2">
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ type DialogTemplateProps = {
|
||||||
selection?: SelectionProps;
|
selection?: SelectionProps;
|
||||||
className?: string;
|
className?: string;
|
||||||
headerClassName?: string;
|
headerClassName?: string;
|
||||||
|
footerClassName?: string;
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
showCancelButton?: boolean;
|
showCancelButton?: boolean;
|
||||||
};
|
};
|
||||||
|
|
@ -40,6 +41,7 @@ const DialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDivE
|
||||||
selection,
|
selection,
|
||||||
className,
|
className,
|
||||||
headerClassName,
|
headerClassName,
|
||||||
|
footerClassName,
|
||||||
showCloseButton,
|
showCloseButton,
|
||||||
showCancelButton = true,
|
showCancelButton = true,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
@ -66,7 +68,7 @@ const DialogTemplate = forwardRef((props: DialogTemplateProps, ref: Ref<HTMLDivE
|
||||||
)}
|
)}
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="px-6">{main ? main : null}</div>
|
<div className="px-6">{main ? main : null}</div>
|
||||||
<DialogFooter>
|
<DialogFooter className={footerClassName}>
|
||||||
<div>{leftButtons ? leftButtons : null}</div>
|
<div>{leftButtons ? leftButtons : null}</div>
|
||||||
<div className="flex h-auto gap-3">
|
<div className="flex h-auto gap-3">
|
||||||
{showCancelButton && (
|
{showCancelButton && (
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "librechat-data-provider",
|
"name": "librechat-data-provider",
|
||||||
"version": "0.6.1",
|
"version": "0.6.2",
|
||||||
"description": "data services for librechat apps",
|
"description": "data services for librechat apps",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"module": "dist/index.es.js",
|
"module": "dist/index.es.js",
|
||||||
|
|
|
||||||
|
|
@ -280,6 +280,13 @@ export type TMessage = z.input<typeof tMessageSchema> & {
|
||||||
files?: Partial<TFile>[];
|
files?: Partial<TFile>[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const coerceNumber = z.union([z.number(), z.string()]).transform((val) => {
|
||||||
|
if (typeof val === 'string') {
|
||||||
|
return val.trim() === '' ? undefined : parseFloat(val);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
|
||||||
export const tConversationSchema = z.object({
|
export const tConversationSchema = z.object({
|
||||||
conversationId: z.string().nullable(),
|
conversationId: z.string().nullable(),
|
||||||
title: z.string().nullable().or(z.literal('New Chat')).default('New Chat'),
|
title: z.string().nullable().or(z.literal('New Chat')).default('New Chat'),
|
||||||
|
|
@ -315,8 +322,8 @@ export const tConversationSchema = z.object({
|
||||||
maxOutputTokens: z.number().optional(),
|
maxOutputTokens: z.number().optional(),
|
||||||
agentOptions: tAgentOptionsSchema.nullable().optional(),
|
agentOptions: tAgentOptionsSchema.nullable().optional(),
|
||||||
file_ids: z.array(z.string()).optional(),
|
file_ids: z.array(z.string()).optional(),
|
||||||
maxContextTokens: z.number().optional(),
|
maxContextTokens: coerceNumber.optional(),
|
||||||
max_tokens: z.number().optional(),
|
max_tokens: coerceNumber.optional(),
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
resendImages: z.boolean().optional(),
|
resendImages: z.boolean().optional(),
|
||||||
/* vision */
|
/* vision */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue