|
| 1 | +import SystemPromptTemplate from '../models/SystemPromptTemplate.js'; |
| 2 | + |
| 3 | +const OUTER_PROMPT = `Create a question distribution plan for a quiz. |
| 4 | +
|
| 5 | +Learning Objectives: |
| 6 | +{{learningObjectives}} |
| 7 | +
|
| 8 | +{{materialsContext}} |
| 9 | +
|
| 10 | +TASK: Distribute EXACTLY {{totalQuestions}} questions across the learning objectives. |
| 11 | +
|
| 12 | +{{innerPrompt}} |
| 13 | +
|
| 14 | +CRITICAL REQUIREMENTS: |
| 15 | +1. The sum of ALL counts MUST equal EXACTLY {{totalQuestions}} |
| 16 | +2. Distribute across ALL learning objectives proportionally |
| 17 | +3. Each item must have count >= 1 |
| 18 | +4. Return ONLY the JSON object below (no text, no markdown, no explanations) |
| 19 | +
|
| 20 | +{ |
| 21 | + "planItems": [ |
| 22 | + { "type": "multiple-choice", "learningObjectiveIndex": 0, "count": 5 }, |
| 23 | + { "type": "flashcard", "learningObjectiveIndex": 1, "count": 3 } |
| 24 | + ] |
| 25 | +}`; |
| 26 | + |
| 27 | +const TEMPLATES = [ |
| 28 | + { |
| 29 | + approach: 'support', |
| 30 | + outerPrompt: OUTER_PROMPT, |
| 31 | + innerPrompt: `Pedagogical Approach: Support Learning |
| 32 | +This approach emphasizes helping students memorize and understand key concepts through flashcards and summaries. |
| 33 | +
|
| 34 | +Question Type Rules: |
| 35 | +- ONLY use these types: flashcard, summary |
| 36 | +- Flashcards should be the MAJORITY (approximately 80-90%) |
| 37 | +- Summaries should be the MINORITY (approximately 10-20%) |
| 38 | +- Each learning objective should have AT MOST 1 summary question |
| 39 | +- Distribute flashcards evenly across all learning objectives |
| 40 | +
|
| 41 | +Design Guidelines: |
| 42 | +- Flashcards for key terms, definitions, and concepts |
| 43 | +- Summaries for broader understanding and synthesis`, |
| 44 | + questionTypeRules: { |
| 45 | + allowedTypes: ['flashcard', 'summary'], |
| 46 | + distribution: new Map([['flashcard', 0.85], ['summary', 0.15]]), |
| 47 | + maxPerLO: new Map([['summary', 1]]) |
| 48 | + }, |
| 49 | + description: 'Support Learning: Focus on memorization and understanding through flashcards and summaries', |
| 50 | + exampleOutput: 'Mostly flashcards (85%) with occasional summaries (15%), max 1 summary per LO', |
| 51 | + isActive: true |
| 52 | + }, |
| 53 | + { |
| 54 | + approach: 'assess', |
| 55 | + outerPrompt: OUTER_PROMPT, |
| 56 | + innerPrompt: `Pedagogical Approach: Assess Understanding |
| 57 | +This approach emphasizes evaluating student comprehension through multiple-choice and true/false questions. |
| 58 | +
|
| 59 | +Question Type Rules: |
| 60 | +- ONLY use these types: multiple-choice, true-false |
| 61 | +- Multiple-choice should be the MAJORITY (approximately 60-70%) |
| 62 | +- True/false should complement (approximately 30-40%) |
| 63 | +- Distribute both types across all learning objectives |
| 64 | +
|
| 65 | +Design Guidelines: |
| 66 | +- Multiple-choice for complex understanding and application |
| 67 | +- True/false for fundamental concepts and quick checks |
| 68 | +- Mix question types within each learning objective for variety`, |
| 69 | + questionTypeRules: { |
| 70 | + allowedTypes: ['multiple-choice', 'true-false'], |
| 71 | + distribution: new Map([['multiple-choice', 0.65], ['true-false', 0.35]]), |
| 72 | + maxPerLO: new Map() |
| 73 | + }, |
| 74 | + description: 'Assess Understanding: Evaluate comprehension with multiple-choice and true/false questions', |
| 75 | + exampleOutput: 'Mix of multiple-choice (65%) and true/false (35%), distributed across all LOs', |
| 76 | + isActive: true |
| 77 | + }, |
| 78 | + { |
| 79 | + approach: 'gamify', |
| 80 | + outerPrompt: OUTER_PROMPT, |
| 81 | + innerPrompt: `Pedagogical Approach: Gamify Learning |
| 82 | +This approach emphasizes creating engaging, game-like experiences through interactive question types. |
| 83 | +
|
| 84 | +Question Type Rules: |
| 85 | +- Use DIVERSE types: matching, ordering, cloze, discussion |
| 86 | +- DO NOT use: multiple-choice, true-false, flashcard, summary |
| 87 | +- Create a VARIED distribution - avoid having all questions of the same type |
| 88 | +- Each learning objective should have AT LEAST 2 different question types |
| 89 | +
|
| 90 | +Design Guidelines: |
| 91 | +- Matching for connecting concepts and relationships |
| 92 | +- Ordering for sequences, processes, and hierarchies |
| 93 | +- Cloze for fill-in-the-blank and context understanding |
| 94 | +- Discussion for critical thinking and analysis |
| 95 | +- Aim for visual variety and engagement |
| 96 | +- Distribute question types so no single type dominates`, |
| 97 | + questionTypeRules: { |
| 98 | + allowedTypes: ['matching', 'ordering', 'cloze', 'discussion'], |
| 99 | + distribution: new Map([ |
| 100 | + ['matching', 0.3], |
| 101 | + ['ordering', 0.25], |
| 102 | + ['cloze', 0.25], |
| 103 | + ['discussion', 0.2] |
| 104 | + ]), |
| 105 | + maxPerLO: new Map() |
| 106 | + }, |
| 107 | + description: 'Gamify Learning: Create engaging experiences with interactive question types', |
| 108 | + exampleOutput: 'Diverse mix of matching (30%), ordering (25%), cloze (25%), and discussion (20%)', |
| 109 | + isActive: true |
| 110 | + } |
| 111 | +]; |
| 112 | + |
| 113 | +/** |
| 114 | + * Initialize system prompt templates if they don't exist |
| 115 | + * This runs automatically on server startup |
| 116 | + */ |
| 117 | +export async function initializePromptTemplates() { |
| 118 | + try { |
| 119 | + // Check if templates already exist |
| 120 | + const existingCount = await SystemPromptTemplate.countDocuments(); |
| 121 | + |
| 122 | + if (existingCount >= 3) { |
| 123 | + console.log(`β
System prompt templates already initialized (${existingCount} templates found)`); |
| 124 | + return; |
| 125 | + } |
| 126 | + |
| 127 | + console.log('π§ Initializing system prompt templates...'); |
| 128 | + |
| 129 | + // Check which templates are missing |
| 130 | + const existingApproaches = await SystemPromptTemplate.find({}, 'approach').lean(); |
| 131 | + const existingApproachNames = new Set(existingApproaches.map(t => t.approach)); |
| 132 | + |
| 133 | + let createdCount = 0; |
| 134 | + for (const template of TEMPLATES) { |
| 135 | + if (!existingApproachNames.has(template.approach)) { |
| 136 | + await SystemPromptTemplate.create(template); |
| 137 | + console.log(`β
Created template for approach: ${template.approach}`); |
| 138 | + createdCount++; |
| 139 | + } |
| 140 | + } |
| 141 | + |
| 142 | + if (createdCount > 0) { |
| 143 | + console.log(`π Successfully initialized ${createdCount} system prompt template(s)`); |
| 144 | + } |
| 145 | + } catch (error) { |
| 146 | + console.error('β Error initializing system prompt templates:', error.message); |
| 147 | + console.error('π‘ You may need to run the initialization script manually:'); |
| 148 | + console.error(' node routes/create/scripts/initializeSystemPrompts.js'); |
| 149 | + } |
| 150 | +} |
| 151 | + |
| 152 | +export default { initializePromptTemplates }; |
0 commit comments