File size: 5,275 Bytes
f8b5d42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import useGetProviderModels, {
  DISABLED_PROVIDERS,
} from "@/hooks/useGetProvidersModels";
import paths from "@/utils/paths";
import { useTranslation } from "react-i18next";
import { Link, useParams } from "react-router-dom";

/**
 * These models do NOT support function calling
 * or do not support system prompts
 * and therefore are not supported for agents.
 * @param {string} provider - The AI provider.
 * @param {string} model - The model name.
 * @returns {boolean} Whether the model is supported for agents.
 */
function supportedModel(provider, model = "") {
  if (provider === "openai") {
    return (
      [
        "gpt-3.5-turbo-0301",
        "gpt-4-turbo-2024-04-09",
        "gpt-4-turbo",
        "o1-preview",
        "o1-preview-2024-09-12",
        "o1-mini",
        "o1-mini-2024-09-12",
        "o3-mini",
        "o3-mini-2025-01-31",
      ].includes(model) === false
    );
  }

  return true;
}

export default function AgentModelSelection({
  provider,
  workspace,
  setHasChanges,
}) {
  const { slug } = useParams();
  const { defaultModels, customModels, loading } =
    useGetProviderModels(provider);

  const { t } = useTranslation();
  if (DISABLED_PROVIDERS.includes(provider)) {
    return (
      <div className="w-full h-10 justify-center items-center flex">
        <p className="text-sm font-base text-white text-opacity-60 text-center">
          Multi-model support is not supported for this provider yet.
          <br />
          Agent's will use{" "}
          <Link
            to={paths.workspace.settings.chatSettings(slug)}
            className="underline"
          >
            the model set for the workspace
          </Link>{" "}
          or{" "}
          <Link to={paths.settings.llmPreference()} className="underline">
            the model set for the system.
          </Link>
        </p>
      </div>
    );
  }

  if (loading) {
    return (
      <div>
        <div className="flex flex-col">
          <label htmlFor="name" className="block input-label">
            {t("agent.mode.chat.title")}
          </label>
          <p className="text-white text-opacity-60 text-xs font-medium py-1.5">
            {t("agent.mode.chat.description")}
          </p>
        </div>
        <select
          name="agentModel"
          required={true}
          disabled={true}
          className="border-none bg-theme-settings-input-bg text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
        >
          <option disabled={true} selected={true}>
            {t("agent.mode.wait")}
          </option>
        </select>
      </div>
    );
  }

  return (
    <div>
      <div className="flex flex-col">
        <label htmlFor="name" className="block input-label">
          {t("agent.mode.title")}
        </label>
        <p className="text-white text-opacity-60 text-xs font-medium py-1.5">
          {t("agent.mode.description")}
        </p>
      </div>

      <select
        name="agentModel"
        required={true}
        onChange={() => {
          setHasChanges(true);
        }}
        className="border-none bg-theme-settings-input-bg text-white text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5"
      >
        {defaultModels.length > 0 && (
          <optgroup label="General models">
            {defaultModels.map((model) => {
              if (!supportedModel(provider, model)) return null;
              return (
                <option
                  key={model}
                  value={model}
                  selected={workspace?.agentModel === model}
                >
                  {model}
                </option>
              );
            })}
          </optgroup>
        )}
        {Array.isArray(customModels) && customModels.length > 0 && (
          <optgroup label="Custom models">
            {customModels.map((model) => {
              if (!supportedModel(provider, model.id)) return null;

              return (
                <option
                  key={model.id}
                  value={model.id}
                  selected={workspace?.agentModel === model.id}
                >
                  {model.id}
                </option>
              );
            })}
          </optgroup>
        )}
        {/* For providers like TogetherAi where we partition model by creator entity. */}
        {!Array.isArray(customModels) &&
          Object.keys(customModels).length > 0 && (
            <>
              {Object.entries(customModels).map(([organization, models]) => (
                <optgroup key={organization} label={organization}>
                  {models.map((model) => {
                    if (!supportedModel(provider, model.id)) return null;
                    return (
                      <option
                        key={model.id}
                        value={model.id}
                        selected={workspace?.agentModel === model.id}
                      >
                        {model.name}
                      </option>
                    );
                  })}
                </optgroup>
              ))}
            </>
          )}
      </select>
    </div>
  );
}