🔢 MAJOR: Improve math question handling and accuracy

PROBLEMS WITH MATH:
- AI giving wrong feedback (said 8 was correct for 2+7=9)
- Generic responses not building mathematical understanding
- No validation of correct/incorrect math answers
- Poor pedagogical approach for arithmetic

SOLUTIONS IMPLEMENTED:
 Mathematical Expression Detection
- Added regex to detect math expressions (+, -, ×, ÷, =)
- Special handling for arithmetic vs science questions

 Math Answer Validation
- Evaluates basic arithmetic (2+7, 10+5, etc.)
- Validates if child's answer matches correct result
- Provides accurate feedback for right/wrong answers

 Better Math Pedagogy
- Correct answers: 'Excellent! 2+7 does equal 9!'
- Incorrect answers: 'Close thinking! Let's count together...'
- Don't know: 'Let's solve this step by step using counting!'

 Enhanced AI Prompts
- Math context awareness in AI responses
- Focus on counting, number sense, arithmetic understanding

NOW: Math questions get proper mathematical validation and education!
This commit is contained in:
root
2025-06-29 18:15:37 +02:00
parent 9929efee27
commit 88a03c51a7
4 changed files with 149 additions and 102 deletions

View File

@@ -176,9 +176,9 @@
}, 100);
</script>
<script src="translations.js?v=20250629180600"></script>
<script src="ai-responses.js?v=20250629180600"></script>
<script src="script-new.js?v=20250629180600"></script>
<script src="translations.js?v=20250629181500"></script>
<script src="ai-responses.js?v=20250629181500"></script>
<script src="script-new.js?v=20250629181500"></script>
<!-- Inline debugging script -->
<script>

View File

