Spaces:
Running
Running
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
|