Spaces:
Sleeping
Sleeping
| """ | |
| create_educational_presentation.py | |
| --------------------------------- | |
| Tool for creating comprehensive educational presentations through iterative research. | |
| This tool conducts deep research on medical topics, creates detailed reports, and converts | |
| them into structured slide presentations for educational purposes. It uses an iterative | |
| research approach with user confirmation before finalizing the presentation. | |
| Key Features: | |
| - Iterative internet research with 4-5 rounds of 3-5 pages each | |
| - User clarification questions before research | |
| - Comprehensive report generation | |
| - Structured slide presentation creation | |
| - Educational flow: objectives → vignette → education → application → Q&A | |
| """ | |
| import asyncio | |
| import json | |
| from typing import Any, Dict, List, Union | |
| from tools.base import Tool | |
| from tools.utils import ToolExecutionError, logger, load_prompt | |
| from core.utils.llm_connector import call_llm | |
| from tools.internet_search import InternetSearchTool | |
| class CreateEducationalPresentationTool(Tool): | |
| """ | |
| Tool for creating comprehensive educational presentations through iterative research. | |
| This tool conducts deep research, creates detailed reports, and converts them into | |
| structured slide presentations for educational purposes. | |
| """ | |
| def __init__(self) -> None: | |
| """Initialize the CreateEducationalPresentationTool.""" | |
| super().__init__() | |
| self.name = "create_educational_presentation" | |
| self.description = "Create comprehensive educational presentations through AI-powered dynamic research and content generation." | |
| self.internet_search = InternetSearchTool() | |
| self.args_schema = { | |
| "type": "object", | |
| "properties": { | |
| "topic": { | |
| "type": "string", | |
| "description": "The medical topic for the educational presentation (e.g., 'sepsis management', 'heart failure diagnosis', 'antibiotic stewardship')" | |
| }, | |
| "target_audience": { | |
| "type": "string", | |
| "description": "The target audience for the presentation", | |
| "enum": ["medical_students", "residents", "attendings", "nurses", "pharmacists", "multidisciplinary"], | |
| "default": "medical_students" | |
| }, | |
| "presentation_duration": { | |
| "type": "integer", | |
| "description": "Expected duration of presentation in minutes", | |
| "default": 45, | |
| "minimum": 15, | |
| "maximum": 120 | |
| }, | |
| "focus_area": { | |
| "type": "string", | |
| "description": "Specific focus area within the topic", | |
| "default": "comprehensive_overview" | |
| }, | |
| "aspects_to_emphasize": { | |
| "type": "string", | |
| "description": "What specific aspects to emphasize (e.g., 'pathophysiology, diagnosis, treatment')" | |
| }, | |
| "guidelines_to_include": { | |
| "type": "string", | |
| "description": "Specific guidelines or evidence to include (e.g., 'IDSA guidelines')" | |
| }, | |
| "learning_objectives": { | |
| "type": "string", | |
| "description": "What should the audience learn (e.g., 'diagnostic skills, treatment decisions')" | |
| }, | |
| "clinical_scenarios": { | |
| "type": "string", | |
| "description": "Specific clinical scenarios to highlight (e.g., 'common presentations')" | |
| }, | |
| "takeaway_message": { | |
| "type": "string", | |
| "description": "Key clinical pearl or takeaway message (e.g., 'early recognition saves lives')" | |
| } | |
| }, | |
| "required": ["topic"] | |
| } | |
| def openai_spec(self, legacy=False): | |
| """Return OpenAI function specification.""" | |
| return { | |
| "name": self.name, | |
| "description": self.description, | |
| "parameters": self.args_schema | |
| } | |
| async def run( | |
| self, | |
| topic: str, | |
| target_audience: str = "medical_students", | |
| presentation_duration: int = 45, | |
| focus_area: str = "comprehensive_overview", | |
| aspects_to_emphasize: Union[str, None] = None, | |
| guidelines_to_include: Union[str, None] = None, | |
| learning_objectives: Union[str, None] = None, | |
| clinical_scenarios: Union[str, None] = None, | |
| takeaway_message: Union[str, None] = None | |
| ) -> Dict[str, Any]: | |
| """ | |
| Create a comprehensive educational presentation through iterative research. | |
| Args: | |
| topic (str): The medical topic for the presentation | |
| target_audience (str): The target audience | |
| presentation_duration (int): Duration in minutes | |
| focus_area (str): Specific focus area | |
| aspects_to_emphasize (str): What specific aspects to emphasize | |
| guidelines_to_include (str): Specific guidelines or evidence to include | |
| learning_objectives (str): What should the audience learn | |
| clinical_scenarios (str): Specific clinical scenarios to highlight | |
| takeaway_message (str): Key clinical pearl or takeaway message | |
| Returns: | |
| Dict[str, Any]: Complete presentation with research, report, and slides | |
| """ | |
| try: | |
| logger.info(f"Starting educational presentation creation for topic: {topic}") | |
| # Build clarification responses from provided parameters | |
| clarification_responses = {} | |
| # Check if we have enough information to proceed | |
| if aspects_to_emphasize and guidelines_to_include and learning_objectives and clinical_scenarios and takeaway_message: | |
| clarification_responses = { | |
| "aspects": aspects_to_emphasize, | |
| "guidelines": guidelines_to_include, | |
| "learning_objectives": learning_objectives, | |
| "clinical_scenarios": clinical_scenarios, | |
| "takeaway_message": takeaway_message | |
| } | |
| else: | |
| # Use intelligent defaults based on the topic and focus area | |
| clarification_responses = self._generate_intelligent_defaults(topic, target_audience, focus_area) | |
| logger.info(f"Using intelligent defaults for presentation creation") | |
| # Proceed with full presentation creation | |
| logger.info(f"Proceeding with presentation creation using responses") | |
| # Step 2: Conduct iterative research | |
| research_results = await self._conduct_iterative_research(topic, clarification_responses) | |
| # Step 3: Generate comprehensive report | |
| research_report = self._generate_research_report(topic, research_results, clarification_responses) | |
| # Step 4: Create presentation structure | |
| presentation_structure = self._create_presentation_structure( | |
| topic, target_audience, presentation_duration, research_report | |
| ) | |
| # Step 5: Create final presentation using existing method | |
| final_presentation = await self.create_final_presentation( | |
| topic, target_audience, presentation_duration, research_report, | |
| presentation_structure, "" | |
| ) | |
| logger.info(f"Successfully created educational presentation for {topic}") | |
| return final_presentation | |
| except Exception as e: | |
| logger.error(f"CreateEducationalPresentationTool failed: {e}", exc_info=True) | |
| raise ToolExecutionError(f"Failed to create educational presentation: {e}") | |
| async def continue_with_research( | |
| self, | |
| topic: str, | |
| target_audience: str, | |
| presentation_duration: int, | |
| focus_area: str, | |
| clarification_responses: Dict[str, str] | |
| ) -> Dict[str, Any]: | |
| """ | |
| Continue with research phase after receiving clarification responses. | |
| Args: | |
| topic (str): The medical topic | |
| target_audience (str): Target audience | |
| presentation_duration (int): Duration in minutes | |
| focus_area (str): Focus area | |
| clarification_responses (Dict[str, str]): User responses to clarification questions | |
| Returns: | |
| Dict[str, Any]: Research results and next steps | |
| """ | |
| try: | |
| logger.info(f"Continuing with research for topic: {topic}") | |
| # Step 2: Conduct iterative research | |
| research_results = await self._conduct_iterative_research(topic, clarification_responses) | |
| # Step 3: Generate comprehensive report | |
| research_report = self._generate_research_report(topic, research_results, clarification_responses) | |
| # Step 4: Create presentation structure | |
| presentation_structure = self._create_presentation_structure( | |
| topic, target_audience, presentation_duration, research_report | |
| ) | |
| return { | |
| "status": "research_complete", | |
| "topic": topic, | |
| "target_audience": target_audience, | |
| "presentation_duration": presentation_duration, | |
| "research_results": research_results, | |
| "research_report": research_report, | |
| "proposed_structure": presentation_structure, | |
| "next_step": "Please review the research report and presentation structure. Confirm to proceed with slide creation." | |
| } | |
| except Exception as e: | |
| logger.error(f"Research phase failed: {e}", exc_info=True) | |
| raise ToolExecutionError(f"Failed to complete research: {e}") | |
| async def create_final_presentation( | |
| self, | |
| topic: str, | |
| target_audience: str, | |
| presentation_duration: int, | |
| research_report: str, | |
| presentation_structure: Dict[str, Any], | |
| user_feedback: str = "" | |
| ) -> Dict[str, Any]: | |
| """ | |
| Create the final presentation slides. | |
| Args: | |
| topic (str): The medical topic | |
| target_audience (str): Target audience | |
| presentation_duration (int): Duration in minutes | |
| research_report (str): The research report | |
| presentation_structure (Dict): Presentation structure | |
| user_feedback (str): User feedback on structure | |
| Returns: | |
| Dict[str, Any]: Complete presentation with slides | |
| """ | |
| try: | |
| logger.info(f"Creating final presentation for topic: {topic}") | |
| # Adjust structure based on user feedback if provided | |
| if user_feedback: | |
| presentation_structure = self._adjust_structure_based_on_feedback( | |
| presentation_structure, user_feedback | |
| ) | |
| # Generate all slides | |
| slides = await self._generate_all_slides( | |
| topic, target_audience, research_report, presentation_structure | |
| ) | |
| # Create speaker notes | |
| speaker_notes = self._generate_speaker_notes(slides, research_report) | |
| # Generate presentation metadata | |
| presentation_metadata = self._generate_presentation_metadata( | |
| topic, target_audience, presentation_duration, len(slides) | |
| ) | |
| return { | |
| "status": "presentation_complete", | |
| "topic": topic, | |
| "target_audience": target_audience, | |
| "presentation_duration": presentation_duration, | |
| "total_slides": len(slides), | |
| "slides": slides, | |
| "speaker_notes": speaker_notes, | |
| "metadata": presentation_metadata, | |
| "research_report": research_report, | |
| "created_date": "2025-07-18" | |
| } | |
| except Exception as e: | |
| logger.error(f"Final presentation creation failed: {e}", exc_info=True) | |
| raise ToolExecutionError(f"Failed to create final presentation: {e}") | |
| def _generate_clarification_questions(self, topic: str, target_audience: str, focus_area: str) -> List[Dict[str, str]]: | |
| """Generate 3-5 clarification questions for the user.""" | |
| questions = [ | |
| { | |
| "question": f"What specific aspects of {topic} would you like to emphasize in this presentation?", | |
| "purpose": "To focus the research on the most relevant areas", | |
| "examples": "e.g., pathophysiology, diagnosis, treatment, recent advances, guidelines" | |
| }, | |
| { | |
| "question": f"Are there any specific guidelines, studies, or evidence you want to include?", | |
| "purpose": "To ensure important references are included", | |
| "examples": "e.g., specific society guidelines, landmark studies, recent publications" | |
| }, | |
| { | |
| "question": f"What learning objectives should the {target_audience} achieve after this presentation?", | |
| "purpose": "To structure the educational content appropriately", | |
| "examples": "e.g., diagnostic skills, treatment decisions, understanding pathophysiology" | |
| }, | |
| { | |
| "question": f"Are there any specific clinical scenarios or patient populations you want to highlight?", | |
| "purpose": "To create relevant clinical vignettes", | |
| "examples": "e.g., pediatric patients, elderly, specific comorbidities, severity levels" | |
| }, | |
| { | |
| "question": f"What should be the takeaway message or key clinical pearl from this presentation?", | |
| "purpose": "To ensure the presentation has a clear, memorable message", | |
| "examples": "e.g., early recognition saves lives, personalized treatment approach, guideline adherence" | |
| } | |
| ] | |
| return questions | |
| def _generate_intelligent_defaults(self, topic: str, target_audience: str, focus_area: str) -> Dict[str, str]: | |
| """ | |
| Generate intelligent default responses based on topic and focus area. | |
| Args: | |
| topic (str): The medical topic | |
| target_audience (str): Target audience | |
| focus_area (str): Focus area | |
| Returns: | |
| Dict[str, str]: Intelligent default responses | |
| """ | |
| try: | |
| # Topic-specific intelligent defaults | |
| topic_lower = topic.lower() | |
| if "dimorphic fungi" in topic_lower or "fungal" in topic_lower: | |
| return { | |
| "aspects": "comprehensive coverage including pathophysiology, diagnosis, treatment, epidemiology, and clinical presentations", | |
| "guidelines": "IDSA guidelines and recent evidence-based recommendations", | |
| "learning_objectives": "comprehensive understanding of diagnosis, treatment, and key clinical presentations for board exam preparation", | |
| "clinical_scenarios": "common clinical presentations of each dimorphic fungus including histoplasmosis, coccidioidomycosis, blastomycosis, and others", | |
| "takeaway_message": "systematic approach to diagnosis and management with focus on board exam question patterns" | |
| } | |
| elif "sepsis" in topic_lower: | |
| return { | |
| "aspects": "pathophysiology, early recognition, diagnosis, management, and outcomes", | |
| "guidelines": "Surviving Sepsis Campaign guidelines and recent updates", | |
| "learning_objectives": "early recognition, appropriate management, and outcome improvement", | |
| "clinical_scenarios": "emergency department presentations, ICU management, and complications", | |
| "takeaway_message": "early recognition and prompt treatment save lives" | |
| } | |
| elif "heart failure" in topic_lower: | |
| return { | |
| "aspects": "pathophysiology, classification, diagnosis, management, and prognosis", | |
| "guidelines": "ACC/AHA heart failure guidelines", | |
| "learning_objectives": "diagnostic skills, treatment optimization, and guideline adherence", | |
| "clinical_scenarios": "acute decompensated heart failure, chronic management, and comorbidities", | |
| "takeaway_message": "guideline-directed medical therapy improves outcomes" | |
| } | |
| else: | |
| # Generic intelligent defaults | |
| return { | |
| "aspects": "comprehensive coverage including pathophysiology, diagnosis, treatment, and recent advances", | |
| "guidelines": "latest evidence-based guidelines from relevant professional societies", | |
| "learning_objectives": "comprehensive understanding of diagnosis, treatment, and key clinical pearls", | |
| "clinical_scenarios": "common clinical presentations and real-world case studies", | |
| "takeaway_message": "evidence-based approach to diagnosis and management" | |
| } | |
| except Exception as e: | |
| logger.warning(f"Failed to generate intelligent defaults: {e}") | |
| # Fallback to basic defaults | |
| return { | |
| "aspects": "comprehensive overview of the topic", | |
| "guidelines": "current evidence-based guidelines", | |
| "learning_objectives": "understanding of key concepts", | |
| "clinical_scenarios": "common clinical presentations", | |
| "takeaway_message": "evidence-based clinical approach" | |
| } | |
| async def _conduct_iterative_research(self, topic: str, clarification_responses: Dict[str, str]) -> Dict[str, Any]: | |
| """Conduct 4-5 rounds of iterative research.""" | |
| research_results = { | |
| "rounds": [], | |
| "total_sources": 0, | |
| "key_themes": [], | |
| "evidence_summary": {} | |
| } | |
| # Import internet search tool | |
| from tools.internet_search import InternetSearchTool | |
| internet_tool = InternetSearchTool() | |
| # Round 1: General topic overview | |
| round1_queries = [ | |
| f"{topic} overview clinical guidelines", | |
| f"{topic} pathophysiology mechanisms", | |
| f"{topic} diagnosis treatment current evidence", | |
| f"{topic} management recommendations 2024", | |
| f"{topic} clinical practice guidelines" | |
| ] | |
| round1_results = await self._conduct_research_round(internet_tool, round1_queries, 1, "General Overview") | |
| research_results["rounds"].append(round1_results) | |
| # Round 2: Specific focus based on clarification | |
| focus_keywords = self._extract_focus_keywords(clarification_responses) | |
| round2_queries = [ | |
| f"{topic} {focus_keywords[0]} latest research", | |
| f"{topic} {focus_keywords[1]} clinical studies", | |
| f"{topic} {focus_keywords[0]} best practices", | |
| f"{topic} guidelines {focus_keywords[1]}", | |
| f"{topic} evidence based {focus_keywords[0]}" | |
| ] | |
| round2_results = await self._conduct_research_round(internet_tool, round2_queries, 2, "Focused Research") | |
| research_results["rounds"].append(round2_results) | |
| # Round 3: Clinical evidence and studies | |
| round3_queries = [ | |
| f"{topic} randomized controlled trials", | |
| f"{topic} systematic review meta-analysis", | |
| f"{topic} clinical outcomes studies", | |
| f"{topic} evidence quality assessment", | |
| f"{topic} landmark studies" | |
| ] | |
| round3_results = await self._conduct_research_round(internet_tool, round3_queries, 3, "Clinical Evidence") | |
| research_results["rounds"].append(round3_results) | |
| # Round 4: Guidelines and recommendations | |
| round4_queries = [ | |
| f"{topic} society guidelines recommendations", | |
| f"{topic} international consensus statements", | |
| f"{topic} practice guidelines updates", | |
| f"{topic} expert consensus recommendations", | |
| f"{topic} clinical practice standards" | |
| ] | |
| round4_results = await self._conduct_research_round(internet_tool, round4_queries, 4, "Guidelines & Recommendations") | |
| research_results["rounds"].append(round4_results) | |
| # Calculate total sources | |
| research_results["total_sources"] = sum(len(round_data["sources"]) for round_data in research_results["rounds"]) | |
| # Extract key themes | |
| research_results["key_themes"] = self._extract_key_themes(research_results["rounds"]) | |
| return research_results | |
| async def _conduct_research_round(self, internet_tool, queries: List[str], round_number: int, round_focus: str) -> Dict[str, Any]: | |
| """Conduct a single round of research.""" | |
| round_results = { | |
| "round_number": round_number, | |
| "focus": round_focus, | |
| "queries": queries, | |
| "sources": [], | |
| "summary": "" | |
| } | |
| for query in queries: | |
| try: | |
| search_results = await internet_tool.run(query) | |
| if search_results: | |
| # Parse and extract key information | |
| parsed_sources = self._parse_search_results(search_results, query) | |
| round_results["sources"].extend(parsed_sources) | |
| # Limit to 3-5 sources per round | |
| if len(round_results["sources"]) >= 5: | |
| break | |
| except Exception as e: | |
| logger.warning(f"Search failed for query '{query}': {e}") | |
| continue | |
| # Generate summary for this round | |
| round_results["summary"] = self._generate_round_summary(round_results["sources"], round_focus) | |
| return round_results | |
| def _parse_search_results(self, search_results: str, query: str) -> List[Dict[str, str]]: | |
| """Parse search results string into structured sources.""" | |
| sources = [] | |
| # Split by entries (each entry starts with **) | |
| import re | |
| entries = re.split(r'\*\*([^*]+)\*\*', search_results) | |
| for i in range(1, len(entries), 2): | |
| if i + 1 < len(entries): | |
| title = entries[i].strip() | |
| content_and_link = entries[i + 1].strip() | |
| # Extract the link | |
| link_match = re.search(r'\[Read more\]\(([^)]+)\)', content_and_link) | |
| url = link_match.group(1) if link_match else "" | |
| # Extract the content | |
| content = re.sub(r'\[Read more\]\([^)]+\)', '', content_and_link).strip() | |
| if title and content: | |
| sources.append({ | |
| "title": title, | |
| "url": url, | |
| "content": content, | |
| "query": query, | |
| "relevance": "high" # Could be improved with actual relevance scoring | |
| }) | |
| return sources | |
| def _extract_focus_keywords(self, clarification_responses: Dict[str, str]) -> List[str]: | |
| """Extract focus keywords from clarification responses.""" | |
| keywords = ["diagnosis", "treatment", "management", "pathophysiology", "guidelines"] | |
| # Extract keywords from user responses | |
| for response in clarification_responses.values(): | |
| if response: | |
| # Simple keyword extraction - could be improved | |
| if "diagnosis" in response.lower(): | |
| keywords.insert(0, "diagnosis") | |
| elif "treatment" in response.lower(): | |
| keywords.insert(0, "treatment") | |
| elif "management" in response.lower(): | |
| keywords.insert(0, "management") | |
| return keywords[:2] # Return top 2 keywords | |
| def _generate_round_summary(self, sources: List[Dict], round_focus: str) -> str: | |
| """Generate a summary for a research round.""" | |
| if not sources: | |
| return f"No relevant sources found for {round_focus}." | |
| # Extract key points from sources | |
| key_points = [] | |
| for source in sources: | |
| content = source.get("content", "") | |
| if len(content) > 50: | |
| # Extract first sentence or key point | |
| first_sentence = content.split('.')[0] | |
| if len(first_sentence) > 20: | |
| key_points.append(first_sentence) | |
| summary = f"**{round_focus}** ({len(sources)} sources):\n" | |
| for i, point in enumerate(key_points[:3], 1): | |
| summary += f"{i}. {point}\n" | |
| return summary | |
| def _extract_key_themes(self, rounds: List[Dict]) -> List[str]: | |
| """Extract key themes from all research rounds.""" | |
| themes = [] | |
| for round_data in rounds: | |
| summary = round_data.get("summary", "") | |
| if "diagnosis" in summary.lower(): | |
| themes.append("Diagnostic Approach") | |
| if "treatment" in summary.lower(): | |
| themes.append("Treatment Strategies") | |
| if "management" in summary.lower(): | |
| themes.append("Clinical Management") | |
| if "guidelines" in summary.lower(): | |
| themes.append("Evidence-Based Guidelines") | |
| if "pathophysiology" in summary.lower(): | |
| themes.append("Pathophysiology") | |
| # Remove duplicates and return unique themes | |
| return list(set(themes)) | |
| def _generate_research_report(self, topic: str, research_results: Dict, clarification_responses: Dict) -> str: | |
| """Generate a comprehensive research report.""" | |
| report = f"# Comprehensive Research Report: {topic.title()}\n\n" | |
| # Executive summary | |
| report += "## Executive Summary\n" | |
| report += f"This report synthesizes findings from {research_results['total_sources']} sources across {len(research_results['rounds'])} research rounds.\n\n" | |
| # Key themes | |
| report += "## Key Themes Identified\n" | |
| for theme in research_results["key_themes"]: | |
| report += f"- {theme}\n" | |
| report += "\n" | |
| # Research rounds summary | |
| report += "## Research Findings by Round\n" | |
| for round_data in research_results["rounds"]: | |
| report += f"### Round {round_data['round_number']}: {round_data['focus']}\n" | |
| report += f"{round_data['summary']}\n\n" | |
| # Evidence synthesis | |
| report += "## Evidence Synthesis\n" | |
| report += f"Based on the research conducted, the following key points emerge about {topic}:\n\n" | |
| # Add synthesized content based on themes | |
| for theme in research_results["key_themes"]: | |
| report += f"**{theme}**: [Evidence-based summary for {theme}]\n\n" | |
| # Clinical implications | |
| report += "## Clinical Implications\n" | |
| report += f"The research findings have the following implications for clinical practice:\n" | |
| report += "- [Key clinical implication 1]\n" | |
| report += "- [Key clinical implication 2]\n" | |
| report += "- [Key clinical implication 3]\n\n" | |
| # Recommendations | |
| report += "## Recommendations\n" | |
| report += "Based on the evidence review:\n" | |
| report += "1. [Recommendation 1]\n" | |
| report += "2. [Recommendation 2]\n" | |
| report += "3. [Recommendation 3]\n\n" | |
| return report | |
| def _create_presentation_structure(self, topic: str, target_audience: str, duration: int, research_report: str) -> Dict[str, Any]: | |
| """Create the presentation structure.""" | |
| # Calculate approximate slides based on duration | |
| slides_estimate = max(10, duration // 3) # ~3 minutes per slide | |
| structure = { | |
| "title": f"{topic.title()}: A Comprehensive Review", | |
| "estimated_slides": slides_estimate, | |
| "estimated_duration": duration, | |
| "sections": [ | |
| { | |
| "section": "Introduction", | |
| "slides": [ | |
| {"title": "Title Slide", "content": f"{topic.title()}", "duration": 1}, | |
| {"title": "Learning Objectives", "content": "What you will learn today", "duration": 2}, | |
| {"title": "Case Vignette", "content": "Clinical scenario introduction", "duration": 3} | |
| ] | |
| }, | |
| { | |
| "section": "Educational Content", | |
| "slides": [ | |
| {"title": "Definition & Overview", "content": f"What is {topic}?", "duration": 5}, | |
| {"title": "Pathophysiology", "content": "Understanding the mechanisms", "duration": 7}, | |
| {"title": "Clinical Presentation", "content": "Recognition and diagnosis", "duration": 7}, | |
| {"title": "Diagnostic Approach", "content": "Evidence-based diagnosis", "duration": 8}, | |
| {"title": "Treatment Strategies", "content": "Management options", "duration": 8}, | |
| {"title": "Guidelines & Evidence", "content": "Current recommendations", "duration": 5} | |
| ] | |
| }, | |
| { | |
| "section": "Application", | |
| "slides": [ | |
| {"title": "Case Application", "content": "Applying knowledge to the vignette", "duration": 5}, | |
| {"title": "Clinical Pearls", "content": "Key takeaways", "duration": 3} | |
| ] | |
| }, | |
| { | |
| "section": "Assessment", | |
| "slides": [ | |
| {"title": "Rapid Fire Questions", "content": "Quick knowledge check", "duration": 5}, | |
| {"title": "Discussion", "content": "Open discussion and Q&A", "duration": 5} | |
| ] | |
| } | |
| ] | |
| } | |
| return structure | |
| def _adjust_structure_based_on_feedback(self, structure: Dict, feedback: str) -> Dict: | |
| """Adjust presentation structure based on user feedback.""" | |
| # Simple feedback processing - could be enhanced | |
| if "more slides" in feedback.lower(): | |
| # Add more detail slides | |
| for section in structure["sections"]: | |
| if section["section"] == "Educational Content": | |
| section["slides"].append({ | |
| "title": "Advanced Topics", | |
| "content": "Additional detailed information", | |
| "duration": 5 | |
| }) | |
| if "shorter" in feedback.lower(): | |
| # Remove some slides | |
| for section in structure["sections"]: | |
| if len(section["slides"]) > 2: | |
| section["slides"] = section["slides"][:2] | |
| return structure | |
| async def _generate_all_slides(self, topic: str, target_audience: str, research_report: str, structure: Dict) -> List[Dict[str, Any]]: | |
| """Generate all presentation slides using AI and research content.""" | |
| slides = [] | |
| slide_number = 1 | |
| logger.info(f"Starting AI-powered slide generation for {topic}") | |
| for section in structure["sections"]: | |
| for slide_template in section["slides"]: | |
| try: | |
| slide = await self._create_ai_slide( | |
| slide_number, | |
| slide_template["title"], | |
| slide_template["content"], | |
| topic, | |
| target_audience, | |
| research_report, | |
| section["section"] | |
| ) | |
| slides.append(slide) | |
| slide_number += 1 | |
| logger.info(f"Generated slide {slide_number-1}: {slide_template['title']}") | |
| except Exception as e: | |
| logger.error(f"Failed to generate slide {slide_number}: {e}") | |
| # Fallback to basic slide structure | |
| slide = self._create_fallback_slide(slide_number, slide_template["title"], section["section"]) | |
| slides.append(slide) | |
| slide_number += 1 | |
| logger.info(f"Completed slide generation: {len(slides)} slides created") | |
| return slides | |
| async def _create_ai_slide(self, slide_number: int, title: str, content_desc: str, topic: str, | |
| target_audience: str, research_report: str, section: str) -> Dict[str, Any]: | |
| """Create an individual slide with AI-generated content based on research.""" | |
| try: | |
| # Load the slide generation prompt | |
| logger.info(f"Generating AI content for slide: {title}") | |
| prompt = load_prompt('generate_presentation_slide.j2', | |
| topic=topic, | |
| target_audience=target_audience.replace('_', ' '), | |
| slide_title=title, | |
| section=section, | |
| content_description=content_desc, | |
| research_report=research_report[:3000] # Limit research content to avoid token limits | |
| ) | |
| # Generate slide content with OpenAI | |
| response = await asyncio.wait_for( | |
| call_llm(prompt), | |
| timeout=30.0 | |
| ) | |
| # Parse AI response | |
| if response.strip().startswith('```json'): | |
| response = response.strip()[7:-3].strip() | |
| elif response.strip().startswith('```'): | |
| response = response.strip()[3:-3].strip() | |
| slide_content = json.loads(response) | |
| # Construct the slide with AI-generated content | |
| slide = { | |
| "slide_number": slide_number, | |
| "title": slide_content.get("slide_title", title), | |
| "section": section, | |
| "content": { | |
| "bullet_points": slide_content.get("main_content", []), | |
| "sub_bullets": slide_content.get("sub_bullets", {}), | |
| "clinical_notes": slide_content.get("clinical_notes", ""), | |
| "references_used": slide_content.get("references_used", ""), | |
| "generation_method": "AI-powered with research integration" | |
| } | |
| } | |
| logger.info(f"Successfully generated AI slide: {title} ({len(slide['content']['bullet_points'])} main points)") | |
| return slide | |
| except Exception as e: | |
| logger.error(f"AI slide generation failed for {title}: {e}") | |
| # Return fallback slide | |
| return self._create_fallback_slide(slide_number, title, section) | |
| def _create_fallback_slide(self, slide_number: int, title: str, section: str) -> Dict[str, Any]: | |
| """Create a basic fallback slide if AI generation fails.""" | |
| return { | |
| "slide_number": slide_number, | |
| "title": title, | |
| "section": section, | |
| "content": { | |
| "bullet_points": [ | |
| f"Content for {title} slide", | |
| "Key points to be covered", | |
| "Clinical applications", | |
| "Important considerations" | |
| ], | |
| "sub_bullets": {}, | |
| "clinical_notes": "Fallback content - consider manual review", | |
| "generation_method": "Fallback template" | |
| } | |
| } | |
| def _create_slide(self, slide_number: int, title: str, content_desc: str, topic: str, target_audience: str, research_report: str, section: str) -> Dict[str, Any]: | |
| """Create an individual slide with detailed, presentation-ready content.""" | |
| slide = { | |
| "slide_number": slide_number, | |
| "title": title, | |
| "section": section, | |
| "content": { | |
| "bullet_points": [], | |
| "images": [], | |
| "notes": "" | |
| } | |
| } | |
| # Generate detailed content based on slide type and topic | |
| if "Title Slide" in title: | |
| slide["content"]["bullet_points"] = [ | |
| f"{topic.title()}: A Comprehensive Review", | |
| f"For {target_audience.replace('_', ' ').title()}", | |
| f"Date: July 18, 2025" | |
| ] | |
| elif "Learning Objectives" in title: | |
| slide["content"]["bullet_points"] = self._generate_learning_objectives_content(topic) | |
| elif "Case Vignette" in title: | |
| slide["content"]["bullet_points"] = self._generate_case_vignette_content(topic) | |
| elif "Definition" in title or "Overview" in title: | |
| slide["content"]["bullet_points"] = self._generate_definition_overview_content(topic) | |
| elif "Pathophysiology" in title: | |
| slide["content"]["bullet_points"] = self._generate_pathophysiology_content(topic) | |
| elif "Clinical Presentation" in title: | |
| slide["content"]["bullet_points"] = self._generate_clinical_presentation_content(topic) | |
| elif "Diagnostic" in title: | |
| slide["content"]["bullet_points"] = self._generate_diagnostic_content(topic) | |
| elif "Treatment" in title: | |
| slide["content"]["bullet_points"] = self._generate_treatment_content(topic) | |
| elif "Guidelines" in title: | |
| slide["content"]["bullet_points"] = self._generate_guidelines_content(topic) | |
| elif "Case Application" in title: | |
| slide["content"]["bullet_points"] = self._generate_case_application_content(topic) | |
| elif "Clinical Pearls" in title: | |
| slide["content"]["bullet_points"] = self._generate_clinical_pearls_content(topic) | |
| elif "Rapid Fire" in title: | |
| slide["content"]["bullet_points"] = self._generate_rapid_fire_content(topic) | |
| elif "Discussion" in title: | |
| slide["content"]["bullet_points"] = self._generate_discussion_content(topic) | |
| else: | |
| # Fallback for other slide types | |
| slide["content"]["bullet_points"] = self._generate_generic_content(title, topic) | |
| return slide | |
| def _generate_learning_objectives_content(self, topic: str) -> List[str]: | |
| """Generate specific learning objectives based on topic.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Identify the three major endemic dimorphic fungi in the United States", | |
| "Describe the unique morphological characteristics of dimorphic fungi", | |
| "Recognize geographic distribution patterns and epidemiologic risk factors", | |
| "Differentiate clinical presentations of histoplasmosis, blastomycosis, and coccidioidomycosis", | |
| "Apply appropriate diagnostic testing strategies and interpret results", | |
| "Implement evidence-based antifungal treatment protocols per IDSA guidelines" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Classify pneumonia by etiology and clinical setting (CAP, HAP, VAP)", | |
| "Recognize clinical presentation and physical examination findings", | |
| "Select appropriate diagnostic tests and interpret chest imaging", | |
| "Apply severity scoring systems (CURB-65, PSI) for risk stratification", | |
| "Implement evidence-based antibiotic therapy based on guidelines", | |
| "Identify complications and indications for hospitalization" | |
| ] | |
| else: | |
| return [ | |
| f"Define key concepts related to {topic}", | |
| f"Recognize clinical manifestations of {topic}", | |
| f"Apply diagnostic approaches for {topic}", | |
| f"Implement evidence-based treatment strategies", | |
| f"Integrate current guidelines into clinical practice" | |
| ] | |
| def _generate_case_vignette_content(self, topic: str) -> List[str]: | |
| """Generate specific case vignette based on topic.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "45-year-old construction worker from Ohio River Valley", | |
| "Recent spelunking activities in Kentucky caves (6 weeks ago)", | |
| "3-week history: fever, nonproductive cough, 15-pound weight loss", | |
| "Physical exam: erythema nodosum, bilateral hilar lymphadenopathy", | |
| "Labs: lymphopenia, elevated ESR, positive Histoplasma urine antigen", | |
| "Question: What is the most likely diagnosis and treatment?" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "68-year-old man with COPD and diabetes", | |
| "Recent cruise ship travel, acute onset (48 hours)", | |
| "Productive cough with rust-colored sputum, pleuritic chest pain", | |
| "Physical exam: dullness to percussion, bronchial breath sounds", | |
| "Labs: elevated WBC with left shift, positive pneumococcal antigen", | |
| "Question: What is the most appropriate treatment approach?" | |
| ] | |
| else: | |
| return [ | |
| f"Clinical scenario presenting with {topic}", | |
| "Relevant patient history and risk factors", | |
| "Physical examination findings", | |
| "Initial diagnostic workup results", | |
| "Clinical decision-making challenge" | |
| ] | |
| def _generate_definition_overview_content(self, topic: str) -> List[str]: | |
| """Generate definition and overview content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Dimorphic fungi: organisms that exist in two distinct morphological forms", | |
| "Yeast form at body temperature (37°C) - pathogenic phase", | |
| "Mold form at room temperature (25°C) - environmental phase", | |
| "Three major endemic fungi in US: Histoplasma, Blastomyces, Coccidioides", | |
| "Cause significant morbidity in immunocompromised and healthy hosts", | |
| "Geographic distribution correlates with environmental factors" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Pneumonia: infection of the lung parenchyma and alveolar spaces", | |
| "Leading cause of infectious disease mortality worldwide", | |
| "Classification: Community-acquired (CAP), Healthcare-associated (HAP/VAP)", | |
| "Etiology: bacterial, viral, fungal, or atypical pathogens", | |
| "Risk factors: age, comorbidities, immunosuppression, aspiration", | |
| "Clinical spectrum: mild outpatient to severe septic shock" | |
| ] | |
| else: | |
| return [ | |
| f"Definition and key characteristics of {topic}", | |
| f"Epidemiology and prevalence of {topic}", | |
| f"Clinical significance in medical practice", | |
| f"Risk factors and predisposing conditions" | |
| ] | |
| def _generate_pathophysiology_content(self, topic: str) -> List[str]: | |
| """Generate pathophysiology content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Inhalation of microconidia from contaminated soil or bird/bat droppings", | |
| "Conversion to yeast form in lung alveoli at body temperature", | |
| "Phagocytosis by alveolar macrophages - intracellular survival", | |
| "Hematogenous dissemination to reticuloendothelial system", | |
| "Host immune response: cell-mediated immunity crucial for control", | |
| "Granulomatous inflammation with potential for reactivation" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Pathogen invasion of lower respiratory tract via inhalation or aspiration", | |
| "Overwhelm of normal host defense mechanisms (mucociliary clearance, alveolar macrophages)", | |
| "Inflammatory response: neutrophil recruitment, cytokine release", | |
| "Alveolar filling with inflammatory exudate and impaired gas exchange", | |
| "Systemic inflammatory response syndrome (SIRS) in severe cases", | |
| "Complications: pleural effusion, empyema, respiratory failure" | |
| ] | |
| else: | |
| return [ | |
| f"Underlying mechanisms of {topic}", | |
| f"Pathophysiologic pathways involved", | |
| f"Host response and immune system involvement", | |
| f"Disease progression and complications" | |
| ] | |
| def _generate_clinical_presentation_content(self, topic: str) -> List[str]: | |
| """Generate clinical presentation content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Histoplasmosis: fever, cough, weight loss, erythema nodosum", | |
| "Blastomycosis: skin lesions, pulmonary symptoms, bone involvement", | |
| "Coccidioidomycosis: Valley fever, arthralgias, desert rheumatism", | |
| "Pulmonary manifestations: nodules, cavitation, hilar lymphadenopathy", | |
| "Disseminated disease: CNS, skin, bone, adrenal involvement", | |
| "Chronic forms: progressive pulmonary fibrosis, cavitary disease" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Classic triad: fever, cough, and dyspnea", | |
| "Productive cough with purulent sputum (bacterial)", | |
| "Pleuritic chest pain and decreased breath sounds", | |
| "Physical signs: dullness to percussion, crackles, bronchial breath sounds", | |
| "Systemic symptoms: malaise, myalgias, headache", | |
| "Severe cases: sepsis, altered mental status, respiratory failure" | |
| ] | |
| else: | |
| return [ | |
| f"Common signs and symptoms of {topic}", | |
| f"Physical examination findings", | |
| f"Disease spectrum and severity variations", | |
| f"Complications and warning signs" | |
| ] | |
| def _generate_diagnostic_content(self, topic: str) -> List[str]: | |
| """Generate diagnostic approach content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Urine antigen testing: rapid, sensitive for Histoplasma", | |
| "Serology: complement fixation, EIA antibodies (takes weeks)", | |
| "Culture: gold standard but requires 2-6 weeks for growth", | |
| "Histopathology: special stains (GMS, PAS) for tissue diagnosis", | |
| "Molecular testing: PCR increasingly available", | |
| "Imaging: chest CT for pulmonary nodules, lymphadenopathy" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Chest X-ray: first-line imaging for consolidation", | |
| "Laboratory: CBC with differential, procalcitonin, blood cultures", | |
| "Sputum culture: if good quality specimen available", | |
| "Urinary antigens: pneumococcal and Legionella", | |
| "Severity assessment: CURB-65, PSI scoring systems", | |
| "Advanced imaging: chest CT if complicated or atypical" | |
| ] | |
| else: | |
| return [ | |
| f"Laboratory tests for {topic}", | |
| f"Imaging studies and interpretation", | |
| f"Differential diagnosis considerations", | |
| f"Confirmatory diagnostic procedures" | |
| ] | |
| def _generate_treatment_content(self, topic: str) -> List[str]: | |
| """Generate treatment strategies content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Mild-moderate disease: Itraconazole 200 mg BID × 6-12 weeks", | |
| "Severe disease: Amphotericin B 0.7-1.0 mg/kg/day × 1-2 weeks", | |
| "Step-down therapy: Itraconazole after amphotericin stabilization", | |
| "CNS disease: Amphotericin B × 4-6 weeks, then fluconazole", | |
| "Duration: 6-12 months for pulmonary, 12-24 months for disseminated", | |
| "Monitoring: drug levels, hepatic function, treatment response" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Outpatient CAP: Amoxicillin or macrolide monotherapy", | |
| "Hospitalized CAP: Beta-lactam + macrolide or fluoroquinolone", | |
| "Severe CAP: Broad-spectrum beta-lactam + macrolide", | |
| "Duration: 5-7 days for most cases, longer if complications", | |
| "Supportive care: oxygen, fluids, bronchodilators if needed", | |
| "Prevention: pneumococcal and influenza vaccination" | |
| ] | |
| else: | |
| return [ | |
| f"First-line treatment options for {topic}", | |
| f"Alternative therapies and second-line agents", | |
| f"Treatment duration and monitoring parameters", | |
| f"Management of complications" | |
| ] | |
| def _generate_guidelines_content(self, topic: str) -> List[str]: | |
| """Generate guidelines and evidence content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "IDSA 2007 Guidelines for Endemic Mycoses (updated recommendations)", | |
| "Treatment recommendations based on disease severity and location", | |
| "Antifungal drug selection considers penetration and efficacy", | |
| "Monitoring guidelines for drug toxicity and therapeutic response", | |
| "Prevention strategies for high-risk populations", | |
| "Quality indicators for optimal clinical outcomes" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "IDSA/ATS 2019 Guidelines for Community-Acquired Pneumonia", | |
| "Antimicrobial selection based on severity and risk factors", | |
| "Biomarker-guided therapy duration (procalcitonin)", | |
| "Quality measures: appropriate antibiotic selection and timing", | |
| "Prevention: vaccination recommendations and smoking cessation", | |
| "Stewardship: narrow-spectrum therapy when possible" | |
| ] | |
| else: | |
| return [ | |
| f"Current clinical practice guidelines for {topic}", | |
| f"Evidence-based recommendations and quality indicators", | |
| f"Emerging research and future directions", | |
| f"Implementation strategies in clinical practice" | |
| ] | |
| def _generate_case_application_content(self, topic: str) -> List[str]: | |
| """Generate case application content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Case diagnosis: Acute pulmonary histoplasmosis", | |
| "Rationale: Geographic exposure + clinical presentation + positive urine antigen", | |
| "Treatment plan: Itraconazole 200 mg BID × 6-12 weeks", | |
| "Monitoring: Clinical response, itraconazole levels, hepatic function", | |
| "Patient education: Prognosis, medication adherence, follow-up", | |
| "Prevention: Avoid high-risk activities in endemic areas" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Case diagnosis: Community-acquired pneumonia, moderate severity", | |
| "CURB-65 score: 2 points (age > 65, confusion absent)", | |
| "Treatment: Ceftriaxone 2g IV daily + azithromycin 500mg IV daily", | |
| "Expected response: Clinical improvement within 48-72 hours", | |
| "Discharge criteria: Stable vital signs, tolerating oral therapy", | |
| "Follow-up: Chest X-ray in 6 weeks if high-risk patient" | |
| ] | |
| else: | |
| return [ | |
| f"Application of diagnostic criteria for {topic}", | |
| f"Treatment decision-making based on evidence", | |
| f"Monitoring response and adjusting therapy", | |
| f"Patient education and follow-up planning" | |
| ] | |
| def _generate_clinical_pearls_content(self, topic: str) -> List[str]: | |
| """Generate clinical pearls content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Geographic history is crucial - ask about travel to endemic areas", | |
| "Urine antigen testing provides rapid diagnosis for Histoplasma", | |
| "Lymphopenia is characteristic of histoplasmosis vs. bacterial infections", | |
| "Erythema nodosum suggests acute infection with good prognosis", | |
| "Itraconazole levels should be checked after 2 weeks of therapy", | |
| "Immunocompromised patients require longer, more intensive treatment" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Procalcitonin > 0.5 ng/mL suggests bacterial etiology", | |
| "Positive urinary antigens guide targeted antibiotic therapy", | |
| "CURB-65 score helps determine site of care (outpatient vs. hospital)", | |
| "Atypical pathogens require macrolide or fluoroquinolone coverage", | |
| "Clinical response expected within 48-72 hours of appropriate therapy", | |
| "Chest X-ray may lag behind clinical improvement by several days" | |
| ] | |
| else: | |
| return [ | |
| f"Key clinical insights for {topic}", | |
| f"Common pitfalls to avoid in diagnosis", | |
| f"Practical tips for optimal patient management", | |
| f"Important prognostic factors to consider" | |
| ] | |
| def _generate_rapid_fire_content(self, topic: str) -> List[str]: | |
| """Generate rapid fire questions content.""" | |
| if "dimorphic fungi" in topic.lower(): | |
| return [ | |
| "Q: Which dimorphic fungus is associated with spelunking? A: Histoplasma", | |
| "Q: What is the most sensitive test for histoplasmosis? A: Urine antigen", | |
| "Q: Which form is pathogenic at body temperature? A: Yeast form", | |
| "Q: What skin finding suggests acute coccidioidomycosis? A: Erythema nodosum", | |
| "Q: First-line treatment for mild histoplasmosis? A: Itraconazole", | |
| "Q: How long should treatment continue? A: 6-12 weeks for pulmonary disease" | |
| ] | |
| elif "pneumonia" in topic.lower(): | |
| return [ | |
| "Q: What is the most common cause of CAP? A: Streptococcus pneumoniae", | |
| "Q: Which score predicts 30-day mortality? A: CURB-65 or PSI", | |
| "Q: When should blood cultures be obtained? A: Before antibiotics in hospitalized patients", | |
| "Q: First-line outpatient treatment for CAP? A: Amoxicillin or macrolide", | |
| "Q: What biomarker helps guide antibiotic duration? A: Procalcitonin", | |
| "Q: How soon should clinical improvement occur? A: Within 48-72 hours" | |
| ] | |
| else: | |
| return [ | |
| f"Quick review questions about {topic}", | |
| f"Key facts and figures to remember", | |
| f"High-yield testing points", | |
| f"Clinical scenarios for practice" | |
| ] | |
| def _generate_discussion_content(self, topic: str) -> List[str]: | |
| """Generate discussion content.""" | |
| return [ | |
| "Questions and answers session", | |
| "Case-based discussion and clinical experiences", | |
| "Challenging scenarios and problem-solving", | |
| "Summary of key learning points", | |
| "Resources for further learning", | |
| "Contact information for follow-up questions" | |
| ] | |
| def _generate_generic_content(self, title: str, topic: str) -> List[str]: | |
| """Generate generic content for unspecified slide types.""" | |
| return [ | |
| f"Key concepts related to {title.lower()} in {topic}", | |
| f"Clinical significance and practical applications", | |
| f"Evidence-based approaches and recommendations", | |
| f"Integration with current clinical practice" | |
| ] | |
| def _generate_speaker_notes(self, slides: List[Dict], research_report: str) -> Dict[str, str]: | |
| """Generate detailed speaker notes for each slide.""" | |
| speaker_notes = {} | |
| for slide in slides: | |
| slide_number = slide["slide_number"] | |
| title = slide["title"] | |
| # Generate specific speaker notes based on slide content | |
| if "Title Slide" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Welcome the audience and introduce the topic.\n" | |
| notes += "Mention the importance of understanding dimorphic fungi in clinical practice.\n" | |
| notes += "Preview the learning objectives and interactive elements.\n" | |
| notes += "Encourage questions throughout the presentation.\n" | |
| elif "Learning Objectives" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Review each learning objective with the audience.\n" | |
| notes += "Explain how these objectives relate to clinical practice.\n" | |
| notes += "Ask: 'What is your current experience with diagnosing fungal infections?'\n" | |
| notes += "Set expectations for active participation.\n" | |
| elif "Case Vignette" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Present the case systematically, pausing for audience input.\n" | |
| notes += "Ask: 'What additional history would you want to obtain?'\n" | |
| notes += "Highlight key clinical clues that point to the diagnosis.\n" | |
| notes += "Build suspense - we'll return to this case later.\n" | |
| elif "Definition" in title or "Overview" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Explain the unique characteristics of dimorphic fungi.\n" | |
| notes += "Use the temperature-dependent morphology as a key teaching point.\n" | |
| notes += "Emphasize the geographic distribution and clinical significance.\n" | |
| notes += "Ask: 'Which endemic areas are you familiar with?'\n" | |
| elif "Pathophysiology" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Walk through the infection process step by step.\n" | |
| notes += "Emphasize the importance of cell-mediated immunity.\n" | |
| notes += "Explain why immunocompromised patients are at higher risk.\n" | |
| notes += "Connect pathophysiology to clinical presentation.\n" | |
| elif "Clinical Presentation" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Describe the spectrum of disease for each fungus.\n" | |
| notes += "Highlight distinguishing features between organisms.\n" | |
| notes += "Use clinical images if available to illustrate skin findings.\n" | |
| notes += "Ask: 'What clinical clues help differentiate these infections?'\n" | |
| elif "Diagnostic" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Discuss the pros and cons of each diagnostic method.\n" | |
| notes += "Emphasize the rapid turnaround time of urine antigen testing.\n" | |
| notes += "Explain when to use each test based on clinical scenario.\n" | |
| notes += "Address common pitfalls in diagnosis.\n" | |
| elif "Treatment" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Review IDSA guidelines for treatment recommendations.\n" | |
| notes += "Explain rationale for drug selection and duration.\n" | |
| notes += "Discuss monitoring parameters and side effects.\n" | |
| notes += "Address when to consult infectious disease specialists.\n" | |
| elif "Guidelines" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Highlight key recommendations from IDSA guidelines.\n" | |
| notes += "Discuss recent updates and changes in recommendations.\n" | |
| notes += "Emphasize evidence-based approach to treatment.\n" | |
| notes += "Provide resources for accessing current guidelines.\n" | |
| elif "Case Application" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Return to the opening case vignette.\n" | |
| notes += "Walk through the diagnostic reasoning process.\n" | |
| notes += "Explain treatment selection and monitoring plan.\n" | |
| notes += "Ask: 'What would you do differently in this case?'\n" | |
| elif "Clinical Pearls" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Emphasize practical tips for clinical practice.\n" | |
| notes += "Share memorable mnemonics or decision aids.\n" | |
| notes += "Highlight common mistakes to avoid.\n" | |
| notes += "Encourage audience to share their own pearls.\n" | |
| elif "Rapid Fire" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Engage the audience with quick questions.\n" | |
| notes += "Encourage rapid responses to build confidence.\n" | |
| notes += "Provide immediate feedback and explanations.\n" | |
| notes += "Use this as a knowledge check before concluding.\n" | |
| elif "Discussion" in title: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += "Open the floor for questions and discussion.\n" | |
| notes += "Encourage sharing of clinical experiences.\n" | |
| notes += "Address any remaining questions or concerns.\n" | |
| notes += "Provide contact information and additional resources.\n" | |
| notes += "Thank the audience for their participation.\n" | |
| else: | |
| notes = f"**Speaker Notes for Slide {slide_number}: {title}**\n\n" | |
| notes += f"Key talking points for {title}.\n" | |
| notes += "Connect to research findings and clinical evidence.\n" | |
| notes += "Engage audience with relevant questions.\n" | |
| notes += "Ensure smooth transition to next slide.\n" | |
| speaker_notes[str(slide_number)] = notes | |
| return speaker_notes | |
| def _generate_presentation_metadata(self, topic: str, target_audience: str, duration: int, total_slides: int) -> Dict[str, Any]: | |
| """Generate presentation metadata.""" | |
| metadata = { | |
| "topic": topic, | |
| "target_audience": target_audience, | |
| "duration_minutes": duration, | |
| "total_slides": total_slides, | |
| "created_date": "2025-07-18", | |
| "presentation_type": "Educational", | |
| "format": "PowerPoint/Slides", | |
| "estimated_time_per_slide": duration / total_slides if total_slides > 0 else 3, | |
| "learning_level": "Intermediate", | |
| "prerequisites": f"Basic knowledge of {topic}", | |
| "materials_needed": "Projector, handouts (optional)" | |
| } | |
| return metadata | |