import os
from vllm import SamplingParams
from video_utils import create_multimodal_prompt_for_qwen

"""
This module contains functions that return various prompts used in the video game builder.
"""

def format_memories_for_prompt(memories):
    """
    Format memories for inclusion in prompts.
    
    Args:
        memories: List of memory entries
    
    Returns:
        Formatted string for prompt inclusion
    """
    if not memories:
        return ""
    
    formatted_lines = []
    for memory in memories:
        iteration = memory.get("iteration", "?")
        notes = memory.get("notes", "").strip()
        if notes:
            formatted_lines.append(f"Iteration {iteration}: {notes}")
    
    if not formatted_lines:
        return ""
    
    return f"""
PAST MEMORIES (last {len(formatted_lines)} iterations):
{chr(10).join(formatted_lines)}
"""


# System prompts
def get_default_system_omni():
    """Get the default system prompt for Qwen."""
    return "You are Qwen, a virtual human developed by the Qwen Team, Alibaba Group, capable of perceiving auditory and visual inputs, as well as generating text and speech."
def get_default_system():
    """Get the default system prompt."""
    return "You are a helpful assistant."
def get_default_system_devstral():
    """Get the default system prompt."""
    return "You are Devstral, a helpful agentic model trained by Mistral AI."

def get_system_prompt(model_path):
    """Get the appropriate system prompt based on the model path."""
    if "Omni" in model_path or "EchoInk" in model_path:
        return get_default_system_omni()
    elif "Devstral" in model_path:
        return get_default_system_devstral()
    else:
        return get_default_system()
    return None

# Instruction libraries
def _get_base_instructions(content_type, cdn_allowed=True):
    """Get base instructions for all content types."""
    # Set CDN instruction based on cdn_allowed parameter
    if cdn_allowed:
        cdn_instruction = "You can use HTML5 Canvas and any javascript library via CDN (e.g., Phaser, Three.js, PixiJS, Babylon.js, Matter.js)"
    else:
        cdn_instruction = "You can use HTML5 Canvas. External Javascript libraries via CDN are not allowed!"
    
    return [
        "Be contained in a single HTML file",
        cdn_instruction,
        "Assume that the user does not have a GPU; the code should run well on CPUs."
        "Have clear, well-commented code with meaningful variable names",
        #"Include proper error handling",
        "Implement smooth animations for all moving elements",
        #f"Include a title screen with a button that has id='start-button' to start the {content_type}. Ensure that audio only starts after pressing the start button.",
        f"Include a title screen with a large button that has id='start-button'. Pressing 'enter' or clicking the button should press the button and start the {content_type}. Ensure that audio only starts after pressing the start button.",
        'DO NOT use alerts (e.g., alert("Game Over!"))'
    ]

def _get_specific_instructions(content_type):
    """Get content-specific instructions."""
    if content_type == "video-game":
        return [
            "Include AI to control the player by default; it should play the game in a smart way.",
            "Allow switching to human control when F4 is pressed",
            "Include game state management and responsive control",
            "No broken behaviors (softlock, hardlock, hitbox bugs, clipping, AI breakdown, etc.)"
        ]
    elif content_type == "animation":
        return [
            "Include interesting visual elements and transitions",
            "Focus on aesthetic appeal",
            "Respect physical laws if relevant to the requested animation",
            "No broken behaviors (jank, broken keyframes, hitbox bugs, clipping, etc.)"
        ]
    else:  # website
        return [
            "Create a responsive website that works well on different screen sizes",
            "Include appropriate navigation and user interface elements",
            "Implement interactive elements where appropriate",
            "Focus on clean design and good user experience",
        ]

def _get_visual_instructions(content_type):
    """Get visual instructions for the content type."""
    if content_type == "video-game":
        return [
            "Use clear, visually distinct elements for game objects",
            "Ensure visual feedback for player actions and game events",
            "Use appropriate colors and visual effects to enhance gameplay",
            "Maintain consistent visual style throughout the game"
        ]
    elif content_type == "animation":
        return [
            "Create visually appealing elements with attention to detail",
            "Implement appropriate visual effects to enhance the animation",
            "Ensure consistent visual style throughout the animation",
            "Use color and composition effectively to convey mood and theme"
        ]
    else:  # website
        return [
            "Use a clean, consistent visual design throughout the website",
            "Ensure readable text with good contrast against backgrounds",
            "Use visual cues to guide user navigation and interaction",
            "Include appropriate spacing and layout for optimal readability"
        ]

