wiki-project / src /utils /ai-enhanced-wikimedia.ts
Nagi15's picture
Add codebase
fcb5a67
import { WikimediaAPI } from './wikimedia-api';
import { AIProviderManager } from './ai-providers';
import { StudyPlan, StudyTopic } from '../types';
export class AIEnhancedWikimedia extends WikimediaAPI {
static async generateEnhancedStudyPlan(topic: string, difficulty: 'beginner' | 'intermediate' | 'advanced' = 'beginner'): Promise<StudyPlan> {
try {
// First, get base content from Wikimedia
const searchResults = await this.searchMultipleProjects(topic, ['wikipedia', 'wikibooks', 'wikiversity'], 15);
if (searchResults.length === 0) {
throw new Error('No content found for this topic');
}
// Check if AI is available and configured
let useAI = false;
try {
const config = AIProviderManager.getConfig();
const provider = AIProviderManager.getProviderById(config.selectedProvider);
if (provider) {
// Check if API key is required and available
if (provider.requiresApiKey) {
useAI = !!(config.apiKeys && config.apiKeys[config.selectedProvider]);
} else {
useAI = true; // Local providers don't need API keys
}
// Test connection if we think AI should be available
if (useAI) {
useAI = await AIProviderManager.testConnection(config.selectedProvider);
}
}
} catch (error) {
console.log('AI availability check failed, using fallback');
useAI = false;
}
if (useAI) {
// Use AI to enhance the study plan
const aiPrompt = `Create a comprehensive study plan for "${topic}" at ${difficulty} level.
Available resources from Wikimedia:
${searchResults.slice(0, 8).map((result, i) => `${i + 1}. ${result.title} - ${result.snippet.substring(0, 100)}...`).join('\n')}
Please create a structured study plan with:
1. A compelling title and description
2. 5-8 learning topics in logical order
3. For each topic, provide:
- Clear learning objectives
- Estimated study time
- Key concepts to focus on
Format as JSON with this structure:
{
"title": "Study Plan Title",
"description": "Brief description",
"topics": [
{
"title": "Topic Title",
"description": "What students will learn",
"objectives": ["objective1", "objective2"],
"estimatedTime": "2 hours",
"keyPoints": ["point1", "point2"]
}
]
}`;
try {
const aiResponse = await AIProviderManager.generateText(aiPrompt, {
maxTokens: 2000,
temperature: 0.7,
systemPrompt: 'You are an expert educational content creator. Create well-structured, engaging study plans that help students learn effectively.'
});
// Parse AI response
let aiPlan;
try {
// Extract JSON from AI response
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) {
aiPlan = JSON.parse(jsonMatch[0]);
} else {
throw new Error('No valid JSON found in AI response');
}
} catch (parseError) {
console.log('Failed to parse AI response, using fallback');
return await this.generateStudyPlan(topic, difficulty);
}
// Create enhanced study plan with real Wikimedia resources
const enhancedTopics: StudyTopic[] = [];
for (let i = 0; i < Math.min(aiPlan.topics.length, searchResults.length); i++) {
const aiTopic = aiPlan.topics[i];
const resource = searchResults[i];
// Get detailed content for each topic
let detailedContent = resource.snippet;
try {
const fullContent = await this.getPageSnippet(resource.title, resource.project);
if (fullContent && fullContent !== 'No description available') {
detailedContent = fullContent;
}
} catch (error) {
console.log(`Could not get detailed content for ${resource.title}`);
}
enhancedTopics.push({
id: `topic-${Date.now()}-${i}`,
title: aiTopic.title || resource.title,
description: aiTopic.description || detailedContent.substring(0, 200) + '...',
content: detailedContent,
completed: false,
estimatedTime: aiTopic.estimatedTime || `${Math.ceil(Math.random() * 2 + 1)} hours`,
resources: [
{
title: resource.title,
url: resource.url,
type: 'article' as const,
project: resource.project
}
]
});
}
const studyPlan: StudyPlan = {
id: `ai-plan-${Date.now()}`,
title: aiPlan.title || `${topic} Study Plan`,
description: aiPlan.description || `AI-enhanced ${difficulty} level study plan for ${topic}`,
difficulty,
estimatedTime: this.estimateStudyTime(enhancedTopics.length, difficulty),
created: new Date().toISOString(),
topics: enhancedTopics
};
return studyPlan;
} catch (aiError) {
console.log('AI enhancement failed, using fallback method:', aiError);
return await this.generateStudyPlan(topic, difficulty);
}
} else {
// AI not available, use standard method
return await this.generateStudyPlan(topic, difficulty);
}
} catch (error) {
console.error('Enhanced study plan generation failed:', error);
// Fallback to original method
return await this.generateStudyPlan(topic, difficulty);
}
}
static async generateQuizFromContent(content: string, title: string): Promise<any> {
// Check AI availability first
let useAI = false;
try {
const config = AIProviderManager.getConfig();
const provider = AIProviderManager.getProviderById(config.selectedProvider);
if (provider) {
if (provider.requiresApiKey) {
useAI = !!(config.apiKeys && config.apiKeys[config.selectedProvider]);
} else {
useAI = true;
}
if (useAI) {
useAI = await AIProviderManager.testConnection(config.selectedProvider);
}
}
} catch (error) {
useAI = false;
}
if (!useAI) {
return this.generateFallbackQuiz(title);
}
const aiPrompt = `Create a quiz based on this content about "${title}":
${content.substring(0, 2000)}
Generate 5 multiple-choice questions that test understanding of key concepts. Format as JSON:
{
"questions": [
{
"question": "Question text",
"options": ["Option A", "Option B", "Option C", "Option D"],
"correct": 0,
"explanation": "Why this answer is correct"
}
]
}`;
try {
const aiResponse = await AIProviderManager.generateText(aiPrompt, {
maxTokens: 1500,
temperature: 0.5,
systemPrompt: 'You are an expert quiz creator. Create challenging but fair questions that test real understanding.'
});
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const quiz = JSON.parse(jsonMatch[0]);
return {
type: 'quiz',
title: `Quiz: ${title}`,
questions: quiz.questions
};
}
} catch (error) {
console.error('AI quiz generation failed:', error);
}
// Fallback to rule-based quiz generation
return this.generateFallbackQuiz(title);
}
static async generateSummaryFromContent(content: string, title: string): Promise<any> {
// Check AI availability
let useAI = false;
try {
const config = AIProviderManager.getConfig();
const provider = AIProviderManager.getProviderById(config.selectedProvider);
if (provider) {
if (provider.requiresApiKey) {
useAI = !!(config.apiKeys && config.apiKeys[config.selectedProvider]);
} else {
useAI = true;
}
if (useAI) {
useAI = await AIProviderManager.testConnection(config.selectedProvider);
}
}
} catch (error) {
useAI = false;
}
if (!useAI) {
return this.generateFallbackSummary(content, title);
}
const aiPrompt = `Summarize this content about "${title}" in a clear, educational way:
${content.substring(0, 3000)}
Create:
1. A concise summary (2-3 paragraphs)
2. 5-7 key points that capture the most important information
Format as JSON:
{
"summary": "Main summary text",
"keyPoints": ["Point 1", "Point 2", ...]
}`;
try {
const aiResponse = await AIProviderManager.generateText(aiPrompt, {
maxTokens: 1000,
temperature: 0.3,
systemPrompt: 'You are an expert at creating clear, educational summaries that help students understand complex topics.'
});
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const summary = JSON.parse(jsonMatch[0]);
return {
type: 'summary',
title: `Summary: ${title}`,
content: summary.summary,
keyPoints: summary.keyPoints
};
}
} catch (error) {
console.error('AI summary generation failed:', error);
}
// Fallback to rule-based summary
return this.generateFallbackSummary(content, title);
}
static async generateStudyOutline(content: string, title: string): Promise<any> {
// Check AI availability
let useAI = false;
try {
const config = AIProviderManager.getConfig();
const provider = AIProviderManager.getProviderById(config.selectedProvider);
if (provider) {
if (provider.requiresApiKey) {
useAI = !!(config.apiKeys && config.apiKeys[config.selectedProvider]);
} else {
useAI = true;
}
if (useAI) {
useAI = await AIProviderManager.testConnection(config.selectedProvider);
}
}
} catch (error) {
useAI = false;
}
if (!useAI) {
return this.generateFallbackOutline(title);
}
const aiPrompt = `Create a detailed study outline for "${title}" based on this content:
${content.substring(0, 2500)}
Organize into 4-6 main sections with subsections. Format as JSON:
{
"sections": [
{
"title": "Section Title",
"points": ["Point 1", "Point 2", "Point 3"]
}
]
}`;
try {
const aiResponse = await AIProviderManager.generateText(aiPrompt, {
maxTokens: 1200,
temperature: 0.4,
systemPrompt: 'You are an expert at creating structured study outlines that help students organize their learning.'
});
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const outline = JSON.parse(jsonMatch[0]);
return {
type: 'outline',
title: `Study Outline: ${title}`,
sections: outline.sections
};
}
} catch (error) {
console.error('AI outline generation failed:', error);
}
// Fallback to rule-based outline
return this.generateFallbackOutline(title);
}
static async generateFlashcards(content: string, title: string): Promise<any> {
// Check AI availability
let useAI = false;
try {
const config = AIProviderManager.getConfig();
const provider = AIProviderManager.getProviderById(config.selectedProvider);
if (provider) {
if (provider.requiresApiKey) {
useAI = !!(config.apiKeys && config.apiKeys[config.selectedProvider]);
} else {
useAI = true;
}
if (useAI) {
useAI = await AIProviderManager.testConnection(config.selectedProvider);
}
}
} catch (error) {
useAI = false;
}
if (!useAI) {
return this.generateFallbackFlashcards(title);
}
const aiPrompt = `Create flashcards for studying "${title}" based on this content:
${content.substring(0, 2000)}
Generate 6-8 flashcards with questions and answers. Format as JSON:
{
"cards": [
{
"front": "Question or term",
"back": "Answer or definition"
}
]
}`;
try {
const aiResponse = await AIProviderManager.generateText(aiPrompt, {
maxTokens: 1000,
temperature: 0.5,
systemPrompt: 'You are an expert at creating effective flashcards that help with memorization and understanding.'
});
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/);
if (jsonMatch) {
const flashcards = JSON.parse(jsonMatch[0]);
return {
type: 'flashcards',
title: `Flashcards: ${title}`,
cards: flashcards.cards
};
}
} catch (error) {
console.error('AI flashcard generation failed:', error);
}
// Fallback to rule-based flashcards
return this.generateFallbackFlashcards(title);
}
// Fallback methods (existing rule-based generation)
private static generateFallbackQuiz(title: string) {
const questions = [
{
question: `What is the main topic discussed in the article about ${title}?`,
options: [
`The fundamental concepts and principles of ${title}`,
`The historical development of ${title}`,
`The practical applications of ${title}`,
`The criticism and controversies surrounding ${title}`
],
correct: 0,
explanation: 'This question tests basic comprehension of the main topic.'
}
];
return {
type: 'quiz',
title: `Quiz: ${title}`,
questions
};
}
private static generateFallbackSummary(content: string, title: string) {
const sentences = content.split('.').filter(s => s.trim().length > 20);
const keySentences = sentences.slice(0, 5);
return {
type: 'summary',
title: `Summary: ${title}`,
content: keySentences.join('. ') + '.',
keyPoints: sentences.slice(5, 10).map(s => s.trim()).filter(s => s.length > 0)
};
}
private static generateFallbackOutline(title: string) {
return {
type: 'outline',
title: `Study Outline: ${title}`,
sections: [
{
title: 'Introduction',
points: [
`Overview and definition of ${title}`,
'Historical context and background',
'Key terminology and concepts'
]
},
{
title: 'Main Concepts',
points: [
'Core principles and theories',
'Important characteristics and features',
'Fundamental mechanisms and processes'
]
}
]
};
}
private static generateFallbackFlashcards(title: string) {
const cards = [
{
front: `What is ${title}?`,
back: `${title} is a comprehensive topic that encompasses various concepts, principles, and applications within its field of study.`
},
{
front: 'Key characteristics',
back: `The main features include fundamental principles, practical applications, and significant impact on related areas.`
}
];
return {
type: 'flashcards',
title: `Flashcards: ${title}`,
cards
};
}
}