Gauntlet-Incept MCP
by Birdsmith
- src
- services
/**
* Question Service
*
* This file implements the core functionality for the Question API endpoints:
* - tagQuestion: Identifies subject, grade, standard, lesson, and difficulty of a given question
* - gradeQuestion: Evaluates a tagged question against quality standards
* - generateQuestion: Creates questions based on specified tags or example questions
*/
// Import utilities and models
const { callLLM } = require('../utils/llmUtils');
const { connectToCCC } = require('../utils/cccUtils');
const { saveToQTI } = require('../utils/qtiUtils');
const { measureAccuracy } = require('../utils/testHarness');
/**
* Tag a question with subject, grade, standard, lesson, and difficulty
*
* @param {Object} question - The question to tag
* @returns {Object} The tags for the question
*/
async function tagQuestion(question) {
try {
// TODO: Implement actual tagging logic using LLM
console.log('Tagging question:', question.substring(0, 50) + '...');
// Placeholder implementation
const tags = {
subject: 'math',
grade: '6',
standard: 'CCSS.Math.6.NS.1',
lesson: 'Division of Fractions',
difficulty: 2
};
return tags;
} catch (error) {
console.error('Error in tagQuestion:', error);
throw new Error('Failed to tag question: ' + error.message);
}
}
/**
* Grade a tagged question against quality standards
*
* @param {Object} question - The question to grade
* @param {Object} tags - The tags for the question
* @returns {Object} The grading result
*/
async function gradeQuestion(question, tags) {
try {
// TODO: Implement actual grading logic using LLM
console.log('Grading question:', question.substring(0, 50) + '...');
console.log('With tags:', tags);
// Placeholder implementation
const gradeResult = {
pass: true,
scorecard: {
consistentWithArticle: true,
appropriateCategorizaton: true,
allPartsPresent: true,
accurateCorrectAnswer: true,
plausibleDistractors: true,
clearExplanations: true,
gradeAppropriateLanguage: true,
grammaticallyCorrect: true,
properlyFormatted: true
},
feedback: 'This question meets all quality standards.'
};
return gradeResult;
} catch (error) {
console.error('Error in gradeQuestion:', error);
throw new Error('Failed to grade question: ' + error.message);
}
}
/**
* Generate a question based on tags or an example question
*
* @param {Object} tags - The tags for the question to generate
* @param {Object} exampleQuestion - An example question to base the generation on
* @returns {Object} The generated question
*/
async function generateQuestion(tags, exampleQuestion) {
try {
// TODO: Implement actual generation logic using LLM
console.log('Generating question with tags:', tags);
if (exampleQuestion) {
console.log('Based on example:', exampleQuestion.substring(0, 50) + '...');
}
// Placeholder implementation
let attempts = 0;
let generatedQuestion;
let gradeResult;
do {
attempts++;
console.log(`Generation attempt ${attempts}`);
// Generate question
generatedQuestion = await generateQuestionInternal(tags, exampleQuestion);
// Grade the generated question
gradeResult = await gradeQuestion(generatedQuestion, tags);
} while (!gradeResult.pass && attempts < 3);
if (!gradeResult.pass) {
throw new Error('Failed to generate a question that meets quality standards after 3 attempts');
}
// Save the generated question to QTI
await saveToQTI(generatedQuestion, tags, 'question');
return {
question: generatedQuestion,
tags: tags,
gradeResult: gradeResult
};
} catch (error) {
console.error('Error in generateQuestion:', error);
throw new Error('Failed to generate question: ' + error.message);
}
}
/**
* Internal function to generate a question without quality control
*
* @param {Object} tags - The tags for the question to generate
* @param {Object} exampleQuestion - An example question to base the generation on
* @returns {Object} The generated question
*/
async function generateQuestionInternal(tags, exampleQuestion) {
// TODO: Implement actual generation logic using LLM
// Placeholder implementation
const questionTemplate = `
What is the result of dividing the fraction 3/4 by 1/2?
A) 3/8
B) 6/4
C) 3/2
D) 1 1/2
Correct Answer: C) 3/2
Explanation for wrong answers:
A) 3/8 - This is incorrect because you multiplied the fractions instead of dividing.
B) 6/4 - This is incorrect because you added the fractions instead of dividing.
D) 1 1/2 - This is incorrect because you converted the answer to a mixed number, but the value is correct.
Solution:
To divide fractions, multiply by the reciprocal of the divisor.
3/4 ÷ 1/2 = 3/4 × 2/1 = 6/4 = 3/2
`;
return questionTemplate;
}
module.exports = {
tagQuestion,
gradeQuestion,
generateQuestion
};