def _get_audio_instructions(content_type):
    """Get audio instructions for the content type."""
    if content_type == "video-game":
        return [
            "Include background music that fits the theme and mood of the game",
            "Add sound effects for key game events (jumps, collisions, item collection)",
            "Implement audio controls (mute/unmute) with the 'M' key",
            "Ensure audio volume is balanced and not overwhelming"
        ]
    elif content_type == "animation":
        return [
            "Include background music that complements the animation's mood and pace",
            "Add sound effects for key animation events and transitions",
            "Synchronize audio timing with visual elements",
            "Implement audio controls (mute/unmute) with the 'M' key"
        ]
    else:  # website
        return [
            "Use subtle background music that doesn't distract from the content",
            "Add sound effects for user interactions (clicks, hovers, form submissions)",
            "Implement audio controls (mute/unmute) with the 'M' key",
            "Ensure audio volume is balanced and not overwhelming"
        ]

def _format_list(items, start_index=1):
    """Format a list of items with numbering."""
    return "\n".join(f"{i}. {item}" for i, item in enumerate(items, start=start_index))

def _format_list_(items, start_index=1):
    """Format a list of items with numbering."""
    return "\n".join(f"{i}) {item}" for i, item in enumerate(items, start=start_index))

def get_content_instructions(content_type, cdn_allowed=True):
    """Get the base and specific instructions for a given content type."""
    base = _format_list(_get_base_instructions(content_type, cdn_allowed) + _get_specific_instructions(content_type))
    visual = _format_list(_get_visual_instructions(content_type))
    audio = _format_list(_get_audio_instructions(content_type))
    
    return base, visual, audio

def get_asset_info(asset_dir, asset_tree, has_audio, content_type):
    """Get asset information for prompts."""
    if not asset_dir or not asset_tree:
        return ""
    
    return f"""
Available Assets:
The following assets are available for use in the javascript code:
{asset_tree}

You can reference any asset using their full path: "{asset_dir}/path/to/asset.png"
IMPORTANT: Do not use placeholder assets. Do not attempt to load assets from online websites. Only refer to assets that are available (see above) or make your own assets (e.g., sounds/music using Tone.js).
"""

def get_initial_content_prompt(content_description, content_type, asset_info, has_audio=False, cdn_allowed=True):
    """Get the prompt for generating initial content."""
    base_instructions, visual_instructions, audio_instructions = get_content_instructions(content_type, cdn_allowed)
    
    content_type_display = "playable game" if content_type == "video-game" else "visually appealing animation" if content_type == "animation" else "functional website"
    
    prompt = f"""{content_type.title()} Description:
{content_description}

{asset_info}

Please provide the complete code for making the {content_type}. The code should:
{base_instructions}

Visual Guidelines:
{visual_instructions}
"""
    
    if asset_info and has_audio:
        prompt += f"""
Audio Guidelines:
{audio_instructions}
"""
    
    prompt += f"""
Focus on creating a complete {content_type_display} that matches the description.
Return the code within ```html and ``` tags.
"""
    
    return prompt

def get_console_logs_section(console_logs_path):
    """Get the console logs section for prompts."""
    if not console_logs_path or not os.path.exists(console_logs_path):
        return ""
    
    try:
        with open(console_logs_path, "r", encoding="utf-8") as f:
            console_logs = f.read()
        
        if not console_logs or console_logs == "No console logs captured":
            return ""
        
        return f"""
Console Logs:
```
{console_logs}
```

Analyze these logs for errors or issues.
"""
    except Exception as e:
        print(f"Error reading console logs: {e}")
        return ""

