Spaces:
Sleeping
Sleeping
| import { openai } from '@ai-sdk/openai'; | |
| import { generateObject } from 'ai'; | |
| import { z } from 'zod'; | |
| // Standardized question schema (same as generate-question) | |
| const QuestionSchema = z.object({ | |
| Question: z.string().describe('The question text'), | |
| Options: z.object({ | |
| A: z.string(), | |
| B: z.string(), | |
| C: z.string(), | |
| D: z.string(), | |
| }).describe('Multiple choice options'), | |
| Answer: z.enum(['A', 'B', 'C', 'D']).describe('The correct answer option'), | |
| }); | |
| export async function POST(req: Request) { | |
| try { | |
| const body = await req.json(); | |
| const { question, direction, sourceArticle } = body as { | |
| question: { | |
| id: string; | |
| type: string; | |
| displayName?: string; | |
| stem: string; | |
| content: { | |
| Question: string; | |
| Options: { A: string; B: string; C: string; D: string }; | |
| Answer: 'A' | 'B' | 'C' | 'D'; | |
| }; | |
| points: number; | |
| createdAt: string | Date; | |
| }; | |
| direction: 'increase' | 'decrease'; | |
| sourceArticle?: string; | |
| }; | |
| if (!question || !direction || !['increase', 'decrease'].includes(direction)) { | |
| return Response.json( | |
| { error: 'Invalid request. Require { question, direction: "increase"|"decrease" }' }, | |
| { status: 400 } | |
| ); | |
| } | |
| const difficultyInstruction = direction === 'increase' | |
| ? 'Increase the difficulty slightly. You may use more complex vocabulary, require deeper inference, include more subtle distractors, or require multi-step reasoning. Avoid changing the topic.' | |
| : 'Decrease the difficulty slightly. Use simpler vocabulary, make distractors more distinguishable, and reduce inference load while keeping the same topic.'; | |
| const systemConstraints = ` | |
| You are given a multiple-choice question with exactly 4 options (A, B, C, D) and one correct answer. ${difficultyInstruction} | |
| Hard constraints: | |
| - Preserve the context/topic and core learning objective. | |
| - Keep exactly 4 options, labeled A, B, C, D. | |
| - Ensure only one option is correct and that it matches the Answer field. | |
| - Keep the format, return ONLY JSON matching the provided schema. No markdown. | |
| `; | |
| const contextArticle = sourceArticle ? `\nSource Article (optional):\n${sourceArticle}` : ''; | |
| const inputQuestion = `Current Question JSON:\n${JSON.stringify( | |
| { | |
| stem: question.stem, | |
| content: question.content, | |
| type: question.type, | |
| displayName: question.displayName, | |
| }, | |
| null, | |
| 2 | |
| )}`; | |
| const prompt = `${systemConstraints} | |
| ${contextArticle} | |
| Rewrite the question to the target difficulty. Output JSON with fields Question, Options{A,B,C,D}, Answer. | |
| ${inputQuestion}`; | |
| const result = await generateObject({ | |
| model: openai('gpt-4o-mini'), | |
| schema: QuestionSchema, | |
| prompt, | |
| }); | |
| return Response.json({ | |
| type: question.type, | |
| displayName: question.displayName, | |
| stem: result.object.Question, | |
| content: { | |
| Question: result.object.Question, | |
| Options: result.object.Options, | |
| Answer: result.object.Answer, | |
| }, | |
| points: question.points ?? 1, | |
| createdAt: new Date().toISOString(), | |
| }); | |
| } catch (error) { | |
| console.error('Error adjusting difficulty:', error); | |
| return Response.json({ error: 'Failed to adjust difficulty' }, { status: 500 }); | |
| } | |
| } | |