mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-08-18 11:40:48 +08:00
Merge branch 'main' into 65-consistent-paths-plus-ui
This commit is contained in:
@@ -12,7 +12,7 @@ export function Avatar() {
|
||||
return <></>;
|
||||
}
|
||||
if (session && session.user) {
|
||||
const email = session.user.email;
|
||||
const displayName = session.user.name || session.user.email;
|
||||
const accountOptions = [
|
||||
{
|
||||
name: "Account Settings",
|
||||
@@ -35,7 +35,7 @@ export function Avatar() {
|
||||
height="40"
|
||||
className="rounded-full"
|
||||
></Image>
|
||||
<p className="hidden lg:flex">{email}</p>
|
||||
<p className="hidden lg:flex">{displayName}</p>
|
||||
{/* Will be changed to username once it is implemented */}
|
||||
</div>
|
||||
</Popover.Button>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import clsx from "clsx";
|
||||
|
||||
export const Button = (
|
||||
props: React.DetailedHTMLProps<React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>
|
||||
) => {
|
||||
const { className, children, ...rest } = props;
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
className={clsx(
|
||||
"inline-flex items-center rounded-md border border-transparent px-4 py-2 text-sm font-medium focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
export interface Message {
|
||||
text: string;
|
||||
is_assistant: boolean;
|
||||
}
|
||||
|
||||
const getColor = (isAssistant: boolean) => (isAssistant ? "bg-slate-800" : "bg-sky-900");
|
||||
|
||||
export const Messages = ({ messages }: { messages: Message[] }) => {
|
||||
const items = messages.map(({ text, is_assistant }: Message, i: number) => {
|
||||
return (
|
||||
<div key={i + text} className={`${getColor(is_assistant)} p-4 my-1 rounded-xl text-white whitespace-pre-wrap`}>
|
||||
{text}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
// Maybe also show a legend of the colors?
|
||||
return <>{items}</>;
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
const RankItem = ({ username, score }) => {
|
||||
return (
|
||||
<div className="flex flex-row justify-between p-6 border-2 border-slate-100 text-left font-semibold hover:bg-sky-50">
|
||||
<div>1</div>
|
||||
<div>@username</div>
|
||||
<div>20.5</div>
|
||||
<div>gold</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default RankItem;
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Card, CardBody, Flex, Heading } from "@chakra-ui/react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
|
||||
export type OptionProps = {
|
||||
img: string;
|
||||
alt: string;
|
||||
title: string;
|
||||
link: string;
|
||||
};
|
||||
|
||||
export const TaskOption = (props: OptionProps) => {
|
||||
const { alt, img, title, link } = props;
|
||||
return (
|
||||
<Link href={link}>
|
||||
<Card
|
||||
maxW="300"
|
||||
minW="300"
|
||||
minH="300"
|
||||
maxH="300"
|
||||
className="transition ease-in-out duration-500 sm:grayscale hover:grayscale-0"
|
||||
>
|
||||
<CardBody width="full" height="full">
|
||||
<Flex direction="column" alignItems="center" justifyContent="center">
|
||||
<Image src={img} alt={alt} width={200} height={200} />
|
||||
<Heading
|
||||
mt={-10}
|
||||
className="bg-gradient-to-r from-indigo-600 via-sky-400 to-indigo-700 bg-clip-text tracking-tight text-transparent"
|
||||
textAlign="center"
|
||||
fontSize="3xl"
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
</Flex>
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Divider, Flex, Heading } from "@chakra-ui/react";
|
||||
import React from "react";
|
||||
|
||||
export type TaskOptionsProps = {
|
||||
title: string;
|
||||
children: JSX.Element | JSX.Element[];
|
||||
};
|
||||
|
||||
export const TaskOptions = (props: TaskOptionsProps) => {
|
||||
const { title, children } = props;
|
||||
return (
|
||||
<Flex gap={10} wrap="wrap" justifyContent="center">
|
||||
<Heading
|
||||
className="bg-gradient-to-r from-indigo-600 via-sky-400 to-indigo-700 bg-clip-text tracking-tight text-transparent"
|
||||
fontSize="5xl"
|
||||
>
|
||||
{title}
|
||||
</Heading>
|
||||
<Divider mt={-8} />
|
||||
{children}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from "react";
|
||||
import { TaskOptions } from "./TaskOptions";
|
||||
import { Flex } from "@chakra-ui/react";
|
||||
import { TaskOption } from "./TaskOption";
|
||||
|
||||
export const TaskSelection = () => {
|
||||
return (
|
||||
<Flex gap={10} wrap="wrap" justifyContent="space-evenly" width="full" height="full" alignItems={"center"}>
|
||||
<TaskOptions key="create" title="Create">
|
||||
<TaskOption
|
||||
alt="Summarize Stories"
|
||||
img="/images/logos/logo.svg"
|
||||
title="Summarize stories"
|
||||
link="/summarize/story"
|
||||
/>
|
||||
<TaskOption alt="Reply as User" img="/images/logos/logo.svg" title="Reply as User" link="/create/user_reply" />
|
||||
<TaskOption
|
||||
alt="Reply as Assistant"
|
||||
img="/images/logos/logo.svg"
|
||||
title="Reply as Assistant"
|
||||
link="/create/assistant_reply"
|
||||
/>
|
||||
</TaskOptions>
|
||||
<TaskOptions key="evaluate" title="Evaluate">
|
||||
<TaskOption alt="Rate Prompts" img="/images/logos/logo.svg" title="Rate Prompts" link="/grading/grade-output" />
|
||||
</TaskOptions>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,3 @@
|
||||
export { TaskSelection } from "./TaskSelection";
|
||||
export { TaskOptions } from "./TaskOptions";
|
||||
export { TaskOption } from "./TaskOption";
|
||||
@@ -0,0 +1,14 @@
|
||||
export const TwoColumns = ({ children }: { children: React.ReactNode[] }) => {
|
||||
if (!Array.isArray(children) || children.length !== 2) {
|
||||
throw new Error("TwoColumns expects 2 children");
|
||||
}
|
||||
|
||||
const [first, second] = children;
|
||||
|
||||
return (
|
||||
<section className="mb-8 lt-lg:mb-12 grid lg:gap-x-12 lg:grid-cols-2">
|
||||
<div className="rounded-lg shadow-lg h-full block bg-white p-6">{first}</div>
|
||||
<div className="rounded-lg shadow-lg h-full block bg-white p-6 mt-6 lg:mt-0">{second}</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
@@ -2,6 +2,7 @@ import type { AuthOptions } from "next-auth";
|
||||
import NextAuth from "next-auth";
|
||||
import DiscordProvider from "next-auth/providers/discord";
|
||||
import EmailProvider from "next-auth/providers/email";
|
||||
import CredentialsProvider from "next-auth/providers/credentials";
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
|
||||
import prisma from "src/lib/prismadb";
|
||||
@@ -32,6 +33,23 @@ if (process.env.DISCORD_CLIENT_ID) {
|
||||
);
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
providers.push(
|
||||
CredentialsProvider({
|
||||
name: "Debug Credentials",
|
||||
credentials: {
|
||||
username: { label: "Username", type: "text" },
|
||||
},
|
||||
async authorize(credentials) {
|
||||
return {
|
||||
id: credentials.username,
|
||||
name: credentials.username,
|
||||
};
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export const authOptions: AuthOptions = {
|
||||
// Ensure we can store user data in a database.
|
||||
adapter: PrismaAdapter(prisma),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Button, Input, Stack } from "@chakra-ui/react";
|
||||
import Head from "next/head";
|
||||
import { FaDiscord, FaEnvelope, FaGithub } from "react-icons/fa";
|
||||
import { FaDiscord, FaEnvelope, FaBug, FaGithub } from "react-icons/fa";
|
||||
import { getCsrfToken, getProviders, signIn } from "next-auth/react";
|
||||
import { useRef } from "react";
|
||||
import Link from "next/link";
|
||||
@@ -8,12 +8,20 @@ import Link from "next/link";
|
||||
import { AuthLayout } from "src/components/AuthLayout";
|
||||
|
||||
export default function Signin({ csrfToken, providers }) {
|
||||
const { discord, email, github } = providers;
|
||||
const { discord, email, github, credentials } = providers;
|
||||
const emailEl = useRef(null);
|
||||
const signinWithEmail = () => {
|
||||
const debugUsernameEl = useRef(null);
|
||||
|
||||
const signinWithEmail = (ev: React.FormEvent) => {
|
||||
ev.preventDefault();
|
||||
signIn(email.id, { callbackUrl: "/", email: emailEl.current.value });
|
||||
};
|
||||
|
||||
function signinWithDebugCredentials(ev: React.FormEvent) {
|
||||
ev.preventDefault();
|
||||
signIn(credentials.id, { callbackUrl: "/", username: debugUsernameEl.current.value });
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -21,20 +29,27 @@ export default function Signin({ csrfToken, providers }) {
|
||||
<meta name="Sign Up" content="Sign up to access Open Assistant" />
|
||||
</Head>
|
||||
<AuthLayout>
|
||||
<Stack spacing="2">
|
||||
<Stack spacing="6">
|
||||
{credentials && (
|
||||
<form onSubmit={signinWithDebugCredentials} className="border-2 border-orange-200 rounded-md p-4 relative">
|
||||
<span className="text-orange-600 absolute -top-3 left-5 bg-white px-1">For Debugging Only</span>
|
||||
<Stack>
|
||||
<Input variant="outline" size="lg" placeholder="Username" ref={debugUsernameEl} />
|
||||
<Button size={"lg"} leftIcon={<FaBug />} colorScheme="gray" type="submit">
|
||||
Continue with Debug User
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
{email && (
|
||||
<Stack>
|
||||
<Input variant="outline" size="lg" placeholder="Email Address" ref={emailEl} />
|
||||
<Button
|
||||
size={"lg"}
|
||||
leftIcon={<FaEnvelope />}
|
||||
colorScheme="gray"
|
||||
onClick={signinWithEmail}
|
||||
// isDisabled="false"
|
||||
>
|
||||
Continue with Email
|
||||
</Button>
|
||||
</Stack>
|
||||
<form onSubmit={signinWithEmail}>
|
||||
<Stack>
|
||||
<Input variant="outline" size="lg" placeholder="Email Address" ref={emailEl} />
|
||||
<Button size={"lg"} leftIcon={<FaEnvelope />} colorScheme="gray">
|
||||
Continue with Email
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
{discord && (
|
||||
<Button
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import { Textarea } from "@chakra-ui/react";
|
||||
import { useRef, useState } from "react";
|
||||
import useSWRMutation from "swr/mutation";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
|
||||
import fetcher from "src/lib/fetcher";
|
||||
import poster from "src/lib/poster";
|
||||
import { Messages } from "src/components/Messages";
|
||||
import { TwoColumns } from "src/components/TwoColumns";
|
||||
import { Button } from "src/components/Button";
|
||||
|
||||
const AssistantReply = () => {
|
||||
const [tasks, setTasks] = useState([]);
|
||||
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
const { isLoading } = useSWRImmutable("/api/new_task/assistant_reply ", fetcher, {
|
||||
onSuccess: (data) => {
|
||||
console.log(data);
|
||||
setTasks([data]);
|
||||
},
|
||||
});
|
||||
|
||||
const { trigger, isMutating } = useSWRMutation("/api/update_task", poster, {
|
||||
onSuccess: async (data) => {
|
||||
const newTask = await data.json();
|
||||
setTasks((oldTasks) => [...oldTasks, newTask]);
|
||||
},
|
||||
});
|
||||
|
||||
const submitResponse = (task: { id: string }) => {
|
||||
const text = inputRef.current.value.trim();
|
||||
trigger({
|
||||
id: task.id,
|
||||
update_type: "text_reply_to_post",
|
||||
content: {
|
||||
text,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Make this a nicer loading screen.
|
||||
*/
|
||||
if (tasks.length == 0) {
|
||||
return <div className="p-6 h-full mx-auto bg-slate-100 text-gray-800">Loading...</div>;
|
||||
}
|
||||
|
||||
const task = tasks[0].task;
|
||||
return (
|
||||
<div className="p-6 h-full mx-auto bg-slate-100 text-gray-800">
|
||||
<TwoColumns>
|
||||
<>
|
||||
<h5 className="text-lg font-semibold">Reply as the assistant</h5>
|
||||
<p className="text-lg py-1">Given the following conversation, provide an adequate reply</p>
|
||||
<Messages messages={task.conversation.messages} />
|
||||
</>
|
||||
<Textarea name="reply" placeholder="Reply..." ref={inputRef} />
|
||||
</TwoColumns>
|
||||
|
||||
<section className="mb-8 p-4 rounded-lg shadow-lg bg-white flex flex-row justify-items-stretch ">
|
||||
<div className="grid grid-cols-[min-content_auto] gap-x-2 text-gray-700">
|
||||
<b>Prompt</b>
|
||||
<span>{tasks[0].id}</span>
|
||||
<b>Output</b>
|
||||
<span>Submit your answer</span>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center ml-auto">
|
||||
<Button className="mr-2 bg-indigo-100 text-indigo-700 hover:bg-indigo-200">Skip</Button>
|
||||
<Button
|
||||
onClick={() => submitResponse(tasks[0])}
|
||||
className="bg-indigo-600 text-white shadow-sm hover:bg-indigo-700"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AssistantReply;
|
||||
@@ -0,0 +1,84 @@
|
||||
import { Textarea } from "@chakra-ui/react";
|
||||
import { useRef, useState } from "react";
|
||||
import useSWRMutation from "swr/mutation";
|
||||
import useSWRImmutable from "swr/immutable";
|
||||
|
||||
import fetcher from "src/lib/fetcher";
|
||||
import poster from "src/lib/poster";
|
||||
import { Messages } from "src/components/Messages";
|
||||
import { TwoColumns } from "src/components/TwoColumns";
|
||||
import { Button } from "src/components/Button";
|
||||
|
||||
const UserReply = () => {
|
||||
const [tasks, setTasks] = useState([]);
|
||||
|
||||
const inputRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
const { isLoading } = useSWRImmutable("/api/new_task/user_reply", fetcher, {
|
||||
onSuccess: (data) => {
|
||||
console.log(data);
|
||||
setTasks([data]);
|
||||
},
|
||||
});
|
||||
|
||||
const { trigger, isMutating } = useSWRMutation("/api/update_task", poster, {
|
||||
onSuccess: async (data) => {
|
||||
const newTask = await data.json();
|
||||
setTasks((oldTasks) => [...oldTasks, newTask]);
|
||||
},
|
||||
});
|
||||
|
||||
const submitResponse = (task: { id: string }) => {
|
||||
const text = inputRef.current.value.trim();
|
||||
trigger({
|
||||
id: task.id,
|
||||
update_type: "text_reply_to_post",
|
||||
content: {
|
||||
text,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO: Make this a nicer loading screen.
|
||||
*/
|
||||
if (tasks.length == 0) {
|
||||
return <div className="p-6 h-full mx-auto bg-slate-100 text-gray-800">Loading...</div>;
|
||||
}
|
||||
|
||||
const task = tasks[0].task;
|
||||
return (
|
||||
<div className="p-6 h-full mx-auto bg-slate-100 text-gray-800">
|
||||
<TwoColumns>
|
||||
<>
|
||||
<h5 className="text-lg font-semibold">Reply as a user</h5>
|
||||
<p className="text-lg py-1">Given the following conversation, provide an adequate reply</p>
|
||||
<Messages messages={task.conversation.messages} />
|
||||
{task.hint && <p className="text-lg py-1">Hint: {task.hint}</p>}
|
||||
</>
|
||||
<Textarea name="reply" placeholder="Reply..." ref={inputRef} />
|
||||
</TwoColumns>
|
||||
|
||||
<section className="mb-8 p-4 rounded-lg shadow-lg bg-white flex flex-row justify-items-stretch ">
|
||||
<div className="grid grid-cols-[min-content_auto] gap-x-2 text-gray-700">
|
||||
<b>Prompt</b>
|
||||
<span>{tasks[0].id}</span>
|
||||
<b>Output</b>
|
||||
<span>Submit your answer</span>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-center ml-auto">
|
||||
<Button className="mr-2 bg-indigo-100 text-indigo-700 hover:bg-indigo-200">Skip</Button>
|
||||
<Button
|
||||
onClick={() => submitResponse(tasks[0])}
|
||||
className="bg-indigo-600 text-white shadow-sm hover:bg-indigo-700"
|
||||
>
|
||||
Submit
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserReply;
|
||||
@@ -8,6 +8,7 @@ import { Faq } from "src/components/Faq";
|
||||
import { Footer } from "src/components/Footer";
|
||||
import { Header } from "src/components/Header";
|
||||
import { Hero } from "src/components/Hero";
|
||||
import { TaskSelection } from "src/components/TaskSelection";
|
||||
|
||||
const Home = () => {
|
||||
const { data: session } = useSession();
|
||||
@@ -43,13 +44,8 @@ const Home = () => {
|
||||
/>
|
||||
</Head>
|
||||
<Header />
|
||||
<main className="h-3/4 z-0 bg-white flex flex-col items-center justify-center gap-2">
|
||||
<Button size="lg" colorScheme="blue" className="drop-shadow">
|
||||
<Link href="/evaluate/rate_summary">Rate a Summary</Link>
|
||||
</Button>
|
||||
<Button size="lg" colorScheme="blue" className="drop-shadow">
|
||||
<Link href="/create/summarize_story">Summarize a story</Link>
|
||||
</Button>
|
||||
<main className="h-3/4 m-20 z-0 bg-white flex flex-col items-center justify-center gap-2">
|
||||
<TaskSelection />
|
||||
</main>
|
||||
<Footer />
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
import RankItem from "@/components/RankItem";
|
||||
import { BarsArrowUpIcon, BarsArrowDownIcon } from "@heroicons/react/24/solid";
|
||||
import Image from "next/image";
|
||||
import { HiBarsArrowUp, HiBarsArrowDown } from "react-icons/hi2";
|
||||
|
||||
const LeaderBoard = () => {
|
||||
const PlaceHolderProps = { username: "test_user", score: 10 };
|
||||
return (
|
||||
<div className=" p-6 h-full mx-auto bg-slate-100 text-gray-800">
|
||||
<div className="flex flex-col">
|
||||
<div className="rounded-lg shadow-lg h-full block bg-white">
|
||||
<div className="p-8">
|
||||
<h5 className="text-2xl font-bold">LeaderBoard</h5>
|
||||
</div>
|
||||
<div className="flex flex-row justify-between px-6 py-3 font-semibold text-md">
|
||||
<div className="flex flex-row items-center justify-center space-x-2">
|
||||
<div>
|
||||
<p>Rank</p>
|
||||
</div>
|
||||
<div className="mt-2 text-slate-400 hover:text-sky-400 hover:cursor-pointer">
|
||||
<HiBarsArrowDown className="w-6 h-6 text-inherit"></HiBarsArrowDown>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center justify-center space-x-2">
|
||||
<div>
|
||||
<p>User</p>
|
||||
</div>
|
||||
<div className="mt-2 text-slate-400 hover:text-sky-400 hover:cursor-pointer">
|
||||
<HiBarsArrowDown className="w-6 h-6 text-inherit"></HiBarsArrowDown>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center justify-center space-x-2">
|
||||
<div>
|
||||
<p>Score</p>
|
||||
</div>
|
||||
<div className="mt-2 text-slate-400 hover:text-sky-400 hover:cursor-pointer">
|
||||
<HiBarsArrowDown className="w-6 h-6 text-inherit"></HiBarsArrowDown>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row items-center justify-center space-x-2">
|
||||
<div>
|
||||
<p>Medal</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* leaderboard items */}
|
||||
<RankItem {...PlaceHolderProps}></RankItem>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LeaderBoard;
|
||||
Reference in New Issue
Block a user