def _get_feedback_criteria(content_type, exclude_technical, has_audio, content_description):
    """Get feedback criteria for a content type."""
    criteria = [f"Description Fidelity: How well does the {content_type} match the following description? Description: {content_description}."]
    
    if content_type == "video-game":
        criteria = [
            "Visual Quality: How appealing are the graphics and animations? Are colors, objects, and layout harmonious?",
            "Gameplay Quality: How engaging and fun is the gameplay?",
            "AI Player Quality: How well does the AI play the game? (if working properly, it should have an AI playing the game automatically)",
            "Fidelity to Description: How well does the game match the original description?",
            "Behavior Correctness: Are there any broken behaviors?"
        ]
    
    elif content_type == "animation":
        criteria = [
            "Visual Quality: How appealing are the graphics and animations? Are colors, shapes, and layout harmonious?",
            "Animation Smoothness: How smooth and fluid are the animations? Are key frames and timing polished?",
            "Creativity: How creative and interesting is the animation?",
            "Fidelity to Description: How well does the animation match the original description?",
            "Behavior Correctness: Are there any broken behaviors?"
        ]
            
    else:  # website
        criteria = [
            "Visual Design: How appealing is the visual design of the website? Are colors, shapes, and layout harmonious?",
            "User Experience: How intuitive and easy to use is the website?",
            "Functionality: How well do the interactive elements work?",
            "Fidelity to Description: How well does the website match the original description?",
            "Behavior Correctness: Are there any broken behaviors?"
        ]
        

    if not exclude_technical:
        criteria.insert(0, "Technical Implementation: Are there bugs or issues?")
    
    if has_audio:
        audio_criterion = "Audio Quality: How well does the audio (sound effects and music) align with the content and enhance its quality?"
        criteria.append(audio_criterion)
    
    return _format_list_(criteria)

def get_evaluator_feedback_prompt(content_description, content_type, has_audio, exclude_technical, current_code, asset_info="", cdn_allowed=True):
    """Get the prompt for evaluator feedback."""
    criteria = _get_feedback_criteria(content_type, True, has_audio, content_description)
    base_instructions, visual_instructions, audio_instructions = get_content_instructions(content_type, cdn_allowed)
    
    prompt = f"""Provide detailed feedback on this {content_type} based on the video recording{' with corresponding audio.' if has_audio else '.'}

For each criterion, please provide a brief assessment with specific observations and suggestions for improvements.
Be specific and actionable. Focus on high-impact improvements.

Feedback Criteria:
{criteria}
"""

    prompt += f"""
Visual Guidelines:
{visual_instructions}
"""
    
    if asset_info and has_audio:
        prompt += f"""
Audio Guidelines:
{audio_instructions}
"""
    return prompt

def _get_critical_issues(content_type, has_audio):
    """Get critical issues for a content type."""
    if content_type == "video-game":
        issues = [
            "Blank screen or game doesn't start automatically",
            "AI not properly controlling the game",
            "Player control with F4 not working",
            "Visual glitches, rendering issues, or gameplay bugs",
        ]
    elif content_type == "animation":
        issues = [
            "Blank screen or animation doesn't start automatically",
            "Animation not running smoothly or has glitches",
            "Visual artifacts or rendering problems",
        ]
    else:  # website
        issues = [
            "Blank screen or website doesn't load properly",
            "Interactive elements not working correctly",
            "Layout issues, rendering problems, or visual glitches",
            "Responsiveness issues",
        ]
    if has_audio:
        issues += ["Audio issues"]
    return issues

def _get_improvements(content_type, has_audio):
    """Get improvements for a content type."""
    if content_type == "video-game":
        issues = [
            "Enhance gameplay mechanics",
            "Improve visual elements",
            "Make AI player more intelligent",
            "Add game progression",
            "Optimize performance",
            "Improve code organization",
        ]
    elif content_type == "animation":
        issues = [
            "Enhance visual elements",
            "Add more complexity and transitions",
            "Improve flow and timing",
            "Add more details and polish",
            "Optimize performance",
            "Improve code organization",
        ]
    else:  # website
        issues = [
            "Enhance visual design",
            "Improve navigation and UI",
            "Add more interactive features",
            "Optimize performance",
            "Improve code organization",
            "Ensure accessibility",
        ]
    if has_audio:
        issues += ["Enhance audio"]
    return issues

def get_critical_issues(content_type, has_audio):
    """Get the critical issues and improvements for a given content type."""
    issues = _format_list(_get_critical_issues(content_type, has_audio))
    improvements = _format_list(_get_improvements(content_type, has_audio))
    
    return f"""
CRITICAL ISSUES TO FIX:
{issues}

IMPROVEMENTS TO MAKE:
{improvements}
"""

