diff --git a/website/src/components/Messages.tsx b/website/src/components/Messages.tsx index 226c6154..fb84559e 100644 --- a/website/src/components/Messages.tsx +++ b/website/src/components/Messages.tsx @@ -12,8 +12,7 @@ export interface Message { export const Messages = ({ messages, post_id }: { messages: Message[]; post_id: string }) => { const items = messages.map((messageProps: Message, i: number) => { - const { message_id } = messageProps; - const { text } = messageProps; + const { message_id, text } = messageProps; return ( diff --git a/website/src/components/Tasks/TaskTypes.tsx b/website/src/components/Tasks/TaskTypes.tsx index 7cec2177..09e106b6 100644 --- a/website/src/components/Tasks/TaskTypes.tsx +++ b/website/src/components/Tasks/TaskTypes.tsx @@ -63,4 +63,11 @@ export const TaskTypes = [ pathname: "/label/label_initial_prompt", type: "label_initial_prompt", }, + { + label: "Label Prompter Reply", + desc: "Provide labels for a prompt.", + category: TaskCategory.Label, + pathname: "/label/label_prompter_reply", + type: "label_prompter_reply", + }, ]; diff --git a/website/src/hooks/tasks/useLabelInitialPrompt.tsx b/website/src/hooks/tasks/useLabelInitialPrompt.tsx index 5d6ca372..69ab4bcc 100644 --- a/website/src/hooks/tasks/useLabelInitialPrompt.tsx +++ b/website/src/hooks/tasks/useLabelInitialPrompt.tsx @@ -15,10 +15,7 @@ export const useLabelInitialPromptTask = () => { const submit = (id: string, message_id: string, text: string, validLabels: string[], labelWeights: number[]) => { console.assert(validLabels.length === labelWeights.length); - const labels = validLabels.reduce( - (obj, label, i) => ((obj[label] = labelWeights[i]), obj), - {} as Record - ); + const labels = Object.fromEntries(validLabels.map((label, i) => [label, labelWeights[i]])); return trigger({ id, update_type: "text_labels", content: { labels, text, message_id } }); }; diff --git a/website/src/hooks/tasks/useLabelPrompterReply.ts b/website/src/hooks/tasks/useLabelPrompterReply.ts new file mode 100644 index 00000000..9b7a61da --- /dev/null +++ b/website/src/hooks/tasks/useLabelPrompterReply.ts @@ -0,0 +1,30 @@ +import { TaskResponse, useGenericTaskAPI } from "./useGenericTaskAPI"; + +export interface LabelPrompterReplyTask { + id: string; + type: "label_prompter_reply"; + message_id: string; + valid_labels: string[]; + reply: string; + conversation: { + messages: Array<{ + text: string; + is_assistant: boolean; + }>; + }; +} + +export type LabelPrompterReplyTaskResponse = TaskResponse; + +export const useLabelPrompterReplyTask = () => { + const { tasks, isLoading, trigger, reset, error } = useGenericTaskAPI("label_prompter_reply"); + + const submit = (id: string, message_id: string, text: string, validLabels: string[], labelWeights: number[]) => { + console.assert(validLabels.length === labelWeights.length); + const labels = Object.fromEntries(validLabels.map((label, i) => [label, labelWeights[i]])); + + return trigger({ id, update_type: "text_labels", content: { labels, text, message_id } }); + }; + + return { tasks, isLoading, submit, reset, error }; +}; diff --git a/website/src/middleware.ts b/website/src/middleware.ts index b6a539b4..d1cd6801 100644 --- a/website/src/middleware.ts +++ b/website/src/middleware.ts @@ -1,8 +1,8 @@ export { default } from "next-auth/middleware"; /** - * Guards all pages under `/grading` and redirects them to the sign in page. + * Guards these pages and redirects them to the sign in page. */ export const config = { - matcher: ["/create/:path*", "/evaluate/:path*", "/account/:path*", "/dashboard"], + matcher: ["/create/:path*", "/evaluate/:path*", "/label/:path*", "/account/:path*", "/dashboard", "/admin/:path*"], }; diff --git a/website/src/pages/label/label_prompter_reply.tsx b/website/src/pages/label/label_prompter_reply.tsx new file mode 100644 index 00000000..743bde97 --- /dev/null +++ b/website/src/pages/label/label_prompter_reply.tsx @@ -0,0 +1,44 @@ +import { useState } from "react"; +import { LoadingScreen } from "src/components/Loading/LoadingScreen"; +import { Message, Messages } from "src/components/Messages"; +import { TaskControls } from "src/components/Survey/TaskControls"; +import { LabelSliderGroup, LabelTask } from "src/components/Tasks/LabelTask"; +import { LabelPrompterReplyTaskResponse, useLabelPrompterReplyTask } from "src/hooks/tasks/useLabelPrompterReply"; + +const LabelPrompterReply = () => { + const [sliderValues, setSliderValues] = useState([]); + + const { tasks, isLoading, submit, reset } = useLabelPrompterReplyTask(); + + if (isLoading || tasks.length === 0) { + return ; + } + + const task = tasks[0].task; + const messages: Message[] = [ + // TODO: could we re-use the task message_id as message id for all messages in the conversation? + // or should we ask the backend team to send message ids in the task? + ...task.conversation.messages.map((m) => ({ ...m, message_id: null })), + { text: task.reply, is_assistant: false, message_id: task.message_id }, + ]; + + return ( + } + inputs={} + controls={ + + submit(id, task.message_id, task.reply, task.valid_labels, sliderValues) + } + /> + } + /> + ); +}; + +export default LabelPrompterReply;