Skip to content

Commit

Permalink
docs: improved UI for docs
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelass committed Jul 15, 2023
1 parent 56f77b3 commit 9a58a17
Show file tree
Hide file tree
Showing 7 changed files with 212 additions and 192 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ const artist = new Agent(new DallEModelAdapter(), {
});

// Assign tasks
const writerResult = writer.assign({
const writerResult = await writer.assign({
question: "Describe the future to an artist so that they can draw it",
});
const artistResult = artist.assign(writerResult.message);
const artistResult = await artist.assign(writerResult.message);
// Do something with the result
console.log(artistResult.message.content);
```
Expand Down
164 changes: 65 additions & 99 deletions docs-gui/components/bot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import { DotLottiePlayer } from "@dotlottie/react-player";
import { Box, Card, CardContent, Checkbox, Container, Modal } from "@mui/joy";
import axios from "axios";
import { useAtom } from "jotai";
import { useEffect } from "react";
import { Controller, FormProvider, useForm } from "react-hook-form";

import {
answerAtom,
Expand Down Expand Up @@ -47,120 +45,88 @@ export function generateMarkdown(guides: Guide[]): string {

export function Bot({
onAnswer,
onExpand,
onQuestion,
}: {
onExpand?(): void;
onQuestion?(): void;
onAnswer?(data: { id: string; message: Record<string, any> }): void;
}) {
const [loading, setLoading] = useAtom(loadingAtom);
const [question, setQuestion] = useAtom(questionAtom);

const [question] = useAtom(questionAtom);
const [search, setSearch] = useAtom(searchAtom);
const [guide, setGuide] = useAtom(guideAtom);
const [language, setLanguage] = useAtom(languageAtom);
const methods = useForm<{
question: string;
guide: boolean;
language: string;
search: boolean;
}>({
defaultValues: { question, guide, language, search },
});

const onSubmit = methods.handleSubmit(
async (formData: {
question: string;
guide?: boolean;
search?: boolean;
language: string;
}) => {
setLoading(true);
setQuestion(formData.question);
setSearch(formData.search);
setGuide(formData.guide);
setLanguage(formData.language);

if (onQuestion) {
onQuestion();
}
const [language] = useAtom(languageAtom);

try {
const { data } = formData.search
? await axios.post("/api/search", {
q: formData.question,
})
: await axios.post("/api/ama", {
question: formData.question,
guide: formData.guide,
language: formData.language,
});
if (onAnswer) {
if (formData.search) {
onAnswer({
id: "search",
message: {
answer: generateMarkdown(data),
},
});
} else {
onAnswer(data);
}
async function handleSubmit() {
setLoading(true);

if (onQuestion) {
onQuestion();
}

try {
const { data } = search
? await axios.post("/api/search", {
q: question,
})
: await axios.post("/api/ama", {
question,
guide,
language,
});
if (onAnswer) {
if (search) {
onAnswer({
id: "search",
message: {
answer: generateMarkdown(data),
},
});
} else {
onAnswer(data);
}
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
);

const { setValue } = methods;

useEffect(() => {
setValue("question", question);
setValue("language", language);
setValue("search", search);
setValue("guide", guide);
}, [setValue, guide, search, language, question]);
}

return (
<Box>
<FormProvider {...methods}>
<Box sx={{ maxWidth: { md: 600, lg: 600 }, mx: "auto" }}>
<Box component="form" sx={{ p: 1 }} onSubmit={onSubmit}>
<ChatInput loading={loading} onSubmit={onSubmit} />
<Box mt={1} sx={{ display: "flex", gap: 2, alignItems: "center" }}>
<Controller
name="search"
control={methods.control}
render={({ field: { value, ...field } }) => (
<Checkbox
{...field}
checked={value}
label="Search"
variant="soft"
sx={{ color: "inherit" }}
/>
)}
/>
<Controller
name="guide"
control={methods.control}
render={({ field: { value, ...field } }) => (
<Checkbox
{...field}
checked={value}
label="Guide"
variant="soft"
sx={{ color: "inherit" }}
/>
)}
/>
<Box sx={{ maxWidth: { md: 600, lg: 600 }, mx: "auto" }}>
<Box component="form" sx={{ p: 1 }} onSubmit={handleSubmit}>
<ChatInput loading={loading} onSubmit={handleSubmit} onExpand={onExpand} />
<Box mt={1} sx={{ display: "flex", gap: 2, alignItems: "center" }}>
<Checkbox
name="search"
checked={search}
onChange={() => {
setSearch(!search);
}}
label="Search"
variant="soft"
sx={{ color: "inherit" }}
/>

<Checkbox
name="guide"
checked={guide}
onChange={() => {
setGuide(!guide);
}}
label="Guide"
variant="soft"
sx={{ color: "inherit" }}
/>

<LanguageSelect />
</Box>
<LanguageSelect />
</Box>
</Box>
</FormProvider>
</Box>
</Box>
);
}
Expand Down Expand Up @@ -190,7 +156,7 @@ export default function HyvSearch() {

return (
<Box>
<Bot onAnswer={handleAnswer} onQuestion={handleQuestion} />
<Bot onAnswer={handleAnswer} onQuestion={handleQuestion} onExpand={handleOpen} />
<Modal disableAutoFocus open={open} onClose={handleClose}>
<Container sx={{ height: "calc(100% - 6rem)", my: "3rem" }}>
<Card variant="plain" sx={{ boxShadow: "lg", height: "100%" }}>
Expand Down
130 changes: 88 additions & 42 deletions docs-gui/components/chat-input.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,104 @@
/* eslint-disable @typescript-eslint/ban-ts-comment */
// @ts-ignore
import FullscreenIcon from "@mui/icons-material/Fullscreen";
// @ts-ignore
import SendIcon from "@mui/icons-material/Send";
import { CircularProgress, IconButton, Textarea } from "@mui/joy";
import { useFormContext } from "react-hook-form";
import { Box, CircularProgress, IconButton, Textarea } from "@mui/joy";
import { useAtom } from "jotai";
import { useState } from "react";

// @ts-ignore
import { questionAtom } from "@/docs/atoms";
/* eslint-enable @typescript-eslint/ban-ts-comment */

export interface ChatInputProps {
loading: boolean;

onSubmit(): void;
onExpand?(): void;
}

export function ChatInput({ loading, onSubmit }: ChatInputProps) {
const { register } = useFormContext();
export function ChatInput({ loading, onSubmit, onExpand }: ChatInputProps) {
const [question, setQuestion] = useAtom(questionAtom);
const [focus, setFocus] = useState(false);
return (
<Textarea
{...register("question", { required: true })}
placeholder="How can I get started with Hyv and gpt-4?"
aria-label="Write your question and press Enter to sumbit"
minRows={1}
maxRows={8}
variant="soft"
onKeyDown={event => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
if (!loading) {
onSubmit();
}
}
}}
endDecorator={
<IconButton
disabled={loading}
variant="solid"
aria-label="Submit"
tabIndex={-1}
onClick={() => {
onSubmit();
}}
>
{loading ? <CircularProgress size="sm" /> : <SendIcon />}
</IconButton>
}
<Box
sx={{
width: "100%",
".MuiTextarea-endDecorator": {
position: "absolute",
bottom: 4,
right: -4,
},
".MuiTextarea-textarea": {
pr: 5,
},
position: "relative",
zIndex: 2,
height: 40,
}}
/>
>
<Textarea
name="question"
placeholder="How can I get started with Hyv and gpt-4?"
aria-label="Write your question and press Enter to sumbit"
minRows={1}
maxRows={focus ? 20 : 1}
variant="soft"
value={question}
sx={{
width: "100%",
"&:focus-within": { boxShadow: "md" },
".MuiTextarea-endDecorator": {
position: "absolute",
bottom: 4,
right: -4,
},
".MuiTextarea-startDecorator": {
position: "absolute",
top: 4,
left: 8,
},
".MuiTextarea-textarea": {
pr: 5,
pl: onExpand ? 5 : undefined,
},
}}
startDecorator={
onExpand ? (
<IconButton
variant="solid"
aria-label="Expand"
onClick={() => {
onExpand();
}}
>
<FullscreenIcon />
</IconButton>
) : undefined
}
endDecorator={
<IconButton
disabled={loading}
variant="solid"
aria-label="Submit"
tabIndex={-1}
onClick={() => {
onSubmit();
}}
>
{loading ? <CircularProgress size="sm" /> : <SendIcon />}
</IconButton>
}
onFocus={() => {
setFocus(true);
}}
onBlur={() => {
setFocus(false);
}}
onKeyDown={event => {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
if (!loading) {
onSubmit();
}
}
}}
onChange={event => {
setQuestion(event.target.value);
}}
/>
</Box>
);
}
Loading

0 comments on commit 9a58a17

Please sign in to comment.