Skip to main content
Glama
enhanced-composition-generator.ts16 kB
/** * Enhanced Composition Generator for Browser Automation * Generates rich educational compositions based on EuConquisto Composer patterns * @version 2.0.0 * @created 2025-07-02 */ export interface CompositionElement { id: string; type: string; content_title: string | null; padding_top?: number; padding_bottom?: number; [key: string]: any; } export interface CompositionData { composition: { id: string; title: string; description: string; author: string; created: string; version: string; metadata?: { disciplina: string; serie: string; duracao_estimada: string; tags: string[]; [key: string]: any; }; elements: CompositionElement[]; }; } export class EnhancedCompositionGenerator { /** * Generate a complete educational composition from a prompt */ generateComposition( prompt: string, subject: string = "Ciências", gradeLevel: string = "7º ano", customTitle?: string ): CompositionData { const timestamp = Date.now(); const title = customTitle || this.extractTitle(prompt, subject); const elements = this.generateElements(prompt, subject, gradeLevel); return { composition: { id: `composition-${timestamp}`, title: title, description: `Composição educacional interativa sobre ${subject} para ${gradeLevel}`, author: "Sistema Inteligente EuConquisto", created: new Date().toISOString().split('T')[0], version: "2.0.0", metadata: { disciplina: subject, serie: gradeLevel, duracao_estimada: this.estimateDuration(elements), tags: this.generateTags(prompt, subject) }, elements: elements } }; } /** * Extract or generate an appropriate title from the prompt */ private extractTitle(prompt: string, subject: string): string { const promptLower = prompt.toLowerCase(); // Science topics if (promptLower.includes('fotossíntese')) { return 'Fotossíntese: Como as Plantas Produzem Alimento'; } if (promptLower.includes('célula')) { return 'A Célula: Unidade Básica da Vida'; } if (promptLower.includes('sistema solar')) { return 'Sistema Solar: Nossa Vizinhança Cósmica'; } // Math topics if (promptLower.includes('fração') || promptLower.includes('frações')) { return 'Frações: Dividindo e Compartilhando'; } if (promptLower.includes('equação') || promptLower.includes('equações')) { return 'Equações: Resolvendo Problemas Matemáticos'; } if (promptLower.includes('geometria')) { return 'Geometria: Formas e Espaços'; } // History topics if (promptLower.includes('independência')) { return 'Independência do Brasil: Nossa História'; } if (promptLower.includes('descobrimento')) { return 'O Descobrimento do Brasil'; } // Default: extract main topic const mainTopic = this.extractMainTopic(prompt); return `${mainTopic}: Aprendendo de Forma Interativa`; } /** * Generate appropriate elements based on the prompt and subject */ private generateElements(prompt: string, subject: string, gradeLevel: string): CompositionElement[] { const elements: CompositionElement[] = []; const timestamp = Date.now(); let elementCounter = 1; // 1. Header element (always present) elements.push(this.createHeaderElement(elementCounter++, subject, gradeLevel)); // 2. Introduction text elements.push(this.createIntroductionElement(elementCounter++, prompt, subject)); // 3. Main content elements based on analysis const contentElements = this.analyzeAndGenerateContent(prompt, subject, elementCounter); elements.push(...contentElements); elementCounter += contentElements.length; // 4. Interactive elements based on learning goals const interactiveElements = this.generateInteractiveElements(prompt, subject, elementCounter); elements.push(...interactiveElements); return elements; } /** * Create header element */ private createHeaderElement(id: number, subject: string, gradeLevel: string): CompositionElement { const subjectColors: Record<string, string> = { 'ciências': '#4CAF50', 'matemática': '#2196F3', 'português': '#FF9800', 'história': '#9C27B0', 'geografia': '#00BCD4', 'geral': '#607D8B' }; const primaryColor = subjectColors[subject.toLowerCase()] || subjectColors['geral']; return { id: `head-${id}`, type: "head-1", content_title: null, primary_color: "#FFFFFF", secondary_color: primaryColor, category: `<p>${subject.toUpperCase()} - ${gradeLevel}</p>`, background_image: "https://images.unsplash.com/photo-1557804506-669a67965ba0?w=1920&h=400&fit=crop", avatar: "https://ui-avatars.com/api/?name=Professor&background=" + primaryColor.substring(1) + "&color=fff&size=120", avatar_border_color: primaryColor, author_name: "<p>Professor(a) Virtual</p>", author_office: `<p>Especialista em ${subject}</p>`, show_category: true, show_author_name: true, show_divider: true }; } /** * Create introduction text element */ private createIntroductionElement(id: number, prompt: string, subject: string): CompositionElement { const topic = this.extractMainTopic(prompt); const introText = ` <h2>Bem-vindo à nossa aula!</h2> <p>Hoje vamos explorar <strong>${topic}</strong> de forma interativa e divertida. Esta composição foi criada especialmente para você aprender de maneira envolvente e eficaz.</p> <p>Ao longo desta aula, você vai:</p> <ul> <li>Compreender os conceitos fundamentais</li> <li>Explorar exemplos práticos</li> <li>Testar seus conhecimentos com atividades interativas</li> </ul>`; return { id: `text-${id}`, type: "text-2", content_title: "Introdução", padding_top: 35, padding_bottom: 35, background_color: "#FFFFFF", text: introText, text_align: "justify", font_size: 16, line_height: 1.6 }; } /** * Analyze prompt and generate appropriate content elements */ private analyzeAndGenerateContent(prompt: string, subject: string, startId: number): CompositionElement[] { const elements: CompositionElement[] = []; const promptLower = prompt.toLowerCase(); let currentId = startId; // Main content text elements.push({ id: `text-${currentId++}`, type: "text-1", content_title: null, padding_top: 20, padding_bottom: 20, background_color: "#FFFFFF", text: this.generateMainContent(prompt, subject) }); // Add visual elements if appropriate if (this.shouldIncludeVisuals(prompt)) { elements.push({ id: `image-${currentId++}`, type: "image-1", content_title: "Ilustração Explicativa", padding_top: 20, padding_bottom: 20, image: this.selectAppropriateImage(prompt, subject), image_max_width: 760, caption: "<p>Visualização do conceito apresentado</p>" }); } // Add video if topic benefits from demonstration if (this.shouldIncludeVideo(prompt)) { elements.push({ id: `video-${currentId++}`, type: "video-1", content_title: "Vídeo Explicativo", padding_top: 20, padding_bottom: 20, video: "https://www.youtube.com/embed/dQw4w9WgXcQ", show_controls: true, autoplay: false }); } return elements; } /** * Generate interactive elements based on learning goals */ private generateInteractiveElements(prompt: string, subject: string, startId: number): CompositionElement[] { const elements: CompositionElement[] = []; const promptLower = prompt.toLowerCase(); let currentId = startId; // Always include at least one interactive element if (promptLower.includes('memoriz') || promptLower.includes('decor')) { // Flashcards for memorization elements.push(this.createFlashcardsElement(currentId++, prompt, subject)); } // Quiz for assessment elements.push(this.createQuizElement(currentId++, prompt, subject)); // Summary section elements.push({ id: `statement-${currentId++}`, type: "statement-1", content_title: null, padding_top: 35, padding_bottom: 35, background_color: "#E8F5E9", primary_color: "#4CAF50", text: "<p><strong>Parabéns!</strong> Você completou esta aula. Revise os conceitos principais e teste seus conhecimentos com as atividades propostas.</p>" }); return elements; } /** * Create flashcards element */ private createFlashcardsElement(id: number, prompt: string, subject: string): CompositionElement { const topic = this.extractMainTopic(prompt); return { id: `flashcards-${id}`, type: "flashcards-1", content_title: "Cartões de Memorização", padding_top: 35, padding_bottom: 35, background_color: "#FFFFFF", card_height: 240, card_width: 240, border_color: "#2196F3", items: [ { id: "card-1", front_card: { text: `<p>O que é ${topic}?</p>`, centered_image: null, fullscreen_image: null }, back_card: { text: `<p>Definição e conceito principal de ${topic}</p>`, centered_image: null, fullscreen_image: null }, opened: false }, { id: "card-2", front_card: { text: "<p>Características Principais</p>", centered_image: null, fullscreen_image: null }, back_card: { text: "<p>Lista das características mais importantes</p>", centered_image: null, fullscreen_image: null }, opened: false }, { id: "card-3", front_card: { text: "<p>Exemplo Prático</p>", centered_image: null, fullscreen_image: null }, back_card: { text: "<p>Aplicação do conceito no dia a dia</p>", centered_image: null, fullscreen_image: null }, opened: false } ] }; } /** * Create quiz element */ private createQuizElement(id: number, prompt: string, subject: string): CompositionElement { const topic = this.extractMainTopic(prompt); return { id: `quiz-${id}`, type: "quiz-1", content_title: "Teste seus Conhecimentos", padding_top: 35, padding_bottom: 35, background_color: "#FFFFFF", primary_color: "#2196F3", remake: "enable", max_attempts: 3, utilization: { enabled: false, percentage: null }, feedback: { type: "default" }, questions: [ { id: "question-1", question: `<p>Qual a principal característica de ${topic}?</p>`, image: null, video: null, answered: false, feedback_default: { text: null, image: null, video: null, media_max_width: null }, feedback_correct: { text: "<p><strong>Correto!</strong> Você demonstrou compreender o conceito principal.</p>", image: null, video: null, media_max_width: null }, feedback_incorrect: { text: "<p>Revise o conteúdo para melhor compreensão do conceito.</p>", image: null, video: null, media_max_width: null }, no_correct_answer: false, no_feedback: false, choices: [ { id: "choice-1", correct: true, text: "<p>Resposta correta sobre o conceito</p>" }, { id: "choice-2", correct: false, text: "<p>Alternativa incorreta 1</p>" }, { id: "choice-3", correct: false, text: "<p>Alternativa incorreta 2</p>" }, { id: "choice-4", correct: false, text: "<p>Alternativa incorreta 3</p>" } ] } ] }; } /** * Helper methods */ private extractMainTopic(prompt: string): string { const words = prompt.toLowerCase() .replace(/[^\w\sàáâãéêíóôõúç]/g, ' ') .split(' ') .filter(word => word.length > 4); // Common topic keywords const topicKeywords = [ 'fotossíntese', 'célula', 'sistema', 'solar', 'fração', 'equação', 'geometria', 'história', 'geografia', 'português' ]; for (const keyword of topicKeywords) { if (prompt.toLowerCase().includes(keyword)) { return keyword.charAt(0).toUpperCase() + keyword.slice(1); } } return words[0] ? words[0].charAt(0).toUpperCase() + words[0].slice(1) : 'Conceito'; } private generateTags(prompt: string, subject: string): string[] { const tags = [subject.toLowerCase(), 'educação', 'interativo']; const words = prompt.toLowerCase().split(' '); words.forEach(word => { if (word.length > 5 && !tags.includes(word)) { tags.push(word); } }); return tags.slice(0, 6); } private estimateDuration(elements: CompositionElement[]): string { const baseTime = 15; // Base time in minutes const timePerElement = 3; // Additional time per element const totalTime = baseTime + (elements.length * timePerElement); return `${totalTime} minutos`; } private generateMainContent(prompt: string, subject: string): string { const topic = this.extractMainTopic(prompt); return ` <h3>Conceito Principal</h3> <p>O estudo de <strong>${topic}</strong> é fundamental para compreender ${subject}. Este conteúdo foi preparado para facilitar seu aprendizado através de explicações claras e exemplos práticos.</p> <h3>Pontos Importantes</h3> <p>Durante esta aula, vamos abordar:</p> <ol> <li>Definição e características principais</li> <li>Como funciona na prática</li> <li>Exemplos do cotidiano</li> <li>Aplicações e importância</li> </ol> <h3>Vamos Aprofundar</h3> <p>Agora que você já conhece os conceitos básicos, vamos explorar mais detalhes sobre ${topic}. Preste atenção nos exemplos e nas atividades interativas que preparamos para você.</p>`; } private shouldIncludeVisuals(prompt: string): boolean { const visualKeywords = ['diagrama', 'imagem', 'foto', 'visual', 'mostrar', 'ver']; return visualKeywords.some(keyword => prompt.toLowerCase().includes(keyword)); } private shouldIncludeVideo(prompt: string): boolean { const videoKeywords = ['vídeo', 'video', 'demonstr', 'experimento', 'processo']; return videoKeywords.some(keyword => prompt.toLowerCase().includes(keyword)); } private selectAppropriateImage(prompt: string, subject: string): string { // Use appropriate stock images based on subject const subjectImages: Record<string, string> = { 'ciências': 'https://images.unsplash.com/photo-1532094349884-543bc11b234d?w=760', 'matemática': 'https://images.unsplash.com/photo-1509228468518-180dd4864904?w=760', 'português': 'https://images.unsplash.com/photo-1457369804613-52c61a468e7d?w=760', 'história': 'https://images.unsplash.com/photo-1604580864964-0462f5d5b1a8?w=760', 'geografia': 'https://images.unsplash.com/photo-1526778548025-fa2f459cd5c1?w=760' }; return subjectImages[subject.toLowerCase()] || 'https://images.unsplash.com/photo-1503676260728-1c00da094a0b?w=760'; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rkm097git/euconquisto-composer-mcp-poc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server