def get_improvement_prompt(content_description, content_type, current_code, asset_info, feedback_section, console_logs_section, has_audio, early_exit=False, search_replace=False, memories=None, cdn_allowed=True):
    """Get the prompt for generating an improved version of the content."""
    base_instructions, visual_instructions, audio_instructions = get_content_instructions(content_type, cdn_allowed)
    critical_issues = get_critical_issues(content_type, has_audio)
    
    # Format memories for inclusion in prompt if provided
    memory_section = format_memories_for_prompt(memories) if memories else ""
    
    prompt = f"""{content_type.title()} Description:
{content_description}

{asset_info}

Current {content_type.title()} Code:
```html
{current_code}
```

{feedback_section}
{console_logs_section}
The code must:
{base_instructions}

Visual Guidelines:
{visual_instructions}
"""
    
    if asset_info and has_audio:
        prompt += f"""
Audio Guidelines:
{audio_instructions}
"""

    # Add memory section if memories are provided
    if memory_section:
        prompt += f"""
{memory_section}
"""

    prompt += f"""
{critical_issues}
"""

    if early_exit:
        prompt += f"""
NOTE: If you are 100% satisfied with the current content (there are no console log errors, the feedback is minimal, the chosen assets fit perfectly, 
and you believe it's production-ready with a complete experience from beginning to end), you can indicate that you're done.
To do this, include the exact text "EARLY_EXIT: TRUE" at the beginning of your response, followed by a brief explanation 
of why you believe the content is complete.
"""

    # Add notes instruction if memories are enabled
    if memories is not None:
        prompt += f"""

IMPORTANT: In addition to providing the improved HTML code, please also provide brief notes about what was observed this iteration, short-term plans, and what you accomplished.
Include this summary in <notes></notes> tags at the end of your response.
"""

    if search_replace:
        prompt += f"""

Option 1: Full HTML Rewrite
If your changes are extensive or affect the overall structure of the code, provide the complete rewritten HTML code within ```html and ``` tags.

Option 2: Search and Replace
If your changes are targeted to specific sections, you can use the search/replace format:

<<<<<<< SEARCH
[exact content to find]
=======
[new content to replace with]
>>>>>>> REPLACE

You can include a few search/replace blocks to make several targeted changes. Each block will be applied in the order provided.

Guidelines for using search/replace:
1. The SEARCH content must match exactly (including whitespace and indentation)
2. Each search/replace block will only replace the first match
3. Keep blocks concise - include just enough lines to uniquely identify the section
4. To delete code: use an empty REPLACE section
5. To add new code: include the surrounding context in SEARCH to identify the insertion point

Choose the most appropriate format based on the nature of your changes:
- Use full rewrite for major restructuring or when changes affect most of the file
- Use search/replace for targeted changes to specific sections while leaving the rest untouched
"""
    else:
        prompt += f"""
    Return the complete improved code within ```html and ``` tags.
    """
    
    return prompt

def get_simplified_improvement_prompt(content_type, feedback_section, early_exit=False, search_replace=False, memories=None):
    """Get a simplified prompt for generating an improved version of the content."""
    
    # Format memories for inclusion in prompt if provided
    memory_section = format_memories_for_prompt(memories) if memories else ""
    
    prompt = f"""The video shows the {content_type} being {'played' if content_type == 'video-game' else 'displayed'}. 
            
{feedback_section}"""

    # Add memory section if memories are provided
    if memory_section:
        prompt += f"""
{memory_section}"""

    prompt += f"""

Continue improving the content based on the feedback and current state."""

    if early_exit:
        prompt += f"""

NOTE: If you are 100% satisfied with the current content (there are no console log errors, the feedback is minimal, the chosen assets fit perfectly, 
and you believe it's production-ready with a complete experience from beginning to end), you can indicate that you're done.
To do this, include the exact text "EARLY_EXIT: TRUE" at the beginning of your response, followed by a brief explanation 
of why you believe the content is complete.
"""

    # Add notes instruction if memories are enabled
    if memories is not None:
        prompt += f"""

IMPORTANT: In addition to providing the improved HTML code, please also provide brief notes about what was observed this iteration, short-term plans, and what you accomplished.
Include this summary in <notes></notes> tags at the end of your response.
"""

    if search_replace:
        prompt += f"""

RESPONSE FORMAT OPTIONS:

Option 1: Full HTML Rewrite
If your changes are extensive or affect the overall structure of the code, provide the complete rewritten HTML code within ```html and ``` tags.

Option 2: Search and Replace
If your changes are targeted to specific sections, you can use the search/replace format:

<<<<<<< SEARCH
[exact content to find]
=======
[new content to replace with]
>>>>>>> REPLACE

You can include multiple search/replace blocks to make several targeted changes. Each block will be applied in the order provided.

Guidelines for using search/replace:
1. The SEARCH content must match exactly (including whitespace and indentation)
2. Each search/replace block will only replace the first match
3. For multiple changes to the same area, use multiple blocks
4. Keep blocks concise - include just enough lines to uniquely identify the section
5. To delete code: use an empty REPLACE section
6. To add new code: include the surrounding context in SEARCH to identify the insertion point

Choose the most appropriate format based on the nature of your changes:
- Use full rewrite for major restructuring or when changes affect most of the file
- Use search/replace for targeted changes to specific sections while leaving the rest untouched
"""
    else:
        prompt += f"""
    Return the complete improved code within ```html and ``` tags.
    """
    
    return prompt

