diff options
author | Nate Sesti <33237525+sestinj@users.noreply.github.com> | 2023-08-22 13:12:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-22 13:12:58 -0700 |
commit | 5eec484dc79bb56dabf9a56af0dbe6bc95227d39 (patch) | |
tree | 07edc01475cfe0ba69372f537d36aa3294680b7d /extension/react-app/src/pages | |
parent | b6435e1e479edb1e4f049098dc8522e944317f2a (diff) | |
download | sncontinue-5eec484dc79bb56dabf9a56af0dbe6bc95227d39.tar.gz sncontinue-5eec484dc79bb56dabf9a56af0dbe6bc95227d39.tar.bz2 sncontinue-5eec484dc79bb56dabf9a56af0dbe6bc95227d39.zip |
Config UI (#399)
* feat: :sparkles: UI for config!
* feat: :sparkles: (latent) edit models in settings
Diffstat (limited to 'extension/react-app/src/pages')
-rw-r--r-- | extension/react-app/src/pages/settings.tsx | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/extension/react-app/src/pages/settings.tsx b/extension/react-app/src/pages/settings.tsx new file mode 100644 index 00000000..8fd91ff5 --- /dev/null +++ b/extension/react-app/src/pages/settings.tsx @@ -0,0 +1,229 @@ +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"); + + if (systemMessage) 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; |