summaryrefslogtreecommitdiff
path: root/extension/react-app/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'extension/react-app/src/components')
-rw-r--r--extension/react-app/src/components/HeaderButtonWithText.tsx4
-rw-r--r--extension/react-app/src/components/InfoHover.tsx19
-rw-r--r--extension/react-app/src/components/Layout.tsx9
-rw-r--r--extension/react-app/src/components/ModelSettings.tsx107
-rw-r--r--extension/react-app/src/components/index.ts50
5 files changed, 176 insertions, 13 deletions
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 (
+ <>
+ <InformationCircleIcon
+ data-tooltip-id={id}
+ data-tooltip-content={msg}
+ className="h-5 w-5 text-gray-500 cursor-help"
+ />
+ <StyledTooltip id={id} place="bottom" />
+ </>
+ );
+};
+
+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 = () => {
<ChatBubbleOvalLeftEllipsisIcon width="1.4em" height="1.4em" />
</HeaderButtonWithText>
</a>
+ <HeaderButtonWithText
+ onClick={() => {
+ navigate("/settings");
+ }}
+ text="Settings"
+ >
+ <Cog6ToothIcon width="1.4em" height="1.4em" />
+ </HeaderButtonWithText>
</Footer>
</div>
</LayoutTopDiv>
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 (
+ <Div dashed={typeof props.llm === undefined}>
+ {props.llm ? (
+ <>
+ <b>{props.role}</b>: <b> {props.llm.class_name || "gpt-4"}</b>
+ <form>
+ {typeof modelOptions.api_key !== undefined && (
+ <>
+ <Label>API Key</Label>
+ <TextInput
+ type="text"
+ defaultValue={props.llm.api_key}
+ placeholder="API Key"
+ {...register(`models.${props.role}.api_key`)}
+ />
+ </>
+ )}
+ {modelOptions.model && (
+ <>
+ <Label>Model</Label>
+ <TextInput
+ type="text"
+ defaultValue={props.llm.model}
+ placeholder="Model"
+ {...register(`models.${props.role}.model`)}
+ />
+ </>
+ )}
+ </form>
+ </>
+ ) : (
+ <div>
+ <b>Add Model</b>
+ <div className="my-4">
+ <Select
+ defaultValue=""
+ onChange={(e) => {
+ if (e.target.value) {
+ e.target.value = "";
+ }
+ }}
+ >
+ <option disabled value="">
+ Select Model Type
+ </option>
+ <option value="newModel1">New Model 1</option>
+ <option value="newModel2">New Model 2</option>
+ <option value="newModel3">New Model 3</option>
+ </Select>
+ </div>
+ </div>
+ )}
+ </Div>
+ );
+}
+
+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`