def get_feedback_section(evaluator_feedback):
    """Get the feedback section for prompts."""
    if not evaluator_feedback:
        return ""
    
    return f"""
EVALUATOR FEEDBACK:
{evaluator_feedback}

Address the issues and suggestions in this feedback.
"""

def _get_evaluation_criteria_items_with_desc(content_type, has_audio, content_description, with_AI=True):
    """Get evaluation criteria items for a content type."""
    criteria = [
        f"""Description Fidelity (0-10): How well does the {content_type} match the following description? Description: "{content_description}".""",
    ]
    
    if content_type == "video-game":
        if with_AI:
            criteria.extend([
                "Visual Design (0-10): How appealing are the graphics and animations? Are colors, objects, and layout harmonious?",
                "Gameplay Quality (0-10): How engaging and fun is the gameplay?",
                #"Technical Implementation (0-10): How well is the game coded? Are there bugs or issues?",
                "AI Player Quality (0-10): How well does the AI play the game?",
                "Behavior Correctness (0-10): Are there any broken behaviors?"
            ])
        else: # No AI, only for comparing to real games
            criteria.extend([
                "Visual Design (0-10): How appealing are the graphics and animations? Are colors, objects, and layout harmonious?",
                "Gameplay Quality (0-10): How engaging and fun is the gameplay?",
                #"Technical Implementation (0-10): How well is the game coded? Are there bugs or issues?",
                #"AI Player Quality (0-10): How well does the AI play the game?",
                "Behavior Correctness (0-10): Are there any broken behaviors?"
            ])
    elif content_type == "animation":
        criteria.extend([
            "Visual Design (0-10): How appealing are the graphics and animations? Are colors, shapes, and layout harmonious?",
            "Smoothness (0-10): How smooth and fluid are the animations? Are key frames and timing polished?",
            "Creativity and Originality (0-10): How creative and interesting is the animation?",
            #"Technical Implementation (0-10): How well is the animation coded? Are there bugs or issues?",
            "Behavior Correctness (0-10): Are there any broken behaviors?"
        ])
    else:  # website
        criteria.extend([
            "Visual Design (0-10): How appealing is the visual design of the website? Are colors, shapes, and layout harmonious?",
            "User Experience (0-10): How intuitive and easy to use is the website?",
            "Functionality (0-10): How well do the interactive elements work?",
            #"Technical Implementation (0-10): How well is the website coded? Are there bugs or issues?",
            "Behavior Correctness (0-10): Are there any broken behaviors?"
        ])
    
    if has_audio:
        criteria.append("Audio Quality (0-10): How well does the audio (sound effects and music) align with the content and enhance its quality?")
    
    #criteria.append("Overall score (0-10): How well would rate this content overall based on your own judgement?")

    return _format_list_(criteria)

def describe_content(has_audio):
    if has_audio:
        return """Please describe the video and the corresponding audio."""
    else:
        return """Please describe the video."""

def get_evaluation_prompt(content_description, content_type, console_logs_section, has_audio, with_AI=True):
    """Get the prompt for evaluating content."""
    criteria = _get_evaluation_criteria_items_with_desc(content_type, has_audio, content_description, with_AI)

    output = f"""Evaluate this {content_type} based on the video recording with corresponding audio.

Consider these evaluation criteria:
{criteria}

For each criterion, please provide a Numerical score (0-10) with a detailed explanation mentionning the strengths and weaknesses.

Then, provide the final answer in <answer> </answer>."""

    if has_audio:
        output += f"""
For example: <answer>a, b, c, d, e, f</answer> (i.e., criterion 1,2,3,4,5,6 respectively have scores a/10, b/10, c/10, d/10, e/10, f/10)."""
    else:
        output += f"""
For example: <answer>a, b, c, d, e</answer> (i.e., criterion 1,2,3,4,5 respectively have scores a/10, b/10, c/10, d/10, e/10)."""

    return output

