dia-gov's picture
Upload 569 files
cd6f98e verified
raw
history blame
7.72 kB
import axios from "axios";
import clsx from "clsx";
import type { GetStaticProps } from "next";
import { useTranslation } from "next-i18next";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import React, { useState } from "react";
import {
FaCheckCircle,
FaCoins,
FaExclamationCircle,
FaGlobe,
FaKey,
FaRobot,
FaSyncAlt,
FaThermometerFull,
} from "react-icons/fa";
import nextI18NextConfig from "../../next-i18next.config.js";
import FadeIn from "../components/motions/FadeIn";
import { useAuth } from "../hooks/useAuth";
import type { LLMModel } from "../hooks/useModels";
import { useModels } from "../hooks/useModels";
import { useSettings } from "../hooks/useSettings";
import DashboardLayout from "../layout/dashboard";
import type { GPTModelNames } from "../types";
import Button from "../ui/button";
import Combo from "../ui/combox";
import Input from "../ui/input";
import type { Language } from "../utils/languages";
import { languages } from "../utils/languages";
const SettingsPage = () => {
const [t] = useTranslation("settings");
const { settings, updateSettings, updateLangauge } = useSettings();
const { session } = useAuth({ protectedRoute: true });
const { models, getModel } = useModels();
const [isApiKeyValid, setIsApiKeyValid] = useState<boolean | undefined>(undefined);
const validateApiKey = async () => {
try {
await axios.get("https://api.openai.com/v1/engines", {
headers: {
Authorization: `Bearer ${settings.customApiKey}`,
},
});
setIsApiKeyValid(true);
} catch (error) {
setIsApiKeyValid(false);
}
};
const disableAdvancedSettings = !session?.user;
const model = getModel(settings.customModelName) || {
name: settings.customModelName,
max_tokens: 2000,
has_access: true,
};
const updateModel = (model: LLMModel) => {
if (settings.maxTokens > model.max_tokens) {
updateSettings("maxTokens", model.max_tokens);
}
updateSettings("customModelName", model.name as GPTModelNames);
};
const onDisconnect = () => {
return Promise.resolve();
};
return (
<DashboardLayout>
<div className="min-h-screen flex-grow">
<div className="">
<FadeIn
initialX={-45}
initialY={0}
delay={0.1}
className="border-b border-slate-6 px-10 py-10"
>
<div>
{" "}
<h1 className="text-4xl font-bold text-slate-12">Settings</h1>
<h2 className="text-xl font-light text-slate-12">Customize your agent experience</h2>
</div>
</FadeIn>
<FadeIn initialY={45} delay={0.1} className="mt-4 px-10">
<div className="flex flex-col gap-3">
<Combo<Language>
label="Language"
value={settings.language}
valueMapper={(e) => e.name}
onChange={(e) => {
updateLangauge(e).catch(console.error);
}}
items={languages}
icon={<FaGlobe />}
/>
<Input
label="API Key"
name="api-key"
placeholder="sk..."
helpText={
<span>
You can optionally use your own API key here. You can find your API key in your{" "}
<a className="link" href="https://platform.openai.com/account/api-keys">
OpenAI dashboard.
</a>
</span>
}
type="text"
value={settings.customApiKey}
onChange={(e) => {
setIsApiKeyValid(undefined);
updateSettings("customApiKey", e.target.value);
}}
icon={<FaKey />}
className="flex-grow-1 mr-2"
right={
<Button
onClick={validateApiKey}
className={clsx(
"transition-400 h-11 w-16 rounded text-sm text-white duration-200",
isApiKeyValid === undefined && "bg-gray-500 hover:bg-gray-700",
isApiKeyValid === true && "bg-green-500 hover:bg-green-700",
isApiKeyValid === false && "bg-red-500 hover:bg-red-700"
)}
>
{isApiKeyValid === undefined && "Test"}
{isApiKeyValid === true && <FaCheckCircle />}
{isApiKeyValid === false && <FaExclamationCircle />}
</Button>
}
/>
</div>
{!disableAdvancedSettings && (
<div className="mt-4 flex flex-col ">
<h1 className="pb-4 text-xl font-bold text-slate-12">Advanced Settings</h1>
<div className="flex flex-col gap-4">
<Combo<LLMModel>
label="Model"
value={model}
valueMapper={(e) => e.name}
onChange={updateModel}
items={models}
icon={<FaRobot />}
/>
<Input
label={`${t("TEMPERATURE")}`}
value={settings.customTemperature}
name="temperature"
type="range"
onChange={(e) =>
updateSettings("customTemperature", parseFloat(e.target.value))
}
attributes={{
min: 0,
max: 1,
step: 0.01,
}}
helpText={t("HIGHER_VALUES_MAKE_OUTPUT_MORE_RANDOM")}
icon={<FaThermometerFull />}
disabled={disableAdvancedSettings}
/>
<Input
label={`${t("LOOP")}`}
value={settings.customMaxLoops}
name="loop"
type="range"
onChange={(e) => updateSettings("customMaxLoops", parseFloat(e.target.value))}
attributes={{
min: 1,
max: 25,
step: 1,
}}
helpText={t("CONTROL_THE_MAXIMUM_NUM_OF_LOOPS")}
icon={<FaSyncAlt />}
disabled={disableAdvancedSettings}
/>
<Input
label={`${t("TOKENS")}`}
value={settings.maxTokens}
name="tokens"
type="range"
onChange={(e) => updateSettings("maxTokens", parseFloat(e.target.value))}
attributes={{
min: 200,
max: model.max_tokens,
step: 100,
}}
helpText={t("CONTROL_MAXIMUM_OF_TOKENS_DESCRIPTION")}
icon={<FaCoins />}
disabled={disableAdvancedSettings}
/>
</div>
</div>
)}
</FadeIn>
</div>
</div>
</DashboardLayout>
);
};
export default SettingsPage;
export const getStaticProps: GetStaticProps = async ({ locale = "en" }) => {
const supportedLocales = languages.map((language) => language.code);
const chosenLocale = supportedLocales.includes(locale) ? locale : "en";
return {
props: {
...(await serverSideTranslations(chosenLocale, nextI18NextConfig.ns)),
},
};
};