From 747c3501d104e9c930d3952eaee8fb216edfd6d1 Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Tue, 10 Jan 2023 20:57:42 +0900 Subject: [PATCH 1/6] Adding a new web api path that returns valid labels and then fetching from that within FlaggableElement. This allows FlaggableElement to fetch all its own data and remove the need to pipe labels through a series of components --- website/src/components/FlaggableElement.tsx | 39 ++++++++++++------- website/src/components/Messages.tsx | 19 +-------- .../src/components/Messages/MessageTable.tsx | 4 +- .../components/Messages/MessageTableEntry.tsx | 6 +-- .../Messages/MessageWithChildren.tsx | 4 +- website/src/components/Tasks/CreateTask.tsx | 5 +-- website/src/components/Tasks/EvaluateTask.tsx | 3 +- website/src/pages/api/new_task/[task_type].ts | 4 -- website/src/pages/api/valid_labels.ts | 23 +++++++++++ .../src/pages/label/label_assistant_reply.tsx | 3 +- .../src/pages/label/label_prompter_reply.tsx | 3 +- website/src/pages/messages/[id]/index.tsx | 2 +- website/src/pages/messages/index.tsx | 12 +----- website/src/types/Task.ts | 1 - 14 files changed, 63 insertions(+), 65 deletions(-) create mode 100644 website/src/pages/api/valid_labels.ts diff --git a/website/src/components/FlaggableElement.tsx b/website/src/components/FlaggableElement.tsx index a7157c4a..d82b5750 100644 --- a/website/src/components/FlaggableElement.tsx +++ b/website/src/components/FlaggableElement.tsx @@ -22,9 +22,11 @@ import { useId, } from "@chakra-ui/react"; import { FlagIcon, QuestionMarkCircleIcon } from "@heroicons/react/20/solid"; -import { useState } from "react"; +import { useEffect, useState } from "react"; +import fetcher from "src/lib/fetcher"; import poster from "src/lib/poster"; import { colors } from "styles/Theme/colors"; +import useSWR from "swr"; import useSWRMutation from "swr/mutation"; interface textFlagLabels { @@ -34,16 +36,27 @@ interface textFlagLabels { } export const FlaggableElement = (props) => { + const [labels, setLabels] = useState([]); + const [checkboxValues, setCheckboxValues] = useState([]); + const [sliderValues, setSliderValues] = useState([]); const [isEditing, setIsEditing] = useBoolean(); - const flaggable_labels = props.flaggable_labels; - const TEXT_LABEL_FLAGS = - flaggable_labels?.valid_labels?.map((valid_label) => { - return { - attributeName: valid_label.name, - labelText: valid_label.display_text, - additionalExplanation: valid_label.help_text, - }; - }) || []; + + const { data, isLoading } = useSWR("/api/valid_labels", fetcher); + useEffect(() => { + if (isLoading) { + return; + } + const { valid_labels } = data; + const newLabels = valid_labels.map((valid_label) => ({ + attributeName: valid_label.name, + labelText: valid_label.display_text, + additionalExplanation: valid_label.help_text, + })); + setSliderValues(new Array(newLabels.length).fill(1)); + setCheckboxValues(new Array(newLabels.length).fill(false)); + setLabels(newLabels); + }, [data, isLoading]); + const { trigger } = useSWRMutation("/api/set_label", poster, { onSuccess: () => { setIsEditing.off(); @@ -52,7 +65,7 @@ export const FlaggableElement = (props) => { const submitResponse = () => { const label_map: Map = new Map(); - TEXT_LABEL_FLAGS.forEach((flag, i) => { + labels.forEach((flag, i) => { if (checkboxValues[i]) { label_map.set(flag.attributeName, sliderValues[i]); } @@ -64,8 +77,6 @@ export const FlaggableElement = (props) => { text: props.text, }); }; - const [checkboxValues, setCheckboxValues] = useState(new Array(TEXT_LABEL_FLAGS.length).fill(false)); - const [sliderValues, setSliderValues] = useState(new Array(TEXT_LABEL_FLAGS.length).fill(1)); const handleCheckboxState = (isChecked, idx) => { setCheckboxValues( @@ -110,7 +121,7 @@ export const FlaggableElement = (props) => { - {TEXT_LABEL_FLAGS.map((option, i) => ( + {labels.map((option, i) => ( { +export const Messages = ({ messages, post_id }: { messages: Message[]; post_id: string }) => { const items = messages.map((messageProps: Message, i: number) => { const { message_id, text } = messageProps; return ( - + ); diff --git a/website/src/components/Messages/MessageTable.tsx b/website/src/components/Messages/MessageTable.tsx index 872b79f1..7797c6a3 100644 --- a/website/src/components/Messages/MessageTable.tsx +++ b/website/src/components/Messages/MessageTable.tsx @@ -1,11 +1,11 @@ import { Stack, StackDivider } from "@chakra-ui/react"; import { MessageTableEntry } from "src/components/Messages/MessageTableEntry"; -export function MessageTable({ messages, valid_labels }) { +export function MessageTable({ messages }) { return ( } spacing="4"> {messages.map((item, idx) => ( - + ))} ); diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index e9e8775a..9fad7262 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -2,7 +2,6 @@ import { Avatar, HStack, LinkBox, useColorModeValue } from "@chakra-ui/react"; import { boolean } from "boolean"; import NextLink from "next/link"; import { FlaggableElement } from "src/components/FlaggableElement"; -import type { ValidLabel } from "src/types/Task"; interface Message { text: string; @@ -12,14 +11,13 @@ interface Message { interface MessageTableEntryProps { item: Message; idx: number; - valid_labels: ValidLabel[]; } export function MessageTableEntry(props: MessageTableEntryProps) { - const { item, idx, valid_labels } = props; + const { item, idx } = props; const bgColor = useColorModeValue(idx % 2 === 0 ? "bg-slate-800" : "bg-black", "bg-sky-900"); return ( - + - + @@ -90,7 +90,7 @@ export function MessageWithChildren(props: MessageWithChildrenProps) { {children.map((item, idx) => ( - + ))} diff --git a/website/src/components/Tasks/CreateTask.tsx b/website/src/components/Tasks/CreateTask.tsx index a424315a..4d8daea0 100644 --- a/website/src/components/Tasks/CreateTask.tsx +++ b/website/src/components/Tasks/CreateTask.tsx @@ -17,7 +17,6 @@ export interface CreateTaskProps { } export const CreateTask = ({ tasks, taskType, trigger, onSkipTask, onNextTask, mainBgClasses }: CreateTaskProps) => { const task = tasks[0].task; - const valid_labels = tasks[0].valid_labels; const [inputText, setInputText] = useState(""); const submitResponse = (task: { id: string }) => { @@ -41,9 +40,7 @@ export const CreateTask = ({ tasks, taskType, trigger, onSkipTask, onNextTask, m <>
{taskType.label}

{taskType.overview}

- {task.conversation ? ( - - ) : null} + {task.conversation ? : null} <>
{taskType.instruction}
diff --git a/website/src/components/Tasks/EvaluateTask.tsx b/website/src/components/Tasks/EvaluateTask.tsx index 61ed3889..d0a1f404 100644 --- a/website/src/components/Tasks/EvaluateTask.tsx +++ b/website/src/components/Tasks/EvaluateTask.tsx @@ -33,7 +33,6 @@ export const EvaluateTask = ({ tasks, trigger, onSkipTask, onNextTask, mainBgCla messages = messages.map((message, index) => ({ ...message, id: index })); } - const valid_labels = tasks[0].valid_labels; const sortables = tasks[0].task.replies ? "replies" : "prompts"; return ( @@ -43,7 +42,7 @@ export const EvaluateTask = ({ tasks, trigger, onSkipTask, onNextTask, mainBgCla

Given the following {sortables}, sort them from best to worst, best being first, worst being last.

- {messages ? : null} + {messages ? : null} diff --git a/website/src/pages/api/new_task/[task_type].ts b/website/src/pages/api/new_task/[task_type].ts index 80334f76..9f3be55c 100644 --- a/website/src/pages/api/new_task/[task_type].ts +++ b/website/src/pages/api/new_task/[task_type].ts @@ -23,7 +23,6 @@ const handler = async (req, res) => { // Fetch the new task. const task = await oasstApiClient.fetchTask(task_type, token); - const valid_labels = await oasstApiClient.fetch_valid_text(); // Store the task and link it to the user.. const registeredTask = await prisma.registeredTask.create({ @@ -37,9 +36,6 @@ const handler = async (req, res) => { }, }); - // Add the valid labels that can be used to flag messages in this Task - registeredTask["valid_labels"] = valid_labels; - // Send the results to the client. res.status(200).json(registeredTask); }; diff --git a/website/src/pages/api/valid_labels.ts b/website/src/pages/api/valid_labels.ts new file mode 100644 index 00000000..ab788c05 --- /dev/null +++ b/website/src/pages/api/valid_labels.ts @@ -0,0 +1,23 @@ +import { getToken } from "next-auth/jwt"; +import { oasstApiClient } from "src/lib/oasst_api_client"; + +/** + * TODO + */ +const handler = async (req, res) => { + const token = await getToken({ req }); + + // Return nothing if the user isn't registered. + if (!token) { + res.status(401).end(); + return; + } + + // Fetch the new task. + const valid_labels = await oasstApiClient.fetch_valid_text(); + + // Send the results to the client. + res.status(200).json(valid_labels); +}; + +export default handler; diff --git a/website/src/pages/label/label_assistant_reply.tsx b/website/src/pages/label/label_assistant_reply.tsx index 99c10f56..59a7bbcc 100644 --- a/website/src/pages/label/label_assistant_reply.tsx +++ b/website/src/pages/label/label_assistant_reply.tsx @@ -16,7 +16,6 @@ const LabelAssistantReply = () => { } const task = tasks[0].task; - const valid_labels = tasks[0].valid_labels; const messages: Message[] = [ ...task.conversation.messages, { text: task.reply, is_assistant: true, message_id: task.message_id }, @@ -26,7 +25,7 @@ const LabelAssistantReply = () => { } + messages={} inputs={} controls={ { } const task = tasks[0].task; - const valid_labels = tasks[0].valid_labels; const messages: Message[] = [ ...task.conversation.messages, { text: task.reply, is_assistant: false, message_id: task.message_id }, @@ -26,7 +25,7 @@ const LabelPrompterReply = () => { } + messages={} inputs={} controls={ { Parent - + )} diff --git a/website/src/pages/messages/index.tsx b/website/src/pages/messages/index.tsx index ed48d47b..9cdc2ac5 100644 --- a/website/src/pages/messages/index.tsx +++ b/website/src/pages/messages/index.tsx @@ -52,11 +52,7 @@ const MessagesDashboard = () => { borderRadius="xl" className="p-6 shadow-sm" > - {receivedMessages ? ( - - ) : ( - - )} + {receivedMessages ? : } @@ -70,11 +66,7 @@ const MessagesDashboard = () => { borderRadius="xl" className="p-6 shadow-sm" > - {receivedUserMessages ? ( - - ) : ( - - )} + {receivedUserMessages ? : } diff --git a/website/src/types/Task.ts b/website/src/types/Task.ts index 6975fa14..7f614ab6 100644 --- a/website/src/types/Task.ts +++ b/website/src/types/Task.ts @@ -27,5 +27,4 @@ export interface TaskResponse { id: string; userId: string; task: Task; - valid_labels: ValidLabel[]; } From 5109f14e4cb5d26f312457e01f33db1b0acb997a Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Wed, 11 Jan 2023 14:58:10 +0900 Subject: [PATCH 2/6] Fixing the answer submission problem after unifying code --- website/src/components/Tasks/Task.tsx | 8 ++++---- website/src/pages/create/assistant_reply.tsx | 2 +- website/src/pages/create/initial_prompt.tsx | 2 +- website/src/pages/create/summarize_story.tsx | 2 +- website/src/pages/create/user_reply.tsx | 2 +- website/src/pages/evaluate/rank_assistant_replies.tsx | 2 +- website/src/pages/evaluate/rank_initial_prompts.tsx | 2 +- website/src/pages/evaluate/rank_user_replies.tsx | 2 +- website/src/pages/label/label_assistant_reply.tsx | 2 +- website/src/pages/label/label_initial_prompt.tsx | 2 +- website/src/pages/label/label_prompter_reply.tsx | 2 +- 11 files changed, 14 insertions(+), 14 deletions(-) diff --git a/website/src/components/Tasks/Task.tsx b/website/src/components/Tasks/Task.tsx index cd4ddeed..99d54311 100644 --- a/website/src/components/Tasks/Task.tsx +++ b/website/src/components/Tasks/Task.tsx @@ -21,7 +21,7 @@ export interface TaskSurveyProps { onReplyChanged: (state: TaskReplyState) => void; } -export const Task = ({ task, trigger, mutate }) => { +export const Task = ({ frontendId, task, trigger, mutate }) => { const [taskStatus, setTaskStatus] = useState("NOT_SUBMITTABLE"); const replyContent = useRef(null); const [showUnchangedWarning, setShowUnchangedWarning] = useState(false); @@ -39,7 +39,7 @@ export const Task = ({ task, trigger, mutate }) => { const rejectTask = (reason: string) => { sendRejection({ - id: task.id, + id: frontendId, reason, }); }; @@ -66,7 +66,7 @@ export const Task = ({ task, trigger, mutate }) => { break; case "SUBMITABLE": { trigger({ - id: task.id, + id: frontendId, update_type: taskType.update_type, content: replyContent.current, }); @@ -107,7 +107,7 @@ export const Task = ({ task, trigger, mutate }) => { onSubmitAnyway={() => { if (taskStatus === "DEFAULT") { trigger({ - id: task.id, + id: frontendId, update_type: taskType.update_type, content: replyContent.current, }); diff --git a/website/src/pages/create/assistant_reply.tsx b/website/src/pages/create/assistant_reply.tsx index f078fa40..f596de86 100644 --- a/website/src/pages/create/assistant_reply.tsx +++ b/website/src/pages/create/assistant_reply.tsx @@ -21,7 +21,7 @@ const AssistantReply = () => { Reply as Assistant - + ); }; diff --git a/website/src/pages/create/initial_prompt.tsx b/website/src/pages/create/initial_prompt.tsx index 01b882f9..4eb1dd94 100644 --- a/website/src/pages/create/initial_prompt.tsx +++ b/website/src/pages/create/initial_prompt.tsx @@ -21,7 +21,7 @@ const InitialPrompt = () => { Reply as Assistant - + ); }; diff --git a/website/src/pages/create/summarize_story.tsx b/website/src/pages/create/summarize_story.tsx index d551b8e6..15d7d99e 100644 --- a/website/src/pages/create/summarize_story.tsx +++ b/website/src/pages/create/summarize_story.tsx @@ -39,7 +39,7 @@ const SummarizeStory = () => { const submitResponse = () => { const text = inputText.trim(); trigger({ - id: tasks[0].task.id, + id: tasks[0].id, update_type: "text_reply_to_message", content: { text, diff --git a/website/src/pages/create/user_reply.tsx b/website/src/pages/create/user_reply.tsx index 51a54b0e..9e34a31d 100644 --- a/website/src/pages/create/user_reply.tsx +++ b/website/src/pages/create/user_reply.tsx @@ -21,7 +21,7 @@ const UserReply = () => { Reply as Assistant - + ); }; diff --git a/website/src/pages/evaluate/rank_assistant_replies.tsx b/website/src/pages/evaluate/rank_assistant_replies.tsx index 6686a42f..bcf23b7a 100644 --- a/website/src/pages/evaluate/rank_assistant_replies.tsx +++ b/website/src/pages/evaluate/rank_assistant_replies.tsx @@ -21,7 +21,7 @@ const RankAssistantReplies = () => { Rank Assistant Replies - + ); }; diff --git a/website/src/pages/evaluate/rank_initial_prompts.tsx b/website/src/pages/evaluate/rank_initial_prompts.tsx index 1350305b..bc26b062 100644 --- a/website/src/pages/evaluate/rank_initial_prompts.tsx +++ b/website/src/pages/evaluate/rank_initial_prompts.tsx @@ -21,7 +21,7 @@ const RankInitialPrompts = () => { Rank Initial Prompts - + ); }; diff --git a/website/src/pages/evaluate/rank_user_replies.tsx b/website/src/pages/evaluate/rank_user_replies.tsx index 0bd23c64..854b75ba 100644 --- a/website/src/pages/evaluate/rank_user_replies.tsx +++ b/website/src/pages/evaluate/rank_user_replies.tsx @@ -21,7 +21,7 @@ const RankUserReplies = () => { Rank User Replies - + ); }; diff --git a/website/src/pages/label/label_assistant_reply.tsx b/website/src/pages/label/label_assistant_reply.tsx index ffc3af4d..36ac6dd6 100644 --- a/website/src/pages/label/label_assistant_reply.tsx +++ b/website/src/pages/label/label_assistant_reply.tsx @@ -21,7 +21,7 @@ const LabelAssistantReply = () => { Label Assistant Reply - + ); }; diff --git a/website/src/pages/label/label_initial_prompt.tsx b/website/src/pages/label/label_initial_prompt.tsx index beea5ee8..d2839e86 100644 --- a/website/src/pages/label/label_initial_prompt.tsx +++ b/website/src/pages/label/label_initial_prompt.tsx @@ -21,7 +21,7 @@ const LabelInitialPrompt = () => { Label Initial Prompt - + ); }; diff --git a/website/src/pages/label/label_prompter_reply.tsx b/website/src/pages/label/label_prompter_reply.tsx index 0eeaad33..03b4f19d 100644 --- a/website/src/pages/label/label_prompter_reply.tsx +++ b/website/src/pages/label/label_prompter_reply.tsx @@ -21,7 +21,7 @@ const LabelPrompterReply = () => { Label Prompter Reply - + ); }; From f4d0ad1cc8823a4ec17e019b167add62a01d2dec Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Wed, 11 Jan 2023 15:05:30 +0900 Subject: [PATCH 3/6] Removing an unused property --- website/src/components/Messages/MessageTable.tsx | 4 ++-- website/src/components/Messages/MessageWithChildren.tsx | 4 ++-- website/src/pages/messages/[id]/index.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/website/src/components/Messages/MessageTable.tsx b/website/src/components/Messages/MessageTable.tsx index 7797c6a3..163cf533 100644 --- a/website/src/components/Messages/MessageTable.tsx +++ b/website/src/components/Messages/MessageTable.tsx @@ -4,8 +4,8 @@ import { MessageTableEntry } from "src/components/Messages/MessageTableEntry"; export function MessageTable({ messages }) { return ( } spacing="4"> - {messages.map((item, idx) => ( - + {messages.map((item) => ( + ))} ); diff --git a/website/src/components/Messages/MessageWithChildren.tsx b/website/src/components/Messages/MessageWithChildren.tsx index 9aeb43c6..c6834510 100644 --- a/website/src/components/Messages/MessageWithChildren.tsx +++ b/website/src/components/Messages/MessageWithChildren.tsx @@ -68,7 +68,7 @@ export function MessageWithChildren(props: MessageWithChildrenProps) { {isFirst ? "Message" : depth === 1 ? "Children" : "Ancestor"} - + @@ -95,7 +95,7 @@ export function MessageWithChildren(props: MessageWithChildrenProps) { {children.map((item, idx) => ( - + ))} diff --git a/website/src/pages/messages/[id]/index.tsx b/website/src/pages/messages/[id]/index.tsx index 649f6162..cf05d0df 100644 --- a/website/src/pages/messages/[id]/index.tsx +++ b/website/src/pages/messages/[id]/index.tsx @@ -48,7 +48,7 @@ const MessageDetail = ({ id }) => { {" "} - + From 454f33282367e48a34b907961bf3d9d7c52fd5e9 Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Wed, 11 Jan 2023 16:36:40 +0900 Subject: [PATCH 4/6] Ensuring the flagging post has a message or post id --- website/src/components/Messages/MessageTableEntry.tsx | 2 +- website/src/pages/api/set_label.ts | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index 756d0b7c..7423aaea 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -16,7 +16,7 @@ export function MessageTableEntry(props: MessageTableEntryProps) { return (
- + { // Parse out the local message_id, task ID and the interaction contents. - const { message_id, label_map, text } = await JSON.parse(req.body); + const { message_id, post_id, label_map, text } = await JSON.parse(req.body); const interactionRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/text_labels`, { method: "POST", @@ -16,7 +16,7 @@ const handler = withoutRole("banned", async (req, res, token) => { }, body: JSON.stringify({ type: "text_labels", - message_id: message_id, + message_id: message_id || post_id, labels: label_map, text: text, user: { @@ -26,6 +26,10 @@ const handler = withoutRole("banned", async (req, res, token) => { }, }), }); + if (interactionRes.status !== 204) { + const r = await interactionRes.json(); + console.error(JSON.stringify(r)); + } res.status(interactionRes.status).end(); }); From aba5b43a37f80fc6bca624a78993996e84b6f0f0 Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Wed, 11 Jan 2023 16:40:28 +0900 Subject: [PATCH 5/6] Minimal fixing for the Message type in one context --- website/src/components/Messages/MessageTableEntry.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/website/src/components/Messages/MessageTableEntry.tsx b/website/src/components/Messages/MessageTableEntry.tsx index 7423aaea..9626b95e 100644 --- a/website/src/components/Messages/MessageTableEntry.tsx +++ b/website/src/components/Messages/MessageTableEntry.tsx @@ -5,6 +5,7 @@ import { FlaggableElement } from "src/components/FlaggableElement"; interface Message { text: string; id: string; + message_id: string; is_assistant: boolean; } interface MessageTableEntryProps { From 9f1064d656c33598338fbe332db13dfb573ed707 Mon Sep 17 00:00:00 2001 From: Keith Stevens Date: Wed, 11 Jan 2023 16:54:39 +0900 Subject: [PATCH 6/6] Complete the handler todo and use withoutRole --- website/src/pages/api/valid_labels.ts | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/website/src/pages/api/valid_labels.ts b/website/src/pages/api/valid_labels.ts index ab788c05..5f61ff2f 100644 --- a/website/src/pages/api/valid_labels.ts +++ b/website/src/pages/api/valid_labels.ts @@ -1,23 +1,12 @@ -import { getToken } from "next-auth/jwt"; +import { withoutRole } from "src/lib/auth"; import { oasstApiClient } from "src/lib/oasst_api_client"; /** - * TODO + * Returns the set of valid labels that can be applied to messages. */ -const handler = async (req, res) => { - const token = await getToken({ req }); - - // Return nothing if the user isn't registered. - if (!token) { - res.status(401).end(); - return; - } - - // Fetch the new task. +const handler = withoutRole("banned", async (req, res) => { const valid_labels = await oasstApiClient.fetch_valid_text(); - - // Send the results to the client. res.status(200).json(valid_labels); -}; +}); export default handler;