Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: message ids, flag and modify tables #145

Merged
merged 5 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions apps/nextjs/src/app/aila/[id]/download/useDownloadView.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { getLastAssistantMessage } from "@oakai/aila/src/helpers/chat/getLastAssistantMessage";
import { AilaPersistedChat } from "@oakai/aila/src/protocol/schema";

import { useProgressForDownloads } from "@/components/AppComponents/Chat/Chat/hooks/useProgressForDownloads";
import { ExportsHookProps } from "@/components/ExportsDialogs/exports.types";
import { useExportAdditionalMaterials } from "@/components/ExportsDialogs/useExportAdditionalMaterials";
import { useExportLessonPlanDoc } from "@/components/ExportsDialogs/useExportLessonPlanDoc";
import { useExportLessonSlides } from "@/components/ExportsDialogs/useExportLessonSlides";
Expand All @@ -12,11 +14,11 @@ export function useDownloadView({
lessonPlan,
messages,
}: AilaPersistedChat) {
const exportProps = {
const exportProps: ExportsHookProps = {
onStart: () => null,
lesson: lessonPlan,
chatId: id,
messageId: messages.length,
messageId: getLastAssistantMessage(messages)?.id,
active: true,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ChatSection = ({
value,
}: {
objectKey: string;
value: unknown;
value: Record<string, unknown> | string | Array<unknown>;
}) => {
return (
<OakFlex $flexDirection="column">
Expand All @@ -29,12 +29,15 @@ const ChatSection = ({
$display={["none", "flex"]}
>
<ModifyButton
section={sectionTitle(objectKey)}
sectionContent={
lessonSectionTitlesAndMiniDescriptions[objectKey]?.description
}
sectionTitle={sectionTitle(objectKey)}
sectionPath={objectKey}
sectionValue={value}
/>
<FlagButton
sectionTitle={sectionTitle(objectKey)}
sectionPath={objectKey}
sectionValue={value}
/>
<FlagButton section={sectionTitle(objectKey)} />
</OakFlex>
</OakFlex>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useRef, useState } from "react";

import { getLastAssistantMessage } from "@oakai/aila/src/helpers/chat/getLastAssistantMessage";
import type { AilaUserFlagType } from "@oakai/db";
import { OakBox, OakP, OakRadioGroup } from "@oaknational/oak-components";
import styled from "styled-components";
Expand All @@ -21,7 +22,17 @@ const flagOptions = [

type FlagButtonOptions = typeof flagOptions;

const FlagButton = ({ section }: { section: string }) => {
type FlagButtonProps = {
sectionTitle: string;
sectionPath: string;
sectionValue: Record<string, unknown> | string | Array<unknown>;
};

const FlagButton = ({
sectionTitle,
sectionPath,
sectionValue,
}: FlagButtonProps) => {
const dropdownRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const [selectedRadio, setSelectedRadio] =
Expand All @@ -32,10 +43,9 @@ const FlagButton = ({ section }: { section: string }) => {
const chat = useLessonChat();

const { id, messages } = chat;
const assistantMessages = messages.filter((m) => m.role === "assistant");
const lastAssistantMessage = assistantMessages[assistantMessages.length - 1];
const lastAssistantMessage = getLastAssistantMessage(messages);

const { mutateAsync } = trpc.chat.appSessions.flagSection.useMutation();
const { mutateAsync } = trpc.chat.chatFeedback.flagSection.useMutation();

const flagSectionContent = async () => {
if (selectedRadio && lastAssistantMessage) {
Expand All @@ -44,6 +54,8 @@ const FlagButton = ({ section }: { section: string }) => {
messageId: lastAssistantMessage.id,
flagType: selectedRadio.enumValue,
userComment: userFeedbackText,
sectionPath,
sectionValue,
};
await mutateAsync(payload);
}
Expand All @@ -67,7 +79,7 @@ const FlagButton = ({ section }: { section: string }) => {
onClickActions={flagSectionContent}
setIsOpen={setIsOpen}
selectedRadio={selectedRadio}
title={`Flag issue with ${section.toLowerCase()}:`}
title={`Flag issue with ${sectionTitle.toLowerCase()}:`}
buttonText={"Send feedback"}
isOpen={isOpen}
dropdownRef={dropdownRef}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useRef, useState } from "react";

import { getLastAssistantMessage } from "@oakai/aila/src/helpers/chat/getLastAssistantMessage";
import type { AilaUserModificationAction } from "@oakai/db";
import { OakBox, OakP, OakRadioGroup } from "@oaknational/oak-components";
import { TextArea } from "@radix-ui/themes";
Expand All @@ -19,13 +20,17 @@ const modifyOptions = [
{ label: "Other", enumValue: "OTHER" },
] as const;

type ModifyButtonProps = {
sectionTitle: string;
sectionPath: string;
sectionValue: Record<string, unknown> | string | Array<unknown>;
};

const ModifyButton = ({
section,
sectionContent,
}: {
section: string;
sectionContent: string;
}) => {
sectionTitle,
sectionPath,
sectionValue,
}: ModifyButtonProps) => {
const dropdownRef = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const [userFeedbackText, setUserFeedbackText] = useState("");
Expand All @@ -37,18 +42,19 @@ const ModifyButton = ({

const { id, messages } = chat;

const { mutateAsync } = trpc.chat.appSessions.modifySection.useMutation();
const { mutateAsync } = trpc.chat.chatFeedback.modifySection.useMutation();

const assistantMessages = messages.filter((m) => m.role === "assistant");
const lastAssistantMessage = assistantMessages[assistantMessages.length - 1];
const lastAssistantMessage = getLastAssistantMessage(messages);

const recordUserModifySectionContent = async () => {
if (selectedRadio && lastAssistantMessage) {
const payload = {
chatId: id,
messageId: lastAssistantMessage.id,
textForMod: sectionContent,
sectionPath,
sectionValue,
action: selectedRadio.enumValue,
actionOtherText: userFeedbackText || null,
};
await mutateAsync(payload);
}
Expand All @@ -59,7 +65,7 @@ const ModifyButton = ({
) {
await Promise.all([
append({
content: `For the ${section}, ${option.label === "Other" ? userFeedbackText : option.label}`,
content: `For the ${sectionTitle}, ${option.label === "Other" ? userFeedbackText : option.label}`,
role: "user",
}),
recordUserModifySectionContent(),
Expand All @@ -80,7 +86,7 @@ const ModifyButton = ({
onClickActions={modifySection}
setIsOpen={setIsOpen}
selectedRadio={selectedRadio}
title={`Ask Aila to modify ${section.toLowerCase()}:`}
title={`Ask Aila to modify ${sectionTitle.toLowerCase()}:`}
buttonText={"Modify section"}
isOpen={isOpen}
dropdownRef={dropdownRef}
Expand All @@ -93,20 +99,18 @@ const ModifyButton = ({
>
{modifyOptions.map((option) => {
return (
<>
<SmallRadioButton
id={`${id}-modify-options-${option.enumValue}`}
key={`${id}-modify-options-${option.enumValue}`}
value={option.enumValue}
label={handleLabelText({
text: option.label,
section,
})}
onClick={() => {
setSelectedRadio(option);
}}
/>
</>
<SmallRadioButton
id={`${id}-modify-options-${option.enumValue}`}
key={`${id}-modify-options-${option.enumValue}`}
value={option.enumValue}
label={handleLabelText({
text: option.label,
section: sectionTitle,
})}
onClick={() => {
setSelectedRadio(option);
}}
/>
);
})}

Expand Down
12 changes: 12 additions & 0 deletions apps/nextjs/src/components/ExportsDialogs/exports.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { LessonDeepPartial } from "@oakai/exports";

export type ExportsHookProps<T = unknown> = T & {
onStart: () => void;
lesson: LessonDeepPartial;
chatId: string;
/**
* Message ID is of the last assistant message. It should never be undefined, but technically it can be.
*/
messageId: string | undefined;
active: boolean;
};
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
import { useEffect, useMemo, useState, useCallback } from "react";

import {
LessonDeepPartial,
exportSlidesFullLessonSchema,
} from "@oakai/exports/browser";
import { exportSlidesFullLessonSchema } from "@oakai/exports/browser";
import { LessonSlidesInputData } from "@oakai/exports/src/schema/input.schema";
import * as Sentry from "@sentry/nextjs";
import { useDebounce } from "@uidotdev/usehooks";
import { ZodError } from "zod";

import { trpc } from "@/utils/trpc";

import { ExportsHookProps } from "./exports.types";

export function useExportAdditionalMaterials({
onStart,
lesson,
active,
chatId,
messageId,
}: {
onStart: () => void;
lesson: LessonDeepPartial;
chatId: string;
messageId: number;
active: boolean;
}) {
}: ExportsHookProps) {
const [dialogOpen, setDialogOpen] = useState(false);
const query = trpc.exports.exportAdditionalMaterialsDoc.useMutation();

Expand Down Expand Up @@ -76,8 +69,18 @@ export function useExportAdditionalMaterials({
if (!active) {
return;
}
console.log("STARTING");

if (!messageId) {
Sentry.captureException(
new Error("Failed to start export: messageId is undefined"),
{
extra: {
chatId,
lesson,
},
},
);
return;
}
if (!debouncedParseResult?.success) {
Sentry.captureException(
new Error("Invalid lesson plan data in useExportAdditionalMaterials"),
Expand All @@ -92,7 +95,7 @@ export function useExportAdditionalMaterials({
query.mutate({
data: debouncedParseResult.data,
chatId,
messageId: messageId.toString(),
messageId,
});
onStart();
setDialogOpen(true);
Expand Down
29 changes: 17 additions & 12 deletions apps/nextjs/src/components/ExportsDialogs/useExportLessonPlanDoc.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
import { useCallback, useEffect, useMemo, useState } from "react";

import {
LessonDeepPartial,
exportDocLessonPlanSchema,
} from "@oakai/exports/browser";
import { exportDocLessonPlanSchema } from "@oakai/exports/browser";
import { LessonPlanDocInputData } from "@oakai/exports/src/schema/input.schema";
import * as Sentry from "@sentry/nextjs";
import { useDebounce } from "@uidotdev/usehooks";
import { ZodError } from "zod";

import { trpc } from "@/utils/trpc";

import { ExportsHookProps } from "./exports.types";

export function useExportLessonPlanDoc({
onStart,
lesson,
active,
chatId,
messageId,
}: {
onStart: () => void;
lesson: LessonDeepPartial;
chatId: string;
messageId: number;
active: boolean;
}) {
}: ExportsHookProps) {
const [dialogOpen, setDialogOpen] = useState(false);
const query = trpc.exports.exportLessonPlanDoc.useMutation();

Expand Down Expand Up @@ -75,6 +68,18 @@ export function useExportLessonPlanDoc({
if (!active) {
return;
}
if (!messageId) {
Sentry.captureException(
new Error("Failed to start export: messageId is undefined"),
{
extra: {
chatId,
lesson,
},
},
);
return;
}

if (!debouncedParseResult?.success) {
Sentry.captureException(
Expand All @@ -90,7 +95,7 @@ export function useExportLessonPlanDoc({
query.mutate({
data: debouncedParseResult.data,
chatId,
messageId: messageId.toString(),
messageId,
});
onStart();
setDialogOpen(true);
Expand Down
Loading
Loading