def get_review_evaluations_prompt(content_description, content_type, evaluations, has_audio, description_feedbacks=None, temp_feedback=0.6, with_AI=True):
    """
    Get the prompt for reviewing multiple evaluations.
    
    Args:
        content_description: Description of the content
        content_type: Type of content ("video-game", "animation", or "website")
        evaluations: List of evaluation texts
        has_audio: audio enabled
        description_feedbacks: List of description feedbacks (optional)
    
    Returns:
        Prompt for reviewing evaluations
    """
    criteria = _get_evaluation_criteria_items_with_desc(content_type, has_audio, content_description, with_AI)
    
    # Combine all evaluations into a single string
    combined_evaluations = "\n\n".join([
        f"EVALUATION {i+1} ({'temp=0.0' if i == 0 else f'temp={temp_feedback} run {i}'}):\n{eval}"
        for i, eval in enumerate(evaluations)
    ])
    
    # Prepare additional sections if provided
    description_section = ""
    if description_feedbacks and len(description_feedbacks) > 0:
        combined_descriptions = "\n\n".join([
            f"DESCRIPTION {i+1}:\n{desc}"
            for i, desc in enumerate(description_feedbacks)
        ])
        description_section = f"""
Additionally, here are {len(description_feedbacks)} descriptions of the content:

{combined_descriptions}
"""
    
    output = f"""You are reviewing evaluations of a {content_type} with the following description:
"{content_description}".

EVALUATION CRITERIA:
{criteria}

Below are {len(evaluations)} evaluations from an evaluator agent:

{combined_evaluations}{description_section}

Please review all the information provided above, which may contain discordant information, and summarize the main recurring points.
Based on your analysis, provide a final score for each criterion.

For each criterion, provide:
1. A summary of the main recurring points across all the provided information
2. Your final numerical score (0-10)
3. A brief justification for your score

Then, provide the final answer in <answer> </answer>."""
    if has_audio:
        output += f"""
For example: <answer>a, b, c, d, e, f</answer> (i.e., criterion 1,2,3,4,5,6 respectively have scores a/10, b/10, c/10, d/10, e/10, f/10)."""
    else:
        output += f"""
For example: <answer>a, b, c, d, e</answer> (i.e., criterion 1,2,3,4,5 respectively have scores a/10, b/10, c/10, d/10, e/10)."""

    return output

############
# Feedback #
############


def get_description_feedback(system_prompt, llm, video_path, audio_path=None, max_tokens=1024, seed=42, temp_feedback=0.7, direct=False, top_p=0.95, top_k=-1, repetition_penalty=1.0):
    """
    Get feedback on the content from the evaluator model.
    
    Args:
        system_prompt: System prompt for the LLM
        llm: The evaluator model (must support video)
        video_path: Path to the content video
        audio_path: Path to the audio file (optional)
        max_tokens: Maximum number of tokens to generate
        seed: Random seed for generation
    
    Returns:
        Feedback from the evaluator and updated seed
    """
    print(f"Getting description from evaluator model...")
    
    # Construct the text part of the prompt
    text_prompt = describe_content(has_audio=llm.model_process_audio)

    if system_prompt is not None:
        messages = [{"role": "system", "content": system_prompt}]
    else:
        messages = []
    
    # Create a multimodal prompt for the evaluator model with video (and audio if enabled)
    messages = create_multimodal_prompt_for_qwen(
        text_prompt, 
        video_path=video_path,
        audio_path=audio_path,
        messages=messages,
        sampling_rate=llm.sampling_rate
    )
    
    # Generate the response
    sampling_params = SamplingParams(
        temperature=temp_feedback,
        top_p=top_p,
        top_k=top_k,
        repetition_penalty=repetition_penalty,
        max_tokens=max_tokens,
        seed=seed
    )
    
    # Increment seed for next generation to ensure different outputs
    seed += 1
    
    # Standard generation for server or non-audio models
    response = llm.generate(messages, sampling_params)
    
    feedback = response[0].outputs[0].text
    if not direct:
        feedback = f"""AUDIO-VISUAL DESCRIPTION (from a text+video+audio model):
{feedback}

"""

    return feedback, seed

