Add definition detection: When child asks 'what is X?' provide simple explanations instead of more questions. Prevents infinite question loops.
This commit is contained in:
@@ -426,6 +426,12 @@ class KidsAIExplorer {
|
||||
|
||||
const isOnlyWhyQuestion = answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?';
|
||||
|
||||
// Check if child is asking for a definition or explanation
|
||||
const isAskingForDefinition = answerLower.startsWith('was ist') || answerLower.startsWith('what is') ||
|
||||
answerLower.includes('was bedeutet') || answerLower.includes('what does') ||
|
||||
answerLower.includes('was heißt') || answerLower.includes('what means') ||
|
||||
(answerLower.includes('?') && (answerLower.includes('ist ein') || answerLower.includes('is a')));
|
||||
|
||||
// Check if it's a substantial answer (has thinking beyond just "don't know")
|
||||
const hasSubstantialThinking = answer.length > 15 && (
|
||||
answerLower.includes('vielleicht') || answerLower.includes('maybe') || answerLower.includes('könnte') || answerLower.includes('could') ||
|
||||
@@ -435,11 +441,32 @@ class KidsAIExplorer {
|
||||
);
|
||||
|
||||
// Pure "don't know" without additional thinking
|
||||
const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking;
|
||||
const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking && !isAskingForDefinition;
|
||||
|
||||
let response;
|
||||
|
||||
if (isNegative || isPureDontKnow) {
|
||||
if (isAskingForDefinition) {
|
||||
// Child is asking for a definition - provide simple, concrete explanation
|
||||
console.log('📤 Sending definition request to /api/respond-to-answer');
|
||||
|
||||
response = await fetch('/api/respond-to-answer', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
answer: answer,
|
||||
question: currentQuestion,
|
||||
originalTopic: originalQuestion,
|
||||
language: this.currentLanguage,
|
||||
context: 'definition_request',
|
||||
stepIndex: questionIndex,
|
||||
instructions: this.currentLanguage === 'de'
|
||||
? 'Das Kind fragt nach einer Definition. Gib eine EINFACHE, konkrete Erklärung für Kinder. Verwende alltägliche Vergleiche und lade zum Ausprobieren ein. Zum Beispiel: "Ein Prisma ist wie ein spezielles Glas, das Licht in Regenbogenfarben zerlegt. Du kannst das mit einem Wasserglas am Fenster ausprobieren!" Keine weiteren Fragen stellen.'
|
||||
: 'The child is asking for a definition. Give a SIMPLE, concrete explanation for children. Use everyday comparisons and invite experimentation. For example: "A prism is like a special glass that breaks light into rainbow colors. You can try this with a water glass at the window!" Don\'t ask more questions.'
|
||||
})
|
||||
});
|
||||
} else if (isNegative || isPureDontKnow) {
|
||||
// For pure "no" or "don't know" answers without thinking, get Socratic guidance questions
|
||||
console.log('📤 Sending guidance request to /api/ask for Socratic questioning');
|
||||
|
||||
@@ -583,6 +610,12 @@ class KidsAIExplorer {
|
||||
|
||||
const isOnlyWhyQuestion = answerLower === 'warum' || answerLower === 'why' || answerLower === 'warum?' || answerLower === 'why?';
|
||||
|
||||
// Check if child is asking for a definition or explanation
|
||||
const isAskingForDefinition = answerLower.startsWith('was ist') || answerLower.startsWith('what is') ||
|
||||
answerLower.includes('was bedeutet') || answerLower.includes('what does') ||
|
||||
answerLower.includes('was heißt') || answerLower.includes('what means') ||
|
||||
(answerLower.includes('?') && (answerLower.includes('ist ein') || answerLower.includes('is a')));
|
||||
|
||||
// Check if it's a substantial answer (has thinking beyond just "don't know")
|
||||
const hasSubstantialThinking = answer.length > 15 && (
|
||||
answerLower.includes('vielleicht') || answerLower.includes('maybe') || answerLower.includes('könnte') || answerLower.includes('could') ||
|
||||
@@ -592,17 +625,38 @@ class KidsAIExplorer {
|
||||
);
|
||||
|
||||
// Pure "don't know" without additional thinking
|
||||
const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking;
|
||||
const isPureDontKnow = (hasDontKnowPhrase || isOnlyWhyQuestion || answer.trim().length < 5) && !hasSubstantialThinking && !isAskingForDefinition;
|
||||
|
||||
let response;
|
||||
|
||||
if (isNegative || isPureDontKnow) {
|
||||
if (isAskingForDefinition) {
|
||||
// Child is asking for a definition - provide simple, concrete explanation
|
||||
console.log('📤 Sending definition request to /api/respond-to-answer');
|
||||
|
||||
response = await fetch('/api/respond-to-answer', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
answer: answer,
|
||||
question: currentQuestion,
|
||||
originalTopic: originalQuestion,
|
||||
language: this.currentLanguage,
|
||||
context: 'definition_request',
|
||||
stepIndex: questionIndex,
|
||||
instructions: this.currentLanguage === 'de'
|
||||
? 'Das Kind fragt nach einer Definition. Gib eine EINFACHE, konkrete Erklärung für Kinder. Verwende alltägliche Vergleiche und lade zum Ausprobieren ein. Zum Beispiel: "Ein Prisma ist wie ein spezielles Glas, das Licht in Regenbogenfarben zerlegt. Du kannst das mit einem Wasserglas am Fenster ausprobieren!" Keine weiteren Fragen stellen.'
|
||||
: 'The child is asking for a definition. Give a SIMPLE, concrete explanation for children. Use everyday comparisons and invite experimentation. For example: "A prism is like a special glass that breaks light into rainbow colors. You can try this with a water glass at the window!" Don\'t ask more questions.'
|
||||
})
|
||||
});
|
||||
} else if (isNegative || isPureDontKnow) {
|
||||
// For pure "no" or "don't know" answers without thinking, get Socratic guidance questions
|
||||
console.log('📤 Sending guidance request to /api/ask for Socratic questioning');
|
||||
|
||||
const guidancePrompt = this.currentLanguage === 'de'
|
||||
? `Ein Kind hat "${answer}" geantwortet auf die Frage "${currentQuestion}" über das Thema "${originalQuestion}". Das Kind weiß die Antwort nicht und braucht einfachere Grundlagen. Gib KEINE weiteren abstrakten Fragen! Stattdessen: 1) Beschreibe eine einfache Beobachtung, die das Kind machen kann (z.B. "Hast du schon mal Licht durch ein Glas Wasser gesehen?") 2) Lade zum praktischen Ausprobieren ein 3) Baue auf dem auf, was das Kind bereits kennt. Verwende konkrete, sichtbare Beispiele statt abstrakter Konzepte.`
|
||||
: `A child answered "${answer}" to the question "${currentQuestion}" about the topic "${originalQuestion}". The child doesn't know and needs simpler foundations. Give NO more abstract questions! Instead: 1) Describe a simple observation the child can make (e.g. "Have you ever seen light through a glass of water?") 2) Invite practical experimentation 3) Build on what the child already knows. Use concrete, visible examples instead of abstract concepts.`;
|
||||
? `Ein Kind hat "${answer}" geantwortet auf die Frage "${currentQuestion}". Das Kind weiß die Antwort nicht. Führe es durch 2-3 aufbauende Socratic Fragen zur Entdeckung, ohne direkte Antworten zu geben. Beginne mit einfachen Beobachtungen, die das Kind kennt.`
|
||||
: `A child answered "${answer}" to the question "${currentQuestion}". The child doesn't know the answer. Guide them through 2-3 building Socratic questions to discovery without giving direct answers. Start with simple observations the child would know.`;
|
||||
|
||||
response = await fetch('/api/ask', {
|
||||
method: 'POST',
|
||||
@@ -626,7 +680,6 @@ class KidsAIExplorer {
|
||||
body: JSON.stringify({
|
||||
answer: answer,
|
||||
question: currentQuestion,
|
||||
originalTopic: originalQuestion,
|
||||
language: this.currentLanguage,
|
||||
stepIndex: questionIndex
|
||||
})
|
||||
|
||||
@@ -546,7 +546,7 @@ function getFallbackAnswer(question, language) {
|
||||
// API endpoint for responding to user answers contextually
|
||||
app.post('/api/respond-to-answer', async (req, res) => {
|
||||
try {
|
||||
const { answer, question, language = 'en', stepIndex } = req.body;
|
||||
const { answer, question, language = 'en', stepIndex, context, instructions } = req.body;
|
||||
|
||||
if (!answer || !question) {
|
||||
return res.status(400).json({
|
||||
@@ -555,9 +555,70 @@ app.post('/api/respond-to-answer', async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
console.log(`📝 Generating response to answer: "${answer}" for question: "${question}"`);
|
||||
console.log(`📝 Generating response to answer: "${answer}" for question: "${question}" with context: ${context}`);
|
||||
|
||||
// Create contextual prompt for responding to the user's answer
|
||||
// Handle definition requests specially
|
||||
if (context === 'definition_request' && instructions) {
|
||||
// For definition requests, use the provided instructions
|
||||
const definitionPrompt = `${instructions}
|
||||
|
||||
CHILD'S QUESTION: "${answer}"
|
||||
CONTEXT: The child asked this while learning about: "${question}"
|
||||
|
||||
Provide a simple, concrete explanation for children using everyday comparisons and practical examples.`;
|
||||
|
||||
// Try OpenAI first for definitions
|
||||
if (process.env.OPENAI_API_KEY) {
|
||||
try {
|
||||
const completion = await openai.chat.completions.create({
|
||||
model: "gpt-3.5-turbo",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: definitionPrompt
|
||||
}
|
||||
],
|
||||
max_tokens: 300,
|
||||
temperature: 0.6
|
||||
});
|
||||
|
||||
const aiResponse = completion.choices[0]?.message?.content?.trim();
|
||||
|
||||
if (aiResponse && aiResponse.length > 10) {
|
||||
console.log('✅ OpenAI definition response generated successfully');
|
||||
return res.json({
|
||||
success: true,
|
||||
response: aiResponse,
|
||||
source: 'OpenAI GPT-3.5 (Definition)'
|
||||
});
|
||||
}
|
||||
} catch (openaiError) {
|
||||
console.log('❌ OpenAI error for definition:', openaiError.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for definitions
|
||||
const answerLower = answer.toLowerCase();
|
||||
let definitionFallback;
|
||||
|
||||
if (answerLower.includes('prisma') || answerLower.includes('prism')) {
|
||||
definitionFallback = language === 'de' ?
|
||||
'🔍 Ein Prisma ist wie ein magisches Glas, das weißes Licht in alle Regenbogenfarben zerlegt! Du kannst das selbst ausprobieren: Halte ein Glas Wasser ins Sonnenlicht und schau, welche Farben entstehen!' :
|
||||
'🔍 A prism is like a magic glass that breaks white light into all the rainbow colors! You can try this yourself: hold a glass of water in the sunlight and see what colors appear!';
|
||||
} else {
|
||||
definitionFallback = language === 'de' ?
|
||||
'🤔 Das ist eine tolle Frage! Lass uns das zusammen erforschen...' :
|
||||
'🤔 That\'s a great question! Let\'s explore this together...';
|
||||
}
|
||||
|
||||
return res.json({
|
||||
success: true,
|
||||
response: definitionFallback,
|
||||
source: 'Fallback Definition'
|
||||
});
|
||||
}
|
||||
|
||||
// Create contextual prompt for responding to the user's answer (existing logic)
|
||||
const isGerman = language === 'de';
|
||||
|
||||
const contextualPrompt = isGerman ?
|
||||
|
||||
Reference in New Issue
Block a user