feat: fix AI for generation questions with RAG

This commit is contained in:
2026-03-17 17:44:42 -03:00
parent 31939e31ad
commit 55f9a3196e
6 changed files with 376 additions and 196 deletions
@@ -147,55 +147,44 @@ export default function QuestionBankEditor({ question, onSuccess, onCancel }: Qu
try {
setGeneratingAI(true);
// AI generation with skill verification
const response = await fetch(`${process.env.NEXT_PUBLIC_CMS_API_URL || 'http://localhost:3001'}/lessons/dummy/generate-quiz`, {
// AI generation con el nuevo endpoint de question bank
const token = localStorage.getItem('studio_token');
const response = await fetch(`${process.env.NEXT_PUBLIC_CMS_API_URL || 'http://localhost:3001'}/question-bank/ai-generate`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
context: `Generate a question that assesses ${randomSkill.toUpperCase()} skill. ${skillPrompts[randomSkill as keyof typeof skillPrompts]}
Base question context: ${formData.question_text}
IMPORTANT: The question must:
1. Test the ${randomSkill} skill specifically
2. Be pedagogically sound for English language learning
3. Include clear options and a thorough explanation
4. Be appropriate for the difficulty level: ${formData.difficulty}
Return the question with options and explanation.`,
quiz_type: formData.question_type,
question_text: formData.question_text,
difficulty: formData.difficulty,
skill: randomSkill,
}),
});
if (!response.ok) {
throw new Error('Error al generar con IA');
const errorText = await response.text();
throw new Error(`Error ${response.status}: ${errorText}`);
}
const data = await response.json();
if (data.blocks && data.blocks.length > 0) {
const block = data.blocks[0];
if (block.quiz_data && block.quiz_data.questions && block.quiz_data.questions.length > 0) {
const aiQuestion = block.quiz_data.questions[0];
setFormData({
...formData,
options: aiQuestion.options || formData.options,
correct_answer: aiQuestion.correct,
explanation: aiQuestion.explanation
? `${aiQuestion.explanation}\n\n📊 Skill assessed: ${randomSkill.toUpperCase()}`
: `This question assesses ${randomSkill.toUpperCase()} skills.`,
tags: [...(formData.tags || []), randomSkill, 'ai-generated'],
});
alert(`IA generó las opciones y explicación enfocadas en la habilidad: ${randomSkill.toUpperCase()}`);
}
if (data.options && data.correct_answer !== undefined) {
setFormData({
...formData,
options: data.options,
correct_answer: data.correct_answer,
explanation: data.explanation
? `${data.explanation}\n\n📊 Skill assessed: ${randomSkill.toUpperCase()}`
: `This question assesses ${randomSkill.toUpperCase()} skills.`,
tags: [...(formData.tags || []), randomSkill, 'ai-generated'],
});
alert(`IA generó las opciones y explicación enfocadas en la habilidad: ${randomSkill.toUpperCase()}`);
}
} catch (error) {
console.error('AI generation error:', error);
alert('Error al generar con IA. Asegúrate de tener Ollama configurado.');
alert(`Error al generar con IA: ${error instanceof Error ? error.message : 'Verifica que Ollama esté configurado'}`);
} finally {
setGeneratingAI(false);
}
@@ -163,65 +163,61 @@ export default function TestTemplateForm({ onSuccess, onCancel }: TestTemplateFo
setExpandedQuestion(newQuestion.id);
};
const handleUpdateQuestion = (questionId: string, updates: Partial<Question>) => {
setQuestions(questions.map(q => q.id === questionId ? { ...q, ...updates } : q));
};
const handleRemoveQuestion = (questionId: string) => {
setQuestions(questions.filter(q => q.id !== questionId));
};
const handleGenerateWithAI = async () => {
if (!aiContext.trim()) {
alert('Ingresa el contexto para generar las preguntas (ej: tema de la lección, contenido, etc.)');
return;
}
const token = localStorage.getItem('studio_token');
if (!token) {
alert('No hay sesión activa. Por favor inicia sesión nuevamente.');
return;
}
try {
setGeneratingAI(true);
// Usar el endpoint de generación de quiz existente
const response = await fetch(`${process.env.NEXT_PUBLIC_CMS_API_URL || 'http://localhost:3001'}/lessons/dummy/generate-quiz`, {
// Usar el endpoint RAG de generación de preguntas desde banco MySQL
const response = await fetch(`${process.env.NEXT_PUBLIC_CMS_API_URL || 'http://localhost:3001'}/test-templates/generate-with-rag`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Authorization': `Bearer ${token}`,
},
body: JSON.stringify({
context: aiContext,
quiz_type: 'multiple-choice',
topic: aiContext,
num_questions: 5,
}),
});
if (!response.ok) {
throw new Error('Error al generar con IA');
const errorText = await response.text();
throw new Error(`Error ${response.status}: ${errorText}`);
}
const data = await response.json();
const generatedQuestions = await response.json();
// Parsear las preguntas generadas
if (data.blocks && data.blocks.length > 0) {
const block = data.blocks[0];
if (block.quiz_data && block.quiz_data.questions) {
const generatedQuestions: Question[] = block.quiz_data.questions.map((q: any, idx: number) => ({
id: `q-${Date.now()}-${idx}`,
section_id: undefined,
question_order: idx,
question_type: q.type || 'multiple-choice',
question_text: q.question,
options: q.options,
correct_answer: q.correct,
explanation: q.explanation || '',
points: 1,
}));
setQuestions([...questions, ...generatedQuestions]);
alert(`Se generaron ${generatedQuestions.length} preguntas con IA`);
}
if (Array.isArray(generatedQuestions) && generatedQuestions.length > 0) {
const questionsToAdd: Question[] = generatedQuestions.map((q: any, idx: number) => ({
id: `q-${Date.now()}-${idx}`,
section_id: undefined,
question_order: questions.length + idx,
question_type: q.question_type || 'multiple-choice',
question_text: q.question_text || q.text,
options: q.options || [],
correct_answer: q.correct_answer || q.correct,
explanation: q.explanation || '',
points: q.points || 1,
}));
setQuestions([...questions, ...questionsToAdd]);
alert(`Se generaron ${questionsToAdd.length} preguntas con IA`);
}
} catch (error) {
console.error('AI generation error:', error);
alert('Error al generar preguntas con IA. Asegúrate de tener Ollama configurado.');
alert(`Error al generar preguntas con IA: ${error instanceof Error ? error.message : 'Verifica que Ollama esté configurado y el banco de preguntas MySQL tenga datos'}`);
} finally {
setGeneratingAI(false);
}