def get_technical_feedback(system_prompt, llm, current_code, content_description, content_type="video-game", max_tokens=1024, console_logs_path=None, seed=42, asset_info=None, temp_feedback=0.7, top_p=0.95, top_k=-1, repetition_penalty=1.0, cdn_allowed=True):
    """
    Get technical implementation feedback from the coding LLM.
    
    Args:
        system_prompt: System prompt for the LLM
        llm: The coding LLM
        current_code: Current HTML code of the content
        content_description: Description of the content
        content_type: Type of content ("video-game", "animation", or "website")
        max_tokens: Maximum number of tokens to generate
        console_logs_path: Path to the console logs file (optional)
        seed: Random seed for generation
        asset_info: Asset information for prompts (optional)
        cdn_allowed: Whether to allow CDN libraries
    
    Returns:
        Technical feedback from the coding LLM and updated seed
    """
    print(f"Getting technical implementation feedback from coding model...")
    
    # Get console logs section
    console_logs_section = get_console_logs_section(console_logs_path)
    
    # Construct the text part of the prompt
    text_prompt = get_technical_feedback_prompt(content_description, content_type, current_code, console_logs_section, asset_info, cdn_allowed)

    if system_prompt is not None:
        messages = [{"role": "system", "content": system_prompt}]
    else:
        messages = []
    
    messages.append({"role": "user", "content": text_prompt})
    
    # Generate the response
    sampling_params = SamplingParams(
        temperature=temp_feedback,
        top_p=top_p,
        top_k=top_k,
        repetition_penalty=repetition_penalty,
        max_tokens=max_tokens,
        seed=seed
    )
    
    # Increment seed for next generation to ensure different outputs
    seed += 1
    
    # Standard generation
    response = llm.generate(messages, sampling_params)
    
    feedback = response[0].outputs[0].text
    
    feedback = f"""TECHNICAL FEEDBACK (from a coding model):
{feedback}

"""

    return feedback, seed

def get_evaluator_feedback(system_prompt, llm, video_path, content_description, audio_path=None, content_type="video-game", max_tokens=1024, console_logs_path=None, seed=42, exclude_technical=False, current_code=None, asset_info=None, temp_feedback=0.7, top_p=0.95, top_k=-1, repetition_penalty=1.0):
    """
    Get feedback on the content from the evaluator model.
    
    Args:
        system_prompt: System prompt for the LLM
        llm: The evaluator model (must support video)
        video_path: Path to the content video
        content_description: Description of the content
        audio_path: Path to the audio file (optional)
        content_type: Type of content ("video-game", "animation", or "website")
        max_tokens: Maximum number of tokens to generate
        console_logs_path: Path to the console logs file (optional)
        seed: Random seed for generation
        exclude_technical: Whether to exclude technical implementation feedback
        current_code: Current HTML code of the content
        asset_info: Asset information for prompts (optional)
    
    Returns:
        Feedback from the evaluator and updated seed
    """
    print(f"Getting feedback from evaluator model...")
    
    # Construct the text part of the prompt
    text_prompt = get_evaluator_feedback_prompt(content_description, content_type, llm.model_process_audio, exclude_technical, current_code, asset_info)

    if system_prompt is not None:
        messages = [{"role": "system", "content": system_prompt}]
    else:
        messages = []
    
    # Create a multimodal prompt for the evaluator model with video (and audio if enabled)
    messages = create_multimodal_prompt_for_qwen(
        text_prompt, 
        video_path=video_path,
        audio_path=audio_path,
        messages=messages,
        sampling_rate=llm.sampling_rate
    )
    
    # Generate the response
    sampling_params = SamplingParams(
        temperature=temp_feedback,
        top_p=top_p,
        top_k=top_k,
        repetition_penalty=repetition_penalty,
        max_tokens=max_tokens,
        seed=seed
    )
    
    # Increment seed for next generation to ensure different outputs
    seed += 1
    
    # Standard generation for server or non-audio models
    response = llm.generate(messages, sampling_params)
    
    feedback = response[0].outputs[0].text
    
    feedback = f"""AUDIO-VISUAL FEEDBACK (from a text+video+audio model):
{feedback}

"""

    return feedback, seed
