| import { useState, useEffect } from "react"; | |
| import System from "@/models/system"; | |
| export default function MistralOptions({ settings }) { | |
| const [inputValue, setInputValue] = useState(settings?.MistralApiKey); | |
| const [mistralKey, setMistralKey] = useState(settings?.MistralApiKey); | |
| return ( | |
| <div className="flex gap-[36px] mt-1.5"> | |
| <div className="flex flex-col w-60"> | |
| <label className="text-white text-sm font-semibold block mb-3"> | |
| Mistral API Key | |
| </label> | |
| <input | |
| type="password" | |
| name="MistralApiKey" | |
| className="border-none bg-theme-settings-input-bg text-white placeholder:text-theme-settings-input-placeholder text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" | |
| placeholder="Mistral API Key" | |
| defaultValue={settings?.MistralApiKey ? "*".repeat(20) : ""} | |
| required={true} | |
| autoComplete="off" | |
| spellCheck={false} | |
| onChange={(e) => setInputValue(e.target.value)} | |
| onBlur={() => setMistralKey(inputValue)} | |
| /> | |
| </div> | |
| {!settings?.credentialsOnly && ( | |
| <MistralModelSelection settings={settings} apiKey={mistralKey} /> | |
| )} | |
| </div> | |
| ); | |
| } | |
| function MistralModelSelection({ apiKey, settings }) { | |
| const [customModels, setCustomModels] = useState([]); | |
| const [loading, setLoading] = useState(true); | |
| useEffect(() => { | |
| async function findCustomModels() { | |
| if (!apiKey) { | |
| setCustomModels([]); | |
| setLoading(false); | |
| return; | |
| } | |
| setLoading(true); | |
| const { models } = await System.customModels( | |
| "mistral", | |
| typeof apiKey === "boolean" ? null : apiKey | |
| ); | |
| setCustomModels(models || []); | |
| setLoading(false); | |
| } | |
| findCustomModels(); | |
| }, [apiKey]); | |
| if (loading || customModels.length == 0) { | |
| return ( | |
| <div className="flex flex-col w-60"> | |
| <label className="text-white text-sm font-semibold block mb-3"> | |
| Chat Model Selection | |
| </label> | |
| <select | |
| name="MistralModelPref" | |
| disabled={true} | |
| className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5" | |
| > | |
| <option disabled={true} selected={true}> | |
| {!!apiKey | |
| ? "-- loading available models --" | |
| : "-- waiting for API key --"} | |
| </option> | |
| </select> | |
| </div> | |
| ); | |
| } | |
| return ( | |
| <div className="flex flex-col w-60"> | |
| <label className="text-white text-sm font-semibold block mb-3"> | |
| Chat Model Selection | |
| </label> | |
| <select | |
| name="MistralModelPref" | |
| required={true} | |
| className="border-none bg-theme-settings-input-bg border-gray-500 text-white text-sm rounded-lg block w-full p-2.5" | |
| > | |
| {customModels.length > 0 && ( | |
| <optgroup label="Available Mistral Models"> | |
| {customModels.map((model) => { | |
| return ( | |
| <option | |
| key={model.id} | |
| value={model.id} | |
| selected={settings?.MistralModelPref === model.id} | |
| > | |
| {model.id} | |
| </option> | |
| ); | |
| })} | |
| </optgroup> | |
| )} | |
| </select> | |
| </div> | |
| ); | |
| } | |