mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-18 09:20:15 +01:00
* style: Enhance ControlCombobox with Carat Display, ClassName, and Disabled State * refactor(ModelPanel): replace SelectDropdown with ControlCombobox for improved accessibility * style: Adjust padding and positioning in ModelPanel for improved layout * style(ControlCombobox): add containerClassName and iconSide props for enhanced customization * style(ControlCombobox): add iconClassName prop for customizable icon styling * refactor(AgentPanel): enhance layout with new button for creating agents and adjust structure for better alignment * refactor(AgentSelect): replace SelectDropDown with ControlCombobox for improved accessibility and layout * feat(translation): add new translation key for improved UI clarity * style(AgentSwitcher, AssistantSwitcher): add iconClassName prop for customizable icon styling * refactor(AgentPanelSkeleton): improve layout of skeleton components to match new visual structure * style(AgentPanel, AgentPanelSkeleton): add margin to flex container for improved layout consistency * a11y(AgentSelect, ControlCombobox): add selectId prop for preventing focus going to start to page after agent selection * fix(AgentSelect): update SELECT_ID constant for improved clarity in component identification * fix(GoogleClient): update type annotation, add abort handling for content generation requests, catch "uncaught" abort errors and GoogleGenerativeAI errors from `@google/generative-ai`
92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
import { useEffect, useMemo } from 'react';
|
|
import { isAssistantsEndpoint, LocalStorageKeys } from 'librechat-data-provider';
|
|
import type { AssistantsEndpoint } from 'librechat-data-provider';
|
|
import type { SwitcherProps, AssistantListItem } from '~/common';
|
|
import { useSetIndexOptions, useSelectAssistant, useLocalize, useAssistantListMap } from '~/hooks';
|
|
import { useChatContext, useAssistantsMapContext } from '~/Providers';
|
|
import ControlCombobox from '~/components/ui/ControlCombobox';
|
|
import Icon from '~/components/Endpoints/Icon';
|
|
|
|
export default function AssistantSwitcher({ isCollapsed }: SwitcherProps) {
|
|
const localize = useLocalize();
|
|
const { setOption } = useSetIndexOptions();
|
|
const { index, conversation } = useChatContext();
|
|
|
|
/* `selectedAssistant` must be defined with `null` to cause re-render on update */
|
|
const { assistant_id: selectedAssistant = null, endpoint } = conversation ?? {};
|
|
|
|
const assistantListMap = useAssistantListMap((res) =>
|
|
res.data.map(({ id, name, metadata }) => ({ id, name, metadata })),
|
|
);
|
|
const assistants: Omit<AssistantListItem, 'model'>[] = useMemo(
|
|
() => assistantListMap[endpoint ?? ''] ?? [],
|
|
[endpoint, assistantListMap],
|
|
);
|
|
const assistantMap = useAssistantsMapContext();
|
|
const { onSelect } = useSelectAssistant(endpoint as AssistantsEndpoint);
|
|
|
|
useEffect(() => {
|
|
if (!selectedAssistant && assistants && assistants.length && assistantMap) {
|
|
const assistant_id =
|
|
localStorage.getItem(`${LocalStorageKeys.ASST_ID_PREFIX}${index}${endpoint}`) ??
|
|
assistants[0]?.id ??
|
|
'';
|
|
const assistant = assistantMap[endpoint ?? ''][assistant_id];
|
|
|
|
if (!assistant) {
|
|
return;
|
|
}
|
|
|
|
if (!isAssistantsEndpoint(endpoint)) {
|
|
return;
|
|
}
|
|
|
|
setOption('model')(assistant.model);
|
|
setOption('assistant_id')(assistant_id);
|
|
}
|
|
}, [index, assistants, selectedAssistant, assistantMap, endpoint, setOption]);
|
|
|
|
const currentAssistant = assistantMap?.[endpoint ?? '']?.[selectedAssistant ?? ''];
|
|
|
|
const assistantOptions = useMemo(() => {
|
|
return assistants.map((assistant) => {
|
|
return {
|
|
label: (assistant.name as string | null) ?? '',
|
|
value: assistant.id,
|
|
icon: (
|
|
<Icon
|
|
isCreatedByUser={false}
|
|
endpoint={endpoint}
|
|
assistantName={(assistant.name as string | null) ?? ''}
|
|
iconURL={assistant.metadata?.avatar ?? ''}
|
|
/>
|
|
),
|
|
};
|
|
});
|
|
}, [assistants, endpoint]);
|
|
|
|
return (
|
|
<ControlCombobox
|
|
selectedValue={currentAssistant?.id ?? ''}
|
|
displayValue={
|
|
assistants.find((assistant) => assistant.id === selectedAssistant)?.name ??
|
|
localize('com_sidepanel_select_assistant')
|
|
}
|
|
selectPlaceholder={localize('com_sidepanel_select_assistant')}
|
|
searchPlaceholder={localize('com_assistants_search_name')}
|
|
isCollapsed={isCollapsed}
|
|
ariaLabel={'assistant'}
|
|
setValue={onSelect}
|
|
items={assistantOptions}
|
|
iconClassName="assistant-item"
|
|
SelectIcon={
|
|
<Icon
|
|
isCreatedByUser={false}
|
|
endpoint={endpoint}
|
|
assistantName={currentAssistant?.name ?? ''}
|
|
iconURL={currentAssistant?.metadata?.avatar ?? ''}
|
|
/>
|
|
}
|
|
/>
|
|
);
|
|
}
|