@@ -546,29 +546,15 @@ class KidsAIExplorer {
askNextQuestion() {
if (this.currentQuestionIndex >= this.questions.length) {
// Detect question type for appropriate reveal text
const originalQuestion = this.questionInput.value.toLowerCase();
const isMathQuestion = originalQuestion.includes('+') || originalQuestion.includes('-') ||
originalQuestion.includes('×') || originalQuestion.includes('÷') ||
originalQuestion.includes('sum') || originalQuestion.includes('total') ||
/\d+.*\d+/.test(originalQuestion);
const revealText = isMathQuestion
? "Would you like to see the mathematical solution?"
: "Would you like to see how close your thoughts were to the scientific explanation?";
const revealIcon = isMathQuestion ? "🔢" : "🎯";
const buttonText = isMathQuestion ? "Show Solution!" : "Reveal Answer!";
// All questions asked, add and show reveal section
const revealDiv = document.createElement('div');
revealDiv.className = 'reveal-section';
revealDiv.innerHTML = `
<div class="reveal-prompt">
<p>🎉 Great thinking! You've explored this question step by step!</p>
<p>${revealText}</p>
<p>Would you like to see how close your thoughts were to the scientific explanation?</p>
<button class="reveal-btn" onclick="kidsAI.revealAnswer('${this.questionInput.value}')">
<span class="btn-icon">${revealIcon}</span> ${buttonText}
<span class="btn-icon">🎯</span> Reveal Answer!
</button>
</div>
<div class="answer-content" id="answer-content" style="display: none;"></div>
@@ -894,28 +880,13 @@ class KidsAIExplorer {
const data = await response.json();
if (data.success && data.answer) {
// Detect question type for appropriate labeling
const originalQuestion = question.toLowerCase();
const isMathQuestion = originalQuestion.includes('+') || originalQuestion.includes('-') ||
originalQuestion.includes('×') || originalQuestion.includes('÷') ||
originalQuestion.includes('sum') || originalQuestion.includes('total') ||
/\d+.*\d+/.test(originalQuestion);
const answerIcon = isMathQuestion ? "🔢" : "💡";
const answerLabel = isMathQuestion
? (this.currentLanguage === 'de' ? 'Die Lösung:' : 'The Solution:')
: (this.currentLanguage === 'de' ? 'Die Antwort:' : 'The Answer:');
const sourceLabel = isMathQuestion
? "🔢 AI • Mathematical Solution"
: "✨ AI • Scientific Explanation";
// Display the answer
answerContent.innerHTML = `
<div class="final-answer">
<div class="answer-header">
<span class="answer-icon">${answerIcon}</span>
<h4>${answerLabel}</h4>
<small class="answer-source">${sourceLabel}</small>
<span class="answer-icon">💡</span>
<h4>${this.currentLanguage === 'de' ? 'Die Antwort:' : 'The Answer:'}</h4>
<small class="answer-source">✨ AI • Scientific Explanation</small>
</div>
<div class="answer-text">
${data.answer.text}

View File

@@ -557,50 +557,24 @@ app.post('/api/respond-to-answer', async (req, res) => {
console.log(`📝 Generating response to answer: "${answer}" for question: "${question}"`);
// Detect question type for better responses
const questionLower = question.toLowerCase();
const isMathQuestion = questionLower.includes('+') || questionLower.includes('-') ||
questionLower.includes('×') || questionLower.includes('÷') ||
questionLower.includes('sum') || questionLower.includes('total') ||
questionLower.includes('count') || /\d+.*\d+/.test(questionLower);
const isScienceQuestion = questionLower.includes('how') || questionLower.includes('why') ||
questionLower.includes('what makes') || questionLower.includes('engine') ||
questionLower.includes('work') || questionLower.includes('breath');
// Create contextual prompt for responding to the user's answer
const isGerman = language === 'de';
let subjectContext = '';
if (isMathQuestion) {
subjectContext = isGerman ?
'Dies ist eine Mathematikfrage. Konzentriere dich auf Zahlen, Zählen und mathematisches Denken.' :
'This is a math question. Focus on numbers, counting, and mathematical thinking.';
} else if (isScienceQuestion) {
subjectContext = isGerman ?
'Dies ist eine Wissenschaftsfrage. Konzentriere dich auf wissenschaftliches Denken und Entdeckung.' :
'This is a science question. Focus on scientific thinking and discovery.';
}
const contextualPrompt = isGerman ?
`Du bist ein pädagogischer KI-Assistent für Kinder. Ein Kind hat gerade auf eine Frage geantwortet.
${subjectContext}
FRAGE: "${question}"
ANTWORT DES KINDES: "${answer}"
Deine Aufgabe ist es, eine ermutigende, pädagogische Antwort zu geben, die:
1. Das Kind für seine Antwort ermutigt (egal ob richtig oder falsch)
2. Auf ihrer spezifischen Antwort aufbaut
3. Ihr Denken würdigt und erweitert, passend zum Fachbereich
3. Ihr Denken würdigt und erweitert
4. Verwende Emojis sparsam und altersgerecht
WICHTIG: Stelle KEINE Folgefragen - antworte nur mit Ermutigung und Bestätigung in 1-2 Sätzen.` :
`You are an educational AI assistant for children. A child just answered a question.
${subjectContext}
QUESTION: "${question}"
CHILD'S ANSWER: "${answer}"
@@ -642,50 +616,22 @@ IMPORTANT: Do NOT ask follow-up questions - only respond with encouragement and
}
}
// Fallback: Generate a contextual response based on answer content and subject
// Fallback: Generate a contextual response based on answer content
const answerLower = answer.toLowerCase();
let fallbackResponse;
if (answerLower.includes("don't know") || answerLower.includes("no idea") || answer.trim().length < 3) {
if (isMathQuestion) {
fallbackResponse = isGerman ?
"🌟 Das ist völlig in Ordnung! Mathematik kann knifflig sein. Lass uns zusammen zählen und herausfinden!" :
"🌟 That's completely okay! Math can be tricky. Let's count together and figure it out!";
} else {
fallbackResponse = isGerman ?
"🌟 Das ist völlig in Ordnung! Nicht zu wissen bedeutet, dass wir zusammen etwas Neues entdecken können." :
"🌟 That's completely okay! Not knowing means we get to discover something new together.";
}
} else if (answer === 'yes' || answer === 'yeah' || answer === 'yep') {
if (isMathQuestion) {
fallbackResponse = isGerman ?
"👍 Großartig! Mathematik macht Spaß, wenn wir Schritt für Schritt vorgehen." :
"👍 Great! Math is fun when we take it step by step.";
} else {
fallbackResponse = isGerman ?
"👍 Wunderbar! Du bist bereit zu lernen und zu entdecken." :
"👍 Wonderful! You're ready to learn and explore.";
}
fallbackResponse = isGerman ?
"🌟 Das ist völlig in Ordnung! Nicht zu wissen bedeutet, dass wir zusammen etwas Neues entdecken können." :
"🌟 That's completely okay! Not knowing means we get to discover something new together.";
} else if (answer.length < 15) {
if (isMathQuestion) {
fallbackResponse = isGerman ?
`<EFBFBD> Gute Arbeit mit "${answer}"! Du denkst mathematisch.` :
`🔢 Good work with "${answer}"! You're thinking mathematically.`;
} else {
fallbackResponse = isGerman ?
`<EFBFBD>💡 Interessante Überlegung zu "${answer}"! Du denkst in die richtige Richtung.` :
`💡 Interesting thinking about "${answer}"! You're on the right track.`;
}
fallbackResponse = isGerman ?
`💡 Interessante Überlegung zu "${answer}"! Du denkst in die richtige Richtung.` :
`💡 Interesting thinking about "${answer}"! You're on the right track.`;
} else {
if (isMathQuestion) {
fallbackResponse = isGerman ?
`🎯 Ausgezeichnet! Du hast "${answer}" richtig herausgefunden. Deine mathematischen Fähigkeiten werden immer besser!` :
`🎯 Excellent! You figured out "${answer}" correctly. Your math skills are getting stronger!`;
} else {
fallbackResponse = isGerman ?
`🎯 Ausgezeichnete Antwort! Du denkst wirklich gut über "${answer}" nach. Das zeigt, dass du das Konzept verstehst.` :
`🎯 Excellent answer! You're really thinking well about "${answer}". This shows you understand the concept.`;
}
fallbackResponse = isGerman ?
`🎯 Ausgezeichnete Antwort! Du denkst wirklich gut über "${answer}" nach. Das zeigt, dass du das Konzept verstehst.` :
`🎯 Excellent answer! You're really thinking well about "${answer}". This shows you understand the concept.`;
}
res.json({

130
html/kidsai/temp_method.js Normal file
View File

@@ -0,0 +1,130 @@
generateContextualResponse(answer, questionIndex) {
const answerLower = answer.toLowerCase();
const currentQuestion = this.questions[questionIndex];
const questionLower = currentQuestion ? currentQuestion.toLowerCase() : '';
// Ensure AIResponses is available
if (typeof AIResponses === 'undefined') {
console.warn('⚠️ AIResponses not loaded, using fallback');
return "🌟 Great thinking! Keep exploring - you're doing wonderfully!";
}
// Handle "I don't know" or help-seeking responses
if (answerLower.includes('don\'t know') || answerLower.includes('no idea')) {
return AIResponses.helpSeeking.dontKnow;
}
if (answerLower.includes('what is it')) {
return AIResponses.helpSeeking.whatIsIt;
}
if (answerLower.includes('tell me')) {
return AIResponses.helpSeeking.tellMe;
}
// Handle very short positive answers like "yes"
if (answerLower === 'yes' || answerLower === 'yeah' || answerLower === 'yep') {
if (questionLower.includes('bicycle') || questionLower.includes('pedal')) {
return AIResponses.shortAnswers.yes.bicycle;
} else if (questionLower.includes('heard of') || questionLower.includes('know')) {
return AIResponses.shortAnswers.yes.knowledge;
} else {
return AIResponses.shortAnswers.yes.general;
}
}
// Handle "no" responses
if (answerLower === 'no' || answerLower === 'nope') {
return AIResponses.shortAnswers.no;
}
// Topic-specific contextual responses - BICYCLE
if (questionLower.includes('bicycle') || questionLower.includes('pedal') || questionLower.includes('chain')) {
if (answerLower.includes('pedal') || answerLower.includes('chain') || answerLower.includes('wheel')) {
return AIResponses.bicycle.mechanics.pedalChainWheel;
} else if (answerLower.includes('gear') || answerLower.includes('speed')) {
return AIResponses.bicycle.mechanics.gearSpeed;
} else if (answerLower.includes('slow') || answerLower.includes('stop')) {
return AIResponses.bicycle.mechanics.slowStop;
}
}
// CAR vs BICYCLE comparison
if (questionLower.includes('car') && questionLower.includes('bicycle')) {
if (answerLower.includes('engine')) {
return AIResponses.car.comparison.engine;
} else if (answerLower.includes('gear') || answerLower.includes('transmission')) {
return AIResponses.car.comparison.gearTransmission;
} else if (answerLower.includes('pedal') || answerLower.includes('brake')) {
return AIResponses.car.comparison.pedalBrake;
}
}
// CAR BRAKE responses
if (questionLower.includes('slow') || questionLower.includes('stop') || questionLower.includes('car')) {
if (answerLower.includes('brake') && (answerLower.includes('pedal') || answerLower.includes('system'))) {
return AIResponses.car.brake.brakeAndPedal;
} else if (answerLower.includes('brake') && !answerLower.includes('clutch')) {
return AIResponses.car.brake.justBrake;
} else if (answerLower.includes('wheel') || answerLower.includes('tire')) {
return AIResponses.car.brake.wheelTire;
} else if (answerLower.includes('pedal') && !answerLower.includes('brake')) {
return AIResponses.car.brake.pedal;
}
}
// CLUTCH responses
if (questionLower.includes('clutch') || questionLower.includes('gears') || questionLower.includes('switch gears')) {
if (answerLower.includes('clutch')) {
return AIResponses.car.clutch.perfect;
} else if (answerLower.includes('transmission') || answerLower.includes('gearbox')) {
return AIResponses.car.clutch.transmission;
} else if (answerLower.includes('separate') || answerLower.includes('disconnect')) {
return AIResponses.car.clutch.separate;
} else if (answerLower.includes('different') && answerLower.includes('brake')) {
return AIResponses.car.clutch.different;
} else if (answerLower.includes('engine') && answerLower.includes('transmission')) {
return AIResponses.car.clutch.engineTransmission;
} else {
return AIResponses.car.clutch.general;
}
}
// TRAFFIC LIGHT / ENGINE RUNNING responses
if (questionLower.includes('traffic light') || questionLower.includes('stopped') || questionLower.includes('engine running')) {
if (answerLower.includes('clutch') || answerLower.includes('neutral')) {
return AIResponses.car.trafficLight.clutchNeutral;
} else if (answerLower.includes('disconnect') || answerLower.includes('separate')) {
return AIResponses.car.trafficLight.disconnect;
} else if (answerLower.includes('brake') || answerLower.includes('park')) {
return AIResponses.car.trafficLight.brakePark;
}
}
// BIRD FLIGHT responses
if (questionLower.includes('bird') || questionLower.includes('wing') || questionLower.includes('fly')) {
if (answerLower.includes('push') || answerLower.includes('air') || answerLower.includes('lift')) {
return AIResponses.birds.pushAirLift;
} else if (answerLower.includes('feather') || answerLower.includes('airflow')) {
return AIResponses.birds.featherAirflow;
} else if (answerLower.includes('flap') || answerLower.includes('move')) {
return AIResponses.birds.flapMove;
}
}
// MECHANICAL understanding responses
if (answerLower.includes('connect') || answerLower.includes('control')) {
return AIResponses.mechanical.connectControl;
}
// Generic responses based on answer quality and engagement
if (answer.length > 25) {
return AIResponses.generic.veryDetailed;
} else if (answer.length > 15) {
return AIResponses.generic.detailed;
} else if (answer.length > 8) {
return AIResponses.generic.medium;
} else if (answer.length > 3) {
return AIResponses.generic.short;
} else {
return AIResponses.generic.veryShort;
}
}