File size: 3,705 Bytes
baa4c21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import type { ProviderInfo } from '~/types/model';
import { useEffect } from 'react';
import type { ModelInfo } from '~/lib/modules/llm/types';

interface ModelSelectorProps {
  model?: string;
  setModel?: (model: string) => void;
  provider?: ProviderInfo;
  setProvider?: (provider: ProviderInfo) => void;
  modelList: ModelInfo[];
  providerList: ProviderInfo[];
  apiKeys: Record<string, string>;
  modelLoading?: string;
}

export const ModelSelector = ({

  model,

  setModel,

  provider,

  setProvider,

  modelList,

  providerList,

  modelLoading,

}: ModelSelectorProps) => {
  // Load enabled providers from cookies

  // Update enabled providers when cookies change
  useEffect(() => {
    // If current provider is disabled, switch to first enabled provider
    if (providerList.length == 0) {
      return;
    }

    if (provider && !providerList.map((p) => p.name).includes(provider.name)) {
      const firstEnabledProvider = providerList[0];
      setProvider?.(firstEnabledProvider);

      // Also update the model to the first available one for the new provider
      const firstModel = modelList.find((m) => m.provider === firstEnabledProvider.name);

      if (firstModel) {
        setModel?.(firstModel.name);
      }
    }
  }, [providerList, provider, setProvider, modelList, setModel]);

  if (providerList.length === 0) {
    return (
      <div className="mb-2 p-4 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary">

        <p className="text-center">

          No providers are currently enabled. Please enable at least one provider in the settings to start using the

          chat.

        </p>

      </div>
    );
  }

  return (
    <div className="mb-2 flex gap-2 flex-col sm:flex-row">

      <select

        value={provider?.name ?? ''}

        onChange={(e) => {

          const newProvider = providerList.find((p: ProviderInfo) => p.name === e.target.value);



          if (newProvider && setProvider) {

            setProvider(newProvider);

          }



          const firstModel = [...modelList].find((m) => m.provider === e.target.value);



          if (firstModel && setModel) {

            setModel(firstModel.name);

          }

        }}

        className="flex-1 p-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary focus:outline-none focus:ring-2 focus:ring-bolt-elements-focus transition-all"

      >

        {providerList.map((provider: ProviderInfo) => (

          <option key={provider.name} value={provider.name}>

            {provider.name}

          </option>

        ))}

      </select>

      <select

        key={provider?.name}

        value={model}

        onChange={(e) => setModel?.(e.target.value)}

        className="flex-1 p-2 rounded-lg border border-bolt-elements-borderColor bg-bolt-elements-prompt-background text-bolt-elements-textPrimary focus:outline-none focus:ring-2 focus:ring-bolt-elements-focus transition-all lg:max-w-[70%]"

        disabled={modelLoading === 'all' || modelLoading === provider?.name}

      >

        {modelLoading == 'all' || modelLoading == provider?.name ? (

          <option key={0} value="">

            Loading...

          </option>

        ) : (

          [...modelList]

            .filter((e) => e.provider == provider?.name && e.name)

            .map((modelOption, index) => (

              <option key={index} value={modelOption.name}>

                {modelOption.label}

              </option>

            ))

        )}

      </select>

    </div>
  );
};