Spaces:
Sleeping
Sleeping
fix: restore working chat and contextualization logic
Browse files- Add missing generateContextualization method to aiService.js
- Update clozeGameEngine to call correct contextualization method
- Fix critical issue where chat was revealing answers by passing target word to AI
- Update conversationManager to use sentence with blanks instead of revealing word
- Ensure concise contextualization with single sentence output
- src/aiService.js +55 -0
- src/clozeGameEngine.js +2 -3
- src/conversationManager.js +8 -5
src/aiService.js
CHANGED
|
@@ -277,6 +277,61 @@ Passage: "${passage}"`
|
|
| 277 |
}
|
| 278 |
}
|
| 279 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
async getContextualization(title, author, passage) {
|
| 281 |
console.log('getContextualization called for:', title, 'by', author);
|
| 282 |
|
|
|
|
| 277 |
}
|
| 278 |
}
|
| 279 |
|
| 280 |
+
async generateContextualization(title, author) {
|
| 281 |
+
console.log('generateContextualization called for:', title, 'by', author);
|
| 282 |
+
|
| 283 |
+
// Check for API key at runtime
|
| 284 |
+
const currentKey = this.getApiKey();
|
| 285 |
+
if (currentKey && !this.apiKey) {
|
| 286 |
+
this.apiKey = currentKey;
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
console.log('API key available for contextualization:', !!this.apiKey);
|
| 290 |
+
|
| 291 |
+
if (!this.apiKey) {
|
| 292 |
+
console.log('No API key, returning fallback contextualization');
|
| 293 |
+
return `π Practice with classic literature from ${author}'s "${title}"`;
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
try {
|
| 297 |
+
const response = await fetch(this.apiUrl, {
|
| 298 |
+
method: 'POST',
|
| 299 |
+
headers: {
|
| 300 |
+
'Content-Type': 'application/json',
|
| 301 |
+
'Authorization': `Bearer ${this.apiKey}`,
|
| 302 |
+
'HTTP-Referer': window.location.origin,
|
| 303 |
+
'X-Title': 'Cloze Reader'
|
| 304 |
+
},
|
| 305 |
+
body: JSON.stringify({
|
| 306 |
+
model: this.model,
|
| 307 |
+
messages: [{
|
| 308 |
+
role: 'system',
|
| 309 |
+
content: 'You are a literary expert. Provide exactly 1 short sentence about this classic work. Be factual and concise. No exaggerative language.'
|
| 310 |
+
}, {
|
| 311 |
+
role: 'user',
|
| 312 |
+
content: `Describe "${title}" by ${author} in one factual sentence.`
|
| 313 |
+
}],
|
| 314 |
+
max_tokens: 50,
|
| 315 |
+
temperature: 0.2
|
| 316 |
+
})
|
| 317 |
+
});
|
| 318 |
+
|
| 319 |
+
if (!response.ok) {
|
| 320 |
+
const errorText = await response.text();
|
| 321 |
+
console.error('Contextualization API error:', response.status, errorText);
|
| 322 |
+
throw new Error(`API request failed: ${response.status}`);
|
| 323 |
+
}
|
| 324 |
+
|
| 325 |
+
const data = await response.json();
|
| 326 |
+
const content = data.choices[0].message.content.trim();
|
| 327 |
+
console.log('Contextualization received:', content);
|
| 328 |
+
return content;
|
| 329 |
+
} catch (error) {
|
| 330 |
+
console.error('Error getting contextualization:', error);
|
| 331 |
+
return `π Practice with classic literature from ${author}'s "${title}"`;
|
| 332 |
+
}
|
| 333 |
+
}
|
| 334 |
+
|
| 335 |
async getContextualization(title, author, passage) {
|
| 336 |
console.log('getContextualization called for:', title, 'by', author);
|
| 337 |
|
src/clozeGameEngine.js
CHANGED
|
@@ -333,10 +333,9 @@ class ClozeGame {
|
|
| 333 |
async generateContextualization() {
|
| 334 |
// Always use AI for contextualization
|
| 335 |
try {
|
| 336 |
-
this.contextualization = await aiService.
|
| 337 |
this.currentBook.title,
|
| 338 |
-
this.currentBook.author
|
| 339 |
-
this.originalText.substring(0, 200) // Pass first 200 chars of passage
|
| 340 |
);
|
| 341 |
return this.contextualization;
|
| 342 |
} catch (error) {
|
|
|
|
| 333 |
async generateContextualization() {
|
| 334 |
// Always use AI for contextualization
|
| 335 |
try {
|
| 336 |
+
this.contextualization = await aiService.generateContextualization(
|
| 337 |
this.currentBook.title,
|
| 338 |
+
this.currentBook.author
|
|
|
|
| 339 |
);
|
| 340 |
return this.contextualization;
|
| 341 |
} catch (error) {
|
src/conversationManager.js
CHANGED
|
@@ -74,12 +74,15 @@ class ChatService {
|
|
| 74 |
const bookTitle = context.bookTitle;
|
| 75 |
const author = context.author;
|
| 76 |
|
|
|
|
|
|
|
|
|
|
| 77 |
try {
|
| 78 |
-
// Use the enhanced contextual hint generation
|
| 79 |
const aiResponse = await this.aiService.generateContextualHint(
|
| 80 |
questionType,
|
| 81 |
-
|
| 82 |
-
|
| 83 |
bookTitle,
|
| 84 |
author
|
| 85 |
);
|
|
@@ -91,8 +94,8 @@ class ChatService {
|
|
| 91 |
console.warn('AI response failed:', error);
|
| 92 |
}
|
| 93 |
|
| 94 |
-
// Fallback - return enhanced fallback response
|
| 95 |
-
return this.aiService.getEnhancedFallback(questionType,
|
| 96 |
}
|
| 97 |
|
| 98 |
// Build focused prompt for specific question types with level awareness
|
|
|
|
| 74 |
const bookTitle = context.bookTitle;
|
| 75 |
const author = context.author;
|
| 76 |
|
| 77 |
+
// Create sentence with blank instead of revealing the word
|
| 78 |
+
const sentenceWithBlank = sentence.replace(new RegExp(`\\b${word}\\b`, 'gi'), '____');
|
| 79 |
+
|
| 80 |
try {
|
| 81 |
+
// Use the enhanced contextual hint generation WITHOUT revealing the target word
|
| 82 |
const aiResponse = await this.aiService.generateContextualHint(
|
| 83 |
questionType,
|
| 84 |
+
'____', // Don't pass the actual word
|
| 85 |
+
sentenceWithBlank,
|
| 86 |
bookTitle,
|
| 87 |
author
|
| 88 |
);
|
|
|
|
| 94 |
console.warn('AI response failed:', error);
|
| 95 |
}
|
| 96 |
|
| 97 |
+
// Fallback - return enhanced fallback response without revealing word
|
| 98 |
+
return this.aiService.getEnhancedFallback(questionType, '____', sentenceWithBlank, bookTitle);
|
| 99 |
}
|
| 100 |
|
| 101 |
// Build focused prompt for specific question types with level awareness
|