From 5eec484dc79bb56dabf9a56af0dbe6bc95227d39 Mon Sep 17 00:00:00 2001 From: Nate Sesti <33237525+sestinj@users.noreply.github.com> Date: Tue, 22 Aug 2023 13:12:58 -0700 Subject: Config UI (#399) * feat: :sparkles: UI for config! * feat: :sparkles: (latent) edit models in settings --- .../src/components/HeaderButtonWithText.tsx | 4 +- extension/react-app/src/components/InfoHover.tsx | 19 ++++ extension/react-app/src/components/Layout.tsx | 9 ++ .../react-app/src/components/ModelSettings.tsx | 107 +++++++++++++++++++++ extension/react-app/src/components/index.ts | 50 ++++++++-- 5 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 extension/react-app/src/components/InfoHover.tsx create mode 100644 extension/react-app/src/components/ModelSettings.tsx (limited to 'extension/react-app/src/components') diff --git a/extension/react-app/src/components/HeaderButtonWithText.tsx b/extension/react-app/src/components/HeaderButtonWithText.tsx index bcd36972..3122c287 100644 --- a/extension/react-app/src/components/HeaderButtonWithText.tsx +++ b/extension/react-app/src/components/HeaderButtonWithText.tsx @@ -1,7 +1,5 @@ import React, { useState } from "react"; -import { Tooltip } from "react-tooltip"; -import styled from "styled-components"; -import { HeaderButton, StyledTooltip, defaultBorderRadius } from "."; +import { HeaderButton, StyledTooltip } from "."; interface HeaderButtonWithTextProps { text: string; diff --git a/extension/react-app/src/components/InfoHover.tsx b/extension/react-app/src/components/InfoHover.tsx new file mode 100644 index 00000000..2cb8ad71 --- /dev/null +++ b/extension/react-app/src/components/InfoHover.tsx @@ -0,0 +1,19 @@ +import { InformationCircleIcon } from "@heroicons/react/24/outline"; +import { StyledTooltip } from "."; + +const InfoHover = ({ msg }: { msg: string }) => { + const id = "info-hover"; + + return ( + <> + + + + ); +}; + +export default InfoHover; diff --git a/extension/react-app/src/components/Layout.tsx b/extension/react-app/src/components/Layout.tsx index cec3f8e1..c0f0929b 100644 --- a/extension/react-app/src/components/Layout.tsx +++ b/extension/react-app/src/components/Layout.tsx @@ -18,6 +18,7 @@ import { BookOpenIcon, ChatBubbleOvalLeftEllipsisIcon, SparklesIcon, + Cog6ToothIcon, } from "@heroicons/react/24/outline"; import HeaderButtonWithText from "./HeaderButtonWithText"; import { useNavigate } from "react-router-dom"; @@ -193,6 +194,14 @@ const Layout = () => { + { + navigate("/settings"); + }} + text="Settings" + > + + diff --git a/extension/react-app/src/components/ModelSettings.tsx b/extension/react-app/src/components/ModelSettings.tsx new file mode 100644 index 00000000..99200502 --- /dev/null +++ b/extension/react-app/src/components/ModelSettings.tsx @@ -0,0 +1,107 @@ +import styled from "styled-components"; +import { LLM } from "../../../schema/LLM"; +import { + Label, + Select, + TextInput, + defaultBorderRadius, + lightGray, + vscForeground, +} from "."; +import { useState } from "react"; +import { useFormContext } from "react-hook-form"; + +const Div = styled.div<{ dashed: boolean }>` + border: 1px ${(props) => (props.dashed ? "dashed" : "solid")} ${lightGray}; + border-radius: ${defaultBorderRadius}; + padding: 8px; + margin-bottom: 16px; +`; + +type ModelOption = "api_key" | "model" | "context_length"; + +const DefaultModelOptions: { + [key: string]: { [key in ModelOption]?: string }; +} = { + OpenAI: { + api_key: "", + model: "gpt-4", + }, + MaybeProxyOpenAI: { + api_key: "", + model: "gpt-4", + }, + Anthropic: { + api_key: "", + model: "claude-2", + }, + default: { + api_key: "", + model: "gpt-4", + }, +}; + +function ModelSettings(props: { llm: any | undefined; role: string }) { + const [modelOptions, setModelOptions] = useState<{ + [key in ModelOption]?: string; + }>(DefaultModelOptions[props.llm?.class_name || "default"]); + + const { register, setValue, getValues } = useFormContext(); + + return ( +
+ {props.llm ? ( + <> + {props.role}: {props.llm.class_name || "gpt-4"} +
+ {typeof modelOptions.api_key !== undefined && ( + <> + + + + )} + {modelOptions.model && ( + <> + + + + )} + + + ) : ( +
+ Add Model +
+ +
+
+ )} +
+ ); +} + +export default ModelSettings; diff --git a/extension/react-app/src/components/index.ts b/extension/react-app/src/components/index.ts index 6705ceb2..f2e154bc 100644 --- a/extension/react-app/src/components/index.ts +++ b/extension/react-app/src/components/index.ts @@ -40,21 +40,29 @@ export const StyledTooltip = styled(Tooltip)` padding-left: 12px; padding-right: 12px; z-index: 100; + + max-width: 80vw; `; export const TextArea = styled.textarea` - width: 100%; + padding: 8px; + font-family: inherit; border-radius: ${defaultBorderRadius}; - border: none; + margin: 16px auto; + height: auto; + width: calc(100% - 32px); background-color: ${secondaryDark}; - resize: vertical; - - padding: 4px; - caret-color: ${vscForeground}; - color: #{vscForeground}; + color: ${vscForeground}; + z-index: 1; + border: 1px solid transparent; &:focus { - outline: 1px solid ${buttonColor}; + outline: 1px solid ${lightGray}; + border: 1px solid transparent; + } + + &::placeholder { + color: ${lightGray}80; } `; @@ -84,11 +92,33 @@ export const H3 = styled.h3` export const TextInput = styled.input.attrs({ type: "text" })` width: 100%; - padding: 12px 20px; + padding: 8px 12px; + margin: 8px 0; + box-sizing: border-box; + border-radius: ${defaultBorderRadius}; + outline: 1px solid ${lightGray}; + border: none; + background-color: ${vscBackground}; + color: ${vscForeground}; + + &:focus { + background: ${secondaryDark}; + } +`; + +export const Select = styled.select` + padding: 8px 12px; margin: 8px 0; box-sizing: border-box; border-radius: ${defaultBorderRadius}; - border: 2px solid gray; + outline: 1px solid ${lightGray}; + border: none; + background-color: ${vscBackground}; + color: ${vscForeground}; +`; + +export const Label = styled.label` + font-size: 13px; `; const spin = keyframes` -- cgit v1.2.3-70-g09d2