⚙️ feat: add conditional visibility for model selector based on startup config (#10729)

This commit is contained in:
Marco Beretta 2025-12-01 18:03:03 +01:00 committed by Danny Avila
parent 8135bea6fa
commit a14c5b50a8
No known key found for this signature in database
GPG key ID: BF31EEB2C5CA0956
2 changed files with 34 additions and 3 deletions

View file

@ -1,14 +1,15 @@
import React, { useMemo } from 'react';
import { TooltipAnchor } from '@librechat/client';
import { getConfigDefaults } from 'librechat-data-provider';
import type { ModelSelectorProps } from '~/common';
import { ModelSelectorProvider, useModelSelectorContext } from './ModelSelectorContext';
import { ModelSelectorChatProvider } from './ModelSelectorChatContext';
import {
renderModelSpecs,
renderEndpoints,
renderSearchResults,
renderCustomGroups,
} from './components';
import { ModelSelectorProvider, useModelSelectorContext } from './ModelSelectorContext';
import { ModelSelectorChatProvider } from './ModelSelectorChatContext';
import { getSelectedIcon, getDisplayValue } from './utils';
import { CustomMenu as Menu } from './CustomMenu';
import DialogManager from './DialogManager';
@ -122,6 +123,14 @@ function ModelSelectorContent() {
}
export default function ModelSelector({ startupConfig }: ModelSelectorProps) {
const interfaceConfig = startupConfig?.interface ?? getConfigDefaults().interface;
const modelSpecs = startupConfig?.modelSpecs?.list ?? [];
// Hide the selector when modelSelect is false and there are no model specs to show
if (interfaceConfig.modelSelect === false && modelSpecs.length === 0) {
return null;
}
return (
<ModelSelectorChatProvider>
<ModelSelectorProvider startupConfig={startupConfig}>

View file

@ -10,6 +10,9 @@ import {
getEndpointField,
LocalStorageKeys,
isAssistantsEndpoint,
isAgentsEndpoint,
PermissionTypes,
Permissions,
} from 'librechat-data-provider';
import type {
TPreset,
@ -32,6 +35,7 @@ import useAssistantListMap from './Assistants/useAssistantListMap';
import { useResetChatBadges } from './useChatBadges';
import { useApplyModelSpecEffects } from './Agents';
import { usePauseGlobalAudio } from './Audio';
import { useHasAccess } from '~/hooks';
import store from '~/store';
const useNewConvo = (index = 0) => {
@ -48,6 +52,11 @@ const useNewConvo = (index = 0) => {
const setSubmission = useSetRecoilState<TSubmission | null>(store.submissionByIndex(index));
const { data: endpointsConfig = {} as TEndpointsConfig } = useGetEndpointsQuery();
const hasAgentAccess = useHasAccess({
permissionType: PermissionTypes.AGENTS,
permission: Permissions.USE,
});
const modelsQuery = useGetModelsQuery();
const assistantsListMap = useAssistantListMap();
const { pauseGlobalAudio } = usePauseGlobalAudio(index);
@ -102,8 +111,21 @@ const useNewConvo = (index = 0) => {
endpointsConfig,
});
// If the selected endpoint is agents but user doesn't have access, find an alternative
if (defaultEndpoint && isAgentsEndpoint(defaultEndpoint) && !hasAgentAccess) {
defaultEndpoint = Object.keys(endpointsConfig ?? {}).find(
(ep) => !isAgentsEndpoint(ep as EModelEndpoint) && endpointsConfig?.[ep],
) as EModelEndpoint | undefined;
}
if (!defaultEndpoint) {
defaultEndpoint = Object.keys(endpointsConfig ?? {})[0] as EModelEndpoint;
// Find first available endpoint that's not agents (if no access) or any endpoint
defaultEndpoint = Object.keys(endpointsConfig ?? {}).find((ep) => {
if (isAgentsEndpoint(ep as EModelEndpoint) && !hasAgentAccess) {
return false;
}
return !!endpointsConfig?.[ep];
}) as EModelEndpoint;
}
const endpointType = getEndpointField(endpointsConfig, defaultEndpoint, 'type');