import React, { useContext, useEffect, useState } from "react"; import { GUIClientContext } from "../App"; import { useSelector } from "react-redux"; import { RootStore } from "../redux/store"; import { useNavigate } from "react-router-dom"; import { ContinueConfig } from "../../../schema/ContinueConfig"; import { Button, Select, TextArea, lightGray, secondaryDark, } from "../components"; import styled from "styled-components"; import { ArrowLeftIcon } from "@heroicons/react/24/outline"; import Loader from "../components/Loader"; import InfoHover from "../components/InfoHover"; import { FormProvider, useForm } from "react-hook-form"; import ModelSettings from "../components/ModelSettings"; const Hr = styled.hr` border: 0.5px solid ${lightGray}; `; const CancelButton = styled(Button)` background-color: transparent; color: ${lightGray}; border: 1px solid ${lightGray}; &:hover { background-color: ${lightGray}; color: black; } `; const SaveButton = styled(Button)` &:hover { opacity: 0.8; } `; const Slider = styled.input.attrs({ type: "range" })` --webkit-appearance: none; width: 100%; background-color: ${secondaryDark}; outline: none; border: none; opacity: 0.7; -webkit-transition: 0.2s; transition: opacity 0.2s; &:hover { opacity: 1; } &::-webkit-slider-runnable-track { width: 100%; height: 8px; cursor: pointer; background: ${lightGray}; border-radius: 4px; } &::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 8px; height: 8px; cursor: pointer; margin-top: -3px; } &::-moz-range-thumb { width: 8px; height: 8px; cursor: pointer; margin-top: -3px; } &:focus { outline: none; border: none; } `; const ALL_MODEL_ROLES = ["default", "small", "medium", "large", "edit", "chat"]; function Settings() { const formMethods = useForm<ContinueConfig>(); const onSubmit = (data: ContinueConfig) => console.log(data); const navigate = useNavigate(); const client = useContext(GUIClientContext); const config = useSelector((state: RootStore) => state.serverState.config); const submitChanges = () => { if (!client) return; const systemMessage = formMethods.watch("system_message"); const temperature = formMethods.watch("temperature"); // const models = formMethods.watch("models"); client.setSystemMessage(systemMessage || ""); if (temperature) client.setTemperature(temperature); // if (models) { // for (const role of ALL_MODEL_ROLES) { // if (models[role]) { // client.setModelForRole(role, models[role] as string, models[role]); // } // } // } }; const submitAndLeave = () => { submitChanges(); navigate("/"); }; return ( <FormProvider {...formMethods}> <div className="w-full"> <form onSubmit={formMethods.handleSubmit(onSubmit)}> <div className="items-center flex"> <ArrowLeftIcon width="1.4em" height="1.4em" onClick={submitAndLeave} className="inline-block ml-4 cursor-pointer" /> <h1 className="text-2xl font-bold m-4 inline-block">Settings</h1> </div> {config ? ( <div className="p-2"> <h3 className="flex gap-1"> System Message <InfoHover msg={`Set a system message with information that the LLM should always keep in mind (e.g. "Please give concise answers. Always respond in Spanish.")`} /> </h3> <TextArea placeholder="Enter system message" {...formMethods.register("system_message")} defaultValue={config.system_message} /> <Hr /> <h3 className="flex gap-1"> Temperature <InfoHover msg={`Set temperature to any value between 0 and 1. Higher values will make the LLM more creative, while lower values will make it more predictable.`} /> </h3> <div className="flex justify-between mx-16 gap-1"> <p>0</p> <Slider type="range" min="0" max="1" step="0.01" defaultValue={config.temperature} {...formMethods.register("temperature")} /> <p>1</p> </div> <div className="text-center" style={{ marginTop: "-25px" }}> <p className="text-sm text-gray-500"> {formMethods.watch("temperature") || config.temperature || "-"} </p> </div> <Hr /> {/** <h3 className="flex gap-1">Models</h3> {ALL_MODEL_ROLES.map((role) => { return ( <> <h4>{role}</h4> <ModelSettings role={role} llm={(config.models as any)[role]} /> </> ); })} <Hr /> <h3 className="flex gap-1"> Custom Commands <InfoHover msg={`Custom commands let you map a prompt to a shortened slash command. They are like slash commands, but more easily defined - write just a prompt instead of a Step class. Their output will always be in chat form`} /> </h3> <Hr /> <h3 className="flex gap-1"> Context Providers <InfoHover msg={`Context Providers let you type '@' and quickly reference sources of information, like files, GitHub Issues, webpages, and more.`} /> </h3> */} </div> ) : ( <Loader /> )} </form> <div className="flex gap-2 justify-end px-4"> <CancelButton onClick={() => { navigate("/"); }} > Cancel </CancelButton> <SaveButton onClick={submitAndLeave}>Save</SaveButton> </div> </div> </FormProvider> ); } export default Settings;