""" Prompt utilities for personalization and content generation. Usage: ------ Import the model_config module: from src.model_config import get_llm_client, get_primary_model, get_backup_model The prompt utilities are used in: - src/tools/audio_utils.py (translations and named entity identification) - src/Slide_Creation_Node_refactor.py (slide narration) """ from typing import List, Optional #code_generation_node.py def get_code_segmentation_prompt(full_code: str, language: str = "python") -> str: """ Generates a clear prompt to send to the LLM to segment code. The input code is delimited so the model knows its boundaries, but the model's output must be raw JSON (no markdown wrappers). """ # Optional: strip extraneous leading/trailing whitespace to avoid weird indentation issues trimmed_code = full_code.strip() return ( f"Break down the following {language} code into logical, self-contained, and explainable segments. " "For each segment, provide the exact code snippet (preserving original line breaks and indentation) " "and a concise explanation (2–4 sentences describing its purpose and functionality).\n\n" "Return the output as a JSON array of objects. Each object must have exactly two keys: " "'code_snippet' (string) and 'explanation' (string). Ensure the segments collectively cover the entire " "provided code in the correct order. Do NOT include any extra text or conversational filler outside the " "main JSON array. Do NOT wrap the returned JSON in markdown (no ``` around it).\n\n" f"{language} Code (delimited by triple backticks):\n```{trimmed_code}```\n" ) # Slide_Creation_Node.py def get_oration_prompt( content: str, user_name: Optional[str] = None, user_age: Optional[int] = None, user_tech_knowledge: Optional[str] = None, user_preferred_activity: Optional[List[str]] = None ) -> List[dict]: """ Returns a system+user message list for generating a formal explanation (oration), optionally personalized based on available user metadata. """ prompt = ( "Craft a succinct, formally structured explanation (industrial training level) using the provided content. " "Avoid informalities (greetings, thanks). Use logical organization and pertinent real-world examples or scenarios " "if applicable to enhance comprehension. Do not include code blocks in the oration." ) if user_name: age_desc = f"{user_age}-year-old" if user_age is not None else "of unspecified age" tech = user_tech_knowledge or "beginner" activities = ', '.join(user_preferred_activity) if user_preferred_activity else "general topics" prompt += ( f" The student is {user_name}, a {age_desc} with {tech} level knowledge. " f"Use examples related to their interests: {activities}." ) return [ {"role": "system", "content": prompt}, {"role": "user", "content": content} ] #three_b_node.py def get_personalization_prompt( topic: str, programming_language: str, presentation_txt: str, user_name: Optional[str] = None, user_age: Optional[int] = None, user_gender: Optional[str] = None, user_tech_knowledge: Optional[str] = None, user_preferred_activity: Optional[List[str]] = None, user_food: Optional[str] = None, user_physical_activities: Optional[str] = None ) -> str: """ Returns the raw prompt body for personalizing a presentation. Caller is responsible for wrapping this into messages for the LLM. """ personalization_context = "" if user_name: age_desc = f"{user_age}-year-old" if user_age is not None else "of unspecified age" gender_part = f" {user_gender}" if user_gender else "" personalization_context += f"You are teaching {user_name}, a {age_desc}{gender_part} student. " if user_tech_knowledge: personalization_context += f"Their technical knowledge level is {user_tech_knowledge}. " if user_preferred_activity: activities = ', '.join(user_preferred_activity) personalization_context += f"They enjoy {activities}. " if user_food: personalization_context += f"Their favorite food is {user_food}. " if user_physical_activities: personalization_context += f"They like {user_physical_activities}. " personalization_context += "Use examples and analogies that relate to their interests and knowledge level. " prompt = ( f"{personalization_context}\n" f"Here is an existing presentation for the topic '{topic}' in '{programming_language}':\n\n" f"{presentation_txt}\n\n" "Please personalize and enhance this presentation for the student described above. " "Keep the structure and number of slides, but adjust examples, analogies, and explanations to better fit the student's interests and background. " "Do not generate from scratch; instead, modify and enrich the provided content. " "Keep each slide concise (max 100 words or 10 lines). " "Format EACH slide strictly as:\n" "Slide :\nTitle: \n\n" "Content:\n" ".\n" "IMPORTANT: When declaring code blocks, do not mention the code extension, programming language, or file type. " "Simply use ``` to start and end the code block." ) return prompt def build_concept_code_prompt(topic: str, programming_language: str) -> str: return ( f"Create a comprehensive {programming_language} program that demonstrates the concept of " f"'{topic}' with practical examples and clear comments." ) def get_code_generation_prompt(programming_language: str, code_prompt: str) -> list[dict]: system_msg = { "role": "system", "content": ( f"Generate executable {programming_language} code based on the provided topic and analogy. " "The code should be complete, runnable, and demonstrate the concept clearly without requiring user input." ) } user_msg = {"role": "user", "content": code_prompt} return [system_msg, user_msg] #three_a_node.py def get_subtitle_prompt(topic: str) -> str: """ Returns a prompt to generate a 3–5 word subtitle based on topic. """ return f"Generate 3-5 word subtitle based on {topic}" def get_presentation_generation_prompt(topic: str, programming_language: str) -> str: """ Returns a prompt for generating a presentation for a given topic and programming language. """ return ( f"Generate content to explain '{topic}' for students, focusing on '{programming_language}'. " "Present the most important basics using concise bullet points. Include small, relevant real-world examples " "with brief code snippets (only if truly necessary and illustrative). Maintain a professional tone. " "DIVIDE THE OUTPUT INTO EXACTLY 4-6 SLIDES to ensure thorough coverage. " "Each slide should cover a distinct aspect of the topic. " "Keep each bullet point to 1-2 lines and limit each slide's content to a maximum of 80 words. " "Code snippets should be 3-5 lines maximum. " "Format EACH slide strictly as:\n" "Slide :\nTitle: \n\nContent:\n" "'.\n" "Include one slide with a real-world analogy to help students understand the concept.\n" "IMPORTANT: When declaring code blocks, do not mention the code extension, programming language, or file type. " "Simply use ``` to start and end the code block." ) def get_topic_code_prompt(topic: str, programming_language: str) -> tuple[str, str]: """ Returns system and user messages for generating executable code for a topic. """ system_message = ( f"Generate executable {programming_language} code based on the provided topic and analogy. " "The code should be complete, runnable, and demonstrate the concept clearly without requiring user input." ) user_message = ( f"Based on this topic '{topic}' create executable {programming_language} code that demonstrates the concept clearly." ) return system_message, user_message #audio_utils.py def get_named_entity_identification_prompt() -> str: """ Returns the prompt for identifying named entities and coding jargon in a text for translation context. """ return ( "Below is a technical explanation that will be translated into another language. " "Your task is to identify parts of the text that are specific named entities—these include:\n" "Coding Jargon: Specific functions, classes, variables, or code snippets (e.g., main(), print()). " "Make sure to include as much coding jargon as possible\n" "Technical Terms: Programming languages (e.g., Python, JavaScript), libraries (e.g., TensorFlow, NumPy)\n" "Proper Nouns: Names of organizations, products, or companies (e.g., Across the Globe, Microsoft).\n" "terms like loops are named entities that should not be translated.\n\n" "Wrap these identified words or phrases in the tag . " "Ensure the final text is formatted exactly as requested and returned within triple single quotes ('''). " "Do not modify the text except to add the tags. Here's the text:" ) def get_regional_translation_prompt(target_language: str, cleaned_text: str) -> str: """ Returns the prompt for translating English text to a specified regional language. """ return f""" Translate the following English text to "{target_language}" and return JSON only: "{cleaned_text}" Guidelines: - Use simple, everyday {target_language}. - Avoid complex words. - Don't translate 'For', 'If', or 'Across The Globe'. - Use pure {target_language} script. - Respond ONLY as JSON like this: {{ "translation": "" }} """ def get_pun_translation_prompt(target_language: str, cleaned_text: str) -> str: """ Builds the prompt for translating English text to a regional language (Punjabi variant). """ return f""" Translate the following English text to "{target_language}" and return JSON only: "{cleaned_text}" Guidelines: - Use simple, everyday {target_language}. - Avoid complex words. - Don't translate 'For', 'If', or 'Across The Globe'. - Use pure {target_language} script. - Respond ONLY as JSON like this: {{ "translation": "" }} """ def get_pun_named_entity_prompt() -> str: """ Returns the prompt for identifying named entities and coding jargon in a text for Punjabi translation context. """ return ( "Below is a technical explanation that will be translated into another language. " "Your task is to identify parts of the text that are specific named entities—these include:\n\n" "Coding Jargon: Specific functions, classes, variables, or code snippets (e.g., main(), print()). " "Make sure to include as much coding jargon as possible\n" "Technical Terms: Programming languages (e.g., Python, JavaScript), libraries (e.g., TensorFlow, NumPy)\n" "Proper Nouns: Names of organizations, products, or companies (e.g., Across the Globe, Microsoft).\n" "terms like loops are named entities that should not be translated.\n\n" "Wrap these identified words or phrases in the tag . " "Ensure the final text is formatted exactly as requested and returned within triple single quotes ('''). " "Do not modify the text except to add the tags. Here's the text:" ) # Slide_Creation_Node_refactor.py def get_tts_narration_prompt( slide_content: str, slide_title: str, topic: str, target_audience: str = "beginners", user_name: Optional[str] = None, previous_slide_title: Optional[str] = None, previous_slide_summary: Optional[str] = None ) -> str: """ Returns a prompt optimized for generating natural, conversational narration text specifically designed for TTS (Text-to-Speech) with Gemini API. This prompt focuses on: - Natural speech patterns with proper punctuation for pauses - Conversational tone that sounds realistic when spoken - Strategic use of commas, periods, and ellipses for pacing - Avoiding robotic bullet-point reading - Context awareness from previous slides for smooth transitions """ personalization = f" The student's name is {user_name}." if user_name else "" # Build context from previous slide if available context_section = "" if previous_slide_title and previous_slide_summary: context_section = f""" PREVIOUS SLIDE CONTEXT: Previous Topic: {previous_slide_title} Key Points Covered: {previous_slide_summary} IMPORTANT: Create a smooth transition from the previous slide. Use phrases like: - "Now that we've covered [previous topic], let's move to..." - "Building on what we just learned about [previous topic]..." - "Next, we'll explore..." - "This connects directly to what we discussed about [previous topic]..." """ return f"""You are creating a narration script for a text-to-speech system. The script will be read aloud by an AI voice, so it must sound natural, engaging, and conversational when spoken. SLIDE INFORMATION: Title: {slide_title} Topic: {topic} Audience: {target_audience}{personalization} {context_section} CONTENT TO NARRATE: {slide_content} TTS NARRATION GUIDELINES: 1. NATURAL SPEECH PATTERNS: - Write as if you're continuing an ongoing conversation with the student - Use conversational phrases like "Let's explore...", "You see...", "Now here's the interesting part..." - Vary sentence length for natural rhythm - DO NOT use greetings like "Welcome", "Hello", or "Hi" - we're in the middle of the lesson 2. PUNCTUATION FOR PACING (Critical for TTS): - Use commas (,) for brief pauses and breath breaks - Use periods (.) for natural sentence endings - Use ellipses (...) for thoughtful pauses or building anticipation - Use em dashes (—) for emphasis or adding related thoughts - Example: "First, let's understand the basics... Python is powerful, flexible, and—most importantly—easy to learn." 3. EMOTIONAL INTELLIGENCE: - Show enthusiasm for interesting concepts: "Here's what makes this amazing!" - Acknowledge difficulty: "This might seem tricky at first, but stick with me..." - Build confidence: "You've got this!", "Let's break this down together." - Use encouraging transitions: "Great! Now that we understand X, let's move to Y." 4. STRICT RULES - AVOID: - Welcome greetings ("Welcome", "Hello", "Hi") - this is NOT the introduction - Robotic bullet-point reading ("Point one. Point two.") - Long, complex sentences without breaks - Academic jargon without explanation - Monotonous structure - Starting fresh as if it's a new lesson - maintain continuity 5. PACING TECHNIQUES: - Start with a transition or hook: "Now let's look at..." or "Here's where it gets interesting..." - Use rhetorical questions to engage: "Why does this matter?" - Break complex ideas into digestible chunks with pauses - End with a memorable takeaway or bridge to the next concept 6. CODE MENTIONS: - When mentioning code, speak it naturally: "the print function" not "print parenthesis close parenthesis" - Add brief context: "the main function, which is where our program starts" OUTPUT REQUIREMENTS: - Generate 3-5 sentences of natural, conversational narration - Length: 60-120 words (optimal for TTS clarity) - Include strategic punctuation for natural pauses - Sound like a friendly, knowledgeable teacher continuing a lesson - Make it engaging and personalized for {target_audience} - NO welcome/greeting phrases - maintain lesson continuity Generate the TTS-optimized narration script now:""" def get_length_limited_narration_prompt(original_text: str, max_seconds: int = 15, wpm: int = 150, user_name: Optional[str] = None) -> str: """ Returns a prompt instructing the LLM to shorten a narration to a target time limit while preserving natural tone and punctuation suitable for TTS. """ max_words = max(10, int(max_seconds * wpm / 60)) personalization = f"Address the learner by their name, {user_name}, at the beginning. " if user_name else "" return ( f"{personalization}Rewrite the following narration so that it is at most {max_words} words long (approx {max_seconds} seconds at {wpm} WPM).\n" "Maintain a friendly, conversational tone suitable for TTS, and preserve punctuation for pauses (commas, ellipses, dashes).\n" "Do not truncate mid-sentence; prefer to rephrase to keep the meaning and natural flow.\n\n" f"Original narration:\n{original_text}\n\n" "Return only the revised, shortened narration text (no extra commentary)." ) def shorten_narration_text(client, original_text: str, max_seconds: int = 15, wpm: int = 150, user_name: Optional[str] = None, model: str = "gpt-4o-mini") -> str: """ Uses the provided client (OpenAI) to shorten a narration to fit within the given time limit. Falls back to a simple word truncation if the client is not available. """ if not original_text or not original_text.strip(): return original_text max_words = max(10, int(max_seconds * wpm / 60)) if len(original_text.split()) <= max_words: return original_text prompt = get_length_limited_narration_prompt(original_text, max_seconds, wpm, user_name) if not client: # Fallback: simple truncation by words preserving punctuation as much as possible. words = original_text.split() shortened = " ".join(words[:max_words]) # Try to end at the last sentence terminator if present for sep in ['. ', '... ', '? ', '! ']: if sep in shortened: shortened = shortened.rsplit(sep, 1)[0] + sep.strip() break return shortened try: completion = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": "You are concise copywriter for TTS narration. Keep it friendly, natural, and short."}, {"role": "user", "content": prompt}, ], temperature=0.6, max_tokens=300, ) shortened = completion.choices[0].message.content or original_text return shortened.strip() except Exception: # Safe fallback words = original_text.split() return " ".join(words[:max_words]) def get_welcome_narration_prompt( topic: str, subtitle: str, user_name: Optional[str] = None, target_audience: str = "beginners" ) -> str: """ Returns a prompt specifically for generating an engaging welcome/introduction narration. This is ONLY for the first slide of the video. This prompt focuses on: - Warm, welcoming tone with greetings - Building excitement about the topic - Setting expectations for what they'll learn - Personal connection with the student """ personalization = f" The student's name is {user_name}." if user_name else "" greeting = f"Hello {user_name}! " if user_name else "Welcome! " return f"""You are creating the opening narration for an educational video. This is the FIRST thing the student will hear, so make it warm, welcoming, and exciting! VIDEO INFORMATION: Topic: {topic} Subtitle: {subtitle} Audience: {target_audience}{personalization} WELCOME NARRATION GUIDELINES: 1. WARM GREETING (REQUIRED): - Start with "{greeting}" - If user name provided: "Hello [name]! Welcome to..." - If no name: "Welcome! Today we're going to..." - Make it personal and friendly 2. BUILD EXCITEMENT: - Show enthusiasm: "I'm so excited to teach you about..." - Highlight what makes this topic interesting: "This is one of the most powerful concepts in programming..." - Use phrases like: "You're about to learn...", "Get ready to discover..." 3. SET EXPECTATIONS: - Briefly mention what they'll learn: "In this video, we'll cover..." - Keep it high-level and motivating - Make it feel achievable: "By the end, you'll be able to..." 4. TTS OPTIMIZATION: - Use commas (,) for brief pauses - Use ellipses (...) for anticipation - Use periods (.) for natural sentence endings - Keep it conversational and natural 5. TONE: - Friendly and encouraging - Enthusiastic but not overwhelming - Professional yet approachable - Like a knowledgeable friend starting a conversation 6. LENGTH: - Keep it concise: 40-80 words - This will be shortened to ~15 seconds - Focus on greeting + excitement + brief overview OUTPUT REQUIREMENTS: - MUST start with a greeting ("Welcome" or "Hello [name]") - Generate 3-5 sentences - Include strategic punctuation for natural TTS delivery - Sound warm, welcoming, and excited to teach - Make the student feel this will be a great learning experience Generate the welcome narration script now:"""