File size: 3,234 Bytes
aa2e6af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { useEffect, useMemo } from 'react';
import { Combobox } from '~/components/ui';
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 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 ?? '',
        value: assistant.id,
        icon: (
          <Icon
            isCreatedByUser={false}
            endpoint={endpoint}
            assistantName={assistant.name ?? ''}
            iconURL={(assistant.metadata?.avatar as string) ?? ''}
          />
        ),
      };
    });
  }, [assistants, endpoint]);

  return (
    <Combobox
      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}
      SelectIcon={
        <Icon
          isCreatedByUser={false}
          endpoint={endpoint}
          assistantName={currentAssistant?.name ?? ''}
          iconURL={(currentAssistant?.metadata?.avatar as string) ?? ''}
        />
      }
    />
  );
}