From fa39e3b74e8611840ea597e858d97abc64005a48 Mon Sep 17 00:00:00 2001 From: "Hans Gabriel B. Daduya" Date: Sun, 17 Dec 2023 15:25:18 +0800 Subject: [PATCH] Improve test generation for long reviewer content (#288) --- apps/expo/app.config.ts | 2 +- apps/expo/src/forms/CreateTestForm/index.tsx | 16 ++++++++--- .../src/screens/create-reviewer/index.tsx | 2 +- packages/api/src/functions/gptHandlers.ts | 3 +-- .../src/functions/randomQuestionsHandlers.ts | 27 +++++++++++++++---- packages/api/src/router/gptApi.ts | 4 +-- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/apps/expo/app.config.ts b/apps/expo/app.config.ts index 70412894..6321773c 100644 --- a/apps/expo/app.config.ts +++ b/apps/expo/app.config.ts @@ -3,7 +3,7 @@ import { ExpoConfig, ConfigContext } from "@expo/config"; const CLERK_PUBLISHABLE_KEY = "pk_test_Z3Jvd2luZy1kb2Jlcm1hbi04OC5jbGVyay5hY2NvdW50cy5kZXYk"; const SERVER_URL = "https://test-trek-prod.vercel.app"; -const SERVER_ENV: "development" | "production" = "production"; +const SERVER_ENV: "development" | "production" = "development"; const defineConfig = (_ctx: ConfigContext): ExpoConfig => ({ name: "TestTrek", diff --git a/apps/expo/src/forms/CreateTestForm/index.tsx b/apps/expo/src/forms/CreateTestForm/index.tsx index 0f1d2a72..d8702d94 100644 --- a/apps/expo/src/forms/CreateTestForm/index.tsx +++ b/apps/expo/src/forms/CreateTestForm/index.tsx @@ -312,7 +312,10 @@ const CreateTestForm: FC = ({ setBottomSheetOpen(false); }; - const createMultipleQuestions = (inputMessage: string) => { + const createMultipleQuestions = ( + inputMessage: string, + messageType: "batch-messages" | "generate-topics", + ) => { const numOfQuestions = numberOfQuestionOptions.find((option) => option.isSelected)?.value ?? 5; @@ -330,7 +333,7 @@ const CreateTestForm: FC = ({ { message: inputMessage, numOfQuestions: numOfQuestions, - messageType: "batch-messages", + messageType, }, { onSuccess: (data) => { @@ -796,7 +799,10 @@ const CreateTestForm: FC = ({ setIsSidebarOpen(true); } else { const reviewerContent = selectedReviewer.content; - createMultipleQuestions(extractHighlightedText(reviewerContent)); + createMultipleQuestions( + extractHighlightedText(reviewerContent), + "batch-messages", + ); } }} /> @@ -806,7 +812,9 @@ const CreateTestForm: FC = ({ aiQuestion={aiQuestion} setAiQuestion={setAiQuestion} isGenerating={isGenerating} - handleQuestionGeneration={() => createMultipleQuestions(aiQuestion)} + handleQuestionGeneration={() => + createMultipleQuestions(aiQuestion, "generate-topics") + } handleClose={() => { setAiQuestion(""); setErrorInAIQuestion(false); diff --git a/apps/expo/src/screens/create-reviewer/index.tsx b/apps/expo/src/screens/create-reviewer/index.tsx index 7dcd4b25..b0072d2e 100644 --- a/apps/expo/src/screens/create-reviewer/index.tsx +++ b/apps/expo/src/screens/create-reviewer/index.tsx @@ -369,7 +369,7 @@ export const CreateReviewerScreen = ({ { message: inputMessage, numOfQuestions: numOfQuestions, - messageType: "generate-topics", + messageType: "batch-messages", }, { onSuccess: (data) => { diff --git a/packages/api/src/functions/gptHandlers.ts b/packages/api/src/functions/gptHandlers.ts index 22a52daa..574d4fdf 100644 --- a/packages/api/src/functions/gptHandlers.ts +++ b/packages/api/src/functions/gptHandlers.ts @@ -104,8 +104,7 @@ export const generateTopicsPrompt = ( message: string, numTopics?: number, ): string => { - return `Create a list of topics (should be of length ${numTopics} topics) based on: "${message}". Format as: - [Topic 1] | [Topic 2] | [Topic 3] | ... | [Topic ${numTopics}]`; + return `Create a list of topics (should be of length ${numTopics} topics) based on: "${message}". Format as: [Topic 1] | [Topic 2] | [Topic 3] | ... | [Topic ${numTopics}]`; }; export const generatePromptForType = ( diff --git a/packages/api/src/functions/randomQuestionsHandlers.ts b/packages/api/src/functions/randomQuestionsHandlers.ts index 58c8b14d..275a6802 100644 --- a/packages/api/src/functions/randomQuestionsHandlers.ts +++ b/packages/api/src/functions/randomQuestionsHandlers.ts @@ -1,6 +1,5 @@ import { generateChoicesPrompt, timeAndPointsPrompt } from "./gptHandlers"; import { fetchGPT } from "../services/gptApiHandlers"; -import { chunk } from "lodash"; import { questionsSchema } from "@acme/schema/src/question"; import { parseMultipleChoiceResponse, @@ -77,11 +76,29 @@ export const parseTopicsList = (topicsList: string): string[] => { export const divideStringIntoChunks = ( string: string, - chunkSize = 3000, + chunkSize = 1000, ): string[] => { - const chunks = chunk(string.split("\n"), chunkSize); + const sentences = string.split(/\.(?!\d)/); // Split sentences based on period not followed by a digit - return chunks.map((chunk) => chunk.join("\n")); + let currentBatch = ""; + const batches: string[] = []; + + for (const sentence of sentences) { + const potentialBatch = currentBatch + sentence + "."; + + if (potentialBatch.length <= chunkSize) { + currentBatch = potentialBatch; + } else { + batches.push(currentBatch.trim()); + currentBatch = sentence + "."; + } + } + + if (currentBatch.trim() !== "") { + batches.push(currentBatch.trim()); + } + + return batches; }; export const generateCombinedQuestionPrompts = ( @@ -189,7 +206,7 @@ export const generateCombinedQuestions = async ( } if (Array.isArray(messages)) { const processedQuestions = await Promise.all( - messages.map(async (_, index) => { + Array.from({ length: arrayLength }).map(async (_, index) => { let retryCount = 0; let finalProcessedQuestions: ParsedQuestion[] = []; let hasOneAnswer = false; diff --git a/packages/api/src/router/gptApi.ts b/packages/api/src/router/gptApi.ts index e956a3df..efb5c881 100644 --- a/packages/api/src/router/gptApi.ts +++ b/packages/api/src/router/gptApi.ts @@ -129,7 +129,7 @@ export const gptApiRouter = router({ let topics: string[] = []; if (messageType === "generate-topics") { - const topicsPrompt = generateTopicsPrompt(message); + const topicsPrompt = generateTopicsPrompt(message, numOfQuestions); const topicsResponse = await fetchGPT(topicsPrompt); @@ -147,7 +147,7 @@ export const gptApiRouter = router({ while (remainingQuestionsLength > 0) { const remainingQuestions = await generateCombinedQuestions( - message, + !messageType ? message : topics, remainingQuestionsLength, 1, );